Commit 62486c35a4

Andrew Kelley <andrew@ziglang.org>
2019-03-12 22:32:32
ability to build musl from source
bundles musl 1.1.21 See #514
1 parent 5734b7a
Changed files (1801)
libc
musl
src
aio
complex
conf
crypt
ctype
dirent
env
errno
exit
fcntl
fenv
include
internal
ipc
ldso
legacy
linux
locale
malloc
math
aarch64
arm
i386
powerpc
powerpc64
s390x
x32
x86_64
misc
mman
mq
multibyte
network
passwd
prng
process
regex
sched
search
select
setjmp
signal
stat
stdio
stdlib
string
temp
termios
thread
aarch64
arm
i386
m68k
microblaze
mips
mips64
mipsn32
or1k
powerpc
powerpc64
s390x
sh
x32
x86_64
time
unistd
src
libc/musl/src/aio/aio.c
@@ -0,0 +1,400 @@
+#include <aio.h>
+#include <pthread.h>
+#include <semaphore.h>
+#include <limits.h>
+#include <errno.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <sys/auxv.h>
+#include "syscall.h"
+#include "atomic.h"
+#include "pthread_impl.h"
+
+/* The following is a threads-based implementation of AIO with minimal
+ * dependence on implementation details. Most synchronization is
+ * performed with pthread primitives, but atomics and futex operations
+ * are used for notification in a couple places where the pthread
+ * primitives would be inefficient or impractical.
+ *
+ * For each fd with outstanding aio operations, an aio_queue structure
+ * is maintained. These are reference-counted and destroyed by the last
+ * aio worker thread to exit. Accessing any member of the aio_queue
+ * structure requires a lock on the aio_queue. Adding and removing aio
+ * queues themselves requires a write lock on the global map object,
+ * a 4-level table mapping file descriptor numbers to aio queues. A
+ * read lock on the map is used to obtain locks on existing queues by
+ * excluding destruction of the queue by a different thread while it is
+ * being locked.
+ *
+ * Each aio queue has a list of active threads/operations. Presently there
+ * is a one to one relationship between threads and operations. The only
+ * members of the aio_thread structure which are accessed by other threads
+ * are the linked list pointers, op (which is immutable), running (which
+ * is updated atomically), and err (which is synchronized via running),
+ * so no locking is necessary. Most of the other other members are used
+ * for sharing data between the main flow of execution and cancellation
+ * cleanup handler.
+ *
+ * Taking any aio locks requires having all signals blocked. This is
+ * necessary because aio_cancel is needed by close, and close is required
+ * to be async-signal safe. All aio worker threads run with all signals
+ * blocked permanently.
+ */
+
+struct aio_thread {
+	pthread_t td;
+	struct aiocb *cb;
+	struct aio_thread *next, *prev;
+	struct aio_queue *q;
+	volatile int running;
+	int err, op;
+	ssize_t ret;
+};
+
+struct aio_queue {
+	int fd, seekable, append, ref, init;
+	pthread_mutex_t lock;
+	pthread_cond_t cond;
+	struct aio_thread *head;
+};
+
+struct aio_args {
+	struct aiocb *cb;
+	struct aio_queue *q;
+	int op;
+	sem_t sem;
+};
+
+static pthread_rwlock_t maplock = PTHREAD_RWLOCK_INITIALIZER;
+static struct aio_queue *****map;
+static volatile int aio_fd_cnt;
+volatile int __aio_fut;
+
+static struct aio_queue *__aio_get_queue(int fd, int need)
+{
+	if (fd < 0) {
+		errno = EBADF;
+		return 0;
+	}
+	int a=fd>>24;
+	unsigned char b=fd>>16, c=fd>>8, d=fd;
+	struct aio_queue *q = 0;
+	pthread_rwlock_rdlock(&maplock);
+	if ((!map || !map[a] || !map[a][b] || !map[a][b][c] || !(q=map[a][b][c][d])) && need) {
+		pthread_rwlock_unlock(&maplock);
+		if (fcntl(fd, F_GETFD) < 0) return 0;
+		pthread_rwlock_wrlock(&maplock);
+		if (!map) map = calloc(sizeof *map, (-1U/2+1)>>24);
+		if (!map) goto out;
+		if (!map[a]) map[a] = calloc(sizeof **map, 256);
+		if (!map[a]) goto out;
+		if (!map[a][b]) map[a][b] = calloc(sizeof ***map, 256);
+		if (!map[a][b]) goto out;
+		if (!map[a][b][c]) map[a][b][c] = calloc(sizeof ****map, 256);
+		if (!map[a][b][c]) goto out;
+		if (!(q = map[a][b][c][d])) {
+			map[a][b][c][d] = q = calloc(sizeof *****map, 1);
+			if (q) {
+				q->fd = fd;
+				pthread_mutex_init(&q->lock, 0);
+				pthread_cond_init(&q->cond, 0);
+				a_inc(&aio_fd_cnt);
+			}
+		}
+	}
+	if (q) pthread_mutex_lock(&q->lock);
+out:
+	pthread_rwlock_unlock(&maplock);
+	return q;
+}
+
+static void __aio_unref_queue(struct aio_queue *q)
+{
+	if (q->ref > 1) {
+		q->ref--;
+		pthread_mutex_unlock(&q->lock);
+		return;
+	}
+
+	/* This is potentially the last reference, but a new reference
+	 * may arrive since we cannot free the queue object without first
+	 * taking the maplock, which requires releasing the queue lock. */
+	pthread_mutex_unlock(&q->lock);
+	pthread_rwlock_wrlock(&maplock);
+	pthread_mutex_lock(&q->lock);
+	if (q->ref == 1) {
+		int fd=q->fd;
+		int a=fd>>24;
+		unsigned char b=fd>>16, c=fd>>8, d=fd;
+		map[a][b][c][d] = 0;
+		a_dec(&aio_fd_cnt);
+		pthread_rwlock_unlock(&maplock);
+		pthread_mutex_unlock(&q->lock);
+		free(q);
+	} else {
+		q->ref--;
+		pthread_rwlock_unlock(&maplock);
+		pthread_mutex_unlock(&q->lock);
+	}
+}
+
+static void cleanup(void *ctx)
+{
+	struct aio_thread *at = ctx;
+	struct aio_queue *q = at->q;
+	struct aiocb *cb = at->cb;
+	struct sigevent sev = cb->aio_sigevent;
+
+	/* There are four potential types of waiters we could need to wake:
+	 *   1. Callers of aio_cancel/close.
+	 *   2. Callers of aio_suspend with a single aiocb.
+	 *   3. Callers of aio_suspend with a list.
+	 *   4. AIO worker threads waiting for sequenced operations.
+	 * Types 1-3 are notified via atomics/futexes, mainly for AS-safety
+	 * considerations. Type 4 is notified later via a cond var. */
+
+	cb->__ret = at->ret;
+	if (a_swap(&at->running, 0) < 0)
+		__wake(&at->running, -1, 1);
+	if (a_swap(&cb->__err, at->err) != EINPROGRESS)
+		__wake(&cb->__err, -1, 1);
+	if (a_swap(&__aio_fut, 0))
+		__wake(&__aio_fut, -1, 1);
+
+	pthread_mutex_lock(&q->lock);
+
+	if (at->next) at->next->prev = at->prev;
+	if (at->prev) at->prev->next = at->next;
+	else q->head = at->next;
+
+	/* Signal aio worker threads waiting for sequenced operations. */
+	pthread_cond_broadcast(&q->cond);
+
+	__aio_unref_queue(q);
+
+	if (sev.sigev_notify == SIGEV_SIGNAL) {
+		siginfo_t si = {
+			.si_signo = sev.sigev_signo,
+			.si_value = sev.sigev_value,
+			.si_code = SI_ASYNCIO,
+			.si_pid = getpid(),
+			.si_uid = getuid()
+		};
+		__syscall(SYS_rt_sigqueueinfo, si.si_pid, si.si_signo, &si);
+	}
+	if (sev.sigev_notify == SIGEV_THREAD) {
+		a_store(&__pthread_self()->cancel, 0);
+		sev.sigev_notify_function(sev.sigev_value);
+	}
+}
+
+static void *io_thread_func(void *ctx)
+{
+	struct aio_thread at, *p;
+
+	struct aio_args *args = ctx;
+	struct aiocb *cb = args->cb;
+	int fd = cb->aio_fildes;
+	int op = args->op;
+	void *buf = (void *)cb->aio_buf;
+	size_t len = cb->aio_nbytes;
+	off_t off = cb->aio_offset;
+
+	struct aio_queue *q = args->q;
+	ssize_t ret;
+
+	pthread_mutex_lock(&q->lock);
+	sem_post(&args->sem);
+
+	at.op = op;
+	at.running = 1;
+	at.ret = -1;
+	at.err = ECANCELED;
+	at.q = q;
+	at.td = __pthread_self();
+	at.cb = cb;
+	at.prev = 0;
+	if ((at.next = q->head)) at.next->prev = &at;
+	q->head = &at;
+
+	if (!q->init) {
+		int seekable = lseek(fd, 0, SEEK_CUR) >= 0;
+		q->seekable = seekable;
+		q->append = !seekable || (fcntl(fd, F_GETFL) & O_APPEND);
+		q->init = 1;
+	}
+
+	pthread_cleanup_push(cleanup, &at);
+
+	/* Wait for sequenced operations. */
+	if (op!=LIO_READ && (op!=LIO_WRITE || q->append)) {
+		for (;;) {
+			for (p=at.next; p && p->op!=LIO_WRITE; p=p->next);
+			if (!p) break;
+			pthread_cond_wait(&q->cond, &q->lock);
+		}
+	}
+
+	pthread_mutex_unlock(&q->lock);
+
+	switch (op) {
+	case LIO_WRITE:
+		ret = q->append ? write(fd, buf, len) : pwrite(fd, buf, len, off);
+		break;
+	case LIO_READ:
+		ret = !q->seekable ? read(fd, buf, len) : pread(fd, buf, len, off);
+		break;
+	case O_SYNC:
+		ret = fsync(fd);
+		break;
+	case O_DSYNC:
+		ret = fdatasync(fd);
+		break;
+	}
+	at.ret = ret;
+	at.err = ret<0 ? errno : 0;
+	
+	pthread_cleanup_pop(1);
+
+	return 0;
+}
+
+static size_t io_thread_stack_size = MINSIGSTKSZ+2048;
+static pthread_once_t init_stack_size_once;
+
+static void init_stack_size()
+{
+	unsigned long val = __getauxval(AT_MINSIGSTKSZ);
+	if (val > MINSIGSTKSZ) io_thread_stack_size = val + 512;
+}
+
+static int submit(struct aiocb *cb, int op)
+{
+	int ret = 0;
+	pthread_attr_t a;
+	sigset_t allmask, origmask;
+	pthread_t td;
+	struct aio_queue *q = __aio_get_queue(cb->aio_fildes, 1);
+	struct aio_args args = { .cb = cb, .op = op, .q = q };
+	sem_init(&args.sem, 0, 0);
+
+	if (!q) {
+		if (errno != EBADF) errno = EAGAIN;
+		cb->__ret = -1;
+		cb->__err = errno;
+		return -1;
+	}
+	q->ref++;
+	pthread_mutex_unlock(&q->lock);
+
+	if (cb->aio_sigevent.sigev_notify == SIGEV_THREAD) {
+		if (cb->aio_sigevent.sigev_notify_attributes)
+			a = *cb->aio_sigevent.sigev_notify_attributes;
+		else
+			pthread_attr_init(&a);
+	} else {
+		pthread_once(&init_stack_size_once, init_stack_size);
+		pthread_attr_init(&a);
+		pthread_attr_setstacksize(&a, io_thread_stack_size);
+		pthread_attr_setguardsize(&a, 0);
+	}
+	pthread_attr_setdetachstate(&a, PTHREAD_CREATE_DETACHED);
+	sigfillset(&allmask);
+	pthread_sigmask(SIG_BLOCK, &allmask, &origmask);
+	cb->__err = EINPROGRESS;
+	if (pthread_create(&td, &a, io_thread_func, &args)) {
+		pthread_mutex_lock(&q->lock);
+		__aio_unref_queue(q);
+		cb->__err = errno = EAGAIN;
+		cb->__ret = ret = -1;
+	}
+	pthread_sigmask(SIG_SETMASK, &origmask, 0);
+
+	if (!ret) {
+		while (sem_wait(&args.sem));
+	}
+
+	return ret;
+}
+
+int aio_read(struct aiocb *cb)
+{
+	return submit(cb, LIO_READ);
+}
+
+int aio_write(struct aiocb *cb)
+{
+	return submit(cb, LIO_WRITE);
+}
+
+int aio_fsync(int op, struct aiocb *cb)
+{
+	if (op != O_SYNC && op != O_DSYNC) {
+		errno = EINVAL;
+		return -1;
+	}
+	return submit(cb, op);
+}
+
+ssize_t aio_return(struct aiocb *cb)
+{
+	return cb->__ret;
+}
+
+int aio_error(const struct aiocb *cb)
+{
+	a_barrier();
+	return cb->__err & 0x7fffffff;
+}
+
+int aio_cancel(int fd, struct aiocb *cb)
+{
+	sigset_t allmask, origmask;
+	int ret = AIO_ALLDONE;
+	struct aio_thread *p;
+	struct aio_queue *q;
+
+	/* Unspecified behavior case. Report an error. */
+	if (cb && fd != cb->aio_fildes) {
+		errno = EINVAL;
+		return -1;
+	}
+
+	sigfillset(&allmask);
+	pthread_sigmask(SIG_BLOCK, &allmask, &origmask);
+
+	errno = ENOENT;
+	if (!(q = __aio_get_queue(fd, 0))) {
+		if (errno == EBADF) ret = -1;
+		goto done;
+	}
+
+	for (p = q->head; p; p = p->next) {
+		if (cb && cb != p->cb) continue;
+		/* Transition target from running to running-with-waiters */
+		if (a_cas(&p->running, 1, -1)) {
+			pthread_cancel(p->td);
+			__wait(&p->running, 0, -1, 1);
+			if (p->err == ECANCELED) ret = AIO_CANCELED;
+		}
+	}
+
+	pthread_mutex_unlock(&q->lock);
+done:
+	pthread_sigmask(SIG_SETMASK, &origmask, 0);
+	return ret;
+}
+
+int __aio_close(int fd)
+{
+	a_barrier();
+	if (aio_fd_cnt) aio_cancel(fd, 0);
+	return fd;
+}
+
+weak_alias(aio_cancel, aio_cancel64);
+weak_alias(aio_error, aio_error64);
+weak_alias(aio_fsync, aio_fsync64);
+weak_alias(aio_read, aio_read64);
+weak_alias(aio_write, aio_write64);
+weak_alias(aio_return, aio_return64);
libc/musl/src/aio/aio_suspend.c
@@ -0,0 +1,76 @@
+#include <aio.h>
+#include <errno.h>
+#include <time.h>
+#include "atomic.h"
+#include "pthread_impl.h"
+
+int aio_suspend(const struct aiocb *const cbs[], int cnt, const struct timespec *ts)
+{
+	int i, tid = 0, ret, expect = 0;
+	struct timespec at;
+	volatile int dummy_fut, *pfut;
+	int nzcnt = 0;
+	const struct aiocb *cb = 0;
+
+	pthread_testcancel();
+
+	if (cnt<0) {
+		errno = EINVAL;
+		return -1;
+	}
+
+	for (i=0; i<cnt; i++) if (cbs[i]) {
+		if (aio_error(cbs[i]) != EINPROGRESS) return 0;
+		nzcnt++;
+		cb = cbs[i];
+	}
+
+	if (ts) {
+		clock_gettime(CLOCK_MONOTONIC, &at);
+		at.tv_sec += ts->tv_sec;
+		if ((at.tv_nsec += ts->tv_nsec) >= 1000000000) {
+			at.tv_nsec -= 1000000000;
+			at.tv_sec++;
+		}
+	}
+
+	for (;;) {
+		for (i=0; i<cnt; i++)
+			if (cbs[i] && aio_error(cbs[i]) != EINPROGRESS)
+				return 0;
+
+		switch (nzcnt) {
+		case 0:
+			pfut = &dummy_fut;
+			break;
+		case 1:
+			pfut = (void *)&cb->__err;
+			expect = EINPROGRESS | 0x80000000;
+			a_cas(pfut, EINPROGRESS, expect);
+			break;
+		default:
+			pfut = &__aio_fut;
+			if (!tid) tid = __pthread_self()->tid;
+			expect = a_cas(pfut, 0, tid);
+			if (!expect) expect = tid;
+			/* Need to recheck the predicate before waiting. */
+			for (i=0; i<cnt; i++)
+				if (cbs[i] && aio_error(cbs[i]) != EINPROGRESS)
+					return 0;
+			break;
+		}
+
+		ret = __timedwait_cp(pfut, expect, CLOCK_MONOTONIC, ts?&at:0, 1);
+
+		switch (ret) {
+		case ETIMEDOUT:
+			ret = EAGAIN;
+		case ECANCELED:
+		case EINTR:
+			errno = ret;
+			return -1;
+		}
+	}
+}
+
+weak_alias(aio_suspend, aio_suspend64);
libc/musl/src/aio/lio_listio.c
@@ -0,0 +1,143 @@
+#include <aio.h>
+#include <errno.h>
+#include <unistd.h>
+#include <string.h>
+#include "pthread_impl.h"
+
+struct lio_state {
+	struct sigevent *sev;
+	int cnt;
+	struct aiocb *cbs[];
+};
+
+static int lio_wait(struct lio_state *st)
+{
+	int i, err, got_err = 0;
+	int cnt = st->cnt;
+	struct aiocb **cbs = st->cbs;
+
+	for (;;) {
+		for (i=0; i<cnt; i++) {
+			if (!cbs[i]) continue;
+			err = aio_error(cbs[i]);
+			if (err==EINPROGRESS)
+				break;
+			if (err) got_err=1;
+			cbs[i] = 0;
+		}
+		if (i==cnt) {
+			if (got_err) {
+				errno = EIO;
+				return -1;
+			}
+			return 0;
+		}
+		if (aio_suspend((void *)cbs, cnt, 0))
+			return -1;
+	}
+}
+
+static void notify_signal(struct sigevent *sev)
+{
+	siginfo_t si = {
+		.si_signo = sev->sigev_signo,
+		.si_value = sev->sigev_value,
+		.si_code = SI_ASYNCIO,
+		.si_pid = getpid(),
+		.si_uid = getuid()
+	};
+	__syscall(SYS_rt_sigqueueinfo, si.si_pid, si.si_signo, &si);
+}
+
+static void *wait_thread(void *p)
+{
+	struct lio_state *st = p;
+	struct sigevent *sev = st->sev;
+	lio_wait(st);
+	free(st);
+	switch (sev->sigev_notify) {
+	case SIGEV_SIGNAL:
+		notify_signal(sev);
+		break;
+	case SIGEV_THREAD:
+		sev->sigev_notify_function(sev->sigev_value);
+		break;
+	}
+	return 0;
+}
+
+int lio_listio(int mode, struct aiocb *restrict const *restrict cbs, int cnt, struct sigevent *restrict sev)
+{
+	int i, ret;
+	struct lio_state *st=0;
+
+	if (cnt < 0) {
+		errno = EINVAL;
+		return -1;
+	}
+
+	if (mode == LIO_WAIT || (sev && sev->sigev_notify != SIGEV_NONE)) {
+		if (!(st = malloc(sizeof *st + cnt*sizeof *cbs))) {
+			errno = EAGAIN;
+			return -1;
+		}
+		st->cnt = cnt;
+		st->sev = sev;
+		memcpy(st->cbs, (void*) cbs, cnt*sizeof *cbs);
+	}
+
+	for (i=0; i<cnt; i++) {
+		if (!cbs[i]) continue;
+		switch (cbs[i]->aio_lio_opcode) {
+		case LIO_READ:
+			ret = aio_read(cbs[i]);
+			break;
+		case LIO_WRITE:
+			ret = aio_write(cbs[i]);
+			break;
+		default:
+			continue;
+		}
+		if (ret) {
+			free(st);
+			errno = EAGAIN;
+			return -1;
+		}
+	}
+
+	if (mode == LIO_WAIT) {
+		ret = lio_wait(st);
+		free(st);
+		return ret;
+	}
+
+	if (st) {
+		pthread_attr_t a;
+		sigset_t set;
+		pthread_t td;
+
+		if (sev->sigev_notify == SIGEV_THREAD) {
+			if (sev->sigev_notify_attributes)
+				a = *sev->sigev_notify_attributes;
+			else
+				pthread_attr_init(&a);
+		} else {
+			pthread_attr_init(&a);
+			pthread_attr_setstacksize(&a, PAGE_SIZE);
+			pthread_attr_setguardsize(&a, 0);
+		}
+		pthread_attr_setdetachstate(&a, PTHREAD_CREATE_DETACHED);
+		sigfillset(&set);
+		pthread_sigmask(SIG_BLOCK, &set, &set);
+		if (pthread_create(&td, &a, wait_thread, st)) {
+			free(st);
+			errno = EAGAIN;
+			return -1;
+		}
+		pthread_sigmask(SIG_SETMASK, &set, 0);
+	}
+
+	return 0;
+}
+
+weak_alias(lio_listio, lio_listio64);
libc/musl/src/complex/__cexp.c
@@ -0,0 +1,87 @@
+/* origin: FreeBSD /usr/src/lib/msun/src/k_exp.c */
+/*-
+ * Copyright (c) 2011 David Schultz <das@FreeBSD.ORG>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include "libm.h"
+
+static const uint32_t k = 1799; /* constant for reduction */
+static const double kln2 = 1246.97177782734161156; /* k * ln2 */
+
+/*
+ * Compute exp(x), scaled to avoid spurious overflow.  An exponent is
+ * returned separately in 'expt'.
+ *
+ * Input:  ln(DBL_MAX) <= x < ln(2 * DBL_MAX / DBL_MIN_DENORM) ~= 1454.91
+ * Output: 2**1023 <= y < 2**1024
+ */
+static double __frexp_exp(double x, int *expt)
+{
+	double exp_x;
+	uint32_t hx;
+
+	/*
+	 * We use exp(x) = exp(x - kln2) * 2**k, carefully chosen to
+	 * minimize |exp(kln2) - 2**k|.  We also scale the exponent of
+	 * exp_x to MAX_EXP so that the result can be multiplied by
+	 * a tiny number without losing accuracy due to denormalization.
+	 */
+	exp_x = exp(x - kln2);
+	GET_HIGH_WORD(hx, exp_x);
+	*expt = (hx >> 20) - (0x3ff + 1023) + k;
+	SET_HIGH_WORD(exp_x, (hx & 0xfffff) | ((0x3ff + 1023) << 20));
+	return exp_x;
+}
+
+/*
+ * __ldexp_cexp(x, expt) compute exp(x) * 2**expt.
+ * It is intended for large arguments (real part >= ln(DBL_MAX))
+ * where care is needed to avoid overflow.
+ *
+ * The present implementation is narrowly tailored for our hyperbolic and
+ * exponential functions.  We assume expt is small (0 or -1), and the caller
+ * has filtered out very large x, for which overflow would be inevitable.
+ */
+double complex __ldexp_cexp(double complex z, int expt)
+{
+	double x, y, exp_x, scale1, scale2;
+	int ex_expt, half_expt;
+
+	x = creal(z);
+	y = cimag(z);
+	exp_x = __frexp_exp(x, &ex_expt);
+	expt += ex_expt;
+
+	/*
+	 * Arrange so that scale1 * scale2 == 2**expt.  We use this to
+	 * compensate for scalbn being horrendously slow.
+	 */
+	half_expt = expt / 2;
+	INSERT_WORDS(scale1, (0x3ff + half_expt) << 20, 0);
+	half_expt = expt - half_expt;
+	INSERT_WORDS(scale2, (0x3ff + half_expt) << 20, 0);
+
+	return CMPLX(cos(y) * exp_x * scale1 * scale2, sin(y) * exp_x * scale1 * scale2);
+}
libc/musl/src/complex/__cexpf.c
@@ -0,0 +1,68 @@
+/* origin: FreeBSD /usr/src/lib/msun/src/k_expf.c */
+/*-
+ * Copyright (c) 2011 David Schultz <das@FreeBSD.ORG>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include "libm.h"
+
+static const uint32_t k = 235; /* constant for reduction */
+static const float kln2 = 162.88958740F; /* k * ln2 */
+
+/*
+ * See __cexp.c for details.
+ *
+ * Input:  ln(FLT_MAX) <= x < ln(2 * FLT_MAX / FLT_MIN_DENORM) ~= 192.7
+ * Output: 2**127 <= y < 2**128
+ */
+static float __frexp_expf(float x, int *expt)
+{
+	float exp_x;
+	uint32_t hx;
+
+	exp_x = expf(x - kln2);
+	GET_FLOAT_WORD(hx, exp_x);
+	*expt = (hx >> 23) - (0x7f + 127) + k;
+	SET_FLOAT_WORD(exp_x, (hx & 0x7fffff) | ((0x7f + 127) << 23));
+	return exp_x;
+}
+
+float complex __ldexp_cexpf(float complex z, int expt)
+{
+	float x, y, exp_x, scale1, scale2;
+	int ex_expt, half_expt;
+
+	x = crealf(z);
+	y = cimagf(z);
+	exp_x = __frexp_expf(x, &ex_expt);
+	expt += ex_expt;
+
+	half_expt = expt / 2;
+	SET_FLOAT_WORD(scale1, (0x7f + half_expt) << 23);
+	half_expt = expt - half_expt;
+	SET_FLOAT_WORD(scale2, (0x7f + half_expt) << 23);
+
+	return CMPLXF(cosf(y) * exp_x * scale1 * scale2,
+	  sinf(y) * exp_x * scale1 * scale2);
+}
libc/musl/src/complex/cabs.c
@@ -0,0 +1,6 @@
+#include "libm.h"
+
+double cabs(double complex z)
+{
+	return hypot(creal(z), cimag(z));
+}
libc/musl/src/complex/cabsf.c
@@ -0,0 +1,6 @@
+#include "libm.h"
+
+float cabsf(float complex z)
+{
+	return hypotf(crealf(z), cimagf(z));
+}
libc/musl/src/complex/cabsl.c
@@ -0,0 +1,13 @@
+#include "libm.h"
+
+#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024
+long double cabsl(long double complex z)
+{
+	return cabs(z);
+}
+#else
+long double cabsl(long double complex z)
+{
+	return hypotl(creall(z), cimagl(z));
+}
+#endif
libc/musl/src/complex/cacos.c
@@ -0,0 +1,11 @@
+#include "libm.h"
+
+// FIXME: Hull et al. "Implementing the complex arcsine and arccosine functions using exception handling" 1997
+
+/* acos(z) = pi/2 - asin(z) */
+
+double complex cacos(double complex z)
+{
+	z = casin(z);
+	return CMPLX(M_PI_2 - creal(z), -cimag(z));
+}
libc/musl/src/complex/cacosf.c
@@ -0,0 +1,9 @@
+#include "libm.h"
+
+// FIXME
+
+float complex cacosf(float complex z)
+{
+	z = casinf(z);
+	return CMPLXF((float)M_PI_2 - crealf(z), -cimagf(z));
+}
libc/musl/src/complex/cacosh.c
@@ -0,0 +1,9 @@
+#include "libm.h"
+
+/* acosh(z) = i acos(z) */
+
+double complex cacosh(double complex z)
+{
+	z = cacos(z);
+	return CMPLX(-cimag(z), creal(z));
+}
libc/musl/src/complex/cacoshf.c
@@ -0,0 +1,7 @@
+#include "libm.h"
+
+float complex cacoshf(float complex z)
+{
+	z = cacosf(z);
+	return CMPLXF(-cimagf(z), crealf(z));
+}
libc/musl/src/complex/cacoshl.c
@@ -0,0 +1,14 @@
+#include "libm.h"
+
+#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024
+long double complex cacoshl(long double complex z)
+{
+	return cacosh(z);
+}
+#else
+long double complex cacoshl(long double complex z)
+{
+	z = cacosl(z);
+	return CMPLXL(-cimagl(z), creall(z));
+}
+#endif
libc/musl/src/complex/cacosl.c
@@ -0,0 +1,16 @@
+#include "libm.h"
+
+#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024
+long double complex cacosl(long double complex z)
+{
+	return cacos(z);
+}
+#else
+// FIXME
+#define PI_2 1.57079632679489661923132169163975144L
+long double complex cacosl(long double complex z)
+{
+	z = casinl(z);
+	return CMPLXL(PI_2 - creall(z), -cimagl(z));
+}
+#endif
libc/musl/src/complex/carg.c
@@ -0,0 +1,6 @@
+#include "libm.h"
+
+double carg(double complex z)
+{
+	return atan2(cimag(z), creal(z));
+}
libc/musl/src/complex/cargf.c
@@ -0,0 +1,6 @@
+#include "libm.h"
+
+float cargf(float complex z)
+{
+	return atan2f(cimagf(z), crealf(z));
+}
libc/musl/src/complex/cargl.c
@@ -0,0 +1,13 @@
+#include "libm.h"
+
+#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024
+long double cargl(long double complex z)
+{
+	return carg(z);
+}
+#else
+long double cargl(long double complex z)
+{
+	return atan2l(cimagl(z), creall(z));
+}
+#endif
libc/musl/src/complex/casin.c
@@ -0,0 +1,17 @@
+#include "libm.h"
+
+// FIXME
+
+/* asin(z) = -i log(i z + sqrt(1 - z*z)) */
+
+double complex casin(double complex z)
+{
+	double complex w;
+	double x, y;
+
+	x = creal(z);
+	y = cimag(z);
+	w = CMPLX(1.0 - (x - y)*(x + y), -2.0*x*y);
+	double complex r = clog(CMPLX(-y, x) + csqrt(w));
+	return CMPLX(cimag(r), -creal(r));
+}
libc/musl/src/complex/casinf.c
@@ -0,0 +1,15 @@
+#include "libm.h"
+
+// FIXME
+
+float complex casinf(float complex z)
+{
+	float complex w;
+	float x, y;
+
+	x = crealf(z);
+	y = cimagf(z);
+	w = CMPLXF(1.0 - (x - y)*(x + y), -2.0*x*y);
+	float complex r = clogf(CMPLXF(-y, x) + csqrtf(w));
+	return CMPLXF(cimagf(r), -crealf(r));
+}
libc/musl/src/complex/casinh.c
@@ -0,0 +1,9 @@
+#include "libm.h"
+
+/* asinh(z) = -i asin(i z) */
+
+double complex casinh(double complex z)
+{
+	z = casin(CMPLX(-cimag(z), creal(z)));
+	return CMPLX(cimag(z), -creal(z));
+}
libc/musl/src/complex/casinhf.c
@@ -0,0 +1,7 @@
+#include "libm.h"
+
+float complex casinhf(float complex z)
+{
+	z = casinf(CMPLXF(-cimagf(z), crealf(z)));
+	return CMPLXF(cimagf(z), -crealf(z));
+}
libc/musl/src/complex/casinhl.c
@@ -0,0 +1,14 @@
+#include "libm.h"
+
+#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024
+long double complex casinhl(long double complex z)
+{
+	return casinh(z);
+}
+#else
+long double complex casinhl(long double complex z)
+{
+	z = casinl(CMPLXL(-cimagl(z), creall(z)));
+	return CMPLXL(cimagl(z), -creall(z));
+}
+#endif
libc/musl/src/complex/casinl.c
@@ -0,0 +1,21 @@
+#include "libm.h"
+
+#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024
+long double complex casinl(long double complex z)
+{
+	return casin(z);
+}
+#else
+// FIXME
+long double complex casinl(long double complex z)
+{
+	long double complex w;
+	long double x, y;
+
+	x = creall(z);
+	y = cimagl(z);
+	w = CMPLXL(1.0 - (x - y)*(x + y), -2.0*x*y);
+	long double complex r = clogl(CMPLXL(-y, x) + csqrtl(w));
+	return CMPLXL(cimagl(r), -creall(r));
+}
+#endif
libc/musl/src/complex/catan.c
@@ -0,0 +1,107 @@
+/* origin: OpenBSD /usr/src/lib/libm/src/s_catan.c */
+/*
+ * Copyright (c) 2008 Stephen L. Moshier <steve@moshier.net>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+/*
+ *      Complex circular arc tangent
+ *
+ *
+ * SYNOPSIS:
+ *
+ * double complex catan();
+ * double complex z, w;
+ *
+ * w = catan (z);
+ *
+ *
+ * DESCRIPTION:
+ *
+ * If
+ *     z = x + iy,
+ *
+ * then
+ *          1       (    2x     )
+ * Re w  =  - arctan(-----------)  +  k PI
+ *          2       (     2    2)
+ *                  (1 - x  - y )
+ *
+ *               ( 2         2)
+ *          1    (x  +  (y+1) )
+ * Im w  =  - log(------------)
+ *          4    ( 2         2)
+ *               (x  +  (y-1) )
+ *
+ * Where k is an arbitrary integer.
+ *
+ * catan(z) = -i catanh(iz).
+ *
+ * ACCURACY:
+ *
+ *                      Relative error:
+ * arithmetic   domain     # trials      peak         rms
+ *    DEC       -10,+10      5900       1.3e-16     7.8e-18
+ *    IEEE      -10,+10     30000       2.3e-15     8.5e-17
+ * The check catan( ctan(z) )  =  z, with |x| and |y| < PI/2,
+ * had peak relative error 1.5e-16, rms relative error
+ * 2.9e-17.  See also clog().
+ */
+
+#include "libm.h"
+
+#define MAXNUM 1.0e308
+
+static const double DP1 = 3.14159265160560607910E0;
+static const double DP2 = 1.98418714791870343106E-9;
+static const double DP3 = 1.14423774522196636802E-17;
+
+static double _redupi(double x)
+{
+	double t;
+	long i;
+
+	t = x/M_PI;
+	if (t >= 0.0)
+		t += 0.5;
+	else
+		t -= 0.5;
+
+	i = t;  /* the multiple */
+	t = i;
+	t = ((x - t * DP1) - t * DP2) - t * DP3;
+	return t;
+}
+
+double complex catan(double complex z)
+{
+	double complex w;
+	double a, t, x, x2, y;
+
+	x = creal(z);
+	y = cimag(z);
+
+	x2 = x * x;
+	a = 1.0 - x2 - (y * y);
+
+	t = 0.5 * atan2(2.0 * x, a);
+	w = _redupi(t);
+
+	t = y - 1.0;
+	a = x2 + (t * t);
+
+	t = y + 1.0;
+	a = (x2 + t * t)/a;
+	w = CMPLX(w, 0.25 * log(a));
+	return w;
+}
libc/musl/src/complex/catanf.c
@@ -0,0 +1,115 @@
+/* origin: OpenBSD /usr/src/lib/libm/src/s_catanf.c */
+/*
+ * Copyright (c) 2008 Stephen L. Moshier <steve@moshier.net>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+/*
+ *      Complex circular arc tangent
+ *
+ *
+ * SYNOPSIS:
+ *
+ * float complex catanf();
+ * float complex z, w;
+ *
+ * w = catanf( z );
+ *
+ *
+ * DESCRIPTION:
+ *
+ * If
+ *     z = x + iy,
+ *
+ * then
+ *          1       (    2x     )
+ * Re w  =  - arctan(-----------)  +  k PI
+ *          2       (     2    2)
+ *                  (1 - x  - y )
+ *
+ *               ( 2         2)
+ *          1    (x  +  (y+1) )
+ * Im w  =  - log(------------)
+ *          4    ( 2         2)
+ *               (x  +  (y-1) )
+ *
+ * Where k is an arbitrary integer.
+ *
+ *
+ * ACCURACY:
+ *
+ *                      Relative error:
+ * arithmetic   domain     # trials      peak         rms
+ *    IEEE      -10,+10     30000        2.3e-6      5.2e-8
+ */
+
+#include "libm.h"
+
+#define MAXNUMF 1.0e38F
+
+static const double DP1 = 3.140625;
+static const double DP2 = 9.67502593994140625E-4;
+static const double DP3 = 1.509957990978376432E-7;
+
+static float _redupif(float xx)
+{
+	float x, t;
+	long i;
+
+	x = xx;
+	t = x/(float)M_PI;
+	if (t >= 0.0f)
+		t += 0.5f;
+	else
+		t -= 0.5f;
+
+	i = t;  /* the multiple */
+	t = i;
+	t = ((x - t * DP1) - t * DP2) - t * DP3;
+	return t;
+}
+
+float complex catanf(float complex z)
+{
+	float complex w;
+	float a, t, x, x2, y;
+
+	x = crealf(z);
+	y = cimagf(z);
+
+	if ((x == 0.0f) && (y > 1.0f))
+		goto ovrf;
+
+	x2 = x * x;
+	a = 1.0f - x2 - (y * y);
+	if (a == 0.0f)
+		goto ovrf;
+
+	t = 0.5f * atan2f(2.0f * x, a);
+	w = _redupif(t);
+
+	t = y - 1.0f;
+	a = x2 + (t * t);
+	if (a == 0.0f)
+		goto ovrf;
+
+	t = y + 1.0f;
+	a = (x2 + (t * t))/a;
+	w = w + (0.25f * logf (a)) * I;
+	return w;
+
+ovrf:
+	// FIXME
+	w = MAXNUMF + MAXNUMF * I;
+	return w;
+}
libc/musl/src/complex/catanh.c
@@ -0,0 +1,9 @@
+#include "libm.h"
+
+/* atanh = -i atan(i z) */
+
+double complex catanh(double complex z)
+{
+	z = catan(CMPLX(-cimag(z), creal(z)));
+	return CMPLX(cimag(z), -creal(z));
+}
libc/musl/src/complex/catanhf.c
@@ -0,0 +1,7 @@
+#include "libm.h"
+
+float complex catanhf(float complex z)
+{
+	z = catanf(CMPLXF(-cimagf(z), crealf(z)));
+	return CMPLXF(cimagf(z), -crealf(z));
+}
libc/musl/src/complex/catanhl.c
@@ -0,0 +1,14 @@
+#include "libm.h"
+
+#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024
+long double complex catanhl(long double complex z)
+{
+	return catanh(z);
+}
+#else
+long double complex catanhl(long double complex z)
+{
+	z = catanl(CMPLXL(-cimagl(z), creall(z)));
+	return CMPLXL(cimagl(z), -creall(z));
+}
+#endif
libc/musl/src/complex/catanl.c
@@ -0,0 +1,126 @@
+/* origin: OpenBSD /usr/src/lib/libm/src/s_catanl.c */
+/*
+ * Copyright (c) 2008 Stephen L. Moshier <steve@moshier.net>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+/*
+ *      Complex circular arc tangent
+ *
+ *
+ * SYNOPSIS:
+ *
+ * long double complex catanl();
+ * long double complex z, w;
+ *
+ * w = catanl( z );
+ *
+ *
+ * DESCRIPTION:
+ *
+ * If
+ *     z = x + iy,
+ *
+ * then
+ *          1       (    2x     )
+ * Re w  =  - arctan(-----------)  +  k PI
+ *          2       (     2    2)
+ *                  (1 - x  - y )
+ *
+ *               ( 2         2)
+ *          1    (x  +  (y+1) )
+ * Im w  =  - log(------------)
+ *          4    ( 2         2)
+ *               (x  +  (y-1) )
+ *
+ * Where k is an arbitrary integer.
+ *
+ *
+ * ACCURACY:
+ *
+ *                      Relative error:
+ * arithmetic   domain     # trials      peak         rms
+ *    DEC       -10,+10      5900       1.3e-16     7.8e-18
+ *    IEEE      -10,+10     30000       2.3e-15     8.5e-17
+ * The check catan( ctan(z) )  =  z, with |x| and |y| < PI/2,
+ * had peak relative error 1.5e-16, rms relative error
+ * 2.9e-17.  See also clog().
+ */
+
+#include <complex.h>
+#include <float.h>
+#include "libm.h"
+
+#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024
+long double complex catanl(long double complex z)
+{
+	return catan(z);
+}
+#else
+static const long double PIL = 3.141592653589793238462643383279502884197169L;
+static const long double DP1 = 3.14159265358979323829596852490908531763125L;
+static const long double DP2 = 1.6667485837041756656403424829301998703007e-19L;
+static const long double DP3 = 1.8830410776607851167459095484560349402753e-39L;
+
+static long double redupil(long double x)
+{
+	long double t;
+	long i;
+
+	t = x / PIL;
+	if (t >= 0.0L)
+		t += 0.5L;
+	else
+		t -= 0.5L;
+
+	i = t;  /* the multiple */
+	t = i;
+	t = ((x - t * DP1) - t * DP2) - t * DP3;
+	return t;
+}
+
+long double complex catanl(long double complex z)
+{
+	long double complex w;
+	long double a, t, x, x2, y;
+
+	x = creall(z);
+	y = cimagl(z);
+
+	if ((x == 0.0L) && (y > 1.0L))
+		goto ovrf;
+
+	x2 = x * x;
+	a = 1.0L - x2 - (y * y);
+	if (a == 0.0L)
+		goto ovrf;
+
+	t = atan2l(2.0L * x, a) * 0.5L;
+	w = redupil(t);
+
+	t = y - 1.0L;
+	a = x2 + (t * t);
+	if (a == 0.0L)
+		goto ovrf;
+
+	t = y + 1.0L;
+	a = (x2 + (t * t)) / a;
+	w = w + (0.25L * logl(a)) * I;
+	return w;
+
+ovrf:
+	// FIXME
+	w = LDBL_MAX + LDBL_MAX * I;
+	return w;
+}
+#endif
libc/musl/src/complex/ccos.c
@@ -0,0 +1,8 @@
+#include "libm.h"
+
+/* cos(z) = cosh(i z) */
+
+double complex ccos(double complex z)
+{
+	return ccosh(CMPLX(-cimag(z), creal(z)));
+}
libc/musl/src/complex/ccosf.c
@@ -0,0 +1,6 @@
+#include "libm.h"
+
+float complex ccosf(float complex z)
+{
+	return ccoshf(CMPLXF(-cimagf(z), crealf(z)));
+}
libc/musl/src/complex/ccosh.c
@@ -0,0 +1,140 @@
+/* origin: FreeBSD /usr/src/lib/msun/src/s_ccosh.c */
+/*-
+ * Copyright (c) 2005 Bruce D. Evans and Steven G. Kargl
+ * 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 unmodified, this list of conditions, and the following
+ *    disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR 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.
+ */
+/*
+ * Hyperbolic cosine of a complex argument z = x + i y.
+ *
+ * cosh(z) = cosh(x+iy)
+ *         = cosh(x) cos(y) + i sinh(x) sin(y).
+ *
+ * Exceptional values are noted in the comments within the source code.
+ * These values and the return value were taken from n1124.pdf.
+ */
+
+#include "libm.h"
+
+static const double huge = 0x1p1023;
+
+double complex ccosh(double complex z)
+{
+	double x, y, h;
+	int32_t hx, hy, ix, iy, lx, ly;
+
+	x = creal(z);
+	y = cimag(z);
+
+	EXTRACT_WORDS(hx, lx, x);
+	EXTRACT_WORDS(hy, ly, y);
+
+	ix = 0x7fffffff & hx;
+	iy = 0x7fffffff & hy;
+
+	/* Handle the nearly-non-exceptional cases where x and y are finite. */
+	if (ix < 0x7ff00000 && iy < 0x7ff00000) {
+		if ((iy | ly) == 0)
+			return CMPLX(cosh(x), x * y);
+		if (ix < 0x40360000)    /* small x: normal case */
+			return CMPLX(cosh(x) * cos(y), sinh(x) * sin(y));
+
+		/* |x| >= 22, so cosh(x) ~= exp(|x|) */
+		if (ix < 0x40862e42) {
+			/* x < 710: exp(|x|) won't overflow */
+			h = exp(fabs(x)) * 0.5;
+			return CMPLX(h * cos(y), copysign(h, x) * sin(y));
+		} else if (ix < 0x4096bbaa) {
+			/* x < 1455: scale to avoid overflow */
+			z = __ldexp_cexp(CMPLX(fabs(x), y), -1);
+			return CMPLX(creal(z), cimag(z) * copysign(1, x));
+		} else {
+			/* x >= 1455: the result always overflows */
+			h = huge * x;
+			return CMPLX(h * h * cos(y), h * sin(y));
+		}
+	}
+
+	/*
+	 * cosh(+-0 +- I Inf) = dNaN + I sign(d(+-0, dNaN))0.
+	 * The sign of 0 in the result is unspecified.  Choice = normally
+	 * the same as dNaN.  Raise the invalid floating-point exception.
+	 *
+	 * cosh(+-0 +- I NaN) = d(NaN) + I sign(d(+-0, NaN))0.
+	 * The sign of 0 in the result is unspecified.  Choice = normally
+	 * the same as d(NaN).
+	 */
+	if ((ix | lx) == 0 && iy >= 0x7ff00000)
+		return CMPLX(y - y, copysign(0, x * (y - y)));
+
+	/*
+	 * cosh(+-Inf +- I 0) = +Inf + I (+-)(+-)0.
+	 *
+	 * cosh(NaN +- I 0)   = d(NaN) + I sign(d(NaN, +-0))0.
+	 * The sign of 0 in the result is unspecified.
+	 */
+	if ((iy | ly) == 0 && ix >= 0x7ff00000) {
+		if (((hx & 0xfffff) | lx) == 0)
+			return CMPLX(x * x, copysign(0, x) * y);
+		return CMPLX(x * x, copysign(0, (x + x) * y));
+	}
+
+	/*
+	 * cosh(x +- I Inf) = dNaN + I dNaN.
+	 * Raise the invalid floating-point exception for finite nonzero x.
+	 *
+	 * cosh(x + I NaN) = d(NaN) + I d(NaN).
+	 * Optionally raises the invalid floating-point exception for finite
+	 * nonzero x.  Choice = don't raise (except for signaling NaNs).
+	 */
+	if (ix < 0x7ff00000 && iy >= 0x7ff00000)
+		return CMPLX(y - y, x * (y - y));
+
+	/*
+	 * cosh(+-Inf + I NaN)  = +Inf + I d(NaN).
+	 *
+	 * cosh(+-Inf +- I Inf) = +Inf + I dNaN.
+	 * The sign of Inf in the result is unspecified.  Choice = always +.
+	 * Raise the invalid floating-point exception.
+	 *
+	 * cosh(+-Inf + I y)   = +Inf cos(y) +- I Inf sin(y)
+	 */
+	if (ix >= 0x7ff00000 && ((hx & 0xfffff) | lx) == 0) {
+		if (iy >= 0x7ff00000)
+			return CMPLX(x * x, x * (y - y));
+		return CMPLX((x * x) * cos(y), x * sin(y));
+	}
+
+	/*
+	 * cosh(NaN + I NaN)  = d(NaN) + I d(NaN).
+	 *
+	 * cosh(NaN +- I Inf) = d(NaN) + I d(NaN).
+	 * Optionally raises the invalid floating-point exception.
+	 * Choice = raise.
+	 *
+	 * cosh(NaN + I y)    = d(NaN) + I d(NaN).
+	 * Optionally raises the invalid floating-point exception for finite
+	 * nonzero y.  Choice = don't raise (except for signaling NaNs).
+	 */
+	return CMPLX((x * x) * (y - y), (x + x) * (y - y));
+}
libc/musl/src/complex/ccoshf.c
@@ -0,0 +1,90 @@
+/* origin: FreeBSD /usr/src/lib/msun/src/s_ccoshf.c */
+/*-
+ * Copyright (c) 2005 Bruce D. Evans and Steven G. Kargl
+ * 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 unmodified, this list of conditions, and the following
+ *    disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR 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.
+ */
+/*
+ * Hyperbolic cosine of a complex argument.  See s_ccosh.c for details.
+ */
+
+#include "libm.h"
+
+static const float huge = 0x1p127;
+
+float complex ccoshf(float complex z)
+{
+	float x, y, h;
+	int32_t hx, hy, ix, iy;
+
+	x = crealf(z);
+	y = cimagf(z);
+
+	GET_FLOAT_WORD(hx, x);
+	GET_FLOAT_WORD(hy, y);
+
+	ix = 0x7fffffff & hx;
+	iy = 0x7fffffff & hy;
+
+	if (ix < 0x7f800000 && iy < 0x7f800000) {
+		if (iy == 0)
+			return CMPLXF(coshf(x), x * y);
+		if (ix < 0x41100000)    /* small x: normal case */
+			return CMPLXF(coshf(x) * cosf(y), sinhf(x) * sinf(y));
+
+		/* |x| >= 9, so cosh(x) ~= exp(|x|) */
+		if (ix < 0x42b17218) {
+			/* x < 88.7: expf(|x|) won't overflow */
+			h = expf(fabsf(x)) * 0.5f;
+			return CMPLXF(h * cosf(y), copysignf(h, x) * sinf(y));
+		} else if (ix < 0x4340b1e7) {
+			/* x < 192.7: scale to avoid overflow */
+			z = __ldexp_cexpf(CMPLXF(fabsf(x), y), -1);
+			return CMPLXF(crealf(z), cimagf(z) * copysignf(1, x));
+		} else {
+			/* x >= 192.7: the result always overflows */
+			h = huge * x;
+			return CMPLXF(h * h * cosf(y), h * sinf(y));
+		}
+	}
+
+	if (ix == 0 && iy >= 0x7f800000)
+		return CMPLXF(y - y, copysignf(0, x * (y - y)));
+
+	if (iy == 0 && ix >= 0x7f800000) {
+		if ((hx & 0x7fffff) == 0)
+			return CMPLXF(x * x, copysignf(0, x) * y);
+		return CMPLXF(x * x, copysignf(0, (x + x) * y));
+	}
+
+	if (ix < 0x7f800000 && iy >= 0x7f800000)
+		return CMPLXF(y - y, x * (y - y));
+
+	if (ix >= 0x7f800000 && (hx & 0x7fffff) == 0) {
+		if (iy >= 0x7f800000)
+			return CMPLXF(x * x, x * (y - y));
+		return CMPLXF((x * x) * cosf(y), x * sinf(y));
+	}
+
+	return CMPLXF((x * x) * (y - y), (x + x) * (y - y));
+}
libc/musl/src/complex/ccoshl.c
@@ -0,0 +1,7 @@
+#include "libm.h"
+
+//FIXME
+long double complex ccoshl(long double complex z)
+{
+	return ccosh(z);
+}
libc/musl/src/complex/ccosl.c
@@ -0,0 +1,13 @@
+#include "libm.h"
+
+#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024
+long double complex ccosl(long double complex z)
+{
+	return ccos(z);
+}
+#else
+long double complex ccosl(long double complex z)
+{
+	return ccoshl(CMPLXL(-cimagl(z), creall(z)));
+}
+#endif
libc/musl/src/complex/cexp.c
@@ -0,0 +1,83 @@
+/* origin: FreeBSD /usr/src/lib/msun/src/s_cexp.c */
+/*-
+ * Copyright (c) 2011 David Schultz <das@FreeBSD.ORG>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include "libm.h"
+
+static const uint32_t
+exp_ovfl  = 0x40862e42,  /* high bits of MAX_EXP * ln2 ~= 710 */
+cexp_ovfl = 0x4096b8e4;  /* (MAX_EXP - MIN_DENORM_EXP) * ln2 */
+
+double complex cexp(double complex z)
+{
+	double x, y, exp_x;
+	uint32_t hx, hy, lx, ly;
+
+	x = creal(z);
+	y = cimag(z);
+
+	EXTRACT_WORDS(hy, ly, y);
+	hy &= 0x7fffffff;
+
+	/* cexp(x + I 0) = exp(x) + I 0 */
+	if ((hy | ly) == 0)
+		return CMPLX(exp(x), y);
+	EXTRACT_WORDS(hx, lx, x);
+	/* cexp(0 + I y) = cos(y) + I sin(y) */
+	if (((hx & 0x7fffffff) | lx) == 0)
+		return CMPLX(cos(y), sin(y));
+
+	if (hy >= 0x7ff00000) {
+		if (lx != 0 || (hx & 0x7fffffff) != 0x7ff00000) {
+			/* cexp(finite|NaN +- I Inf|NaN) = NaN + I NaN */
+			return CMPLX(y - y, y - y);
+		} else if (hx & 0x80000000) {
+			/* cexp(-Inf +- I Inf|NaN) = 0 + I 0 */
+			return CMPLX(0.0, 0.0);
+		} else {
+			/* cexp(+Inf +- I Inf|NaN) = Inf + I NaN */
+			return CMPLX(x, y - y);
+		}
+	}
+
+	if (hx >= exp_ovfl && hx <= cexp_ovfl) {
+		/*
+		 * x is between 709.7 and 1454.3, so we must scale to avoid
+		 * overflow in exp(x).
+		 */
+		return __ldexp_cexp(z, 0);
+	} else {
+		/*
+		 * Cases covered here:
+		 *  -  x < exp_ovfl and exp(x) won't overflow (common case)
+		 *  -  x > cexp_ovfl, so exp(x) * s overflows for all s > 0
+		 *  -  x = +-Inf (generated by exp())
+		 *  -  x = NaN (spurious inexact exception from y)
+		 */
+		exp_x = exp(x);
+		return CMPLX(exp_x * cos(y), exp_x * sin(y));
+	}
+}
libc/musl/src/complex/cexpf.c
@@ -0,0 +1,83 @@
+/* origin: FreeBSD /usr/src/lib/msun/src/s_cexpf.c */
+/*-
+ * Copyright (c) 2011 David Schultz <das@FreeBSD.ORG>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include "libm.h"
+
+static const uint32_t
+exp_ovfl  = 0x42b17218,  /* MAX_EXP * ln2 ~= 88.722839355 */
+cexp_ovfl = 0x43400074;  /* (MAX_EXP - MIN_DENORM_EXP) * ln2 */
+
+float complex cexpf(float complex z)
+{
+	float x, y, exp_x;
+	uint32_t hx, hy;
+
+	x = crealf(z);
+	y = cimagf(z);
+
+	GET_FLOAT_WORD(hy, y);
+	hy &= 0x7fffffff;
+
+	/* cexp(x + I 0) = exp(x) + I 0 */
+	if (hy == 0)
+		return CMPLXF(expf(x), y);
+	GET_FLOAT_WORD(hx, x);
+	/* cexp(0 + I y) = cos(y) + I sin(y) */
+	if ((hx & 0x7fffffff) == 0)
+		return CMPLXF(cosf(y), sinf(y));
+
+	if (hy >= 0x7f800000) {
+		if ((hx & 0x7fffffff) != 0x7f800000) {
+			/* cexp(finite|NaN +- I Inf|NaN) = NaN + I NaN */
+			return CMPLXF(y - y, y - y);
+		} else if (hx & 0x80000000) {
+			/* cexp(-Inf +- I Inf|NaN) = 0 + I 0 */
+			return CMPLXF(0.0, 0.0);
+		} else {
+			/* cexp(+Inf +- I Inf|NaN) = Inf + I NaN */
+			return CMPLXF(x, y - y);
+		}
+	}
+
+	if (hx >= exp_ovfl && hx <= cexp_ovfl) {
+		/*
+		 * x is between 88.7 and 192, so we must scale to avoid
+		 * overflow in expf(x).
+		 */
+		return __ldexp_cexpf(z, 0);
+	} else {
+		/*
+		 * Cases covered here:
+		 *  -  x < exp_ovfl and exp(x) won't overflow (common case)
+		 *  -  x > cexp_ovfl, so exp(x) * s overflows for all s > 0
+		 *  -  x = +-Inf (generated by exp())
+		 *  -  x = NaN (spurious inexact exception from y)
+		 */
+		exp_x = expf(x);
+		return CMPLXF(exp_x * cosf(y), exp_x * sinf(y));
+	}
+}
libc/musl/src/complex/cexpl.c
@@ -0,0 +1,7 @@
+#include "libm.h"
+
+//FIXME
+long double complex cexpl(long double complex z)
+{
+	return cexp(z);
+}
libc/musl/src/complex/cimag.c
@@ -0,0 +1,6 @@
+#include "libm.h"
+
+double (cimag)(double complex z)
+{
+	return cimag(z);
+}
libc/musl/src/complex/cimagf.c
@@ -0,0 +1,6 @@
+#include "libm.h"
+
+float (cimagf)(float complex z)
+{
+	return cimagf(z);
+}
libc/musl/src/complex/cimagl.c
@@ -0,0 +1,6 @@
+#include "libm.h"
+
+long double (cimagl)(long double complex z)
+{
+	return cimagl(z);
+}
libc/musl/src/complex/clog.c
@@ -0,0 +1,14 @@
+#include "libm.h"
+
+// FIXME
+
+/* log(z) = log(|z|) + i arg(z) */
+
+double complex clog(double complex z)
+{
+	double r, phi;
+
+	r = cabs(z);
+	phi = carg(z);
+	return CMPLX(log(r), phi);
+}
libc/musl/src/complex/clogf.c
@@ -0,0 +1,12 @@
+#include "libm.h"
+
+// FIXME
+
+float complex clogf(float complex z)
+{
+	float r, phi;
+
+	r = cabsf(z);
+	phi = cargf(z);
+	return CMPLXF(logf(r), phi);
+}
libc/musl/src/complex/clogl.c
@@ -0,0 +1,18 @@
+#include "libm.h"
+
+#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024
+long double complex clogl(long double complex z)
+{
+	return clog(z);
+}
+#else
+// FIXME
+long double complex clogl(long double complex z)
+{
+	long double r, phi;
+
+	r = cabsl(z);
+	phi = cargl(z);
+	return CMPLXL(logl(r), phi);
+}
+#endif
libc/musl/src/complex/conj.c
@@ -0,0 +1,6 @@
+#include "libm.h"
+
+double complex conj(double complex z)
+{
+	return CMPLX(creal(z), -cimag(z));
+}
libc/musl/src/complex/conjf.c
@@ -0,0 +1,6 @@
+#include "libm.h"
+
+float complex conjf(float complex z)
+{
+	return CMPLXF(crealf(z), -cimagf(z));
+}
libc/musl/src/complex/conjl.c
@@ -0,0 +1,6 @@
+#include "libm.h"
+
+long double complex conjl(long double complex z)
+{
+	return CMPLXL(creall(z), -cimagl(z));
+}
libc/musl/src/complex/cpow.c
@@ -0,0 +1,8 @@
+#include "libm.h"
+
+/* pow(z, c) = exp(c log(z)), See C99 G.6.4.1 */
+
+double complex cpow(double complex z, double complex c)
+{
+	return cexp(c * clog(z));
+}
libc/musl/src/complex/cpowf.c
@@ -0,0 +1,6 @@
+#include "libm.h"
+
+float complex cpowf(float complex z, float complex c)
+{
+	return cexpf(c * clogf(z));
+}
libc/musl/src/complex/cpowl.c
@@ -0,0 +1,13 @@
+#include "libm.h"
+
+#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024
+long double complex cpowl(long double complex z, long double complex c)
+{
+	return cpow(z, c);
+}
+#else
+long double complex cpowl(long double complex z, long double complex c)
+{
+	return cexpl(c * clogl(z));
+}
+#endif
libc/musl/src/complex/cproj.c
@@ -0,0 +1,8 @@
+#include "libm.h"
+
+double complex cproj(double complex z)
+{
+	if (isinf(creal(z)) || isinf(cimag(z)))
+		return CMPLX(INFINITY, copysign(0.0, creal(z)));
+	return z;
+}
libc/musl/src/complex/cprojf.c
@@ -0,0 +1,8 @@
+#include "libm.h"
+
+float complex cprojf(float complex z)
+{
+	if (isinf(crealf(z)) || isinf(cimagf(z)))
+		return CMPLXF(INFINITY, copysignf(0.0, crealf(z)));
+	return z;
+}
libc/musl/src/complex/cprojl.c
@@ -0,0 +1,15 @@
+#include "libm.h"
+
+#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024
+long double complex cprojl(long double complex z)
+{
+	return cproj(z);
+}
+#else
+long double complex cprojl(long double complex z)
+{
+	if (isinf(creall(z)) || isinf(cimagl(z)))
+		return CMPLXL(INFINITY, copysignl(0.0, creall(z)));
+	return z;
+}
+#endif
libc/musl/src/complex/creal.c
@@ -0,0 +1,6 @@
+#include <complex.h>
+
+double (creal)(double complex z)
+{
+	return creal(z);
+}
libc/musl/src/complex/crealf.c
@@ -0,0 +1,6 @@
+#include <complex.h>
+
+float (crealf)(float complex z)
+{
+	return crealf(z);
+}
libc/musl/src/complex/creall.c
@@ -0,0 +1,6 @@
+#include <complex.h>
+
+long double (creall)(long double complex z)
+{
+	return creall(z);
+}
libc/musl/src/complex/csin.c
@@ -0,0 +1,9 @@
+#include "libm.h"
+
+/* sin(z) = -i sinh(i z) */
+
+double complex csin(double complex z)
+{
+	z = csinh(CMPLX(-cimag(z), creal(z)));
+	return CMPLX(cimag(z), -creal(z));
+}
libc/musl/src/complex/csinf.c
@@ -0,0 +1,7 @@
+#include "libm.h"
+
+float complex csinf(float complex z)
+{
+	z = csinhf(CMPLXF(-cimagf(z), crealf(z)));
+	return CMPLXF(cimagf(z), -crealf(z));
+}
libc/musl/src/complex/csinh.c
@@ -0,0 +1,141 @@
+/* origin: FreeBSD /usr/src/lib/msun/src/s_csinh.c */
+/*-
+ * Copyright (c) 2005 Bruce D. Evans and Steven G. Kargl
+ * 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 unmodified, this list of conditions, and the following
+ *    disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR 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.
+ */
+/*
+ * Hyperbolic sine of a complex argument z = x + i y.
+ *
+ * sinh(z) = sinh(x+iy)
+ *         = sinh(x) cos(y) + i cosh(x) sin(y).
+ *
+ * Exceptional values are noted in the comments within the source code.
+ * These values and the return value were taken from n1124.pdf.
+ */
+
+#include "libm.h"
+
+static const double huge = 0x1p1023;
+
+double complex csinh(double complex z)
+{
+	double x, y, h;
+	int32_t hx, hy, ix, iy, lx, ly;
+
+	x = creal(z);
+	y = cimag(z);
+
+	EXTRACT_WORDS(hx, lx, x);
+	EXTRACT_WORDS(hy, ly, y);
+
+	ix = 0x7fffffff & hx;
+	iy = 0x7fffffff & hy;
+
+	/* Handle the nearly-non-exceptional cases where x and y are finite. */
+	if (ix < 0x7ff00000 && iy < 0x7ff00000) {
+		if ((iy | ly) == 0)
+			return CMPLX(sinh(x), y);
+		if (ix < 0x40360000)    /* small x: normal case */
+			return CMPLX(sinh(x) * cos(y), cosh(x) * sin(y));
+
+		/* |x| >= 22, so cosh(x) ~= exp(|x|) */
+		if (ix < 0x40862e42) {
+			/* x < 710: exp(|x|) won't overflow */
+			h = exp(fabs(x)) * 0.5;
+			return CMPLX(copysign(h, x) * cos(y), h * sin(y));
+		} else if (ix < 0x4096bbaa) {
+			/* x < 1455: scale to avoid overflow */
+			z = __ldexp_cexp(CMPLX(fabs(x), y), -1);
+			return CMPLX(creal(z) * copysign(1, x), cimag(z));
+		} else {
+			/* x >= 1455: the result always overflows */
+			h = huge * x;
+			return CMPLX(h * cos(y), h * h * sin(y));
+		}
+	}
+
+	/*
+	 * sinh(+-0 +- I Inf) = sign(d(+-0, dNaN))0 + I dNaN.
+	 * The sign of 0 in the result is unspecified.  Choice = normally
+	 * the same as dNaN.  Raise the invalid floating-point exception.
+	 *
+	 * sinh(+-0 +- I NaN) = sign(d(+-0, NaN))0 + I d(NaN).
+	 * The sign of 0 in the result is unspecified.  Choice = normally
+	 * the same as d(NaN).
+	 */
+	if ((ix | lx) == 0 && iy >= 0x7ff00000)
+		return CMPLX(copysign(0, x * (y - y)), y - y);
+
+	/*
+	 * sinh(+-Inf +- I 0) = +-Inf + I +-0.
+	 *
+	 * sinh(NaN +- I 0)   = d(NaN) + I +-0.
+	 */
+	if ((iy | ly) == 0 && ix >= 0x7ff00000) {
+		if (((hx & 0xfffff) | lx) == 0)
+			return CMPLX(x, y);
+		return CMPLX(x, copysign(0, y));
+	}
+
+	/*
+	 * sinh(x +- I Inf) = dNaN + I dNaN.
+	 * Raise the invalid floating-point exception for finite nonzero x.
+	 *
+	 * sinh(x + I NaN) = d(NaN) + I d(NaN).
+	 * Optionally raises the invalid floating-point exception for finite
+	 * nonzero x.  Choice = don't raise (except for signaling NaNs).
+	 */
+	if (ix < 0x7ff00000 && iy >= 0x7ff00000)
+		return CMPLX(y - y, x * (y - y));
+
+	/*
+	 * sinh(+-Inf + I NaN)  = +-Inf + I d(NaN).
+	 * The sign of Inf in the result is unspecified.  Choice = normally
+	 * the same as d(NaN).
+	 *
+	 * sinh(+-Inf +- I Inf) = +Inf + I dNaN.
+	 * The sign of Inf in the result is unspecified.  Choice = always +.
+	 * Raise the invalid floating-point exception.
+	 *
+	 * sinh(+-Inf + I y)   = +-Inf cos(y) + I Inf sin(y)
+	 */
+	if (ix >= 0x7ff00000 && ((hx & 0xfffff) | lx) == 0) {
+		if (iy >= 0x7ff00000)
+			return CMPLX(x * x, x * (y - y));
+		return CMPLX(x * cos(y), INFINITY * sin(y));
+	}
+
+	/*
+	 * sinh(NaN + I NaN)  = d(NaN) + I d(NaN).
+	 *
+	 * sinh(NaN +- I Inf) = d(NaN) + I d(NaN).
+	 * Optionally raises the invalid floating-point exception.
+	 * Choice = raise.
+	 *
+	 * sinh(NaN + I y)    = d(NaN) + I d(NaN).
+	 * Optionally raises the invalid floating-point exception for finite
+	 * nonzero y.  Choice = don't raise (except for signaling NaNs).
+	 */
+	return CMPLX((x * x) * (y - y), (x + x) * (y - y));
+}
libc/musl/src/complex/csinhf.c
@@ -0,0 +1,90 @@
+/* origin: FreeBSD /usr/src/lib/msun/src/s_csinhf.c */
+/*-
+ * Copyright (c) 2005 Bruce D. Evans and Steven G. Kargl
+ * 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 unmodified, this list of conditions, and the following
+ *    disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR 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.
+ */
+/*
+ * Hyperbolic sine of a complex argument z.  See s_csinh.c for details.
+ */
+
+#include "libm.h"
+
+static const float huge = 0x1p127;
+
+float complex csinhf(float complex z)
+{
+	float x, y, h;
+	int32_t hx, hy, ix, iy;
+
+	x = crealf(z);
+	y = cimagf(z);
+
+	GET_FLOAT_WORD(hx, x);
+	GET_FLOAT_WORD(hy, y);
+
+	ix = 0x7fffffff & hx;
+	iy = 0x7fffffff & hy;
+
+	if (ix < 0x7f800000 && iy < 0x7f800000) {
+		if (iy == 0)
+			return CMPLXF(sinhf(x), y);
+		if (ix < 0x41100000)    /* small x: normal case */
+			return CMPLXF(sinhf(x) * cosf(y), coshf(x) * sinf(y));
+
+		/* |x| >= 9, so cosh(x) ~= exp(|x|) */
+		if (ix < 0x42b17218) {
+			/* x < 88.7: expf(|x|) won't overflow */
+			h = expf(fabsf(x)) * 0.5f;
+			return CMPLXF(copysignf(h, x) * cosf(y), h * sinf(y));
+		} else if (ix < 0x4340b1e7) {
+			/* x < 192.7: scale to avoid overflow */
+			z = __ldexp_cexpf(CMPLXF(fabsf(x), y), -1);
+			return CMPLXF(crealf(z) * copysignf(1, x), cimagf(z));
+		} else {
+			/* x >= 192.7: the result always overflows */
+			h = huge * x;
+			return CMPLXF(h * cosf(y), h * h * sinf(y));
+		}
+	}
+
+	if (ix == 0 && iy >= 0x7f800000)
+		return CMPLXF(copysignf(0, x * (y - y)), y - y);
+
+	if (iy == 0 && ix >= 0x7f800000) {
+		if ((hx & 0x7fffff) == 0)
+			return CMPLXF(x, y);
+		return CMPLXF(x, copysignf(0, y));
+	}
+
+	if (ix < 0x7f800000 && iy >= 0x7f800000)
+		return CMPLXF(y - y, x * (y - y));
+
+	if (ix >= 0x7f800000 && (hx & 0x7fffff) == 0) {
+		if (iy >= 0x7f800000)
+			return CMPLXF(x * x, x * (y - y));
+		return CMPLXF(x * cosf(y), INFINITY * sinf(y));
+	}
+
+	return CMPLXF((x * x) * (y - y), (x + x) * (y - y));
+}
libc/musl/src/complex/csinhl.c
@@ -0,0 +1,7 @@
+#include "libm.h"
+
+//FIXME
+long double complex csinhl(long double complex z)
+{
+	return csinh(z);
+}
libc/musl/src/complex/csinl.c
@@ -0,0 +1,14 @@
+#include "libm.h"
+
+#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024
+long double complex csinl(long double complex z)
+{
+	return csin(z);
+}
+#else
+long double complex csinl(long double complex z)
+{
+	z = csinhl(CMPLXL(-cimagl(z), creall(z)));
+	return CMPLXL(cimagl(z), -creall(z));
+}
+#endif
libc/musl/src/complex/csqrt.c
@@ -0,0 +1,100 @@
+/* origin: FreeBSD /usr/src/lib/msun/src/s_csqrt.c */
+/*-
+ * Copyright (c) 2007 David Schultz <das@FreeBSD.ORG>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include "libm.h"
+
+/*
+ * gcc doesn't implement complex multiplication or division correctly,
+ * so we need to handle infinities specially. We turn on this pragma to
+ * notify conforming c99 compilers that the fast-but-incorrect code that
+ * gcc generates is acceptable, since the special cases have already been
+ * handled.
+ */
+#pragma STDC CX_LIMITED_RANGE ON
+
+/* We risk spurious overflow for components >= DBL_MAX / (1 + sqrt(2)). */
+#define THRESH  0x1.a827999fcef32p+1022
+
+double complex csqrt(double complex z)
+{
+	double complex result;
+	double a, b;
+	double t;
+	int scale;
+
+	a = creal(z);
+	b = cimag(z);
+
+	/* Handle special cases. */
+	if (z == 0)
+		return CMPLX(0, b);
+	if (isinf(b))
+		return CMPLX(INFINITY, b);
+	if (isnan(a)) {
+		t = (b - b) / (b - b);  /* raise invalid if b is not a NaN */
+		return CMPLX(a, t);   /* return NaN + NaN i */
+	}
+	if (isinf(a)) {
+		/*
+		 * csqrt(inf + NaN i)  = inf +  NaN i
+		 * csqrt(inf + y i)    = inf +  0 i
+		 * csqrt(-inf + NaN i) = NaN +- inf i
+		 * csqrt(-inf + y i)   = 0   +  inf i
+		 */
+		if (signbit(a))
+			return CMPLX(fabs(b - b), copysign(a, b));
+		else
+			return CMPLX(a, copysign(b - b, b));
+	}
+	/*
+	 * The remaining special case (b is NaN) is handled just fine by
+	 * the normal code path below.
+	 */
+
+	/* Scale to avoid overflow. */
+	if (fabs(a) >= THRESH || fabs(b) >= THRESH) {
+		a *= 0.25;
+		b *= 0.25;
+		scale = 1;
+	} else {
+		scale = 0;
+	}
+
+	/* Algorithm 312, CACM vol 10, Oct 1967. */
+	if (a >= 0) {
+		t = sqrt((a + hypot(a, b)) * 0.5);
+		result = CMPLX(t, b / (2 * t));
+	} else {
+		t = sqrt((-a + hypot(a, b)) * 0.5);
+		result = CMPLX(fabs(b) / (2 * t), copysign(t, b));
+	}
+
+	/* Rescale. */
+	if (scale)
+		result *= 2;
+	return result;
+}
libc/musl/src/complex/csqrtf.c
@@ -0,0 +1,82 @@
+/* origin: FreeBSD /usr/src/lib/msun/src/s_csqrtf.c */
+/*-
+ * Copyright (c) 2007 David Schultz <das@FreeBSD.ORG>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include "libm.h"
+
+/*
+ * gcc doesn't implement complex multiplication or division correctly,
+ * so we need to handle infinities specially. We turn on this pragma to
+ * notify conforming c99 compilers that the fast-but-incorrect code that
+ * gcc generates is acceptable, since the special cases have already been
+ * handled.
+ */
+#pragma STDC CX_LIMITED_RANGE ON
+
+float complex csqrtf(float complex z)
+{
+	float a = crealf(z), b = cimagf(z);
+	double t;
+
+	/* Handle special cases. */
+	if (z == 0)
+		return CMPLXF(0, b);
+	if (isinf(b))
+		return CMPLXF(INFINITY, b);
+	if (isnan(a)) {
+		t = (b - b) / (b - b);  /* raise invalid if b is not a NaN */
+		return CMPLXF(a, t);  /* return NaN + NaN i */
+	}
+	if (isinf(a)) {
+		/*
+		 * csqrtf(inf + NaN i)  = inf +  NaN i
+		 * csqrtf(inf + y i)    = inf +  0 i
+		 * csqrtf(-inf + NaN i) = NaN +- inf i
+		 * csqrtf(-inf + y i)   = 0   +  inf i
+		 */
+		if (signbit(a))
+			return CMPLXF(fabsf(b - b), copysignf(a, b));
+		else
+			return CMPLXF(a, copysignf(b - b, b));
+	}
+	/*
+	 * The remaining special case (b is NaN) is handled just fine by
+	 * the normal code path below.
+	 */
+
+	/*
+	 * We compute t in double precision to avoid overflow and to
+	 * provide correct rounding in nearly all cases.
+	 * This is Algorithm 312, CACM vol 10, Oct 1967.
+	 */
+	if (a >= 0) {
+		t = sqrt((a + hypot(a, b)) * 0.5);
+		return CMPLXF(t, b / (2.0 * t));
+	} else {
+		t = sqrt((-a + hypot(a, b)) * 0.5);
+		return CMPLXF(fabsf(b) / (2.0 * t), copysignf(t, b));
+	}
+}
libc/musl/src/complex/csqrtl.c
@@ -0,0 +1,7 @@
+#include "libm.h"
+
+//FIXME
+long double complex csqrtl(long double complex z)
+{
+	return csqrt(z);
+}
libc/musl/src/complex/ctan.c
@@ -0,0 +1,9 @@
+#include "libm.h"
+
+/* tan(z) = -i tanh(i z) */
+
+double complex ctan(double complex z)
+{
+	z = ctanh(CMPLX(-cimag(z), creal(z)));
+	return CMPLX(cimag(z), -creal(z));
+}
libc/musl/src/complex/ctanf.c
@@ -0,0 +1,7 @@
+#include "libm.h"
+
+float complex ctanf(float complex z)
+{
+	z = ctanhf(CMPLXF(-cimagf(z), crealf(z)));
+	return CMPLXF(cimagf(z), -crealf(z));
+}
libc/musl/src/complex/ctanh.c
@@ -0,0 +1,129 @@
+/* origin: FreeBSD /usr/src/lib/msun/src/s_ctanh.c */
+/*-
+ * Copyright (c) 2011 David Schultz
+ * 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 unmodified, this list of conditions, and the following
+ *    disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR 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.
+ */
+/*
+ * Hyperbolic tangent of a complex argument z = x + i y.
+ *
+ * The algorithm is from:
+ *
+ *   W. Kahan.  Branch Cuts for Complex Elementary Functions or Much
+ *   Ado About Nothing's Sign Bit.  In The State of the Art in
+ *   Numerical Analysis, pp. 165 ff.  Iserles and Powell, eds., 1987.
+ *
+ * Method:
+ *
+ *   Let t    = tan(x)
+ *       beta = 1/cos^2(y)
+ *       s    = sinh(x)
+ *       rho  = cosh(x)
+ *
+ *   We have:
+ *
+ *   tanh(z) = sinh(z) / cosh(z)
+ *
+ *             sinh(x) cos(y) + i cosh(x) sin(y)
+ *           = ---------------------------------
+ *             cosh(x) cos(y) + i sinh(x) sin(y)
+ *
+ *             cosh(x) sinh(x) / cos^2(y) + i tan(y)
+ *           = -------------------------------------
+ *                    1 + sinh^2(x) / cos^2(y)
+ *
+ *             beta rho s + i t
+ *           = ----------------
+ *               1 + beta s^2
+ *
+ * Modifications:
+ *
+ *   I omitted the original algorithm's handling of overflow in tan(x) after
+ *   verifying with nearpi.c that this can't happen in IEEE single or double
+ *   precision.  I also handle large x differently.
+ */
+
+#include "libm.h"
+
+double complex ctanh(double complex z)
+{
+	double x, y;
+	double t, beta, s, rho, denom;
+	uint32_t hx, ix, lx;
+
+	x = creal(z);
+	y = cimag(z);
+
+	EXTRACT_WORDS(hx, lx, x);
+	ix = hx & 0x7fffffff;
+
+	/*
+	 * ctanh(NaN + i 0) = NaN + i 0
+	 *
+	 * ctanh(NaN + i y) = NaN + i NaN               for y != 0
+	 *
+	 * The imaginary part has the sign of x*sin(2*y), but there's no
+	 * special effort to get this right.
+	 *
+	 * ctanh(+-Inf +- i Inf) = +-1 +- 0
+	 *
+	 * ctanh(+-Inf + i y) = +-1 + 0 sin(2y)         for y finite
+	 *
+	 * The imaginary part of the sign is unspecified.  This special
+	 * case is only needed to avoid a spurious invalid exception when
+	 * y is infinite.
+	 */
+	if (ix >= 0x7ff00000) {
+		if ((ix & 0xfffff) | lx)        /* x is NaN */
+			return CMPLX(x, (y == 0 ? y : x * y));
+		SET_HIGH_WORD(x, hx - 0x40000000);      /* x = copysign(1, x) */
+		return CMPLX(x, copysign(0, isinf(y) ? y : sin(y) * cos(y)));
+	}
+
+	/*
+	 * ctanh(+-0 + i NAN) = +-0 + i NaN
+	 * ctanh(+-0 +- i Inf) = +-0 + i NaN
+	 * ctanh(x + i NAN) = NaN + i NaN
+	 * ctanh(x +- i Inf) = NaN + i NaN
+	 */
+	if (!isfinite(y))
+		return CMPLX(x ? y - y : x, y - y);
+
+	/*
+	 * ctanh(+-huge + i +-y) ~= +-1 +- i 2sin(2y)/exp(2x), using the
+	 * approximation sinh^2(huge) ~= exp(2*huge) / 4.
+	 * We use a modified formula to avoid spurious overflow.
+	 */
+	if (ix >= 0x40360000) { /* x >= 22 */
+		double exp_mx = exp(-fabs(x));
+		return CMPLX(copysign(1, x), 4 * sin(y) * cos(y) * exp_mx * exp_mx);
+	}
+
+	/* Kahan's algorithm */
+	t = tan(y);
+	beta = 1.0 + t * t;     /* = 1 / cos^2(y) */
+	s = sinh(x);
+	rho = sqrt(1 + s * s);  /* = cosh(x) */
+	denom = 1 + beta * s * s;
+	return CMPLX((beta * rho * s) / denom, t / denom);
+}
libc/musl/src/complex/ctanhf.c
@@ -0,0 +1,66 @@
+/* origin: FreeBSD /usr/src/lib/msun/src/s_ctanhf.c */
+/*-
+ * Copyright (c) 2011 David Schultz
+ * 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 unmodified, this list of conditions, and the following
+ *    disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR 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.
+ */
+/*
+ * Hyperbolic tangent of a complex argument z.  See s_ctanh.c for details.
+ */
+
+#include "libm.h"
+
+float complex ctanhf(float complex z)
+{
+	float x, y;
+	float t, beta, s, rho, denom;
+	uint32_t hx, ix;
+
+	x = crealf(z);
+	y = cimagf(z);
+
+	GET_FLOAT_WORD(hx, x);
+	ix = hx & 0x7fffffff;
+
+	if (ix >= 0x7f800000) {
+		if (ix & 0x7fffff)
+			return CMPLXF(x, (y == 0 ? y : x * y));
+		SET_FLOAT_WORD(x, hx - 0x40000000);
+		return CMPLXF(x, copysignf(0, isinf(y) ? y : sinf(y) * cosf(y)));
+	}
+
+	if (!isfinite(y))
+		return CMPLXF(ix ? y - y : x, y - y);
+
+	if (ix >= 0x41300000) { /* x >= 11 */
+		float exp_mx = expf(-fabsf(x));
+		return CMPLXF(copysignf(1, x), 4 * sinf(y) * cosf(y) * exp_mx * exp_mx);
+	}
+
+	t = tanf(y);
+	beta = 1.0 + t * t;
+	s = sinhf(x);
+	rho = sqrtf(1 + s * s);
+	denom = 1 + beta * s * s;
+	return CMPLXF((beta * rho * s) / denom, t / denom);
+}
libc/musl/src/complex/ctanhl.c
@@ -0,0 +1,7 @@
+#include "libm.h"
+
+//FIXME
+long double complex ctanhl(long double complex z)
+{
+	return ctanh(z);
+}
libc/musl/src/complex/ctanl.c
@@ -0,0 +1,14 @@
+#include "libm.h"
+
+#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024
+long double complex ctanl(long double complex z)
+{
+	return ctan(z);
+}
+#else
+long double complex ctanl(long double complex z)
+{
+	z = ctanhl(CMPLXL(-cimagl(z), creall(z)));
+	return CMPLXL(cimagl(z), -creall(z));
+}
+#endif
libc/musl/src/conf/confstr.c
@@ -0,0 +1,17 @@
+#include <unistd.h>
+#include <stdio.h>
+#include <errno.h>
+
+size_t confstr(int name, char *buf, size_t len)
+{
+	const char *s = "";
+	if (!name) {
+		s = "/bin:/usr/bin";
+	} else if ((name&~4U)!=1 && name-_CS_POSIX_V6_ILP32_OFF32_CFLAGS>33U) {
+		errno = EINVAL;
+		return 0;
+	}
+	// snprintf is overkill but avoid wasting code size to implement
+	// this completely useless function and its truncation semantics
+	return snprintf(buf, len, "%s", s) + 1;
+}
libc/musl/src/conf/fpathconf.c
@@ -0,0 +1,35 @@
+#include <unistd.h>
+#include <limits.h>
+#include <errno.h>
+
+long fpathconf(int fd, int name)
+{
+	static const short values[] = {
+		[_PC_LINK_MAX] = _POSIX_LINK_MAX,
+		[_PC_MAX_CANON] = _POSIX_MAX_CANON,
+		[_PC_MAX_INPUT] = _POSIX_MAX_INPUT,
+		[_PC_NAME_MAX] = NAME_MAX,
+		[_PC_PATH_MAX] = PATH_MAX,
+		[_PC_PIPE_BUF] = PIPE_BUF,
+		[_PC_CHOWN_RESTRICTED] = 1,
+		[_PC_NO_TRUNC] = 1,
+		[_PC_VDISABLE] = 0,
+		[_PC_SYNC_IO] = 1,
+		[_PC_ASYNC_IO] = -1,
+		[_PC_PRIO_IO] = -1,
+		[_PC_SOCK_MAXBUF] = -1,
+		[_PC_FILESIZEBITS] = FILESIZEBITS,
+		[_PC_REC_INCR_XFER_SIZE] = 4096,
+		[_PC_REC_MAX_XFER_SIZE] = 4096,
+		[_PC_REC_MIN_XFER_SIZE] = 4096,
+		[_PC_REC_XFER_ALIGN] = 4096,
+		[_PC_ALLOC_SIZE_MIN] = 4096,
+		[_PC_SYMLINK_MAX] = -1,
+		[_PC_2_SYMLINKS] = 1
+	};
+	if (name >= sizeof(values)/sizeof(values[0])) {
+		errno = EINVAL;
+		return -1;
+	}
+	return values[name];
+}
libc/musl/src/conf/legacy.c
@@ -0,0 +1,22 @@
+#include <sys/sysinfo.h>
+#include <unistd.h>
+
+int get_nprocs_conf()
+{
+	return sysconf(_SC_NPROCESSORS_CONF);
+}
+
+int get_nprocs()
+{
+	return sysconf(_SC_NPROCESSORS_ONLN);
+}
+
+long get_phys_pages()
+{
+	return sysconf(_SC_PHYS_PAGES);	
+}
+
+long get_avphys_pages()
+{
+	return sysconf(_SC_AVPHYS_PAGES);	
+}
libc/musl/src/conf/pathconf.c
@@ -0,0 +1,6 @@
+#include <unistd.h>
+
+long pathconf(const char *path, int name)
+{
+	return fpathconf(-1, name);
+}
libc/musl/src/conf/sysconf.c
@@ -0,0 +1,219 @@
+#include <unistd.h>
+#include <limits.h>
+#include <errno.h>
+#include <sys/resource.h>
+#include <signal.h>
+#include <sys/sysinfo.h>
+#include "syscall.h"
+#include "libc.h"
+
+#define JT(x) (-256|(x))
+#define VER JT(1)
+#define JT_ARG_MAX JT(2)
+#define JT_MQ_PRIO_MAX JT(3)
+#define JT_PAGE_SIZE JT(4)
+#define JT_SEM_VALUE_MAX JT(5)
+#define JT_NPROCESSORS_CONF JT(6)
+#define JT_NPROCESSORS_ONLN JT(7)
+#define JT_PHYS_PAGES JT(8)
+#define JT_AVPHYS_PAGES JT(9)
+#define JT_ZERO JT(10)
+#define JT_DELAYTIMER_MAX JT(11)
+
+#define RLIM(x) (-32768|(RLIMIT_ ## x))
+
+long sysconf(int name)
+{
+	static const short values[] = {
+		[_SC_ARG_MAX] = JT_ARG_MAX,
+		[_SC_CHILD_MAX] = RLIM(NPROC),
+		[_SC_CLK_TCK] = 100,
+		[_SC_NGROUPS_MAX] = 32,
+		[_SC_OPEN_MAX] = RLIM(NOFILE),
+		[_SC_STREAM_MAX] = -1,
+		[_SC_TZNAME_MAX] = TZNAME_MAX,
+		[_SC_JOB_CONTROL] = 1,
+		[_SC_SAVED_IDS] = 1,
+		[_SC_REALTIME_SIGNALS] = VER,
+		[_SC_PRIORITY_SCHEDULING] = -1,
+		[_SC_TIMERS] = VER,
+		[_SC_ASYNCHRONOUS_IO] = VER,
+		[_SC_PRIORITIZED_IO] = -1,
+		[_SC_SYNCHRONIZED_IO] = -1,
+		[_SC_FSYNC] = VER,
+		[_SC_MAPPED_FILES] = VER,
+		[_SC_MEMLOCK] = VER,
+		[_SC_MEMLOCK_RANGE] = VER,
+		[_SC_MEMORY_PROTECTION] = VER,
+		[_SC_MESSAGE_PASSING] = VER,
+		[_SC_SEMAPHORES] = VER,
+		[_SC_SHARED_MEMORY_OBJECTS] = VER,
+		[_SC_AIO_LISTIO_MAX] = -1,
+		[_SC_AIO_MAX] = -1,
+		[_SC_AIO_PRIO_DELTA_MAX] = JT_ZERO, /* ?? */
+		[_SC_DELAYTIMER_MAX] = JT_DELAYTIMER_MAX,
+		[_SC_MQ_OPEN_MAX] = -1,
+		[_SC_MQ_PRIO_MAX] = JT_MQ_PRIO_MAX,
+		[_SC_VERSION] = VER,
+		[_SC_PAGE_SIZE] = JT_PAGE_SIZE,
+		[_SC_RTSIG_MAX] = _NSIG - 1 - 31 - 3,
+		[_SC_SEM_NSEMS_MAX] = SEM_NSEMS_MAX,
+		[_SC_SEM_VALUE_MAX] = JT_SEM_VALUE_MAX,
+		[_SC_SIGQUEUE_MAX] = -1,
+		[_SC_TIMER_MAX] = -1,
+		[_SC_BC_BASE_MAX] = _POSIX2_BC_BASE_MAX,
+		[_SC_BC_DIM_MAX] = _POSIX2_BC_DIM_MAX,
+		[_SC_BC_SCALE_MAX] = _POSIX2_BC_SCALE_MAX,
+		[_SC_BC_STRING_MAX] = _POSIX2_BC_STRING_MAX,
+		[_SC_COLL_WEIGHTS_MAX] = COLL_WEIGHTS_MAX,
+		[_SC_EXPR_NEST_MAX] = -1,
+		[_SC_LINE_MAX] = -1,
+		[_SC_RE_DUP_MAX] = RE_DUP_MAX,
+		[_SC_2_VERSION] = VER,
+		[_SC_2_C_BIND] = VER,
+		[_SC_2_C_DEV] = -1,
+		[_SC_2_FORT_DEV] = -1,
+		[_SC_2_FORT_RUN] = -1,
+		[_SC_2_SW_DEV] = -1,
+		[_SC_2_LOCALEDEF] = -1,
+		[_SC_IOV_MAX] = IOV_MAX,
+		[_SC_THREADS] = VER,
+		[_SC_THREAD_SAFE_FUNCTIONS] = VER,
+		[_SC_GETGR_R_SIZE_MAX] = -1,
+		[_SC_GETPW_R_SIZE_MAX] = -1,
+		[_SC_LOGIN_NAME_MAX] = 256,
+		[_SC_TTY_NAME_MAX] = TTY_NAME_MAX,
+		[_SC_THREAD_DESTRUCTOR_ITERATIONS] = PTHREAD_DESTRUCTOR_ITERATIONS,
+		[_SC_THREAD_KEYS_MAX] = PTHREAD_KEYS_MAX,
+		[_SC_THREAD_STACK_MIN] = PTHREAD_STACK_MIN,
+		[_SC_THREAD_THREADS_MAX] = -1,
+		[_SC_THREAD_ATTR_STACKADDR] = VER,
+		[_SC_THREAD_ATTR_STACKSIZE] = VER,
+		[_SC_THREAD_PRIORITY_SCHEDULING] = VER,
+		[_SC_THREAD_PRIO_INHERIT] = -1,
+		[_SC_THREAD_PRIO_PROTECT] = -1,
+		[_SC_THREAD_PROCESS_SHARED] = VER,
+		[_SC_NPROCESSORS_CONF] = JT_NPROCESSORS_CONF,
+		[_SC_NPROCESSORS_ONLN] = JT_NPROCESSORS_ONLN,
+		[_SC_PHYS_PAGES] = JT_PHYS_PAGES,
+		[_SC_AVPHYS_PAGES] = JT_AVPHYS_PAGES,
+		[_SC_ATEXIT_MAX] = -1,
+		[_SC_PASS_MAX] = -1,
+		[_SC_XOPEN_VERSION] = _XOPEN_VERSION,
+		[_SC_XOPEN_XCU_VERSION] = _XOPEN_VERSION,
+		[_SC_XOPEN_UNIX] = 1,
+		[_SC_XOPEN_CRYPT] = -1,
+		[_SC_XOPEN_ENH_I18N] = 1,
+		[_SC_XOPEN_SHM] = 1,
+		[_SC_2_CHAR_TERM] = -1,
+		[_SC_2_UPE] = -1,
+		[_SC_XOPEN_XPG2] = -1,
+		[_SC_XOPEN_XPG3] = -1,
+		[_SC_XOPEN_XPG4] = -1,
+		[_SC_NZERO] = NZERO,
+		[_SC_XBS5_ILP32_OFF32] = -1,
+		[_SC_XBS5_ILP32_OFFBIG] = sizeof(long)==4 ? 1 : -1,
+		[_SC_XBS5_LP64_OFF64] = sizeof(long)==8 ? 1 : -1,
+		[_SC_XBS5_LPBIG_OFFBIG] = -1,
+		[_SC_XOPEN_LEGACY] = -1,
+		[_SC_XOPEN_REALTIME] = -1,
+		[_SC_XOPEN_REALTIME_THREADS] = -1,
+		[_SC_ADVISORY_INFO] = VER,
+		[_SC_BARRIERS] = VER,
+		[_SC_CLOCK_SELECTION] = VER,
+		[_SC_CPUTIME] = VER,
+		[_SC_THREAD_CPUTIME] = VER,
+		[_SC_MONOTONIC_CLOCK] = VER,
+		[_SC_READER_WRITER_LOCKS] = VER,
+		[_SC_SPIN_LOCKS] = VER,
+		[_SC_REGEXP] = 1,
+		[_SC_SHELL] = 1,
+		[_SC_SPAWN] = VER,
+		[_SC_SPORADIC_SERVER] = -1,
+		[_SC_THREAD_SPORADIC_SERVER] = -1,
+		[_SC_TIMEOUTS] = VER,
+		[_SC_TYPED_MEMORY_OBJECTS] = -1,
+		[_SC_2_PBS] = -1,
+		[_SC_2_PBS_ACCOUNTING] = -1,
+		[_SC_2_PBS_LOCATE] = -1,
+		[_SC_2_PBS_MESSAGE] = -1,
+		[_SC_2_PBS_TRACK] = -1,
+		[_SC_SYMLOOP_MAX] = SYMLOOP_MAX,
+		[_SC_STREAMS] = JT_ZERO,
+		[_SC_2_PBS_CHECKPOINT] = -1,
+		[_SC_V6_ILP32_OFF32] = -1,
+		[_SC_V6_ILP32_OFFBIG] = sizeof(long)==4 ? 1 : -1,
+		[_SC_V6_LP64_OFF64] = sizeof(long)==8 ? 1 : -1,
+		[_SC_V6_LPBIG_OFFBIG] = -1,
+		[_SC_HOST_NAME_MAX] = HOST_NAME_MAX,
+		[_SC_TRACE] = -1,
+		[_SC_TRACE_EVENT_FILTER] = -1,
+		[_SC_TRACE_INHERIT] = -1,
+		[_SC_TRACE_LOG] = -1,
+
+		[_SC_IPV6] = VER,
+		[_SC_RAW_SOCKETS] = VER,
+		[_SC_V7_ILP32_OFF32] = -1,
+		[_SC_V7_ILP32_OFFBIG] = sizeof(long)==4 ? 1 : -1,
+		[_SC_V7_LP64_OFF64] = sizeof(long)==8 ? 1 : -1,
+		[_SC_V7_LPBIG_OFFBIG] = -1,
+		[_SC_SS_REPL_MAX] = -1,
+		[_SC_TRACE_EVENT_NAME_MAX] = -1,
+		[_SC_TRACE_NAME_MAX] = -1,
+		[_SC_TRACE_SYS_MAX] = -1,
+		[_SC_TRACE_USER_EVENT_MAX] = -1,
+		[_SC_XOPEN_STREAMS] = JT_ZERO,
+		[_SC_THREAD_ROBUST_PRIO_INHERIT] = -1,
+		[_SC_THREAD_ROBUST_PRIO_PROTECT] = -1,
+	};
+
+	if (name >= sizeof(values)/sizeof(values[0]) || !values[name]) {
+		errno = EINVAL;
+		return -1;
+	} else if (values[name] >= -1) {
+		return values[name];
+	} else if (values[name] < -256) {
+		struct rlimit lim;
+		getrlimit(values[name]&16383, &lim);
+		if (lim.rlim_cur == RLIM_INFINITY)
+			return -1;
+		return lim.rlim_cur > LONG_MAX ? LONG_MAX : lim.rlim_cur;
+	}
+
+	switch ((unsigned char)values[name]) {
+	case VER & 255:
+		return _POSIX_VERSION;
+	case JT_ARG_MAX & 255:
+		return ARG_MAX;
+	case JT_MQ_PRIO_MAX & 255:
+		return MQ_PRIO_MAX;
+	case JT_PAGE_SIZE & 255:
+		return PAGE_SIZE;
+	case JT_SEM_VALUE_MAX & 255:
+		return SEM_VALUE_MAX;
+	case JT_DELAYTIMER_MAX & 255:
+		return DELAYTIMER_MAX;
+	case JT_NPROCESSORS_CONF & 255:
+	case JT_NPROCESSORS_ONLN & 255: ;
+		unsigned char set[128] = {1};
+		int i, cnt;
+		__syscall(SYS_sched_getaffinity, 0, sizeof set, set);
+		for (i=cnt=0; i<sizeof set; i++)
+			for (; set[i]; set[i]&=set[i]-1, cnt++);
+		return cnt;
+	case JT_PHYS_PAGES & 255:
+	case JT_AVPHYS_PAGES & 255: ;
+		unsigned long long mem;
+		struct sysinfo si;
+		__lsysinfo(&si);
+		if (!si.mem_unit) si.mem_unit = 1;
+		if (name==_SC_PHYS_PAGES) mem = si.totalram;
+		else mem = si.freeram + si.bufferram;
+		mem *= si.mem_unit;
+		mem /= PAGE_SIZE;
+		return (mem > LONG_MAX) ? LONG_MAX : mem;
+	case JT_ZERO & 255:
+		return 0;
+	}
+	return values[name];
+}
libc/musl/src/crypt/crypt.c
@@ -0,0 +1,14 @@
+#include <unistd.h>
+#include <crypt.h>
+
+char *crypt(const char *key, const char *salt)
+{
+	/* This buffer is sufficiently large for all
+	 * currently-supported hash types. It needs to be updated if
+	 * longer hashes are added. The cast to struct crypt_data * is
+	 * purely to meet the public API requirements of the crypt_r
+	 * function; the implementation of crypt_r uses the object
+	 * purely as a char buffer. */
+	static char buf[128];
+	return __crypt_r(key, salt, (struct crypt_data *)buf);
+}
libc/musl/src/crypt/crypt_blowfish.c
@@ -0,0 +1,798 @@
+/* Modified by Rich Felker in for inclusion in musl libc, based on
+ * Solar Designer's second size-optimized version sent to the musl
+ * mailing list. */
+
+/*
+ * The crypt_blowfish homepage is:
+ *
+ *	http://www.openwall.com/crypt/
+ *
+ * This code comes from John the Ripper password cracker, with reentrant
+ * and crypt(3) interfaces added, but optimizations specific to password
+ * cracking removed.
+ *
+ * Written by Solar Designer <solar at openwall.com> in 1998-2012.
+ * No copyright is claimed, and the software is hereby placed in the public
+ * domain.  In case this attempt to disclaim copyright and place the software
+ * in the public domain is deemed null and void, then the software is
+ * Copyright (c) 1998-2012 Solar Designer and it is hereby released to the
+ * general public under the following terms:
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted.
+ *
+ * There's ABSOLUTELY NO WARRANTY, express or implied.
+ *
+ * It is my intent that you should be able to use this on your system,
+ * as part of a software package, or anywhere else to improve security,
+ * ensure compatibility, or for any other purpose.  I would appreciate
+ * it if you give credit where it is due and keep your modifications in
+ * the public domain as well, but I don't require that in order to let
+ * you place this code and any modifications you make under a license
+ * of your choice.
+ *
+ * This implementation is mostly compatible with OpenBSD's bcrypt.c (prefix
+ * "$2a$") by Niels Provos <provos at citi.umich.edu>, and uses some of his
+ * ideas.  The password hashing algorithm was designed by David Mazieres
+ * <dm at lcs.mit.edu>.  For more information on the level of compatibility,
+ * please refer to the comments in BF_set_key() below and to the included
+ * crypt(3) man page.
+ *
+ * There's a paper on the algorithm that explains its design decisions:
+ *
+ *	http://www.usenix.org/events/usenix99/provos.html
+ *
+ * Some of the tricks in BF_ROUND might be inspired by Eric Young's
+ * Blowfish library (I can't be sure if I would think of something if I
+ * hadn't seen his code).
+ */
+
+#include <string.h>
+#include <stdint.h>
+
+typedef uint32_t BF_word;
+typedef int32_t BF_word_signed;
+
+/* Number of Blowfish rounds, this is also hardcoded into a few places */
+#define BF_N				16
+
+typedef BF_word BF_key[BF_N + 2];
+
+typedef union {
+	struct {
+		BF_key P;
+		BF_word S[4][0x100];
+	} s;
+	BF_word PS[BF_N + 2 + 4 * 0x100];
+} BF_ctx;
+
+/*
+ * Magic IV for 64 Blowfish encryptions that we do at the end.
+ * The string is "OrpheanBeholderScryDoubt" on big-endian.
+ */
+static const BF_word BF_magic_w[6] = {
+	0x4F727068, 0x65616E42, 0x65686F6C,
+	0x64657253, 0x63727944, 0x6F756274
+};
+
+/*
+ * P-box and S-box tables initialized with digits of Pi.
+ */
+static const BF_ctx BF_init_state = {{
+	{
+		0x243f6a88, 0x85a308d3, 0x13198a2e, 0x03707344,
+		0xa4093822, 0x299f31d0, 0x082efa98, 0xec4e6c89,
+		0x452821e6, 0x38d01377, 0xbe5466cf, 0x34e90c6c,
+		0xc0ac29b7, 0xc97c50dd, 0x3f84d5b5, 0xb5470917,
+		0x9216d5d9, 0x8979fb1b
+	}, {
+		{
+			0xd1310ba6, 0x98dfb5ac, 0x2ffd72db, 0xd01adfb7,
+			0xb8e1afed, 0x6a267e96, 0xba7c9045, 0xf12c7f99,
+			0x24a19947, 0xb3916cf7, 0x0801f2e2, 0x858efc16,
+			0x636920d8, 0x71574e69, 0xa458fea3, 0xf4933d7e,
+			0x0d95748f, 0x728eb658, 0x718bcd58, 0x82154aee,
+			0x7b54a41d, 0xc25a59b5, 0x9c30d539, 0x2af26013,
+			0xc5d1b023, 0x286085f0, 0xca417918, 0xb8db38ef,
+			0x8e79dcb0, 0x603a180e, 0x6c9e0e8b, 0xb01e8a3e,
+			0xd71577c1, 0xbd314b27, 0x78af2fda, 0x55605c60,
+			0xe65525f3, 0xaa55ab94, 0x57489862, 0x63e81440,
+			0x55ca396a, 0x2aab10b6, 0xb4cc5c34, 0x1141e8ce,
+			0xa15486af, 0x7c72e993, 0xb3ee1411, 0x636fbc2a,
+			0x2ba9c55d, 0x741831f6, 0xce5c3e16, 0x9b87931e,
+			0xafd6ba33, 0x6c24cf5c, 0x7a325381, 0x28958677,
+			0x3b8f4898, 0x6b4bb9af, 0xc4bfe81b, 0x66282193,
+			0x61d809cc, 0xfb21a991, 0x487cac60, 0x5dec8032,
+			0xef845d5d, 0xe98575b1, 0xdc262302, 0xeb651b88,
+			0x23893e81, 0xd396acc5, 0x0f6d6ff3, 0x83f44239,
+			0x2e0b4482, 0xa4842004, 0x69c8f04a, 0x9e1f9b5e,
+			0x21c66842, 0xf6e96c9a, 0x670c9c61, 0xabd388f0,
+			0x6a51a0d2, 0xd8542f68, 0x960fa728, 0xab5133a3,
+			0x6eef0b6c, 0x137a3be4, 0xba3bf050, 0x7efb2a98,
+			0xa1f1651d, 0x39af0176, 0x66ca593e, 0x82430e88,
+			0x8cee8619, 0x456f9fb4, 0x7d84a5c3, 0x3b8b5ebe,
+			0xe06f75d8, 0x85c12073, 0x401a449f, 0x56c16aa6,
+			0x4ed3aa62, 0x363f7706, 0x1bfedf72, 0x429b023d,
+			0x37d0d724, 0xd00a1248, 0xdb0fead3, 0x49f1c09b,
+			0x075372c9, 0x80991b7b, 0x25d479d8, 0xf6e8def7,
+			0xe3fe501a, 0xb6794c3b, 0x976ce0bd, 0x04c006ba,
+			0xc1a94fb6, 0x409f60c4, 0x5e5c9ec2, 0x196a2463,
+			0x68fb6faf, 0x3e6c53b5, 0x1339b2eb, 0x3b52ec6f,
+			0x6dfc511f, 0x9b30952c, 0xcc814544, 0xaf5ebd09,
+			0xbee3d004, 0xde334afd, 0x660f2807, 0x192e4bb3,
+			0xc0cba857, 0x45c8740f, 0xd20b5f39, 0xb9d3fbdb,
+			0x5579c0bd, 0x1a60320a, 0xd6a100c6, 0x402c7279,
+			0x679f25fe, 0xfb1fa3cc, 0x8ea5e9f8, 0xdb3222f8,
+			0x3c7516df, 0xfd616b15, 0x2f501ec8, 0xad0552ab,
+			0x323db5fa, 0xfd238760, 0x53317b48, 0x3e00df82,
+			0x9e5c57bb, 0xca6f8ca0, 0x1a87562e, 0xdf1769db,
+			0xd542a8f6, 0x287effc3, 0xac6732c6, 0x8c4f5573,
+			0x695b27b0, 0xbbca58c8, 0xe1ffa35d, 0xb8f011a0,
+			0x10fa3d98, 0xfd2183b8, 0x4afcb56c, 0x2dd1d35b,
+			0x9a53e479, 0xb6f84565, 0xd28e49bc, 0x4bfb9790,
+			0xe1ddf2da, 0xa4cb7e33, 0x62fb1341, 0xcee4c6e8,
+			0xef20cada, 0x36774c01, 0xd07e9efe, 0x2bf11fb4,
+			0x95dbda4d, 0xae909198, 0xeaad8e71, 0x6b93d5a0,
+			0xd08ed1d0, 0xafc725e0, 0x8e3c5b2f, 0x8e7594b7,
+			0x8ff6e2fb, 0xf2122b64, 0x8888b812, 0x900df01c,
+			0x4fad5ea0, 0x688fc31c, 0xd1cff191, 0xb3a8c1ad,
+			0x2f2f2218, 0xbe0e1777, 0xea752dfe, 0x8b021fa1,
+			0xe5a0cc0f, 0xb56f74e8, 0x18acf3d6, 0xce89e299,
+			0xb4a84fe0, 0xfd13e0b7, 0x7cc43b81, 0xd2ada8d9,
+			0x165fa266, 0x80957705, 0x93cc7314, 0x211a1477,
+			0xe6ad2065, 0x77b5fa86, 0xc75442f5, 0xfb9d35cf,
+			0xebcdaf0c, 0x7b3e89a0, 0xd6411bd3, 0xae1e7e49,
+			0x00250e2d, 0x2071b35e, 0x226800bb, 0x57b8e0af,
+			0x2464369b, 0xf009b91e, 0x5563911d, 0x59dfa6aa,
+			0x78c14389, 0xd95a537f, 0x207d5ba2, 0x02e5b9c5,
+			0x83260376, 0x6295cfa9, 0x11c81968, 0x4e734a41,
+			0xb3472dca, 0x7b14a94a, 0x1b510052, 0x9a532915,
+			0xd60f573f, 0xbc9bc6e4, 0x2b60a476, 0x81e67400,
+			0x08ba6fb5, 0x571be91f, 0xf296ec6b, 0x2a0dd915,
+			0xb6636521, 0xe7b9f9b6, 0xff34052e, 0xc5855664,
+			0x53b02d5d, 0xa99f8fa1, 0x08ba4799, 0x6e85076a
+		}, {
+			0x4b7a70e9, 0xb5b32944, 0xdb75092e, 0xc4192623,
+			0xad6ea6b0, 0x49a7df7d, 0x9cee60b8, 0x8fedb266,
+			0xecaa8c71, 0x699a17ff, 0x5664526c, 0xc2b19ee1,
+			0x193602a5, 0x75094c29, 0xa0591340, 0xe4183a3e,
+			0x3f54989a, 0x5b429d65, 0x6b8fe4d6, 0x99f73fd6,
+			0xa1d29c07, 0xefe830f5, 0x4d2d38e6, 0xf0255dc1,
+			0x4cdd2086, 0x8470eb26, 0x6382e9c6, 0x021ecc5e,
+			0x09686b3f, 0x3ebaefc9, 0x3c971814, 0x6b6a70a1,
+			0x687f3584, 0x52a0e286, 0xb79c5305, 0xaa500737,
+			0x3e07841c, 0x7fdeae5c, 0x8e7d44ec, 0x5716f2b8,
+			0xb03ada37, 0xf0500c0d, 0xf01c1f04, 0x0200b3ff,
+			0xae0cf51a, 0x3cb574b2, 0x25837a58, 0xdc0921bd,
+			0xd19113f9, 0x7ca92ff6, 0x94324773, 0x22f54701,
+			0x3ae5e581, 0x37c2dadc, 0xc8b57634, 0x9af3dda7,
+			0xa9446146, 0x0fd0030e, 0xecc8c73e, 0xa4751e41,
+			0xe238cd99, 0x3bea0e2f, 0x3280bba1, 0x183eb331,
+			0x4e548b38, 0x4f6db908, 0x6f420d03, 0xf60a04bf,
+			0x2cb81290, 0x24977c79, 0x5679b072, 0xbcaf89af,
+			0xde9a771f, 0xd9930810, 0xb38bae12, 0xdccf3f2e,
+			0x5512721f, 0x2e6b7124, 0x501adde6, 0x9f84cd87,
+			0x7a584718, 0x7408da17, 0xbc9f9abc, 0xe94b7d8c,
+			0xec7aec3a, 0xdb851dfa, 0x63094366, 0xc464c3d2,
+			0xef1c1847, 0x3215d908, 0xdd433b37, 0x24c2ba16,
+			0x12a14d43, 0x2a65c451, 0x50940002, 0x133ae4dd,
+			0x71dff89e, 0x10314e55, 0x81ac77d6, 0x5f11199b,
+			0x043556f1, 0xd7a3c76b, 0x3c11183b, 0x5924a509,
+			0xf28fe6ed, 0x97f1fbfa, 0x9ebabf2c, 0x1e153c6e,
+			0x86e34570, 0xeae96fb1, 0x860e5e0a, 0x5a3e2ab3,
+			0x771fe71c, 0x4e3d06fa, 0x2965dcb9, 0x99e71d0f,
+			0x803e89d6, 0x5266c825, 0x2e4cc978, 0x9c10b36a,
+			0xc6150eba, 0x94e2ea78, 0xa5fc3c53, 0x1e0a2df4,
+			0xf2f74ea7, 0x361d2b3d, 0x1939260f, 0x19c27960,
+			0x5223a708, 0xf71312b6, 0xebadfe6e, 0xeac31f66,
+			0xe3bc4595, 0xa67bc883, 0xb17f37d1, 0x018cff28,
+			0xc332ddef, 0xbe6c5aa5, 0x65582185, 0x68ab9802,
+			0xeecea50f, 0xdb2f953b, 0x2aef7dad, 0x5b6e2f84,
+			0x1521b628, 0x29076170, 0xecdd4775, 0x619f1510,
+			0x13cca830, 0xeb61bd96, 0x0334fe1e, 0xaa0363cf,
+			0xb5735c90, 0x4c70a239, 0xd59e9e0b, 0xcbaade14,
+			0xeecc86bc, 0x60622ca7, 0x9cab5cab, 0xb2f3846e,
+			0x648b1eaf, 0x19bdf0ca, 0xa02369b9, 0x655abb50,
+			0x40685a32, 0x3c2ab4b3, 0x319ee9d5, 0xc021b8f7,
+			0x9b540b19, 0x875fa099, 0x95f7997e, 0x623d7da8,
+			0xf837889a, 0x97e32d77, 0x11ed935f, 0x16681281,
+			0x0e358829, 0xc7e61fd6, 0x96dedfa1, 0x7858ba99,
+			0x57f584a5, 0x1b227263, 0x9b83c3ff, 0x1ac24696,
+			0xcdb30aeb, 0x532e3054, 0x8fd948e4, 0x6dbc3128,
+			0x58ebf2ef, 0x34c6ffea, 0xfe28ed61, 0xee7c3c73,
+			0x5d4a14d9, 0xe864b7e3, 0x42105d14, 0x203e13e0,
+			0x45eee2b6, 0xa3aaabea, 0xdb6c4f15, 0xfacb4fd0,
+			0xc742f442, 0xef6abbb5, 0x654f3b1d, 0x41cd2105,
+			0xd81e799e, 0x86854dc7, 0xe44b476a, 0x3d816250,
+			0xcf62a1f2, 0x5b8d2646, 0xfc8883a0, 0xc1c7b6a3,
+			0x7f1524c3, 0x69cb7492, 0x47848a0b, 0x5692b285,
+			0x095bbf00, 0xad19489d, 0x1462b174, 0x23820e00,
+			0x58428d2a, 0x0c55f5ea, 0x1dadf43e, 0x233f7061,
+			0x3372f092, 0x8d937e41, 0xd65fecf1, 0x6c223bdb,
+			0x7cde3759, 0xcbee7460, 0x4085f2a7, 0xce77326e,
+			0xa6078084, 0x19f8509e, 0xe8efd855, 0x61d99735,
+			0xa969a7aa, 0xc50c06c2, 0x5a04abfc, 0x800bcadc,
+			0x9e447a2e, 0xc3453484, 0xfdd56705, 0x0e1e9ec9,
+			0xdb73dbd3, 0x105588cd, 0x675fda79, 0xe3674340,
+			0xc5c43465, 0x713e38d8, 0x3d28f89e, 0xf16dff20,
+			0x153e21e7, 0x8fb03d4a, 0xe6e39f2b, 0xdb83adf7
+		}, {
+			0xe93d5a68, 0x948140f7, 0xf64c261c, 0x94692934,
+			0x411520f7, 0x7602d4f7, 0xbcf46b2e, 0xd4a20068,
+			0xd4082471, 0x3320f46a, 0x43b7d4b7, 0x500061af,
+			0x1e39f62e, 0x97244546, 0x14214f74, 0xbf8b8840,
+			0x4d95fc1d, 0x96b591af, 0x70f4ddd3, 0x66a02f45,
+			0xbfbc09ec, 0x03bd9785, 0x7fac6dd0, 0x31cb8504,
+			0x96eb27b3, 0x55fd3941, 0xda2547e6, 0xabca0a9a,
+			0x28507825, 0x530429f4, 0x0a2c86da, 0xe9b66dfb,
+			0x68dc1462, 0xd7486900, 0x680ec0a4, 0x27a18dee,
+			0x4f3ffea2, 0xe887ad8c, 0xb58ce006, 0x7af4d6b6,
+			0xaace1e7c, 0xd3375fec, 0xce78a399, 0x406b2a42,
+			0x20fe9e35, 0xd9f385b9, 0xee39d7ab, 0x3b124e8b,
+			0x1dc9faf7, 0x4b6d1856, 0x26a36631, 0xeae397b2,
+			0x3a6efa74, 0xdd5b4332, 0x6841e7f7, 0xca7820fb,
+			0xfb0af54e, 0xd8feb397, 0x454056ac, 0xba489527,
+			0x55533a3a, 0x20838d87, 0xfe6ba9b7, 0xd096954b,
+			0x55a867bc, 0xa1159a58, 0xcca92963, 0x99e1db33,
+			0xa62a4a56, 0x3f3125f9, 0x5ef47e1c, 0x9029317c,
+			0xfdf8e802, 0x04272f70, 0x80bb155c, 0x05282ce3,
+			0x95c11548, 0xe4c66d22, 0x48c1133f, 0xc70f86dc,
+			0x07f9c9ee, 0x41041f0f, 0x404779a4, 0x5d886e17,
+			0x325f51eb, 0xd59bc0d1, 0xf2bcc18f, 0x41113564,
+			0x257b7834, 0x602a9c60, 0xdff8e8a3, 0x1f636c1b,
+			0x0e12b4c2, 0x02e1329e, 0xaf664fd1, 0xcad18115,
+			0x6b2395e0, 0x333e92e1, 0x3b240b62, 0xeebeb922,
+			0x85b2a20e, 0xe6ba0d99, 0xde720c8c, 0x2da2f728,
+			0xd0127845, 0x95b794fd, 0x647d0862, 0xe7ccf5f0,
+			0x5449a36f, 0x877d48fa, 0xc39dfd27, 0xf33e8d1e,
+			0x0a476341, 0x992eff74, 0x3a6f6eab, 0xf4f8fd37,
+			0xa812dc60, 0xa1ebddf8, 0x991be14c, 0xdb6e6b0d,
+			0xc67b5510, 0x6d672c37, 0x2765d43b, 0xdcd0e804,
+			0xf1290dc7, 0xcc00ffa3, 0xb5390f92, 0x690fed0b,
+			0x667b9ffb, 0xcedb7d9c, 0xa091cf0b, 0xd9155ea3,
+			0xbb132f88, 0x515bad24, 0x7b9479bf, 0x763bd6eb,
+			0x37392eb3, 0xcc115979, 0x8026e297, 0xf42e312d,
+			0x6842ada7, 0xc66a2b3b, 0x12754ccc, 0x782ef11c,
+			0x6a124237, 0xb79251e7, 0x06a1bbe6, 0x4bfb6350,
+			0x1a6b1018, 0x11caedfa, 0x3d25bdd8, 0xe2e1c3c9,
+			0x44421659, 0x0a121386, 0xd90cec6e, 0xd5abea2a,
+			0x64af674e, 0xda86a85f, 0xbebfe988, 0x64e4c3fe,
+			0x9dbc8057, 0xf0f7c086, 0x60787bf8, 0x6003604d,
+			0xd1fd8346, 0xf6381fb0, 0x7745ae04, 0xd736fccc,
+			0x83426b33, 0xf01eab71, 0xb0804187, 0x3c005e5f,
+			0x77a057be, 0xbde8ae24, 0x55464299, 0xbf582e61,
+			0x4e58f48f, 0xf2ddfda2, 0xf474ef38, 0x8789bdc2,
+			0x5366f9c3, 0xc8b38e74, 0xb475f255, 0x46fcd9b9,
+			0x7aeb2661, 0x8b1ddf84, 0x846a0e79, 0x915f95e2,
+			0x466e598e, 0x20b45770, 0x8cd55591, 0xc902de4c,
+			0xb90bace1, 0xbb8205d0, 0x11a86248, 0x7574a99e,
+			0xb77f19b6, 0xe0a9dc09, 0x662d09a1, 0xc4324633,
+			0xe85a1f02, 0x09f0be8c, 0x4a99a025, 0x1d6efe10,
+			0x1ab93d1d, 0x0ba5a4df, 0xa186f20f, 0x2868f169,
+			0xdcb7da83, 0x573906fe, 0xa1e2ce9b, 0x4fcd7f52,
+			0x50115e01, 0xa70683fa, 0xa002b5c4, 0x0de6d027,
+			0x9af88c27, 0x773f8641, 0xc3604c06, 0x61a806b5,
+			0xf0177a28, 0xc0f586e0, 0x006058aa, 0x30dc7d62,
+			0x11e69ed7, 0x2338ea63, 0x53c2dd94, 0xc2c21634,
+			0xbbcbee56, 0x90bcb6de, 0xebfc7da1, 0xce591d76,
+			0x6f05e409, 0x4b7c0188, 0x39720a3d, 0x7c927c24,
+			0x86e3725f, 0x724d9db9, 0x1ac15bb4, 0xd39eb8fc,
+			0xed545578, 0x08fca5b5, 0xd83d7cd3, 0x4dad0fc4,
+			0x1e50ef5e, 0xb161e6f8, 0xa28514d9, 0x6c51133c,
+			0x6fd5c7e7, 0x56e14ec4, 0x362abfce, 0xddc6c837,
+			0xd79a3234, 0x92638212, 0x670efa8e, 0x406000e0
+		}, {
+			0x3a39ce37, 0xd3faf5cf, 0xabc27737, 0x5ac52d1b,
+			0x5cb0679e, 0x4fa33742, 0xd3822740, 0x99bc9bbe,
+			0xd5118e9d, 0xbf0f7315, 0xd62d1c7e, 0xc700c47b,
+			0xb78c1b6b, 0x21a19045, 0xb26eb1be, 0x6a366eb4,
+			0x5748ab2f, 0xbc946e79, 0xc6a376d2, 0x6549c2c8,
+			0x530ff8ee, 0x468dde7d, 0xd5730a1d, 0x4cd04dc6,
+			0x2939bbdb, 0xa9ba4650, 0xac9526e8, 0xbe5ee304,
+			0xa1fad5f0, 0x6a2d519a, 0x63ef8ce2, 0x9a86ee22,
+			0xc089c2b8, 0x43242ef6, 0xa51e03aa, 0x9cf2d0a4,
+			0x83c061ba, 0x9be96a4d, 0x8fe51550, 0xba645bd6,
+			0x2826a2f9, 0xa73a3ae1, 0x4ba99586, 0xef5562e9,
+			0xc72fefd3, 0xf752f7da, 0x3f046f69, 0x77fa0a59,
+			0x80e4a915, 0x87b08601, 0x9b09e6ad, 0x3b3ee593,
+			0xe990fd5a, 0x9e34d797, 0x2cf0b7d9, 0x022b8b51,
+			0x96d5ac3a, 0x017da67d, 0xd1cf3ed6, 0x7c7d2d28,
+			0x1f9f25cf, 0xadf2b89b, 0x5ad6b472, 0x5a88f54c,
+			0xe029ac71, 0xe019a5e6, 0x47b0acfd, 0xed93fa9b,
+			0xe8d3c48d, 0x283b57cc, 0xf8d56629, 0x79132e28,
+			0x785f0191, 0xed756055, 0xf7960e44, 0xe3d35e8c,
+			0x15056dd4, 0x88f46dba, 0x03a16125, 0x0564f0bd,
+			0xc3eb9e15, 0x3c9057a2, 0x97271aec, 0xa93a072a,
+			0x1b3f6d9b, 0x1e6321f5, 0xf59c66fb, 0x26dcf319,
+			0x7533d928, 0xb155fdf5, 0x03563482, 0x8aba3cbb,
+			0x28517711, 0xc20ad9f8, 0xabcc5167, 0xccad925f,
+			0x4de81751, 0x3830dc8e, 0x379d5862, 0x9320f991,
+			0xea7a90c2, 0xfb3e7bce, 0x5121ce64, 0x774fbe32,
+			0xa8b6e37e, 0xc3293d46, 0x48de5369, 0x6413e680,
+			0xa2ae0810, 0xdd6db224, 0x69852dfd, 0x09072166,
+			0xb39a460a, 0x6445c0dd, 0x586cdecf, 0x1c20c8ae,
+			0x5bbef7dd, 0x1b588d40, 0xccd2017f, 0x6bb4e3bb,
+			0xdda26a7e, 0x3a59ff45, 0x3e350a44, 0xbcb4cdd5,
+			0x72eacea8, 0xfa6484bb, 0x8d6612ae, 0xbf3c6f47,
+			0xd29be463, 0x542f5d9e, 0xaec2771b, 0xf64e6370,
+			0x740e0d8d, 0xe75b1357, 0xf8721671, 0xaf537d5d,
+			0x4040cb08, 0x4eb4e2cc, 0x34d2466a, 0x0115af84,
+			0xe1b00428, 0x95983a1d, 0x06b89fb4, 0xce6ea048,
+			0x6f3f3b82, 0x3520ab82, 0x011a1d4b, 0x277227f8,
+			0x611560b1, 0xe7933fdc, 0xbb3a792b, 0x344525bd,
+			0xa08839e1, 0x51ce794b, 0x2f32c9b7, 0xa01fbac9,
+			0xe01cc87e, 0xbcc7d1f6, 0xcf0111c3, 0xa1e8aac7,
+			0x1a908749, 0xd44fbd9a, 0xd0dadecb, 0xd50ada38,
+			0x0339c32a, 0xc6913667, 0x8df9317c, 0xe0b12b4f,
+			0xf79e59b7, 0x43f5bb3a, 0xf2d519ff, 0x27d9459c,
+			0xbf97222c, 0x15e6fc2a, 0x0f91fc71, 0x9b941525,
+			0xfae59361, 0xceb69ceb, 0xc2a86459, 0x12baa8d1,
+			0xb6c1075e, 0xe3056a0c, 0x10d25065, 0xcb03a442,
+			0xe0ec6e0e, 0x1698db3b, 0x4c98a0be, 0x3278e964,
+			0x9f1f9532, 0xe0d392df, 0xd3a0342b, 0x8971f21e,
+			0x1b0a7441, 0x4ba3348c, 0xc5be7120, 0xc37632d8,
+			0xdf359f8d, 0x9b992f2e, 0xe60b6f47, 0x0fe3f11d,
+			0xe54cda54, 0x1edad891, 0xce6279cf, 0xcd3e7e6f,
+			0x1618b166, 0xfd2c1d05, 0x848fd2c5, 0xf6fb2299,
+			0xf523f357, 0xa6327623, 0x93a83531, 0x56cccd02,
+			0xacf08162, 0x5a75ebb5, 0x6e163697, 0x88d273cc,
+			0xde966292, 0x81b949d0, 0x4c50901b, 0x71c65614,
+			0xe6c6c7bd, 0x327a140a, 0x45e1d006, 0xc3f27b9a,
+			0xc9aa53fd, 0x62a80f00, 0xbb25bfe2, 0x35bdd2f6,
+			0x71126905, 0xb2040222, 0xb6cbcf7c, 0xcd769c2b,
+			0x53113ec0, 0x1640e3d3, 0x38abbd60, 0x2547adf0,
+			0xba38209c, 0xf746ce76, 0x77afa1c5, 0x20756060,
+			0x85cbfe4e, 0x8ae88dd8, 0x7aaaf9b0, 0x4cf9aa7e,
+			0x1948c25c, 0x02fb8a8c, 0x01c36ae4, 0xd6ebe1f9,
+			0x90d4f869, 0xa65cdea0, 0x3f09252d, 0xc208e69f,
+			0xb74e6132, 0xce77e25b, 0x578fdfe3, 0x3ac372e6
+		}
+	}
+}};
+
+static const unsigned char BF_itoa64[64 + 1] =
+	"./ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
+
+static const unsigned char BF_atoi64[0x60] = {
+	64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 0, 1,
+	54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 64, 64, 64, 64, 64,
+	64, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,
+	17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 64, 64, 64, 64, 64,
+	64, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42,
+	43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 64, 64, 64, 64, 64
+};
+
+#define BF_safe_atoi64(dst, src) \
+{ \
+	tmp = (unsigned char)(src); \
+	if ((unsigned int)(tmp -= 0x20) >= 0x60) return -1; \
+	tmp = BF_atoi64[tmp]; \
+	if (tmp > 63) return -1; \
+	(dst) = tmp; \
+}
+
+static int BF_decode(BF_word *dst, const char *src, int size)
+{
+	unsigned char *dptr = (unsigned char *)dst;
+	unsigned char *end = dptr + size;
+	const unsigned char *sptr = (const unsigned char *)src;
+	unsigned int tmp, c1, c2, c3, c4;
+
+	do {
+		BF_safe_atoi64(c1, *sptr++);
+		BF_safe_atoi64(c2, *sptr++);
+		*dptr++ = (c1 << 2) | ((c2 & 0x30) >> 4);
+		if (dptr >= end) break;
+
+		BF_safe_atoi64(c3, *sptr++);
+		*dptr++ = ((c2 & 0x0F) << 4) | ((c3 & 0x3C) >> 2);
+		if (dptr >= end) break;
+
+		BF_safe_atoi64(c4, *sptr++);
+		*dptr++ = ((c3 & 0x03) << 6) | c4;
+	} while (dptr < end);
+
+	return 0;
+}
+
+static void BF_encode(char *dst, const BF_word *src, int size)
+{
+	const unsigned char *sptr = (const unsigned char *)src;
+	const unsigned char *end = sptr + size;
+	unsigned char *dptr = (unsigned char *)dst;
+	unsigned int c1, c2;
+
+	do {
+		c1 = *sptr++;
+		*dptr++ = BF_itoa64[c1 >> 2];
+		c1 = (c1 & 0x03) << 4;
+		if (sptr >= end) {
+			*dptr++ = BF_itoa64[c1];
+			break;
+		}
+
+		c2 = *sptr++;
+		c1 |= c2 >> 4;
+		*dptr++ = BF_itoa64[c1];
+		c1 = (c2 & 0x0f) << 2;
+		if (sptr >= end) {
+			*dptr++ = BF_itoa64[c1];
+			break;
+		}
+
+		c2 = *sptr++;
+		c1 |= c2 >> 6;
+		*dptr++ = BF_itoa64[c1];
+		*dptr++ = BF_itoa64[c2 & 0x3f];
+	} while (sptr < end);
+}
+
+static void BF_swap(BF_word *x, int count)
+{
+	if ((union { int i; char c; }){1}.c)
+	do {
+		BF_word tmp = *x;
+		tmp = (tmp << 16) | (tmp >> 16);
+		*x++ = ((tmp & 0x00FF00FF) << 8) | ((tmp >> 8) & 0x00FF00FF);
+	} while (--count);
+}
+
+#define BF_ROUND(L, R, N) \
+	tmp1 = L & 0xFF; \
+	tmp2 = L >> 8; \
+	tmp2 &= 0xFF; \
+	tmp3 = L >> 16; \
+	tmp3 &= 0xFF; \
+	tmp4 = L >> 24; \
+	tmp1 = ctx->s.S[3][tmp1]; \
+	tmp2 = ctx->s.S[2][tmp2]; \
+	tmp3 = ctx->s.S[1][tmp3]; \
+	tmp3 += ctx->s.S[0][tmp4]; \
+	tmp3 ^= tmp2; \
+	R ^= ctx->s.P[N + 1]; \
+	tmp3 += tmp1; \
+	R ^= tmp3;
+
+static BF_word BF_encrypt(BF_ctx *ctx,
+    BF_word L, BF_word R,
+    BF_word *start, BF_word *end)
+{
+	BF_word tmp1, tmp2, tmp3, tmp4;
+	BF_word *ptr = start;
+
+	do {
+		L ^= ctx->s.P[0];
+#if 0
+		BF_ROUND(L, R, 0);
+		BF_ROUND(R, L, 1);
+		BF_ROUND(L, R, 2);
+		BF_ROUND(R, L, 3);
+		BF_ROUND(L, R, 4);
+		BF_ROUND(R, L, 5);
+		BF_ROUND(L, R, 6);
+		BF_ROUND(R, L, 7);
+		BF_ROUND(L, R, 8);
+		BF_ROUND(R, L, 9);
+		BF_ROUND(L, R, 10);
+		BF_ROUND(R, L, 11);
+		BF_ROUND(L, R, 12);
+		BF_ROUND(R, L, 13);
+		BF_ROUND(L, R, 14);
+		BF_ROUND(R, L, 15);
+#else
+		for (int i=0; i<16; i+=2) {
+			BF_ROUND(L, R, i);
+			BF_ROUND(R, L, i+1);
+		}
+#endif
+		tmp4 = R;
+		R = L;
+		L = tmp4 ^ ctx->s.P[BF_N + 1];
+		*ptr++ = L;
+		*ptr++ = R;
+	} while (ptr < end);
+
+	return L;
+}
+
+static void BF_set_key(const char *key, BF_key expanded, BF_key initial,
+    unsigned char flags)
+{
+	const char *ptr = key;
+	unsigned int bug, i, j;
+	BF_word safety, sign, diff, tmp[2];
+
+/*
+ * There was a sign extension bug in older revisions of this function.  While
+ * we would have liked to simply fix the bug and move on, we have to provide
+ * a backwards compatibility feature (essentially the bug) for some systems and
+ * a safety measure for some others.  The latter is needed because for certain
+ * multiple inputs to the buggy algorithm there exist easily found inputs to
+ * the correct algorithm that produce the same hash.  Thus, we optionally
+ * deviate from the correct algorithm just enough to avoid such collisions.
+ * While the bug itself affected the majority of passwords containing
+ * characters with the 8th bit set (although only a percentage of those in a
+ * collision-producing way), the anti-collision safety measure affects
+ * only a subset of passwords containing the '\xff' character (not even all of
+ * those passwords, just some of them).  This character is not found in valid
+ * UTF-8 sequences and is rarely used in popular 8-bit character encodings.
+ * Thus, the safety measure is unlikely to cause much annoyance, and is a
+ * reasonable tradeoff to use when authenticating against existing hashes that
+ * are not reliably known to have been computed with the correct algorithm.
+ *
+ * We use an approach that tries to minimize side-channel leaks of password
+ * information - that is, we mostly use fixed-cost bitwise operations instead
+ * of branches or table lookups.  (One conditional branch based on password
+ * length remains.  It is not part of the bug aftermath, though, and is
+ * difficult and possibly unreasonable to avoid given the use of C strings by
+ * the caller, which results in similar timing leaks anyway.)
+ *
+ * For actual implementation, we set an array index in the variable "bug"
+ * (0 means no bug, 1 means sign extension bug emulation) and a flag in the
+ * variable "safety" (bit 16 is set when the safety measure is requested).
+ * Valid combinations of settings are:
+ *
+ * Prefix "$2a$": bug = 0, safety = 0x10000
+ * Prefix "$2x$": bug = 1, safety = 0
+ * Prefix "$2y$": bug = 0, safety = 0
+ */
+	bug = flags & 1;
+	safety = ((BF_word)flags & 2) << 15;
+
+	sign = diff = 0;
+
+	for (i = 0; i < BF_N + 2; i++) {
+		tmp[0] = tmp[1] = 0;
+		for (j = 0; j < 4; j++) {
+			tmp[0] <<= 8;
+			tmp[0] |= (unsigned char)*ptr; /* correct */
+			tmp[1] <<= 8;
+			tmp[1] |= (signed char)*ptr; /* bug */
+/*
+ * Sign extension in the first char has no effect - nothing to overwrite yet,
+ * and those extra 24 bits will be fully shifted out of the 32-bit word.  For
+ * chars 2, 3, 4 in each four-char block, we set bit 7 of "sign" if sign
+ * extension in tmp[1] occurs.  Once this flag is set, it remains set.
+ */
+			if (j)
+				sign |= tmp[1] & 0x80;
+			if (!*ptr)
+				ptr = key;
+			else
+				ptr++;
+		}
+		diff |= tmp[0] ^ tmp[1]; /* Non-zero on any differences */
+
+		expanded[i] = tmp[bug];
+		initial[i] = BF_init_state.s.P[i] ^ tmp[bug];
+	}
+
+/*
+ * At this point, "diff" is zero iff the correct and buggy algorithms produced
+ * exactly the same result.  If so and if "sign" is non-zero, which indicates
+ * that there was a non-benign sign extension, this means that we have a
+ * collision between the correctly computed hash for this password and a set of
+ * passwords that could be supplied to the buggy algorithm.  Our safety measure
+ * is meant to protect from such many-buggy to one-correct collisions, by
+ * deviating from the correct algorithm in such cases.  Let's check for this.
+ */
+	diff |= diff >> 16; /* still zero iff exact match */
+	diff &= 0xffff; /* ditto */
+	diff += 0xffff; /* bit 16 set iff "diff" was non-zero (on non-match) */
+	sign <<= 9; /* move the non-benign sign extension flag to bit 16 */
+	sign &= ~diff & safety; /* action needed? */
+
+/*
+ * If we have determined that we need to deviate from the correct algorithm,
+ * flip bit 16 in initial expanded key.  (The choice of 16 is arbitrary, but
+ * let's stick to it now.  It came out of the approach we used above, and it's
+ * not any worse than any other choice we could make.)
+ *
+ * It is crucial that we don't do the same to the expanded key used in the main
+ * Eksblowfish loop.  By doing it to only one of these two, we deviate from a
+ * state that could be directly specified by a password to the buggy algorithm
+ * (and to the fully correct one as well, but that's a side-effect).
+ */
+	initial[0] ^= sign;
+}
+
+static char *BF_crypt(const char *key, const char *setting,
+	char *output, BF_word min)
+{
+	static const unsigned char flags_by_subtype[26] =
+		{2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+		0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 4, 0};
+	struct {
+		BF_ctx ctx;
+		BF_key expanded_key;
+		union {
+			BF_word salt[4];
+			BF_word output[6];
+		} binary;
+	} data;
+	BF_word count;
+	int i;
+
+	if (setting[0] != '$' ||
+	    setting[1] != '2' ||
+	    setting[2] - 'a' > 25U ||
+	    !flags_by_subtype[setting[2] - 'a'] ||
+	    setting[3] != '$' ||
+	    setting[4] - '0' > 1U ||
+	    setting[5] - '0' > 9U ||
+	    setting[6] != '$') {
+		return NULL;
+	}
+
+	count = (BF_word)1 << ((setting[4] - '0') * 10 + (setting[5] - '0'));
+	if (count < min || BF_decode(data.binary.salt, &setting[7], 16)) {
+		return NULL;
+	}
+	BF_swap(data.binary.salt, 4);
+
+	BF_set_key(key, data.expanded_key, data.ctx.s.P,
+	    flags_by_subtype[setting[2] - 'a']);
+
+	memcpy(data.ctx.s.S, BF_init_state.s.S, sizeof(data.ctx.s.S));
+
+	{
+		BF_word L = 0, R = 0;
+		BF_word *ptr = &data.ctx.PS[0];
+		do {
+			L = BF_encrypt(&data.ctx,
+			    L ^ data.binary.salt[0], R ^ data.binary.salt[1],
+			    ptr, ptr);
+			R = *(ptr + 1);
+			ptr += 2;
+
+			if (ptr >= &data.ctx.PS[BF_N + 2 + 4 * 0x100])
+				break;
+
+			L = BF_encrypt(&data.ctx,
+			    L ^ data.binary.salt[2], R ^ data.binary.salt[3],
+			    ptr, ptr);
+			R = *(ptr + 1);
+			ptr += 2;
+		} while (1);
+	}
+
+	do {
+		int done;
+
+		for (i = 0; i < BF_N + 2; i += 2) {
+			data.ctx.s.P[i] ^= data.expanded_key[i];
+			data.ctx.s.P[i + 1] ^= data.expanded_key[i + 1];
+		}
+
+		done = 0;
+		do {
+			BF_encrypt(&data.ctx, 0, 0,
+			    &data.ctx.PS[0],
+			    &data.ctx.PS[BF_N + 2 + 4 * 0x100]);
+
+			if (done)
+				break;
+			done = 1;
+
+			{
+				BF_word tmp1, tmp2, tmp3, tmp4;
+
+				tmp1 = data.binary.salt[0];
+				tmp2 = data.binary.salt[1];
+				tmp3 = data.binary.salt[2];
+				tmp4 = data.binary.salt[3];
+				for (i = 0; i < BF_N; i += 4) {
+					data.ctx.s.P[i] ^= tmp1;
+					data.ctx.s.P[i + 1] ^= tmp2;
+					data.ctx.s.P[i + 2] ^= tmp3;
+					data.ctx.s.P[i + 3] ^= tmp4;
+				}
+				data.ctx.s.P[16] ^= tmp1;
+				data.ctx.s.P[17] ^= tmp2;
+			}
+		} while (1);
+	} while (--count);
+
+	for (i = 0; i < 6; i += 2) {
+		BF_word L, LR[2];
+
+		L = BF_magic_w[i];
+		LR[1] = BF_magic_w[i + 1];
+
+		count = 64;
+		do {
+			L = BF_encrypt(&data.ctx, L, LR[1],
+			    &LR[0], &LR[0]);
+		} while (--count);
+
+		data.binary.output[i] = L;
+		data.binary.output[i + 1] = LR[1];
+	}
+
+	memcpy(output, setting, 7 + 22 - 1);
+	output[7 + 22 - 1] = BF_itoa64[
+		BF_atoi64[setting[7 + 22 - 1] - 0x20] & 0x30];
+
+/* This has to be bug-compatible with the original implementation, so
+ * only encode 23 of the 24 bytes. :-) */
+	BF_swap(data.binary.output, 6);
+	BF_encode(&output[7 + 22], data.binary.output, 23);
+	output[7 + 22 + 31] = '\0';
+
+	return output;
+}
+
+/*
+ * Please preserve the runtime self-test.  It serves two purposes at once:
+ *
+ * 1. We really can't afford the risk of producing incompatible hashes e.g.
+ * when there's something like gcc bug 26587 again, whereas an application or
+ * library integrating this code might not also integrate our external tests or
+ * it might not run them after every build.  Even if it does, the miscompile
+ * might only occur on the production build, but not on a testing build (such
+ * as because of different optimization settings).  It is painful to recover
+ * from incorrectly-computed hashes - merely fixing whatever broke is not
+ * enough.  Thus, a proactive measure like this self-test is needed.
+ *
+ * 2. We don't want to leave sensitive data from our actual password hash
+ * computation on the stack or in registers.  Previous revisions of the code
+ * would do explicit cleanups, but simply running the self-test after hash
+ * computation is more reliable.
+ *
+ * The performance cost of this quick self-test is around 0.6% at the "$2a$08"
+ * setting.
+ */
+char *__crypt_blowfish(const char *key, const char *setting, char *output)
+{
+	const char *test_key = "8b \xd0\xc1\xd2\xcf\xcc\xd8";
+	const char *test_setting = "$2a$00$abcdefghijklmnopqrstuu";
+	static const char test_hash[2][34] =
+		{"VUrPmXD6q/nVSSp7pNDhCR9071IfIRe\0\x55", /* $2x$ */
+		"i1D709vfamulimlGcq0qq3UvuUasvEa\0\x55"}; /* $2a$, $2y$ */
+	char *retval;
+	const char *p;
+	int ok;
+	struct {
+		char s[7 + 22 + 1];
+		char o[7 + 22 + 31 + 1 + 1 + 1];
+	} buf;
+
+/* Hash the supplied password */
+	retval = BF_crypt(key, setting, output, 16);
+
+/*
+ * Do a quick self-test.  It is important that we make both calls to BF_crypt()
+ * from the same scope such that they likely use the same stack locations,
+ * which makes the second call overwrite the first call's sensitive data on the
+ * stack and makes it more likely that any alignment related issues would be
+ * detected by the self-test.
+ */
+	memcpy(buf.s, test_setting, sizeof(buf.s));
+	if (retval)
+		buf.s[2] = setting[2];
+	memset(buf.o, 0x55, sizeof(buf.o));
+	buf.o[sizeof(buf.o) - 1] = 0;
+	p = BF_crypt(test_key, buf.s, buf.o, 1);
+
+	ok = (p == buf.o &&
+	    !memcmp(p, buf.s, 7 + 22) &&
+	    !memcmp(p + (7 + 22),
+	    test_hash[buf.s[2] & 1],
+	    31 + 1 + 1 + 1));
+
+	{
+		const char *k = "\xff\xa3" "34" "\xff\xff\xff\xa3" "345";
+		BF_key ae, ai, ye, yi;
+		BF_set_key(k, ae, ai, 2); /* $2a$ */
+		BF_set_key(k, ye, yi, 4); /* $2y$ */
+		ai[0] ^= 0x10000; /* undo the safety (for comparison) */
+		ok = ok && ai[0] == 0xdb9c59bc && ye[17] == 0x33343500 &&
+		    !memcmp(ae, ye, sizeof(ae)) &&
+		    !memcmp(ai, yi, sizeof(ai));
+	}
+
+	if (ok && retval)
+		return retval;
+
+	return "*";
+}
libc/musl/src/crypt/crypt_des.c
@@ -0,0 +1,1016 @@
+/*
+ * This version has been further modified by Rich Felker, primary author
+ * and maintainer of musl libc, to remove table generation code and
+ * replaced all runtime-generated constant tables with static-initialized
+ * tables in the binary, in the interest of minimizing non-shareable
+ * memory usage and stack size requirements.
+ */
+/*
+ * This version is derived from the original implementation of FreeSec
+ * (release 1.1) by David Burren.  I've made it reentrant, reduced its memory
+ * usage from about 70 KB to about 7 KB (with only minimal performance impact
+ * and keeping code size about the same), made the handling of invalid salts
+ * mostly UFC-crypt compatible, added a quick runtime self-test (which also
+ * serves to zeroize the stack from sensitive data), and added optional tests.
+ * - Solar Designer <solar at openwall.com>
+ */
+
+/*
+ * FreeSec: libcrypt for NetBSD
+ *
+ * Copyright (c) 1994 David Burren
+ * Copyright (c) 2000,2002,2010,2012 Solar Designer
+ * 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.
+ * 3. Neither the name of the author nor the names of other contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ *	$Owl: Owl/packages/glibc/crypt_freesec.c,v 1.6 2010/02/20 14:45:06 solar Exp $
+ *	$Id: crypt.c,v 1.15 1994/09/13 04:58:49 davidb Exp $
+ *
+ * This is an original implementation of the DES and the crypt(3) interfaces
+ * by David Burren.  It has been heavily re-worked by Solar Designer.
+ */
+
+#include <stdint.h>
+#include <string.h>
+
+#include "crypt_des.h"
+
+#define _PASSWORD_EFMT1 '_'
+
+static const unsigned char key_shifts[16] = {
+	1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1
+};
+
+static const uint32_t psbox[8][64] = {
+	{
+		0x00808200,0x00000000,0x00008000,0x00808202,
+		0x00808002,0x00008202,0x00000002,0x00008000,
+		0x00000200,0x00808200,0x00808202,0x00000200,
+		0x00800202,0x00808002,0x00800000,0x00000002,
+		0x00000202,0x00800200,0x00800200,0x00008200,
+		0x00008200,0x00808000,0x00808000,0x00800202,
+		0x00008002,0x00800002,0x00800002,0x00008002,
+		0x00000000,0x00000202,0x00008202,0x00800000,
+		0x00008000,0x00808202,0x00000002,0x00808000,
+		0x00808200,0x00800000,0x00800000,0x00000200,
+		0x00808002,0x00008000,0x00008200,0x00800002,
+		0x00000200,0x00000002,0x00800202,0x00008202,
+		0x00808202,0x00008002,0x00808000,0x00800202,
+		0x00800002,0x00000202,0x00008202,0x00808200,
+		0x00000202,0x00800200,0x00800200,0x00000000,
+		0x00008002,0x00008200,0x00000000,0x00808002,
+	},{
+		0x40084010,0x40004000,0x00004000,0x00084010,
+		0x00080000,0x00000010,0x40080010,0x40004010,
+		0x40000010,0x40084010,0x40084000,0x40000000,
+		0x40004000,0x00080000,0x00000010,0x40080010,
+		0x00084000,0x00080010,0x40004010,0x00000000,
+		0x40000000,0x00004000,0x00084010,0x40080000,
+		0x00080010,0x40000010,0x00000000,0x00084000,
+		0x00004010,0x40084000,0x40080000,0x00004010,
+		0x00000000,0x00084010,0x40080010,0x00080000,
+		0x40004010,0x40080000,0x40084000,0x00004000,
+		0x40080000,0x40004000,0x00000010,0x40084010,
+		0x00084010,0x00000010,0x00004000,0x40000000,
+		0x00004010,0x40084000,0x00080000,0x40000010,
+		0x00080010,0x40004010,0x40000010,0x00080010,
+		0x00084000,0x00000000,0x40004000,0x00004010,
+		0x40000000,0x40080010,0x40084010,0x00084000,
+	},{
+		0x00000104,0x04010100,0x00000000,0x04010004,
+		0x04000100,0x00000000,0x00010104,0x04000100,
+		0x00010004,0x04000004,0x04000004,0x00010000,
+		0x04010104,0x00010004,0x04010000,0x00000104,
+		0x04000000,0x00000004,0x04010100,0x00000100,
+		0x00010100,0x04010000,0x04010004,0x00010104,
+		0x04000104,0x00010100,0x00010000,0x04000104,
+		0x00000004,0x04010104,0x00000100,0x04000000,
+		0x04010100,0x04000000,0x00010004,0x00000104,
+		0x00010000,0x04010100,0x04000100,0x00000000,
+		0x00000100,0x00010004,0x04010104,0x04000100,
+		0x04000004,0x00000100,0x00000000,0x04010004,
+		0x04000104,0x00010000,0x04000000,0x04010104,
+		0x00000004,0x00010104,0x00010100,0x04000004,
+		0x04010000,0x04000104,0x00000104,0x04010000,
+		0x00010104,0x00000004,0x04010004,0x00010100,
+	},{
+		0x80401000,0x80001040,0x80001040,0x00000040,
+		0x00401040,0x80400040,0x80400000,0x80001000,
+		0x00000000,0x00401000,0x00401000,0x80401040,
+		0x80000040,0x00000000,0x00400040,0x80400000,
+		0x80000000,0x00001000,0x00400000,0x80401000,
+		0x00000040,0x00400000,0x80001000,0x00001040,
+		0x80400040,0x80000000,0x00001040,0x00400040,
+		0x00001000,0x00401040,0x80401040,0x80000040,
+		0x00400040,0x80400000,0x00401000,0x80401040,
+		0x80000040,0x00000000,0x00000000,0x00401000,
+		0x00001040,0x00400040,0x80400040,0x80000000,
+		0x80401000,0x80001040,0x80001040,0x00000040,
+		0x80401040,0x80000040,0x80000000,0x00001000,
+		0x80400000,0x80001000,0x00401040,0x80400040,
+		0x80001000,0x00001040,0x00400000,0x80401000,
+		0x00000040,0x00400000,0x00001000,0x00401040,
+	},{
+		0x00000080,0x01040080,0x01040000,0x21000080,
+		0x00040000,0x00000080,0x20000000,0x01040000,
+		0x20040080,0x00040000,0x01000080,0x20040080,
+		0x21000080,0x21040000,0x00040080,0x20000000,
+		0x01000000,0x20040000,0x20040000,0x00000000,
+		0x20000080,0x21040080,0x21040080,0x01000080,
+		0x21040000,0x20000080,0x00000000,0x21000000,
+		0x01040080,0x01000000,0x21000000,0x00040080,
+		0x00040000,0x21000080,0x00000080,0x01000000,
+		0x20000000,0x01040000,0x21000080,0x20040080,
+		0x01000080,0x20000000,0x21040000,0x01040080,
+		0x20040080,0x00000080,0x01000000,0x21040000,
+		0x21040080,0x00040080,0x21000000,0x21040080,
+		0x01040000,0x00000000,0x20040000,0x21000000,
+		0x00040080,0x01000080,0x20000080,0x00040000,
+		0x00000000,0x20040000,0x01040080,0x20000080,
+	},{
+		0x10000008,0x10200000,0x00002000,0x10202008,
+		0x10200000,0x00000008,0x10202008,0x00200000,
+		0x10002000,0x00202008,0x00200000,0x10000008,
+		0x00200008,0x10002000,0x10000000,0x00002008,
+		0x00000000,0x00200008,0x10002008,0x00002000,
+		0x00202000,0x10002008,0x00000008,0x10200008,
+		0x10200008,0x00000000,0x00202008,0x10202000,
+		0x00002008,0x00202000,0x10202000,0x10000000,
+		0x10002000,0x00000008,0x10200008,0x00202000,
+		0x10202008,0x00200000,0x00002008,0x10000008,
+		0x00200000,0x10002000,0x10000000,0x00002008,
+		0x10000008,0x10202008,0x00202000,0x10200000,
+		0x00202008,0x10202000,0x00000000,0x10200008,
+		0x00000008,0x00002000,0x10200000,0x00202008,
+		0x00002000,0x00200008,0x10002008,0x00000000,
+		0x10202000,0x10000000,0x00200008,0x10002008,
+	},{
+		0x00100000,0x02100001,0x02000401,0x00000000,
+		0x00000400,0x02000401,0x00100401,0x02100400,
+		0x02100401,0x00100000,0x00000000,0x02000001,
+		0x00000001,0x02000000,0x02100001,0x00000401,
+		0x02000400,0x00100401,0x00100001,0x02000400,
+		0x02000001,0x02100000,0x02100400,0x00100001,
+		0x02100000,0x00000400,0x00000401,0x02100401,
+		0x00100400,0x00000001,0x02000000,0x00100400,
+		0x02000000,0x00100400,0x00100000,0x02000401,
+		0x02000401,0x02100001,0x02100001,0x00000001,
+		0x00100001,0x02000000,0x02000400,0x00100000,
+		0x02100400,0x00000401,0x00100401,0x02100400,
+		0x00000401,0x02000001,0x02100401,0x02100000,
+		0x00100400,0x00000000,0x00000001,0x02100401,
+		0x00000000,0x00100401,0x02100000,0x00000400,
+		0x02000001,0x02000400,0x00000400,0x00100001,
+	},{
+		0x08000820,0x00000800,0x00020000,0x08020820,
+		0x08000000,0x08000820,0x00000020,0x08000000,
+		0x00020020,0x08020000,0x08020820,0x00020800,
+		0x08020800,0x00020820,0x00000800,0x00000020,
+		0x08020000,0x08000020,0x08000800,0x00000820,
+		0x00020800,0x00020020,0x08020020,0x08020800,
+		0x00000820,0x00000000,0x00000000,0x08020020,
+		0x08000020,0x08000800,0x00020820,0x00020000,
+		0x00020820,0x00020000,0x08020800,0x00000800,
+		0x00000020,0x08020020,0x00000800,0x00020820,
+		0x08000800,0x00000020,0x08000020,0x08020000,
+		0x08020020,0x08000000,0x00020000,0x08000820,
+		0x00000000,0x08020820,0x00020020,0x08000020,
+		0x08020000,0x08000800,0x08000820,0x00000000,
+		0x08020820,0x00020800,0x00020800,0x00000820,
+		0x00000820,0x00020020,0x08000000,0x08020800,
+	},
+};
+static const uint32_t ip_maskl[16][16] = {
+	{
+		0x00000000,0x00010000,0x00000000,0x00010000,
+		0x01000000,0x01010000,0x01000000,0x01010000,
+		0x00000000,0x00010000,0x00000000,0x00010000,
+		0x01000000,0x01010000,0x01000000,0x01010000,
+	},{
+		0x00000000,0x00000001,0x00000000,0x00000001,
+		0x00000100,0x00000101,0x00000100,0x00000101,
+		0x00000000,0x00000001,0x00000000,0x00000001,
+		0x00000100,0x00000101,0x00000100,0x00000101,
+	},{
+		0x00000000,0x00020000,0x00000000,0x00020000,
+		0x02000000,0x02020000,0x02000000,0x02020000,
+		0x00000000,0x00020000,0x00000000,0x00020000,
+		0x02000000,0x02020000,0x02000000,0x02020000,
+	},{
+		0x00000000,0x00000002,0x00000000,0x00000002,
+		0x00000200,0x00000202,0x00000200,0x00000202,
+		0x00000000,0x00000002,0x00000000,0x00000002,
+		0x00000200,0x00000202,0x00000200,0x00000202,
+	},{
+		0x00000000,0x00040000,0x00000000,0x00040000,
+		0x04000000,0x04040000,0x04000000,0x04040000,
+		0x00000000,0x00040000,0x00000000,0x00040000,
+		0x04000000,0x04040000,0x04000000,0x04040000,
+	},{
+		0x00000000,0x00000004,0x00000000,0x00000004,
+		0x00000400,0x00000404,0x00000400,0x00000404,
+		0x00000000,0x00000004,0x00000000,0x00000004,
+		0x00000400,0x00000404,0x00000400,0x00000404,
+	},{
+		0x00000000,0x00080000,0x00000000,0x00080000,
+		0x08000000,0x08080000,0x08000000,0x08080000,
+		0x00000000,0x00080000,0x00000000,0x00080000,
+		0x08000000,0x08080000,0x08000000,0x08080000,
+	},{
+		0x00000000,0x00000008,0x00000000,0x00000008,
+		0x00000800,0x00000808,0x00000800,0x00000808,
+		0x00000000,0x00000008,0x00000000,0x00000008,
+		0x00000800,0x00000808,0x00000800,0x00000808,
+	},{
+		0x00000000,0x00100000,0x00000000,0x00100000,
+		0x10000000,0x10100000,0x10000000,0x10100000,
+		0x00000000,0x00100000,0x00000000,0x00100000,
+		0x10000000,0x10100000,0x10000000,0x10100000,
+	},{
+		0x00000000,0x00000010,0x00000000,0x00000010,
+		0x00001000,0x00001010,0x00001000,0x00001010,
+		0x00000000,0x00000010,0x00000000,0x00000010,
+		0x00001000,0x00001010,0x00001000,0x00001010,
+	},{
+		0x00000000,0x00200000,0x00000000,0x00200000,
+		0x20000000,0x20200000,0x20000000,0x20200000,
+		0x00000000,0x00200000,0x00000000,0x00200000,
+		0x20000000,0x20200000,0x20000000,0x20200000,
+	},{
+		0x00000000,0x00000020,0x00000000,0x00000020,
+		0x00002000,0x00002020,0x00002000,0x00002020,
+		0x00000000,0x00000020,0x00000000,0x00000020,
+		0x00002000,0x00002020,0x00002000,0x00002020,
+	},{
+		0x00000000,0x00400000,0x00000000,0x00400000,
+		0x40000000,0x40400000,0x40000000,0x40400000,
+		0x00000000,0x00400000,0x00000000,0x00400000,
+		0x40000000,0x40400000,0x40000000,0x40400000,
+	},{
+		0x00000000,0x00000040,0x00000000,0x00000040,
+		0x00004000,0x00004040,0x00004000,0x00004040,
+		0x00000000,0x00000040,0x00000000,0x00000040,
+		0x00004000,0x00004040,0x00004000,0x00004040,
+	},{
+		0x00000000,0x00800000,0x00000000,0x00800000,
+		0x80000000,0x80800000,0x80000000,0x80800000,
+		0x00000000,0x00800000,0x00000000,0x00800000,
+		0x80000000,0x80800000,0x80000000,0x80800000,
+	},{
+		0x00000000,0x00000080,0x00000000,0x00000080,
+		0x00008000,0x00008080,0x00008000,0x00008080,
+		0x00000000,0x00000080,0x00000000,0x00000080,
+		0x00008000,0x00008080,0x00008000,0x00008080,
+	},
+};
+static const uint32_t ip_maskr[16][16] = {
+	{
+		0x00000000,0x00000000,0x00010000,0x00010000,
+		0x00000000,0x00000000,0x00010000,0x00010000,
+		0x01000000,0x01000000,0x01010000,0x01010000,
+		0x01000000,0x01000000,0x01010000,0x01010000,
+	},{
+		0x00000000,0x00000000,0x00000001,0x00000001,
+		0x00000000,0x00000000,0x00000001,0x00000001,
+		0x00000100,0x00000100,0x00000101,0x00000101,
+		0x00000100,0x00000100,0x00000101,0x00000101,
+	},{
+		0x00000000,0x00000000,0x00020000,0x00020000,
+		0x00000000,0x00000000,0x00020000,0x00020000,
+		0x02000000,0x02000000,0x02020000,0x02020000,
+		0x02000000,0x02000000,0x02020000,0x02020000,
+	},{
+		0x00000000,0x00000000,0x00000002,0x00000002,
+		0x00000000,0x00000000,0x00000002,0x00000002,
+		0x00000200,0x00000200,0x00000202,0x00000202,
+		0x00000200,0x00000200,0x00000202,0x00000202,
+	},{
+		0x00000000,0x00000000,0x00040000,0x00040000,
+		0x00000000,0x00000000,0x00040000,0x00040000,
+		0x04000000,0x04000000,0x04040000,0x04040000,
+		0x04000000,0x04000000,0x04040000,0x04040000,
+	},{
+		0x00000000,0x00000000,0x00000004,0x00000004,
+		0x00000000,0x00000000,0x00000004,0x00000004,
+		0x00000400,0x00000400,0x00000404,0x00000404,
+		0x00000400,0x00000400,0x00000404,0x00000404,
+	},{
+		0x00000000,0x00000000,0x00080000,0x00080000,
+		0x00000000,0x00000000,0x00080000,0x00080000,
+		0x08000000,0x08000000,0x08080000,0x08080000,
+		0x08000000,0x08000000,0x08080000,0x08080000,
+	},{
+		0x00000000,0x00000000,0x00000008,0x00000008,
+		0x00000000,0x00000000,0x00000008,0x00000008,
+		0x00000800,0x00000800,0x00000808,0x00000808,
+		0x00000800,0x00000800,0x00000808,0x00000808,
+	},{
+		0x00000000,0x00000000,0x00100000,0x00100000,
+		0x00000000,0x00000000,0x00100000,0x00100000,
+		0x10000000,0x10000000,0x10100000,0x10100000,
+		0x10000000,0x10000000,0x10100000,0x10100000,
+	},{
+		0x00000000,0x00000000,0x00000010,0x00000010,
+		0x00000000,0x00000000,0x00000010,0x00000010,
+		0x00001000,0x00001000,0x00001010,0x00001010,
+		0x00001000,0x00001000,0x00001010,0x00001010,
+	},{
+		0x00000000,0x00000000,0x00200000,0x00200000,
+		0x00000000,0x00000000,0x00200000,0x00200000,
+		0x20000000,0x20000000,0x20200000,0x20200000,
+		0x20000000,0x20000000,0x20200000,0x20200000,
+	},{
+		0x00000000,0x00000000,0x00000020,0x00000020,
+		0x00000000,0x00000000,0x00000020,0x00000020,
+		0x00002000,0x00002000,0x00002020,0x00002020,
+		0x00002000,0x00002000,0x00002020,0x00002020,
+	},{
+		0x00000000,0x00000000,0x00400000,0x00400000,
+		0x00000000,0x00000000,0x00400000,0x00400000,
+		0x40000000,0x40000000,0x40400000,0x40400000,
+		0x40000000,0x40000000,0x40400000,0x40400000,
+	},{
+		0x00000000,0x00000000,0x00000040,0x00000040,
+		0x00000000,0x00000000,0x00000040,0x00000040,
+		0x00004000,0x00004000,0x00004040,0x00004040,
+		0x00004000,0x00004000,0x00004040,0x00004040,
+	},{
+		0x00000000,0x00000000,0x00800000,0x00800000,
+		0x00000000,0x00000000,0x00800000,0x00800000,
+		0x80000000,0x80000000,0x80800000,0x80800000,
+		0x80000000,0x80000000,0x80800000,0x80800000,
+	},{
+		0x00000000,0x00000000,0x00000080,0x00000080,
+		0x00000000,0x00000000,0x00000080,0x00000080,
+		0x00008000,0x00008000,0x00008080,0x00008080,
+		0x00008000,0x00008000,0x00008080,0x00008080,
+	},
+};
+static const uint32_t fp_maskl[8][16] = {
+	{
+		0x00000000,0x40000000,0x00400000,0x40400000,
+		0x00004000,0x40004000,0x00404000,0x40404000,
+		0x00000040,0x40000040,0x00400040,0x40400040,
+		0x00004040,0x40004040,0x00404040,0x40404040,
+	},{
+		0x00000000,0x10000000,0x00100000,0x10100000,
+		0x00001000,0x10001000,0x00101000,0x10101000,
+		0x00000010,0x10000010,0x00100010,0x10100010,
+		0x00001010,0x10001010,0x00101010,0x10101010,
+	},{
+		0x00000000,0x04000000,0x00040000,0x04040000,
+		0x00000400,0x04000400,0x00040400,0x04040400,
+		0x00000004,0x04000004,0x00040004,0x04040004,
+		0x00000404,0x04000404,0x00040404,0x04040404,
+	},{
+		0x00000000,0x01000000,0x00010000,0x01010000,
+		0x00000100,0x01000100,0x00010100,0x01010100,
+		0x00000001,0x01000001,0x00010001,0x01010001,
+		0x00000101,0x01000101,0x00010101,0x01010101,
+	},{
+		0x00000000,0x80000000,0x00800000,0x80800000,
+		0x00008000,0x80008000,0x00808000,0x80808000,
+		0x00000080,0x80000080,0x00800080,0x80800080,
+		0x00008080,0x80008080,0x00808080,0x80808080,
+	},{
+		0x00000000,0x20000000,0x00200000,0x20200000,
+		0x00002000,0x20002000,0x00202000,0x20202000,
+		0x00000020,0x20000020,0x00200020,0x20200020,
+		0x00002020,0x20002020,0x00202020,0x20202020,
+	},{
+		0x00000000,0x08000000,0x00080000,0x08080000,
+		0x00000800,0x08000800,0x00080800,0x08080800,
+		0x00000008,0x08000008,0x00080008,0x08080008,
+		0x00000808,0x08000808,0x00080808,0x08080808,
+	},{
+		0x00000000,0x02000000,0x00020000,0x02020000,
+		0x00000200,0x02000200,0x00020200,0x02020200,
+		0x00000002,0x02000002,0x00020002,0x02020002,
+		0x00000202,0x02000202,0x00020202,0x02020202,
+	},
+};
+static const uint32_t fp_maskr[8][16] = {
+	{
+		0x00000000,0x40000000,0x00400000,0x40400000,
+		0x00004000,0x40004000,0x00404000,0x40404000,
+		0x00000040,0x40000040,0x00400040,0x40400040,
+		0x00004040,0x40004040,0x00404040,0x40404040,
+	},{
+		0x00000000,0x10000000,0x00100000,0x10100000,
+		0x00001000,0x10001000,0x00101000,0x10101000,
+		0x00000010,0x10000010,0x00100010,0x10100010,
+		0x00001010,0x10001010,0x00101010,0x10101010,
+	},{
+		0x00000000,0x04000000,0x00040000,0x04040000,
+		0x00000400,0x04000400,0x00040400,0x04040400,
+		0x00000004,0x04000004,0x00040004,0x04040004,
+		0x00000404,0x04000404,0x00040404,0x04040404,
+	},{
+		0x00000000,0x01000000,0x00010000,0x01010000,
+		0x00000100,0x01000100,0x00010100,0x01010100,
+		0x00000001,0x01000001,0x00010001,0x01010001,
+		0x00000101,0x01000101,0x00010101,0x01010101,
+	},{
+		0x00000000,0x80000000,0x00800000,0x80800000,
+		0x00008000,0x80008000,0x00808000,0x80808000,
+		0x00000080,0x80000080,0x00800080,0x80800080,
+		0x00008080,0x80008080,0x00808080,0x80808080,
+	},{
+		0x00000000,0x20000000,0x00200000,0x20200000,
+		0x00002000,0x20002000,0x00202000,0x20202000,
+		0x00000020,0x20000020,0x00200020,0x20200020,
+		0x00002020,0x20002020,0x00202020,0x20202020,
+	},{
+		0x00000000,0x08000000,0x00080000,0x08080000,
+		0x00000800,0x08000800,0x00080800,0x08080800,
+		0x00000008,0x08000008,0x00080008,0x08080008,
+		0x00000808,0x08000808,0x00080808,0x08080808,
+	},{
+		0x00000000,0x02000000,0x00020000,0x02020000,
+		0x00000200,0x02000200,0x00020200,0x02020200,
+		0x00000002,0x02000002,0x00020002,0x02020002,
+		0x00000202,0x02000202,0x00020202,0x02020202,
+	},
+};
+static const uint32_t key_perm_maskl[8][16] = {
+	{
+		0x00000000,0x00000000,0x00000010,0x00000010,
+		0x00001000,0x00001000,0x00001010,0x00001010,
+		0x00100000,0x00100000,0x00100010,0x00100010,
+		0x00101000,0x00101000,0x00101010,0x00101010,
+	},{
+		0x00000000,0x00000000,0x00000020,0x00000020,
+		0x00002000,0x00002000,0x00002020,0x00002020,
+		0x00200000,0x00200000,0x00200020,0x00200020,
+		0x00202000,0x00202000,0x00202020,0x00202020,
+	},{
+		0x00000000,0x00000000,0x00000040,0x00000040,
+		0x00004000,0x00004000,0x00004040,0x00004040,
+		0x00400000,0x00400000,0x00400040,0x00400040,
+		0x00404000,0x00404000,0x00404040,0x00404040,
+	},{
+		0x00000000,0x00000000,0x00000080,0x00000080,
+		0x00008000,0x00008000,0x00008080,0x00008080,
+		0x00800000,0x00800000,0x00800080,0x00800080,
+		0x00808000,0x00808000,0x00808080,0x00808080,
+	},{
+		0x00000000,0x00000001,0x00000100,0x00000101,
+		0x00010000,0x00010001,0x00010100,0x00010101,
+		0x01000000,0x01000001,0x01000100,0x01000101,
+		0x01010000,0x01010001,0x01010100,0x01010101,
+	},{
+		0x00000000,0x00000002,0x00000200,0x00000202,
+		0x00020000,0x00020002,0x00020200,0x00020202,
+		0x02000000,0x02000002,0x02000200,0x02000202,
+		0x02020000,0x02020002,0x02020200,0x02020202,
+	},{
+		0x00000000,0x00000004,0x00000400,0x00000404,
+		0x00040000,0x00040004,0x00040400,0x00040404,
+		0x04000000,0x04000004,0x04000400,0x04000404,
+		0x04040000,0x04040004,0x04040400,0x04040404,
+	},{
+		0x00000000,0x00000008,0x00000800,0x00000808,
+		0x00080000,0x00080008,0x00080800,0x00080808,
+		0x08000000,0x08000008,0x08000800,0x08000808,
+		0x08080000,0x08080008,0x08080800,0x08080808,
+	},
+};
+static const uint32_t key_perm_maskr[12][16] = {
+	{
+		0x00000000,0x00000001,0x00000000,0x00000001,
+		0x00000000,0x00000001,0x00000000,0x00000001,
+		0x00000000,0x00000001,0x00000000,0x00000001,
+		0x00000000,0x00000001,0x00000000,0x00000001,
+	},{
+		0x00000000,0x00000000,0x00100000,0x00100000,
+		0x00001000,0x00001000,0x00101000,0x00101000,
+		0x00000010,0x00000010,0x00100010,0x00100010,
+		0x00001010,0x00001010,0x00101010,0x00101010,
+	},{
+		0x00000000,0x00000002,0x00000000,0x00000002,
+		0x00000000,0x00000002,0x00000000,0x00000002,
+		0x00000000,0x00000002,0x00000000,0x00000002,
+		0x00000000,0x00000002,0x00000000,0x00000002,
+	},{
+		0x00000000,0x00000000,0x00200000,0x00200000,
+		0x00002000,0x00002000,0x00202000,0x00202000,
+		0x00000020,0x00000020,0x00200020,0x00200020,
+		0x00002020,0x00002020,0x00202020,0x00202020,
+	},{
+		0x00000000,0x00000004,0x00000000,0x00000004,
+		0x00000000,0x00000004,0x00000000,0x00000004,
+		0x00000000,0x00000004,0x00000000,0x00000004,
+		0x00000000,0x00000004,0x00000000,0x00000004,
+	},{
+		0x00000000,0x00000000,0x00400000,0x00400000,
+		0x00004000,0x00004000,0x00404000,0x00404000,
+		0x00000040,0x00000040,0x00400040,0x00400040,
+		0x00004040,0x00004040,0x00404040,0x00404040,
+	},{
+		0x00000000,0x00000008,0x00000000,0x00000008,
+		0x00000000,0x00000008,0x00000000,0x00000008,
+		0x00000000,0x00000008,0x00000000,0x00000008,
+		0x00000000,0x00000008,0x00000000,0x00000008,
+	},{
+		0x00000000,0x00000000,0x00800000,0x00800000,
+		0x00008000,0x00008000,0x00808000,0x00808000,
+		0x00000080,0x00000080,0x00800080,0x00800080,
+		0x00008080,0x00008080,0x00808080,0x00808080,
+	},{
+		0x00000000,0x00000000,0x01000000,0x01000000,
+		0x00010000,0x00010000,0x01010000,0x01010000,
+		0x00000100,0x00000100,0x01000100,0x01000100,
+		0x00010100,0x00010100,0x01010100,0x01010100,
+	},{
+		0x00000000,0x00000000,0x02000000,0x02000000,
+		0x00020000,0x00020000,0x02020000,0x02020000,
+		0x00000200,0x00000200,0x02000200,0x02000200,
+		0x00020200,0x00020200,0x02020200,0x02020200,
+	},{
+		0x00000000,0x00000000,0x04000000,0x04000000,
+		0x00040000,0x00040000,0x04040000,0x04040000,
+		0x00000400,0x00000400,0x04000400,0x04000400,
+		0x00040400,0x00040400,0x04040400,0x04040400,
+	},{
+		0x00000000,0x00000000,0x08000000,0x08000000,
+		0x00080000,0x00080000,0x08080000,0x08080000,
+		0x00000800,0x00000800,0x08000800,0x08000800,
+		0x00080800,0x00080800,0x08080800,0x08080800,
+	},
+};
+static const uint32_t comp_maskl0[4][8] = {
+	{
+		0x00000000,0x00020000,0x00000001,0x00020001,
+		0x00080000,0x000a0000,0x00080001,0x000a0001,
+	},{
+		0x00000000,0x00001000,0x00000000,0x00001000,
+		0x00000040,0x00001040,0x00000040,0x00001040,
+	},{
+		0x00000000,0x00400000,0x00000020,0x00400020,
+		0x00008000,0x00408000,0x00008020,0x00408020,
+	},{
+		0x00000000,0x00100000,0x00000800,0x00100800,
+		0x00000000,0x00100000,0x00000800,0x00100800,
+	},
+};
+static const uint32_t comp_maskr0[4][8] = {
+	{
+		0x00000000,0x00200000,0x00020000,0x00220000,
+		0x00000002,0x00200002,0x00020002,0x00220002,
+	},{
+		0x00000000,0x00000000,0x00100000,0x00100000,
+		0x00000004,0x00000004,0x00100004,0x00100004,
+	},{
+		0x00000000,0x00004000,0x00000800,0x00004800,
+		0x00000000,0x00004000,0x00000800,0x00004800,
+	},{
+		0x00000000,0x00400000,0x00008000,0x00408000,
+		0x00000008,0x00400008,0x00008008,0x00408008,
+	},
+};
+static const uint32_t comp_maskl1[4][16] = {
+	{
+		0x00000000,0x00000010,0x00004000,0x00004010,
+		0x00040000,0x00040010,0x00044000,0x00044010,
+		0x00000100,0x00000110,0x00004100,0x00004110,
+		0x00040100,0x00040110,0x00044100,0x00044110,
+	},{
+		0x00000000,0x00800000,0x00000002,0x00800002,
+		0x00000200,0x00800200,0x00000202,0x00800202,
+		0x00200000,0x00a00000,0x00200002,0x00a00002,
+		0x00200200,0x00a00200,0x00200202,0x00a00202,
+	},{
+		0x00000000,0x00002000,0x00000004,0x00002004,
+		0x00000400,0x00002400,0x00000404,0x00002404,
+		0x00000000,0x00002000,0x00000004,0x00002004,
+		0x00000400,0x00002400,0x00000404,0x00002404,
+	},{
+		0x00000000,0x00010000,0x00000008,0x00010008,
+		0x00000080,0x00010080,0x00000088,0x00010088,
+		0x00000000,0x00010000,0x00000008,0x00010008,
+		0x00000080,0x00010080,0x00000088,0x00010088,
+	},
+};
+static const uint32_t comp_maskr1[4][16] = {
+	{
+		0x00000000,0x00000000,0x00000080,0x00000080,
+		0x00002000,0x00002000,0x00002080,0x00002080,
+		0x00000001,0x00000001,0x00000081,0x00000081,
+		0x00002001,0x00002001,0x00002081,0x00002081,
+	},{
+		0x00000000,0x00000010,0x00800000,0x00800010,
+		0x00010000,0x00010010,0x00810000,0x00810010,
+		0x00000200,0x00000210,0x00800200,0x00800210,
+		0x00010200,0x00010210,0x00810200,0x00810210,
+	},{
+		0x00000000,0x00000400,0x00001000,0x00001400,
+		0x00080000,0x00080400,0x00081000,0x00081400,
+		0x00000020,0x00000420,0x00001020,0x00001420,
+		0x00080020,0x00080420,0x00081020,0x00081420,
+	},{
+		0x00000000,0x00000100,0x00040000,0x00040100,
+		0x00000000,0x00000100,0x00040000,0x00040100,
+		0x00000040,0x00000140,0x00040040,0x00040140,
+		0x00000040,0x00000140,0x00040040,0x00040140,
+	},
+};
+
+static const unsigned char ascii64[] =
+    "./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
+/*   0000000000111111111122222222223333333333444444444455555555556666 */
+/*   0123456789012345678901234567890123456789012345678901234567890123 */
+
+/*
+ * We match the behavior of UFC-crypt on systems where "char" is signed by
+ * default (the majority), regardless of char's signedness on our system.
+ */
+static uint32_t ascii_to_bin(int ch)
+{
+	int sch = (ch < 0x80) ? ch : -(0x100 - ch);
+	int retval;
+
+	retval = sch - '.';
+	if (sch >= 'A') {
+		retval = sch - ('A' - 12);
+		if (sch >= 'a')
+			retval = sch - ('a' - 38);
+	}
+	retval &= 0x3f;
+
+	return retval;
+}
+
+/*
+ * When we choose to "support" invalid salts, nevertheless disallow those
+ * containing characters that would violate the passwd file format.
+ */
+static inline int ascii_is_unsafe(unsigned char ch)
+{
+	return !ch || ch == '\n' || ch == ':';
+}
+
+static uint32_t setup_salt(uint32_t salt)
+{
+	uint32_t obit, saltbit, saltbits;
+	unsigned int i;
+
+	saltbits = 0;
+	saltbit = 1;
+	obit = 0x800000;
+	for (i = 0; i < 24; i++) {
+		if (salt & saltbit)
+			saltbits |= obit;
+		saltbit <<= 1;
+		obit >>= 1;
+	}
+
+	return saltbits;
+}
+
+void __des_setkey(const unsigned char *key, struct expanded_key *ekey)
+{
+	uint32_t k0, k1, rawkey0, rawkey1;
+	unsigned int shifts, round, i, ibit;
+
+	rawkey0 =
+	    (uint32_t)key[3] |
+	    ((uint32_t)key[2] << 8) |
+	    ((uint32_t)key[1] << 16) |
+	    ((uint32_t)key[0] << 24);
+	rawkey1 =
+	    (uint32_t)key[7] |
+	    ((uint32_t)key[6] << 8) |
+	    ((uint32_t)key[5] << 16) |
+	    ((uint32_t)key[4] << 24);
+
+	/*
+	 * Do key permutation and split into two 28-bit subkeys.
+	 */
+	k0 = k1 = 0;
+	for (i = 0, ibit = 28; i < 4; i++, ibit -= 4) {
+		unsigned int j = i << 1;
+		k0 |= key_perm_maskl[i][(rawkey0 >> ibit) & 0xf] |
+		      key_perm_maskl[i + 4][(rawkey1 >> ibit) & 0xf];
+		k1 |= key_perm_maskr[j][(rawkey0 >> ibit) & 0xf];
+		ibit -= 4;
+		k1 |= key_perm_maskr[j + 1][(rawkey0 >> ibit) & 0xf] |
+		      key_perm_maskr[i + 8][(rawkey1 >> ibit) & 0xf];
+	}
+
+	/*
+	 * Rotate subkeys and do compression permutation.
+	 */
+	shifts = 0;
+	for (round = 0; round < 16; round++) {
+		uint32_t t0, t1;
+		uint32_t kl, kr;
+
+		shifts += key_shifts[round];
+
+		t0 = (k0 << shifts) | (k0 >> (28 - shifts));
+		t1 = (k1 << shifts) | (k1 >> (28 - shifts));
+
+		kl = kr = 0;
+		ibit = 25;
+		for (i = 0; i < 4; i++) {
+			kl |= comp_maskl0[i][(t0 >> ibit) & 7];
+			kr |= comp_maskr0[i][(t1 >> ibit) & 7];
+			ibit -= 4;
+			kl |= comp_maskl1[i][(t0 >> ibit) & 0xf];
+			kr |= comp_maskr1[i][(t1 >> ibit) & 0xf];
+			ibit -= 3;
+		}
+		ekey->l[round] = kl;
+		ekey->r[round] = kr;
+	}
+}
+
+/*
+ * l_in, r_in, l_out, and r_out are in pseudo-"big-endian" format.
+ */
+void __do_des(uint32_t l_in, uint32_t r_in,
+    uint32_t *l_out, uint32_t *r_out,
+    uint32_t count, uint32_t saltbits, const struct expanded_key *ekey)
+{
+	uint32_t l, r;
+
+	/*
+	 * Do initial permutation (IP).
+	 */
+	l = r = 0;
+	if (l_in | r_in) {
+		unsigned int i, ibit;
+		for (i = 0, ibit = 28; i < 8; i++, ibit -= 4) {
+			l |= ip_maskl[i][(l_in >> ibit) & 0xf] |
+			     ip_maskl[i + 8][(r_in >> ibit) & 0xf];
+			r |= ip_maskr[i][(l_in >> ibit) & 0xf] |
+			     ip_maskr[i + 8][(r_in >> ibit) & 0xf];
+		}
+	}
+
+	while (count--) {
+		/*
+		 * Do each round.
+		 */
+		unsigned int round = 16;
+		const uint32_t *kl = ekey->l;
+		const uint32_t *kr = ekey->r;
+		uint32_t f;
+		while (round--) {
+			uint32_t r48l, r48r;
+			/*
+			 * Expand R to 48 bits (simulate the E-box).
+			 */
+			r48l	= ((r & 0x00000001) << 23)
+				| ((r & 0xf8000000) >> 9)
+				| ((r & 0x1f800000) >> 11)
+				| ((r & 0x01f80000) >> 13)
+				| ((r & 0x001f8000) >> 15);
+
+			r48r	= ((r & 0x0001f800) << 7)
+				| ((r & 0x00001f80) << 5)
+				| ((r & 0x000001f8) << 3)
+				| ((r & 0x0000001f) << 1)
+				| ((r & 0x80000000) >> 31);
+			/*
+			 * Do salting for crypt() and friends, and
+			 * XOR with the permuted key.
+			 */
+			f = (r48l ^ r48r) & saltbits;
+			r48l ^= f ^ *kl++;
+			r48r ^= f ^ *kr++;
+			/*
+			 * Do S-box lookups (which shrink it back to 32 bits)
+			 * and do the P-box permutation at the same time.
+			 */
+			f = psbox[0][r48l >> 18]
+			  | psbox[1][(r48l >> 12) & 0x3f]
+			  | psbox[2][(r48l >> 6) & 0x3f]
+			  | psbox[3][r48l & 0x3f]
+			  | psbox[4][r48r >> 18]
+			  | psbox[5][(r48r >> 12) & 0x3f]
+			  | psbox[6][(r48r >> 6) & 0x3f]
+			  | psbox[7][r48r & 0x3f];
+			/*
+			 * Now that we've permuted things, complete f().
+			 */
+			f ^= l;
+			l = r;
+			r = f;
+		}
+		r = l;
+		l = f;
+	}
+
+	/*
+	 * Do final permutation (inverse of IP).
+	 */
+	{
+		unsigned int i, ibit;
+		uint32_t lo, ro;
+		lo = ro = 0;
+		for (i = 0, ibit = 28; i < 4; i++, ibit -= 4) {
+			ro |= fp_maskr[i][(l >> ibit) & 0xf] |
+			      fp_maskr[i + 4][(r >> ibit) & 0xf];
+			ibit -= 4;
+			lo |= fp_maskl[i][(l >> ibit) & 0xf] |
+			      fp_maskl[i + 4][(r >> ibit) & 0xf];
+		}
+		*l_out = lo;
+		*r_out = ro;
+	}
+}
+
+static void des_cipher(const unsigned char *in, unsigned char *out,
+    uint32_t count, uint32_t saltbits, const struct expanded_key *ekey)
+{
+	uint32_t l_out, r_out, rawl, rawr;
+
+	rawl =
+	    (uint32_t)in[3] |
+	    ((uint32_t)in[2] << 8) |
+	    ((uint32_t)in[1] << 16) |
+	    ((uint32_t)in[0] << 24);
+	rawr =
+	    (uint32_t)in[7] |
+	    ((uint32_t)in[6] << 8) |
+	    ((uint32_t)in[5] << 16) |
+	    ((uint32_t)in[4] << 24);
+
+	__do_des(rawl, rawr, &l_out, &r_out, count, saltbits, ekey);
+
+	out[0] = l_out >> 24;
+	out[1] = l_out >> 16;
+	out[2] = l_out >> 8;
+	out[3] = l_out;
+	out[4] = r_out >> 24;
+	out[5] = r_out >> 16;
+	out[6] = r_out >> 8;
+	out[7] = r_out;
+}
+
+static char *_crypt_extended_r_uut(const char *_key, const char *_setting, char *output)
+{
+	const unsigned char *key = (const unsigned char *)_key;
+	const unsigned char *setting = (const unsigned char *)_setting;
+	struct expanded_key ekey;
+	unsigned char keybuf[8];
+	unsigned char *p, *q;
+	uint32_t count, salt, l, r0, r1;
+	unsigned int i;
+
+	/*
+	 * Copy the key, shifting each character left by one bit and padding
+	 * with zeroes.
+	 */
+	q = keybuf;
+	while (q <= &keybuf[sizeof(keybuf) - 1]) {
+		*q++ = *key << 1;
+		if (*key)
+			key++;
+	}
+	__des_setkey(keybuf, &ekey);
+
+	if (*setting == _PASSWORD_EFMT1) {
+		/*
+		 * "new"-style:
+		 *	setting - underscore, 4 chars of count, 4 chars of salt
+		 *	key - unlimited characters
+		 */
+		for (i = 1, count = 0; i < 5; i++) {
+			uint32_t value = ascii_to_bin(setting[i]);
+			if (ascii64[value] != setting[i])
+				return NULL;
+			count |= value << (i - 1) * 6;
+		}
+		if (!count)
+			return NULL;
+
+		for (i = 5, salt = 0; i < 9; i++) {
+			uint32_t value = ascii_to_bin(setting[i]);
+			if (ascii64[value] != setting[i])
+				return NULL;
+			salt |= value << (i - 5) * 6;
+		}
+
+		while (*key) {
+			/*
+			 * Encrypt the key with itself.
+			 */
+			des_cipher(keybuf, keybuf, 1, 0, &ekey);
+			/*
+			 * And XOR with the next 8 characters of the key.
+			 */
+			q = keybuf;
+			while (q <= &keybuf[sizeof(keybuf) - 1] && *key)
+				*q++ ^= *key++ << 1;
+			__des_setkey(keybuf, &ekey);
+		}
+
+		memcpy(output, setting, 9);
+		output[9] = '\0';
+		p = (unsigned char *)output + 9;
+	} else {
+		/*
+		 * "old"-style:
+		 *	setting - 2 chars of salt
+		 *	key - up to 8 characters
+		 */
+		count = 25;
+
+		if (ascii_is_unsafe(setting[0]) || ascii_is_unsafe(setting[1]))
+			return NULL;
+
+		salt = (ascii_to_bin(setting[1]) << 6)
+		     |  ascii_to_bin(setting[0]);
+
+		output[0] = setting[0];
+		output[1] = setting[1];
+		p = (unsigned char *)output + 2;
+	}
+
+	/*
+	 * Do it.
+	 */
+	__do_des(0, 0, &r0, &r1, count, setup_salt(salt), &ekey);
+
+	/*
+	 * Now encode the result...
+	 */
+	l = (r0 >> 8);
+	*p++ = ascii64[(l >> 18) & 0x3f];
+	*p++ = ascii64[(l >> 12) & 0x3f];
+	*p++ = ascii64[(l >> 6) & 0x3f];
+	*p++ = ascii64[l & 0x3f];
+
+	l = (r0 << 16) | ((r1 >> 16) & 0xffff);
+	*p++ = ascii64[(l >> 18) & 0x3f];
+	*p++ = ascii64[(l >> 12) & 0x3f];
+	*p++ = ascii64[(l >> 6) & 0x3f];
+	*p++ = ascii64[l & 0x3f];
+
+	l = r1 << 2;
+	*p++ = ascii64[(l >> 12) & 0x3f];
+	*p++ = ascii64[(l >> 6) & 0x3f];
+	*p++ = ascii64[l & 0x3f];
+	*p = 0;
+
+	return output;
+}
+
+char *__crypt_des(const char *key, const char *setting, char *output)
+{
+	const char *test_key = "\x80\xff\x80\x01 "
+	    "\x7f\x81\x80\x80\x0d\x0a\xff\x7f \x81 test";
+	const char *test_setting = "_0.../9Zz";
+	const char *test_hash = "_0.../9ZzX7iSJNd21sU";
+	char test_buf[21];
+	char *retval;
+	const char *p;
+
+	if (*setting != _PASSWORD_EFMT1) {
+		test_setting = "\x80x";
+		test_hash = "\x80x22/wK52ZKGA";
+	}
+
+	/*
+	 * Hash the supplied password.
+	 */
+	retval = _crypt_extended_r_uut(key, setting, output);
+
+	/*
+	 * Perform a quick self-test.  It is important that we make both calls
+	 * to _crypt_extended_r_uut() from the same scope such that they likely
+	 * use the same stack locations, which makes the second call overwrite
+	 * the first call's sensitive data on the stack and makes it more
+	 * likely that any alignment related issues would be detected.
+	 */
+	p = _crypt_extended_r_uut(test_key, test_setting, test_buf);
+	if (p && !strcmp(p, test_hash) && retval)
+		return retval;
+
+	return (setting[0]=='*') ? "x" : "*";
+}
libc/musl/src/crypt/crypt_des.h
@@ -0,0 +1,14 @@
+#ifndef CRYPT_DES_H
+#define CRYPT_DES_H
+
+#include <stdint.h>
+
+struct expanded_key {
+	uint32_t l[16], r[16];
+};
+
+hidden void __des_setkey(const unsigned char *, struct expanded_key *);
+hidden void __do_des(uint32_t, uint32_t, uint32_t *, uint32_t *,
+                     uint32_t, uint32_t, const struct expanded_key *);
+
+#endif
libc/musl/src/crypt/crypt_md5.c
@@ -0,0 +1,285 @@
+/*
+ * md5 crypt implementation
+ *
+ * original md5 crypt design is from Poul-Henning Kamp
+ * this implementation was created based on the code in freebsd
+ * at least 32bit int is assumed, key is limited and $1$ prefix is mandatory,
+ * on error "*" is returned
+ */
+#include <string.h>
+#include <stdint.h>
+
+/* public domain md5 implementation based on rfc1321 and libtomcrypt */
+
+struct md5 {
+	uint64_t len;    /* processed message length */
+	uint32_t h[4];   /* hash state */
+	uint8_t buf[64]; /* message block buffer */
+};
+
+static uint32_t rol(uint32_t n, int k) { return (n << k) | (n >> (32-k)); }
+#define F(x,y,z) (z ^ (x & (y ^ z)))
+#define G(x,y,z) (y ^ (z & (y ^ x)))
+#define H(x,y,z) (x ^ y ^ z)
+#define I(x,y,z) (y ^ (x | ~z))
+#define FF(a,b,c,d,w,s,t) a += F(b,c,d) + w + t; a = rol(a,s) + b
+#define GG(a,b,c,d,w,s,t) a += G(b,c,d) + w + t; a = rol(a,s) + b
+#define HH(a,b,c,d,w,s,t) a += H(b,c,d) + w + t; a = rol(a,s) + b
+#define II(a,b,c,d,w,s,t) a += I(b,c,d) + w + t; a = rol(a,s) + b
+
+static const uint32_t tab[64] = {
+0xd76aa478, 0xe8c7b756, 0x242070db, 0xc1bdceee, 0xf57c0faf, 0x4787c62a, 0xa8304613, 0xfd469501,
+0x698098d8, 0x8b44f7af, 0xffff5bb1, 0x895cd7be, 0x6b901122, 0xfd987193, 0xa679438e, 0x49b40821,
+0xf61e2562, 0xc040b340, 0x265e5a51, 0xe9b6c7aa, 0xd62f105d, 0x02441453, 0xd8a1e681, 0xe7d3fbc8,
+0x21e1cde6, 0xc33707d6, 0xf4d50d87, 0x455a14ed, 0xa9e3e905, 0xfcefa3f8, 0x676f02d9, 0x8d2a4c8a,
+0xfffa3942, 0x8771f681, 0x6d9d6122, 0xfde5380c, 0xa4beea44, 0x4bdecfa9, 0xf6bb4b60, 0xbebfbc70,
+0x289b7ec6, 0xeaa127fa, 0xd4ef3085, 0x04881d05, 0xd9d4d039, 0xe6db99e5, 0x1fa27cf8, 0xc4ac5665,
+0xf4292244, 0x432aff97, 0xab9423a7, 0xfc93a039, 0x655b59c3, 0x8f0ccc92, 0xffeff47d, 0x85845dd1,
+0x6fa87e4f, 0xfe2ce6e0, 0xa3014314, 0x4e0811a1, 0xf7537e82, 0xbd3af235, 0x2ad7d2bb, 0xeb86d391
+};
+
+static void processblock(struct md5 *s, const uint8_t *buf)
+{
+	uint32_t i, W[16], a, b, c, d;
+
+	for (i = 0; i < 16; i++) {
+		W[i] = buf[4*i];
+		W[i] |= (uint32_t)buf[4*i+1]<<8;
+		W[i] |= (uint32_t)buf[4*i+2]<<16;
+		W[i] |= (uint32_t)buf[4*i+3]<<24;
+	}
+
+	a = s->h[0];
+	b = s->h[1];
+	c = s->h[2];
+	d = s->h[3];
+
+	i = 0;
+	while (i < 16) {
+		FF(a,b,c,d, W[i],  7, tab[i]); i++;
+		FF(d,a,b,c, W[i], 12, tab[i]); i++;
+		FF(c,d,a,b, W[i], 17, tab[i]); i++;
+		FF(b,c,d,a, W[i], 22, tab[i]); i++;
+	}
+	while (i < 32) {
+		GG(a,b,c,d, W[(5*i+1)%16],  5, tab[i]); i++;
+		GG(d,a,b,c, W[(5*i+1)%16],  9, tab[i]); i++;
+		GG(c,d,a,b, W[(5*i+1)%16], 14, tab[i]); i++;
+		GG(b,c,d,a, W[(5*i+1)%16], 20, tab[i]); i++;
+	}
+	while (i < 48) {
+		HH(a,b,c,d, W[(3*i+5)%16],  4, tab[i]); i++;
+		HH(d,a,b,c, W[(3*i+5)%16], 11, tab[i]); i++;
+		HH(c,d,a,b, W[(3*i+5)%16], 16, tab[i]); i++;
+		HH(b,c,d,a, W[(3*i+5)%16], 23, tab[i]); i++;
+	}
+	while (i < 64) {
+		II(a,b,c,d, W[7*i%16],  6, tab[i]); i++;
+		II(d,a,b,c, W[7*i%16], 10, tab[i]); i++;
+		II(c,d,a,b, W[7*i%16], 15, tab[i]); i++;
+		II(b,c,d,a, W[7*i%16], 21, tab[i]); i++;
+	}
+
+	s->h[0] += a;
+	s->h[1] += b;
+	s->h[2] += c;
+	s->h[3] += d;
+}
+
+static void pad(struct md5 *s)
+{
+	unsigned r = s->len % 64;
+
+	s->buf[r++] = 0x80;
+	if (r > 56) {
+		memset(s->buf + r, 0, 64 - r);
+		r = 0;
+		processblock(s, s->buf);
+	}
+	memset(s->buf + r, 0, 56 - r);
+	s->len *= 8;
+	s->buf[56] = s->len;
+	s->buf[57] = s->len >> 8;
+	s->buf[58] = s->len >> 16;
+	s->buf[59] = s->len >> 24;
+	s->buf[60] = s->len >> 32;
+	s->buf[61] = s->len >> 40;
+	s->buf[62] = s->len >> 48;
+	s->buf[63] = s->len >> 56;
+	processblock(s, s->buf);
+}
+
+static void md5_init(struct md5 *s)
+{
+	s->len = 0;
+	s->h[0] = 0x67452301;
+	s->h[1] = 0xefcdab89;
+	s->h[2] = 0x98badcfe;
+	s->h[3] = 0x10325476;
+}
+
+static void md5_sum(struct md5 *s, uint8_t *md)
+{
+	int i;
+
+	pad(s);
+	for (i = 0; i < 4; i++) {
+		md[4*i] = s->h[i];
+		md[4*i+1] = s->h[i] >> 8;
+		md[4*i+2] = s->h[i] >> 16;
+		md[4*i+3] = s->h[i] >> 24;
+	}
+}
+
+static void md5_update(struct md5 *s, const void *m, unsigned long len)
+{
+	const uint8_t *p = m;
+	unsigned r = s->len % 64;
+
+	s->len += len;
+	if (r) {
+		if (len < 64 - r) {
+			memcpy(s->buf + r, p, len);
+			return;
+		}
+		memcpy(s->buf + r, p, 64 - r);
+		len -= 64 - r;
+		p += 64 - r;
+		processblock(s, s->buf);
+	}
+	for (; len >= 64; len -= 64, p += 64)
+		processblock(s, p);
+	memcpy(s->buf, p, len);
+}
+
+/*-
+ * Copyright (c) 2003 Poul-Henning Kamp
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/* key limit is not part of the original design, added for DoS protection */
+#define KEY_MAX 30000
+#define SALT_MAX 8
+
+static const unsigned char b64[] =
+"./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
+
+static char *to64(char *s, unsigned int u, int n)
+{
+	while (--n >= 0) {
+		*s++ = b64[u % 64];
+		u /= 64;
+	}
+	return s;
+}
+
+static char *md5crypt(const char *key, const char *setting, char *output)
+{
+	struct md5 ctx;
+	unsigned char md[16];
+	unsigned int i, klen, slen;
+	const char *salt;
+	char *p;
+
+	/* reject large keys */
+	klen = strnlen(key, KEY_MAX+1);
+	if (klen > KEY_MAX)
+		return 0;
+
+	/* setting: $1$salt$ (closing $ is optional) */
+	if (strncmp(setting, "$1$", 3) != 0)
+		return 0;
+	salt = setting + 3;
+	for (i = 0; i < SALT_MAX && salt[i] && salt[i] != '$'; i++);
+	slen = i;
+
+	/* md5(key salt key) */
+	md5_init(&ctx);
+	md5_update(&ctx, key, klen);
+	md5_update(&ctx, salt, slen);
+	md5_update(&ctx, key, klen);
+	md5_sum(&ctx, md);
+
+	/* md5(key $1$ salt repeated-md weird-key[0]-0) */
+	md5_init(&ctx);
+	md5_update(&ctx, key, klen);
+	md5_update(&ctx, setting, 3 + slen);
+	for (i = klen; i > sizeof md; i -= sizeof md)
+		md5_update(&ctx, md, sizeof md);
+	md5_update(&ctx, md, i);
+	md[0] = 0;
+	for (i = klen; i; i >>= 1)
+		if (i & 1)
+			md5_update(&ctx, md, 1);
+		else
+			md5_update(&ctx, key, 1);
+	md5_sum(&ctx, md);
+
+	/* md = f(md, key, salt) iteration */
+	for (i = 0; i < 1000; i++) {
+		md5_init(&ctx);
+		if (i % 2)
+			md5_update(&ctx, key, klen);
+		else
+			md5_update(&ctx, md, sizeof md);
+		if (i % 3)
+			md5_update(&ctx, salt, slen);
+		if (i % 7)
+			md5_update(&ctx, key, klen);
+		if (i % 2)
+			md5_update(&ctx, md, sizeof md);
+		else
+			md5_update(&ctx, key, klen);
+		md5_sum(&ctx, md);
+	}
+
+	/* output is $1$salt$hash */
+	memcpy(output, setting, 3 + slen);
+	p = output + 3 + slen;
+	*p++ = '$';
+	static const unsigned char perm[][3] = {
+		0,6,12,1,7,13,2,8,14,3,9,15,4,10,5 };
+	for (i=0; i<5; i++) p = to64(p,
+		(md[perm[i][0]]<<16)|(md[perm[i][1]]<<8)|md[perm[i][2]], 4);
+	p = to64(p, md[11], 2);
+	*p = 0;
+
+	return output;
+}
+
+char *__crypt_md5(const char *key, const char *setting, char *output)
+{
+	static const char testkey[] = "Xy01@#\x01\x02\x80\x7f\xff\r\n\x81\t !";
+	static const char testsetting[] = "$1$abcd0123$";
+	static const char testhash[] = "$1$abcd0123$9Qcg8DyviekV3tDGMZynJ1";
+	char testbuf[64];
+	char *p, *q;
+
+	p = md5crypt(key, setting, output);
+	/* self test and stack cleanup */
+	q = md5crypt(testkey, testsetting, testbuf);
+	if (!p || q != testbuf || memcmp(testbuf, testhash, sizeof testhash))
+		return "*";
+	return p;
+}
libc/musl/src/crypt/crypt_r.c
@@ -0,0 +1,23 @@
+#include <crypt.h>
+
+char *__crypt_r(const char *key, const char *salt, struct crypt_data *data)
+{
+	/* Per the crypt_r API, the caller has provided a pointer to
+	 * struct crypt_data; however, this implementation does not
+	 * use the structure to store any internal state, and treats
+	 * it purely as a char buffer for storing the result. */
+	char *output = (char *)data;
+	if (salt[0] == '$' && salt[1] && salt[2]) {
+		if (salt[1] == '1' && salt[2] == '$')
+			return __crypt_md5(key, salt, output);
+		if (salt[1] == '2' && salt[3] == '$')
+			return __crypt_blowfish(key, salt, output);
+		if (salt[1] == '5' && salt[2] == '$')
+			return __crypt_sha256(key, salt, output);
+		if (salt[1] == '6' && salt[2] == '$')
+			return __crypt_sha512(key, salt, output);
+	}
+	return __crypt_des(key, salt, output);
+}
+
+weak_alias(__crypt_r, crypt_r);
libc/musl/src/crypt/crypt_sha256.c
@@ -0,0 +1,322 @@
+/*
+ * public domain sha256 crypt implementation
+ *
+ * original sha crypt design: http://people.redhat.com/drepper/SHA-crypt.txt
+ * in this implementation at least 32bit int is assumed,
+ * key length is limited, the $5$ prefix is mandatory, '\n' and ':' is rejected
+ * in the salt and rounds= setting must contain a valid iteration count,
+ * on error "*" is returned.
+ */
+#include <ctype.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <stdint.h>
+
+/* public domain sha256 implementation based on fips180-3 */
+
+struct sha256 {
+	uint64_t len;    /* processed message length */
+	uint32_t h[8];   /* hash state */
+	uint8_t buf[64]; /* message block buffer */
+};
+
+static uint32_t ror(uint32_t n, int k) { return (n >> k) | (n << (32-k)); }
+#define Ch(x,y,z)  (z ^ (x & (y ^ z)))
+#define Maj(x,y,z) ((x & y) | (z & (x | y)))
+#define S0(x)      (ror(x,2) ^ ror(x,13) ^ ror(x,22))
+#define S1(x)      (ror(x,6) ^ ror(x,11) ^ ror(x,25))
+#define R0(x)      (ror(x,7) ^ ror(x,18) ^ (x>>3))
+#define R1(x)      (ror(x,17) ^ ror(x,19) ^ (x>>10))
+
+static const uint32_t K[64] = {
+0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
+0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,
+0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
+0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,
+0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,
+0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
+0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,
+0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2
+};
+
+static void processblock(struct sha256 *s, const uint8_t *buf)
+{
+	uint32_t W[64], t1, t2, a, b, c, d, e, f, g, h;
+	int i;
+
+	for (i = 0; i < 16; i++) {
+		W[i] = (uint32_t)buf[4*i]<<24;
+		W[i] |= (uint32_t)buf[4*i+1]<<16;
+		W[i] |= (uint32_t)buf[4*i+2]<<8;
+		W[i] |= buf[4*i+3];
+	}
+	for (; i < 64; i++)
+		W[i] = R1(W[i-2]) + W[i-7] + R0(W[i-15]) + W[i-16];
+	a = s->h[0];
+	b = s->h[1];
+	c = s->h[2];
+	d = s->h[3];
+	e = s->h[4];
+	f = s->h[5];
+	g = s->h[6];
+	h = s->h[7];
+	for (i = 0; i < 64; i++) {
+		t1 = h + S1(e) + Ch(e,f,g) + K[i] + W[i];
+		t2 = S0(a) + Maj(a,b,c);
+		h = g;
+		g = f;
+		f = e;
+		e = d + t1;
+		d = c;
+		c = b;
+		b = a;
+		a = t1 + t2;
+	}
+	s->h[0] += a;
+	s->h[1] += b;
+	s->h[2] += c;
+	s->h[3] += d;
+	s->h[4] += e;
+	s->h[5] += f;
+	s->h[6] += g;
+	s->h[7] += h;
+}
+
+static void pad(struct sha256 *s)
+{
+	unsigned r = s->len % 64;
+
+	s->buf[r++] = 0x80;
+	if (r > 56) {
+		memset(s->buf + r, 0, 64 - r);
+		r = 0;
+		processblock(s, s->buf);
+	}
+	memset(s->buf + r, 0, 56 - r);
+	s->len *= 8;
+	s->buf[56] = s->len >> 56;
+	s->buf[57] = s->len >> 48;
+	s->buf[58] = s->len >> 40;
+	s->buf[59] = s->len >> 32;
+	s->buf[60] = s->len >> 24;
+	s->buf[61] = s->len >> 16;
+	s->buf[62] = s->len >> 8;
+	s->buf[63] = s->len;
+	processblock(s, s->buf);
+}
+
+static void sha256_init(struct sha256 *s)
+{
+	s->len = 0;
+	s->h[0] = 0x6a09e667;
+	s->h[1] = 0xbb67ae85;
+	s->h[2] = 0x3c6ef372;
+	s->h[3] = 0xa54ff53a;
+	s->h[4] = 0x510e527f;
+	s->h[5] = 0x9b05688c;
+	s->h[6] = 0x1f83d9ab;
+	s->h[7] = 0x5be0cd19;
+}
+
+static void sha256_sum(struct sha256 *s, uint8_t *md)
+{
+	int i;
+
+	pad(s);
+	for (i = 0; i < 8; i++) {
+		md[4*i] = s->h[i] >> 24;
+		md[4*i+1] = s->h[i] >> 16;
+		md[4*i+2] = s->h[i] >> 8;
+		md[4*i+3] = s->h[i];
+	}
+}
+
+static void sha256_update(struct sha256 *s, const void *m, unsigned long len)
+{
+	const uint8_t *p = m;
+	unsigned r = s->len % 64;
+
+	s->len += len;
+	if (r) {
+		if (len < 64 - r) {
+			memcpy(s->buf + r, p, len);
+			return;
+		}
+		memcpy(s->buf + r, p, 64 - r);
+		len -= 64 - r;
+		p += 64 - r;
+		processblock(s, s->buf);
+	}
+	for (; len >= 64; len -= 64, p += 64)
+		processblock(s, p);
+	memcpy(s->buf, p, len);
+}
+
+static const unsigned char b64[] =
+"./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
+
+static char *to64(char *s, unsigned int u, int n)
+{
+	while (--n >= 0) {
+		*s++ = b64[u % 64];
+		u /= 64;
+	}
+	return s;
+}
+
+/* key limit is not part of the original design, added for DoS protection.
+ * rounds limit has been lowered (versus the reference/spec), also for DoS
+ * protection. runtime is O(klen^2 + klen*rounds) */
+#define KEY_MAX 256
+#define SALT_MAX 16
+#define ROUNDS_DEFAULT 5000
+#define ROUNDS_MIN 1000
+#define ROUNDS_MAX 9999999
+
+/* hash n bytes of the repeated md message digest */
+static void hashmd(struct sha256 *s, unsigned int n, const void *md)
+{
+	unsigned int i;
+
+	for (i = n; i > 32; i -= 32)
+		sha256_update(s, md, 32);
+	sha256_update(s, md, i);
+}
+
+static char *sha256crypt(const char *key, const char *setting, char *output)
+{
+	struct sha256 ctx;
+	unsigned char md[32], kmd[32], smd[32];
+	unsigned int i, r, klen, slen;
+	char rounds[20] = "";
+	const char *salt;
+	char *p;
+
+	/* reject large keys */
+	klen = strnlen(key, KEY_MAX+1);
+	if (klen > KEY_MAX)
+		return 0;
+
+	/* setting: $5$rounds=n$salt$ (rounds=n$ and closing $ are optional) */
+	if (strncmp(setting, "$5$", 3) != 0)
+		return 0;
+	salt = setting + 3;
+
+	r = ROUNDS_DEFAULT;
+	if (strncmp(salt, "rounds=", sizeof "rounds=" - 1) == 0) {
+		unsigned long u;
+		char *end;
+
+		/*
+		 * this is a deviation from the reference:
+		 * bad rounds setting is rejected if it is
+		 * - empty
+		 * - unterminated (missing '$')
+		 * - begins with anything but a decimal digit
+		 * the reference implementation treats these bad
+		 * rounds as part of the salt or parse them with
+		 * strtoul semantics which may cause problems
+		 * including non-portable hashes that depend on
+		 * the host's value of ULONG_MAX.
+		 */
+		salt += sizeof "rounds=" - 1;
+		if (!isdigit(*salt))
+			return 0;
+		u = strtoul(salt, &end, 10);
+		if (*end != '$')
+			return 0;
+		salt = end+1;
+		if (u < ROUNDS_MIN)
+			r = ROUNDS_MIN;
+		else if (u > ROUNDS_MAX)
+			return 0;
+		else
+			r = u;
+		/* needed when rounds is zero prefixed or out of bounds */
+		sprintf(rounds, "rounds=%u$", r);
+	}
+
+	for (i = 0; i < SALT_MAX && salt[i] && salt[i] != '$'; i++)
+		/* reject characters that interfere with /etc/shadow parsing */
+		if (salt[i] == '\n' || salt[i] == ':')
+			return 0;
+	slen = i;
+
+	/* B = sha(key salt key) */
+	sha256_init(&ctx);
+	sha256_update(&ctx, key, klen);
+	sha256_update(&ctx, salt, slen);
+	sha256_update(&ctx, key, klen);
+	sha256_sum(&ctx, md);
+
+	/* A = sha(key salt repeat-B alternate-B-key) */
+	sha256_init(&ctx);
+	sha256_update(&ctx, key, klen);
+	sha256_update(&ctx, salt, slen);
+	hashmd(&ctx, klen, md);
+	for (i = klen; i > 0; i >>= 1)
+		if (i & 1)
+			sha256_update(&ctx, md, sizeof md);
+		else
+			sha256_update(&ctx, key, klen);
+	sha256_sum(&ctx, md);
+
+	/* DP = sha(repeat-key), this step takes O(klen^2) time */
+	sha256_init(&ctx);
+	for (i = 0; i < klen; i++)
+		sha256_update(&ctx, key, klen);
+	sha256_sum(&ctx, kmd);
+
+	/* DS = sha(repeat-salt) */
+	sha256_init(&ctx);
+	for (i = 0; i < 16 + md[0]; i++)
+		sha256_update(&ctx, salt, slen);
+	sha256_sum(&ctx, smd);
+
+	/* iterate A = f(A,DP,DS), this step takes O(rounds*klen) time */
+	for (i = 0; i < r; i++) {
+		sha256_init(&ctx);
+		if (i % 2)
+			hashmd(&ctx, klen, kmd);
+		else
+			sha256_update(&ctx, md, sizeof md);
+		if (i % 3)
+			sha256_update(&ctx, smd, slen);
+		if (i % 7)
+			hashmd(&ctx, klen, kmd);
+		if (i % 2)
+			sha256_update(&ctx, md, sizeof md);
+		else
+			hashmd(&ctx, klen, kmd);
+		sha256_sum(&ctx, md);
+	}
+
+	/* output is $5$rounds=n$salt$hash */
+	p = output;
+	p += sprintf(p, "$5$%s%.*s$", rounds, slen, salt);
+	static const unsigned char perm[][3] = {
+		0,10,20,21,1,11,12,22,2,3,13,23,24,4,14,
+		15,25,5,6,16,26,27,7,17,18,28,8,9,19,29 };
+	for (i=0; i<10; i++) p = to64(p,
+		(md[perm[i][0]]<<16)|(md[perm[i][1]]<<8)|md[perm[i][2]], 4);
+	p = to64(p, (md[31]<<8)|md[30], 3);
+	*p = 0;
+	return output;
+}
+
+char *__crypt_sha256(const char *key, const char *setting, char *output)
+{
+	static const char testkey[] = "Xy01@#\x01\x02\x80\x7f\xff\r\n\x81\t !";
+	static const char testsetting[] = "$5$rounds=1234$abc0123456789$";
+	static const char testhash[] = "$5$rounds=1234$abc0123456789$3VfDjPt05VHFn47C/ojFZ6KRPYrOjj1lLbH.dkF3bZ6";
+	char testbuf[128];
+	char *p, *q;
+
+	p = sha256crypt(key, setting, output);
+	/* self test and stack cleanup */
+	q = sha256crypt(testkey, testsetting, testbuf);
+	if (!p || q != testbuf || memcmp(testbuf, testhash, sizeof testhash))
+		return "*";
+	return p;
+}
libc/musl/src/crypt/crypt_sha512.c
@@ -0,0 +1,371 @@
+/*
+ * public domain sha512 crypt implementation
+ *
+ * original sha crypt design: http://people.redhat.com/drepper/SHA-crypt.txt
+ * in this implementation at least 32bit int is assumed,
+ * key length is limited, the $6$ prefix is mandatory, '\n' and ':' is rejected
+ * in the salt and rounds= setting must contain a valid iteration count,
+ * on error "*" is returned.
+ */
+#include <ctype.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <stdint.h>
+
+/* public domain sha512 implementation based on fips180-3 */
+/* >=2^64 bits messages are not supported (about 2000 peta bytes) */
+
+struct sha512 {
+	uint64_t len;     /* processed message length */
+	uint64_t h[8];    /* hash state */
+	uint8_t buf[128]; /* message block buffer */
+};
+
+static uint64_t ror(uint64_t n, int k) { return (n >> k) | (n << (64-k)); }
+#define Ch(x,y,z)  (z ^ (x & (y ^ z)))
+#define Maj(x,y,z) ((x & y) | (z & (x | y)))
+#define S0(x)      (ror(x,28) ^ ror(x,34) ^ ror(x,39))
+#define S1(x)      (ror(x,14) ^ ror(x,18) ^ ror(x,41))
+#define R0(x)      (ror(x,1) ^ ror(x,8) ^ (x>>7))
+#define R1(x)      (ror(x,19) ^ ror(x,61) ^ (x>>6))
+
+static const uint64_t K[80] = {
+0x428a2f98d728ae22ULL, 0x7137449123ef65cdULL, 0xb5c0fbcfec4d3b2fULL, 0xe9b5dba58189dbbcULL,
+0x3956c25bf348b538ULL, 0x59f111f1b605d019ULL, 0x923f82a4af194f9bULL, 0xab1c5ed5da6d8118ULL,
+0xd807aa98a3030242ULL, 0x12835b0145706fbeULL, 0x243185be4ee4b28cULL, 0x550c7dc3d5ffb4e2ULL,
+0x72be5d74f27b896fULL, 0x80deb1fe3b1696b1ULL, 0x9bdc06a725c71235ULL, 0xc19bf174cf692694ULL,
+0xe49b69c19ef14ad2ULL, 0xefbe4786384f25e3ULL, 0x0fc19dc68b8cd5b5ULL, 0x240ca1cc77ac9c65ULL,
+0x2de92c6f592b0275ULL, 0x4a7484aa6ea6e483ULL, 0x5cb0a9dcbd41fbd4ULL, 0x76f988da831153b5ULL,
+0x983e5152ee66dfabULL, 0xa831c66d2db43210ULL, 0xb00327c898fb213fULL, 0xbf597fc7beef0ee4ULL,
+0xc6e00bf33da88fc2ULL, 0xd5a79147930aa725ULL, 0x06ca6351e003826fULL, 0x142929670a0e6e70ULL,
+0x27b70a8546d22ffcULL, 0x2e1b21385c26c926ULL, 0x4d2c6dfc5ac42aedULL, 0x53380d139d95b3dfULL,
+0x650a73548baf63deULL, 0x766a0abb3c77b2a8ULL, 0x81c2c92e47edaee6ULL, 0x92722c851482353bULL,
+0xa2bfe8a14cf10364ULL, 0xa81a664bbc423001ULL, 0xc24b8b70d0f89791ULL, 0xc76c51a30654be30ULL,
+0xd192e819d6ef5218ULL, 0xd69906245565a910ULL, 0xf40e35855771202aULL, 0x106aa07032bbd1b8ULL,
+0x19a4c116b8d2d0c8ULL, 0x1e376c085141ab53ULL, 0x2748774cdf8eeb99ULL, 0x34b0bcb5e19b48a8ULL,
+0x391c0cb3c5c95a63ULL, 0x4ed8aa4ae3418acbULL, 0x5b9cca4f7763e373ULL, 0x682e6ff3d6b2b8a3ULL,
+0x748f82ee5defb2fcULL, 0x78a5636f43172f60ULL, 0x84c87814a1f0ab72ULL, 0x8cc702081a6439ecULL,
+0x90befffa23631e28ULL, 0xa4506cebde82bde9ULL, 0xbef9a3f7b2c67915ULL, 0xc67178f2e372532bULL,
+0xca273eceea26619cULL, 0xd186b8c721c0c207ULL, 0xeada7dd6cde0eb1eULL, 0xf57d4f7fee6ed178ULL,
+0x06f067aa72176fbaULL, 0x0a637dc5a2c898a6ULL, 0x113f9804bef90daeULL, 0x1b710b35131c471bULL,
+0x28db77f523047d84ULL, 0x32caab7b40c72493ULL, 0x3c9ebe0a15c9bebcULL, 0x431d67c49c100d4cULL,
+0x4cc5d4becb3e42b6ULL, 0x597f299cfc657e2aULL, 0x5fcb6fab3ad6faecULL, 0x6c44198c4a475817ULL
+};
+
+static void processblock(struct sha512 *s, const uint8_t *buf)
+{
+	uint64_t W[80], t1, t2, a, b, c, d, e, f, g, h;
+	int i;
+
+	for (i = 0; i < 16; i++) {
+		W[i] = (uint64_t)buf[8*i]<<56;
+		W[i] |= (uint64_t)buf[8*i+1]<<48;
+		W[i] |= (uint64_t)buf[8*i+2]<<40;
+		W[i] |= (uint64_t)buf[8*i+3]<<32;
+		W[i] |= (uint64_t)buf[8*i+4]<<24;
+		W[i] |= (uint64_t)buf[8*i+5]<<16;
+		W[i] |= (uint64_t)buf[8*i+6]<<8;
+		W[i] |= buf[8*i+7];
+	}
+	for (; i < 80; i++)
+		W[i] = R1(W[i-2]) + W[i-7] + R0(W[i-15]) + W[i-16];
+	a = s->h[0];
+	b = s->h[1];
+	c = s->h[2];
+	d = s->h[3];
+	e = s->h[4];
+	f = s->h[5];
+	g = s->h[6];
+	h = s->h[7];
+	for (i = 0; i < 80; i++) {
+		t1 = h + S1(e) + Ch(e,f,g) + K[i] + W[i];
+		t2 = S0(a) + Maj(a,b,c);
+		h = g;
+		g = f;
+		f = e;
+		e = d + t1;
+		d = c;
+		c = b;
+		b = a;
+		a = t1 + t2;
+	}
+	s->h[0] += a;
+	s->h[1] += b;
+	s->h[2] += c;
+	s->h[3] += d;
+	s->h[4] += e;
+	s->h[5] += f;
+	s->h[6] += g;
+	s->h[7] += h;
+}
+
+static void pad(struct sha512 *s)
+{
+	unsigned r = s->len % 128;
+
+	s->buf[r++] = 0x80;
+	if (r > 112) {
+		memset(s->buf + r, 0, 128 - r);
+		r = 0;
+		processblock(s, s->buf);
+	}
+	memset(s->buf + r, 0, 120 - r);
+	s->len *= 8;
+	s->buf[120] = s->len >> 56;
+	s->buf[121] = s->len >> 48;
+	s->buf[122] = s->len >> 40;
+	s->buf[123] = s->len >> 32;
+	s->buf[124] = s->len >> 24;
+	s->buf[125] = s->len >> 16;
+	s->buf[126] = s->len >> 8;
+	s->buf[127] = s->len;
+	processblock(s, s->buf);
+}
+
+static void sha512_init(struct sha512 *s)
+{
+	s->len = 0;
+	s->h[0] = 0x6a09e667f3bcc908ULL;
+	s->h[1] = 0xbb67ae8584caa73bULL;
+	s->h[2] = 0x3c6ef372fe94f82bULL;
+	s->h[3] = 0xa54ff53a5f1d36f1ULL;
+	s->h[4] = 0x510e527fade682d1ULL;
+	s->h[5] = 0x9b05688c2b3e6c1fULL;
+	s->h[6] = 0x1f83d9abfb41bd6bULL;
+	s->h[7] = 0x5be0cd19137e2179ULL;
+}
+
+static void sha512_sum(struct sha512 *s, uint8_t *md)
+{
+	int i;
+
+	pad(s);
+	for (i = 0; i < 8; i++) {
+		md[8*i] = s->h[i] >> 56;
+		md[8*i+1] = s->h[i] >> 48;
+		md[8*i+2] = s->h[i] >> 40;
+		md[8*i+3] = s->h[i] >> 32;
+		md[8*i+4] = s->h[i] >> 24;
+		md[8*i+5] = s->h[i] >> 16;
+		md[8*i+6] = s->h[i] >> 8;
+		md[8*i+7] = s->h[i];
+	}
+}
+
+static void sha512_update(struct sha512 *s, const void *m, unsigned long len)
+{
+	const uint8_t *p = m;
+	unsigned r = s->len % 128;
+
+	s->len += len;
+	if (r) {
+		if (len < 128 - r) {
+			memcpy(s->buf + r, p, len);
+			return;
+		}
+		memcpy(s->buf + r, p, 128 - r);
+		len -= 128 - r;
+		p += 128 - r;
+		processblock(s, s->buf);
+	}
+	for (; len >= 128; len -= 128, p += 128)
+		processblock(s, p);
+	memcpy(s->buf, p, len);
+}
+
+static const unsigned char b64[] =
+"./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
+
+static char *to64(char *s, unsigned int u, int n)
+{
+	while (--n >= 0) {
+		*s++ = b64[u % 64];
+		u /= 64;
+	}
+	return s;
+}
+
+/* key limit is not part of the original design, added for DoS protection.
+ * rounds limit has been lowered (versus the reference/spec), also for DoS
+ * protection. runtime is O(klen^2 + klen*rounds) */
+#define KEY_MAX 256
+#define SALT_MAX 16
+#define ROUNDS_DEFAULT 5000
+#define ROUNDS_MIN 1000
+#define ROUNDS_MAX 9999999
+
+/* hash n bytes of the repeated md message digest */
+static void hashmd(struct sha512 *s, unsigned int n, const void *md)
+{
+	unsigned int i;
+
+	for (i = n; i > 64; i -= 64)
+		sha512_update(s, md, 64);
+	sha512_update(s, md, i);
+}
+
+static char *sha512crypt(const char *key, const char *setting, char *output)
+{
+	struct sha512 ctx;
+	unsigned char md[64], kmd[64], smd[64];
+	unsigned int i, r, klen, slen;
+	char rounds[20] = "";
+	const char *salt;
+	char *p;
+
+	/* reject large keys */
+	for (i = 0; i <= KEY_MAX && key[i]; i++);
+	if (i > KEY_MAX)
+		return 0;
+	klen = i;
+
+	/* setting: $6$rounds=n$salt$ (rounds=n$ and closing $ are optional) */
+	if (strncmp(setting, "$6$", 3) != 0)
+		return 0;
+	salt = setting + 3;
+
+	r = ROUNDS_DEFAULT;
+	if (strncmp(salt, "rounds=", sizeof "rounds=" - 1) == 0) {
+		unsigned long u;
+		char *end;
+
+		/*
+		 * this is a deviation from the reference:
+		 * bad rounds setting is rejected if it is
+		 * - empty
+		 * - unterminated (missing '$')
+		 * - begins with anything but a decimal digit
+		 * the reference implementation treats these bad
+		 * rounds as part of the salt or parse them with
+		 * strtoul semantics which may cause problems
+		 * including non-portable hashes that depend on
+		 * the host's value of ULONG_MAX.
+		 */
+		salt += sizeof "rounds=" - 1;
+		if (!isdigit(*salt))
+			return 0;
+		u = strtoul(salt, &end, 10);
+		if (*end != '$')
+			return 0;
+		salt = end+1;
+		if (u < ROUNDS_MIN)
+			r = ROUNDS_MIN;
+		else if (u > ROUNDS_MAX)
+			return 0;
+		else
+			r = u;
+		/* needed when rounds is zero prefixed or out of bounds */
+		sprintf(rounds, "rounds=%u$", r);
+	}
+
+	for (i = 0; i < SALT_MAX && salt[i] && salt[i] != '$'; i++)
+		/* reject characters that interfere with /etc/shadow parsing */
+		if (salt[i] == '\n' || salt[i] == ':')
+			return 0;
+	slen = i;
+
+	/* B = sha(key salt key) */
+	sha512_init(&ctx);
+	sha512_update(&ctx, key, klen);
+	sha512_update(&ctx, salt, slen);
+	sha512_update(&ctx, key, klen);
+	sha512_sum(&ctx, md);
+
+	/* A = sha(key salt repeat-B alternate-B-key) */
+	sha512_init(&ctx);
+	sha512_update(&ctx, key, klen);
+	sha512_update(&ctx, salt, slen);
+	hashmd(&ctx, klen, md);
+	for (i = klen; i > 0; i >>= 1)
+		if (i & 1)
+			sha512_update(&ctx, md, sizeof md);
+		else
+			sha512_update(&ctx, key, klen);
+	sha512_sum(&ctx, md);
+
+	/* DP = sha(repeat-key), this step takes O(klen^2) time */
+	sha512_init(&ctx);
+	for (i = 0; i < klen; i++)
+		sha512_update(&ctx, key, klen);
+	sha512_sum(&ctx, kmd);
+
+	/* DS = sha(repeat-salt) */
+	sha512_init(&ctx);
+	for (i = 0; i < 16 + md[0]; i++)
+		sha512_update(&ctx, salt, slen);
+	sha512_sum(&ctx, smd);
+
+	/* iterate A = f(A,DP,DS), this step takes O(rounds*klen) time */
+	for (i = 0; i < r; i++) {
+		sha512_init(&ctx);
+		if (i % 2)
+			hashmd(&ctx, klen, kmd);
+		else
+			sha512_update(&ctx, md, sizeof md);
+		if (i % 3)
+			sha512_update(&ctx, smd, slen);
+		if (i % 7)
+			hashmd(&ctx, klen, kmd);
+		if (i % 2)
+			sha512_update(&ctx, md, sizeof md);
+		else
+			hashmd(&ctx, klen, kmd);
+		sha512_sum(&ctx, md);
+	}
+
+	/* output is $6$rounds=n$salt$hash */
+	p = output;
+	p += sprintf(p, "$6$%s%.*s$", rounds, slen, salt);
+#if 1
+	static const unsigned char perm[][3] = {
+		0,21,42,22,43,1,44,2,23,3,24,45,25,46,4,
+		47,5,26,6,27,48,28,49,7,50,8,29,9,30,51,
+		31,52,10,53,11,32,12,33,54,34,55,13,56,14,35,
+		15,36,57,37,58,16,59,17,38,18,39,60,40,61,19,
+		62,20,41 };
+	for (i=0; i<21; i++) p = to64(p,
+		(md[perm[i][0]]<<16)|(md[perm[i][1]]<<8)|md[perm[i][2]], 4);
+#else
+	p = to64(p, (md[0]<<16)|(md[21]<<8)|md[42], 4);
+	p = to64(p, (md[22]<<16)|(md[43]<<8)|md[1], 4);
+	p = to64(p, (md[44]<<16)|(md[2]<<8)|md[23], 4);
+	p = to64(p, (md[3]<<16)|(md[24]<<8)|md[45], 4);
+	p = to64(p, (md[25]<<16)|(md[46]<<8)|md[4], 4);
+	p = to64(p, (md[47]<<16)|(md[5]<<8)|md[26], 4);
+	p = to64(p, (md[6]<<16)|(md[27]<<8)|md[48], 4);
+	p = to64(p, (md[28]<<16)|(md[49]<<8)|md[7], 4);
+	p = to64(p, (md[50]<<16)|(md[8]<<8)|md[29], 4);
+	p = to64(p, (md[9]<<16)|(md[30]<<8)|md[51], 4);
+	p = to64(p, (md[31]<<16)|(md[52]<<8)|md[10], 4);
+	p = to64(p, (md[53]<<16)|(md[11]<<8)|md[32], 4);
+	p = to64(p, (md[12]<<16)|(md[33]<<8)|md[54], 4);
+	p = to64(p, (md[34]<<16)|(md[55]<<8)|md[13], 4);
+	p = to64(p, (md[56]<<16)|(md[14]<<8)|md[35], 4);
+	p = to64(p, (md[15]<<16)|(md[36]<<8)|md[57], 4);
+	p = to64(p, (md[37]<<16)|(md[58]<<8)|md[16], 4);
+	p = to64(p, (md[59]<<16)|(md[17]<<8)|md[38], 4);
+	p = to64(p, (md[18]<<16)|(md[39]<<8)|md[60], 4);
+	p = to64(p, (md[40]<<16)|(md[61]<<8)|md[19], 4);
+	p = to64(p, (md[62]<<16)|(md[20]<<8)|md[41], 4);
+#endif
+	p = to64(p, md[63], 2);
+	*p = 0;
+	return output;
+}
+
+char *__crypt_sha512(const char *key, const char *setting, char *output)
+{
+	static const char testkey[] = "Xy01@#\x01\x02\x80\x7f\xff\r\n\x81\t !";
+	static const char testsetting[] = "$6$rounds=1234$abc0123456789$";
+	static const char testhash[] = "$6$rounds=1234$abc0123456789$BCpt8zLrc/RcyuXmCDOE1ALqMXB2MH6n1g891HhFj8.w7LxGv.FTkqq6Vxc/km3Y0jE0j24jY5PIv/oOu6reg1";
+	char testbuf[128];
+	char *p, *q;
+
+	p = sha512crypt(key, setting, output);
+	/* self test and stack cleanup */
+	q = sha512crypt(testkey, testsetting, testbuf);
+	if (!p || q != testbuf || memcmp(testbuf, testhash, sizeof testhash))
+		return "*";
+	return p;
+}
libc/musl/src/crypt/encrypt.c
@@ -0,0 +1,52 @@
+#include <stdint.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+#include "crypt_des.h"
+
+static struct expanded_key __encrypt_key;
+
+void setkey(const char *key)
+{
+	unsigned char bkey[8];
+	int i, j;
+
+	for (i = 0; i < 8; i++) {
+		bkey[i] = 0;
+		for (j = 7; j >= 0; j--, key++)
+			bkey[i] |= (uint32_t)(*key & 1) << j;
+	}
+
+	__des_setkey(bkey, &__encrypt_key);
+}
+
+void encrypt(char *block, int edflag)
+{
+	struct expanded_key decrypt_key, *key;
+	uint32_t b[2];
+	int i, j;
+	char *p;
+
+	p = block;
+	for (i = 0; i < 2; i++) {
+		b[i] = 0;
+		for (j = 31; j >= 0; j--, p++)
+			b[i] |= (uint32_t)(*p & 1) << j;
+	}
+
+	key = &__encrypt_key;
+	if (edflag) {
+		key = &decrypt_key;
+		for (i = 0; i < 16; i++) {
+			decrypt_key.l[i] = __encrypt_key.l[15-i];
+			decrypt_key.r[i] = __encrypt_key.r[15-i];
+		}
+	}
+
+	__do_des(b[0], b[1], b, b + 1, 1, 0, key);
+
+	p = block;
+	for (i = 0; i < 2; i++)
+		for (j = 31; j >= 0; j--)
+			*p++ = b[i]>>j & 1;
+}
libc/musl/src/ctype/__ctype_b_loc.c
@@ -0,0 +1,41 @@
+#include <endian.h>
+
+#if __BYTE_ORDER == __BIG_ENDIAN
+#define X(x) x
+#else
+#define X(x) (((x)/256 | (x)*256) % 65536)
+#endif
+
+static const unsigned short table[] = {
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+X(0x200),X(0x200),X(0x200),X(0x200),X(0x200),X(0x200),X(0x200),X(0x200),
+X(0x200),X(0x320),X(0x220),X(0x220),X(0x220),X(0x220),X(0x200),X(0x200),
+X(0x200),X(0x200),X(0x200),X(0x200),X(0x200),X(0x200),X(0x200),X(0x200),
+X(0x200),X(0x200),X(0x200),X(0x200),X(0x200),X(0x200),X(0x200),X(0x200),
+X(0x160),X(0x4c0),X(0x4c0),X(0x4c0),X(0x4c0),X(0x4c0),X(0x4c0),X(0x4c0),
+X(0x4c0),X(0x4c0),X(0x4c0),X(0x4c0),X(0x4c0),X(0x4c0),X(0x4c0),X(0x4c0),
+X(0x8d8),X(0x8d8),X(0x8d8),X(0x8d8),X(0x8d8),X(0x8d8),X(0x8d8),X(0x8d8),
+X(0x8d8),X(0x8d8),X(0x4c0),X(0x4c0),X(0x4c0),X(0x4c0),X(0x4c0),X(0x4c0),
+X(0x4c0),X(0x8d5),X(0x8d5),X(0x8d5),X(0x8d5),X(0x8d5),X(0x8d5),X(0x8c5),
+X(0x8c5),X(0x8c5),X(0x8c5),X(0x8c5),X(0x8c5),X(0x8c5),X(0x8c5),X(0x8c5),
+X(0x8c5),X(0x8c5),X(0x8c5),X(0x8c5),X(0x8c5),X(0x8c5),X(0x8c5),X(0x8c5),
+X(0x8c5),X(0x8c5),X(0x8c5),X(0x4c0),X(0x4c0),X(0x4c0),X(0x4c0),X(0x4c0),
+X(0x4c0),X(0x8d6),X(0x8d6),X(0x8d6),X(0x8d6),X(0x8d6),X(0x8d6),X(0x8c6),
+X(0x8c6),X(0x8c6),X(0x8c6),X(0x8c6),X(0x8c6),X(0x8c6),X(0x8c6),X(0x8c6),
+X(0x8c6),X(0x8c6),X(0x8c6),X(0x8c6),X(0x8c6),X(0x8c6),X(0x8c6),X(0x8c6),
+X(0x8c6),X(0x8c6),X(0x8c6),X(0x4c0),X(0x4c0),X(0x4c0),X(0x4c0),X(0x200),
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+};
+
+static const unsigned short *const ptable = table+128;
+
+const unsigned short **__ctype_b_loc(void)
+{
+	return (void *)&ptable;
+}
libc/musl/src/ctype/__ctype_get_mb_cur_max.c
@@ -0,0 +1,7 @@
+#include <stdlib.h>
+#include "locale_impl.h"
+
+size_t __ctype_get_mb_cur_max()
+{
+	return MB_CUR_MAX;
+}
libc/musl/src/ctype/__ctype_tolower_loc.c
@@ -0,0 +1,30 @@
+#include <stdint.h>
+
+static const int32_t table[] = {
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,
+16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,
+32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,
+48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,
+64,
+'a','b','c','d','e','f','g','h','i','j','k','l','m',
+'n','o','p','q','r','s','t','u','v','w','x','y','z',
+91,92,93,94,95,96,
+'a','b','c','d','e','f','g','h','i','j','k','l','m',
+'n','o','p','q','r','s','t','u','v','w','x','y','z',
+123,124,125,126,127,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+};
+
+static const int32_t *const ptable = table+128;
+
+const int32_t **__ctype_tolower_loc(void)
+{
+	return (void *)&ptable;
+}
libc/musl/src/ctype/__ctype_toupper_loc.c
@@ -0,0 +1,30 @@
+#include <stdint.h>
+
+static const int32_t table[] = {
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,
+16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,
+32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,
+48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,
+64,
+'A','B','C','D','E','F','G','H','I','J','K','L','M',
+'N','O','P','Q','R','S','T','U','V','W','X','Y','Z',
+91,92,93,94,95,96,
+'A','B','C','D','E','F','G','H','I','J','K','L','M',
+'N','O','P','Q','R','S','T','U','V','W','X','Y','Z',
+123,124,125,126,127,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+};
+
+static const int32_t *const ptable = table+128;
+
+const int32_t **__ctype_toupper_loc(void)
+{
+	return (void *)&ptable;
+}
libc/musl/src/ctype/alpha.h
@@ -0,0 +1,163 @@
+18,17,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,17,34,35,36,17,37,38,39,40,
+41,42,43,44,17,45,46,47,16,16,48,16,16,16,16,16,16,16,49,50,51,16,52,53,16,16,
+17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,54,
+17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,
+17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,
+17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,
+17,17,17,55,17,17,17,17,56,17,57,58,59,60,61,62,17,17,17,17,17,17,17,17,17,17,
+17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,
+17,17,17,17,17,17,17,63,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,
+16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,17,64,65,17,66,67,
+68,69,70,71,72,73,74,17,75,76,77,78,79,80,16,16,16,81,82,83,84,85,86,87,88,89,
+16,90,16,91,92,16,16,17,17,17,93,94,95,16,16,16,16,16,16,16,16,16,16,17,17,17,
+17,96,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,17,17,97,16,16,16,16,16,16,
+16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,
+16,17,17,98,99,16,16,16,100,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,
+17,17,17,17,17,17,17,101,17,17,102,16,16,16,16,16,16,16,16,16,16,16,16,16,16,
+16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,17,103,
+104,16,16,16,16,16,16,16,16,16,105,16,16,16,16,16,16,16,16,16,16,16,16,16,16,
+16,16,16,16,16,16,16,16,16,106,107,108,109,16,16,16,16,16,16,16,16,110,16,16,
+16,16,16,16,16,111,112,16,16,16,16,113,16,16,114,16,16,16,16,16,16,16,16,16,
+16,16,16,16,
+16,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,
+255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+255,255,255,255,255,255,255,255,255,255,255,0,0,0,0,0,0,0,0,254,255,255,7,254,
+255,255,7,0,0,0,0,0,4,32,4,255,255,127,255,255,255,127,255,255,255,255,255,
+255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+255,195,255,3,0,31,80,0,0,0,0,0,0,0,0,0,0,32,0,0,0,0,0,223,188,64,215,255,255,
+251,255,255,255,255,255,255,255,255,255,191,255,255,255,255,255,255,255,255,
+255,255,255,255,255,255,255,255,255,3,252,255,255,255,255,255,255,255,255,255,
+255,255,255,255,255,255,255,255,255,255,255,254,255,255,255,127,2,254,255,255,
+255,255,0,0,0,0,0,255,191,182,0,255,255,255,7,7,0,0,0,255,7,255,255,255,255,
+255,255,255,254,255,195,255,255,255,255,255,255,255,255,255,255,255,255,239,
+31,254,225,255,
+159,0,0,255,255,255,255,255,255,0,224,255,255,255,255,255,255,255,255,255,255,
+255,255,3,0,255,255,255,255,255,7,48,4,255,255,255,252,255,31,0,0,255,255,255,
+1,255,7,0,0,0,0,0,0,255,255,223,63,0,0,240,255,248,3,255,255,255,255,255,255,
+255,255,255,239,255,223,225,255,207,255,254,255,239,159,249,255,255,253,197,
+227,159,89,128,176,207,255,3,16,238,135,249,255,255,253,109,195,135,25,2,94,
+192,255,63,0,238,191,251,255,255,253,237,227,191,27,1,0,207,255,0,30,238,159,
+249,255,255,253,237,227,159,25,192,176,207,255,2,0,236,199,61,214,24,199,255,
+195,199,29,129,0,192,255,0,0,239,223,253,255,255,253,255,227,223,29,96,7,207,
+255,0,0,239,223,253,255,255,253,239,227,223,29,96,64,207,255,6,0,239,223,253,
+255,255,255,255,231,223,93,240,128,207,255,0,252,236,255,127,252,255,255,251,
+47,127,128,95,255,192,255,12,0,254,255,255,255,255,127,255,7,63,32,255,3,0,0,
+0,0,150,37,240,254,174,236,255,59,95,32,255,243,0,0,0,
+0,1,0,0,0,255,3,0,0,255,254,255,255,255,31,254,255,3,255,255,254,255,255,255,
+31,0,0,0,0,0,0,0,0,255,255,255,255,255,255,127,249,255,3,255,255,231,193,255,
+255,127,64,255,51,255,255,255,255,191,32,255,255,255,255,255,247,255,255,255,
+255,255,255,255,255,255,61,127,61,255,255,255,255,255,61,255,255,255,255,61,
+127,61,255,127,255,255,255,255,255,255,255,61,255,255,255,255,255,255,255,255,
+135,0,0,0,0,255,255,0,0,255,255,255,255,255,255,255,255,255,255,63,63,254,255,
+255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+255,255,255,255,255,159,255,255,254,255,255,7,255,255,255,255,255,255,255,255,
+255,199,255,1,255,223,15,0,255,255,15,0,255,255,15,0,255,223,13,0,255,255,255,
+255,255,255,207,255,255,1,128,16,255,3,0,0,0,0,255,3,255,255,255,255,255,255,
+255,255,255,255,255,0,255,255,255,255,255,7,255,255,255,255,255,255,255,255,
+63,
+0,255,255,255,127,255,15,255,1,192,255,255,255,255,63,31,0,255,255,255,255,
+255,15,255,255,255,3,255,3,0,0,0,0,255,255,255,15,255,255,255,255,255,255,255,
+127,254,255,31,0,255,3,255,3,128,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,
+255,239,255,239,15,255,3,0,0,0,0,255,255,255,255,255,243,255,255,255,255,255,
+255,191,255,3,0,255,255,255,255,255,255,63,0,255,227,255,255,255,255,255,63,
+255,1,0,0,0,0,0,0,0,0,0,0,0,222,111,0,255,255,255,255,255,255,255,255,255,255,
+255,255,255,255,255,255,255,255,255,255,255,255,255,255,0,0,0,0,128,255,31,0,
+255,255,63,63,255,255,255,255,63,63,255,170,255,255,255,63,255,255,255,255,
+255,255,223,95,220,31,207,15,255,31,220,31,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,128,
+0,0,255,31,0,0,0,0,0,0,0,0,0,0,0,0,132,252,47,62,80,189,255,243,224,67,0,0,
+255,255,255,255,255,1,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,192,255,255,255,255,255,255,3,0,
+0,255,255,255,255,255,127,255,255,255,255,255,127,255,255,255,255,255,255,255,
+255,255,255,255,255,255,255,255,255,31,120,12,0,255,255,255,255,191,32,255,
+255,255,255,255,255,255,128,0,0,255,255,127,0,127,127,127,127,127,127,127,127,
+255,255,255,255,0,0,0,0,0,128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,224,0,0,0,254,3,62,31,254,255,255,255,255,255,255,255,255,255,127,224,254,
+255,255,255,255,255,255,255,255,255,255,247,224,255,255,255,255,127,254,255,
+255,255,255,255,255,255,255,255,255,127,0,0,255,255,255,7,0,0,0,0,0,0,255,255,
+255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+255,255,255,63,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,255,255,255,255,255,
+255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,7,0,
+0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,31,0,0,
+0,0,0,0,0,0,255,255,255,255,255,63,255,31,255,255,255,15,0,0,255,255,255,255,
+255,127,240,143,255,255,255,255,255,255,255,255,255,255,255,255,255,255,0,0,0,
+0,128,255,252,255,255,255,255,255,255,255,255,255,255,255,255,249,255,255,255,
+127,255,0,0,0,0,0,0,0,128,255,187,247,255,255,255,0,0,0,255,255,255,255,255,
+255,15,0,255,255,255,255,255,255,255,255,47,0,255,3,0,0,252,40,255,255,255,
+255,255,7,255,255,255,255,7,0,255,255,255,31,255,255,255,255,255,255,247,255,
+0,128,255,3,223,255,255,127,255,255,255,255,255,255,127,0,255,63,255,3,255,
+255,127,196,255,255,255,255,255,255,255,127,5,0,0,56,255,255,60,0,126,126,126,
+0,127,127,255,255,255,255,255,247,63,0,255,255,255,255,255,255,255,255,255,
+255,255,255,255,255,255,7,255,3,255,255,255,255,255,255,255,255,255,255,255,
+255,255,255,255,255,255,255,255,255,15,0,255,255,127,248,255,255,255,255,255,
+15,255,255,255,255,255,255,255,255,255,255,255,255,255,63,255,255,255,255,255,
+255,255,255,255,255,255,255,255,3,0,0,0,0,127,0,248,224,255,253,127,95,219,
+255,255,255,255,255,255,255,255,255,255,255,255,255,3,0,0,0,248,255,255,255,
+255,255,255,255,255,255,255,255,255,63,0,0,255,255,255,255,255,255,255,255,
+252,255,255,255,255,255,255,0,0,0,0,0,255,15,0,0,0,0,0,0,0,0,0,0,0,0,0,0,223,
+255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,31,0,0,255,3,
+254,255,255,7,254,255,255,7,192,255,255,255,255,255,255,255,255,255,255,127,
+252,252,252,28,0,0,0,0,255,239,255,255,127,255,255,183,255,63,255,63,0,0,0,0,
+255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,7,0,0,0,0,0,0,0,0,
+255,255,255,255,255,255,31,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,255,255,255,31,255,255,255,255,255,255,1,0,0,0,0,
+0,255,255,255,255,0,224,255,255,255,7,255,255,255,255,255,7,255,255,255,63,
+255,255,255,255,15,255,62,0,0,0,0,0,255,255,255,255,255,255,255,255,255,255,
+255,255,255,255,255,255,255,255,255,63,255,3,255,255,255,255,15,255,255,255,
+255,15,255,255,255,255,255,0,255,255,255,255,255,255,15,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,255,255,255,255,255,255,127,0,255,255,63,0,255,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,63,253,255,255,255,255,191,145,255,255,63,0,255,255,
+127,0,255,255,255,127,0,0,0,0,0,0,0,0,255,255,55,0,255,255,63,0,255,255,255,3,
+0,0,0,0,0,0,0,0,255,255,255,255,255,255,255,192,0,0,0,0,0,0,0,0,111,240,239,
+254,255,255,15,0,0,0,0,0,255,255,255,31,255,255,255,31,0,0,0,0,255,254,255,
+255,31,0,0,0,255,255,255,255,255,255,63,0,255,255,63,0,255,255,7,0,255,255,3,
+0,0,0,0,0,0,0,0,0,0,0,0,
+0,255,255,255,255,255,255,255,255,255,1,0,0,0,0,0,0,255,255,255,255,255,255,7,
+0,255,255,255,255,255,255,7,0,255,255,255,255,255,255,255,255,63,0,0,0,192,
+255,0,0,252,255,255,255,255,255,255,1,0,0,255,255,255,1,255,3,255,255,255,255,
+255,255,199,255,0,0,255,255,255,255,71,0,255,255,255,255,255,255,255,255,30,0,
+255,23,0,0,0,0,255,255,251,255,255,255,159,64,0,0,0,0,0,0,0,0,127,189,255,191,
+255,1,255,255,255,255,255,255,255,1,255,3,239,159,249,255,255,253,237,227,159,
+25,129,224,15,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,
+255,255,187,7,255,3,0,0,0,0,255,255,255,255,255,255,255,255,179,0,255,3,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,63,127,0,0,0,63,0,0,
+0,0,255,255,255,255,255,255,255,127,17,0,255,3,0,0,0,0,255,255,255,255,255,
+255,63,0,255,3,0,0,0,0,0,
+0,255,255,255,227,255,7,255,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,255,255,255,3,
+0,128,255,255,255,255,255,255,231,127,0,0,255,255,255,255,255,255,207,255,255,
+0,0,0,0,0,255,255,255,255,255,255,255,1,255,253,255,255,255,255,127,127,1,0,
+255,3,0,0,252,255,255,255,252,255,255,254,127,0,0,0,0,0,0,0,0,0,127,251,255,
+255,255,255,127,180,203,0,255,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,
+255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,3,0,0,
+0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,255,255,255,255,255,255,255,127,0,
+0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+255,255,255,255,255,15,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,255,255,255,255,255,127,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+255,255,255,255,255,255,255,255,127,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,255,255,255,255,255,255,255,1,255,255,255,127,255,3,0,0,0,0,0,0,0,0,0,0,0,
+0,255,255,255,63,0,0,255,255,255,255,255,255,127,0,15,0,255,3,248,255,255,224,
+255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,255,255,31,0,255,
+255,255,255,255,127,0,0,248,255,0,0,0,0,0,0,0,0,3,0,0,0,255,255,255,255,255,
+255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+255,255,255,255,255,31,0,0,255,255,255,255,255,255,255,255,255,255,255,255,
+255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,7,0,
+255,255,255,127,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,255,255,255,255,
+255,255,255,255,255,255,255,
+255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+255,255,255,255,255,255,255,255,255,255,255,255,255,15,255,255,255,255,255,
+255,255,255,255,255,255,255,255,7,255,31,255,1,255,67,0,0,0,0,0,0,0,0,0,0,0,0,
+255,255,255,255,255,255,255,255,255,255,223,255,255,255,255,255,255,255,255,
+223,100,222,255,235,239,255,255,255,255,255,255,255,191,231,223,223,255,255,
+255,123,95,252,253,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+255,255,255,255,255,255,255,255,63,255,255,255,253,255,255,247,255,255,255,
+247,255,255,223,255,255,255,223,255,255,127,255,255,255,127,255,255,255,253,
+255,255,255,253,255,255,247,207,255,255,255,255,255,255,127,255,255,249,219,7,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,
+255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,31,0,
+0,0,0,0,0,
+0,255,255,255,255,255,255,255,255,143,0,255,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,239,255,255,255,150,254,247,10,132,234,150,170,150,247,247,94,255,251,
+255,15,238,251,255,15,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,3,255,255,255,3,
+255,255,255,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
libc/musl/src/ctype/isalnum.c
@@ -0,0 +1,13 @@
+#include <ctype.h>
+
+int isalnum(int c)
+{
+	return isalpha(c) || isdigit(c);
+}
+
+int __isalnum_l(int c, locale_t l)
+{
+	return isalnum(c);
+}
+
+weak_alias(__isalnum_l, isalnum_l);
libc/musl/src/ctype/isalpha.c
@@ -0,0 +1,14 @@
+#include <ctype.h>
+#undef isalpha
+
+int isalpha(int c)
+{
+	return ((unsigned)c|32)-'a' < 26;
+}
+
+int __isalpha_l(int c, locale_t l)
+{
+	return isalpha(c);
+}
+
+weak_alias(__isalpha_l, isalpha_l);
libc/musl/src/ctype/isascii.c
@@ -0,0 +1,7 @@
+#include <ctype.h>
+#undef isascii
+
+int isascii(int c)
+{
+	return !(c&~0x7f);
+}
libc/musl/src/ctype/isblank.c
@@ -0,0 +1,13 @@
+#include <ctype.h>
+
+int isblank(int c)
+{
+	return (c == ' ' || c == '\t');
+}
+
+int __isblank_l(int c, locale_t l)
+{
+	return isblank(c);
+}
+
+weak_alias(__isblank_l, isblank_l);
libc/musl/src/ctype/iscntrl.c
@@ -0,0 +1,13 @@
+#include <ctype.h>
+
+int iscntrl(int c)
+{
+	return (unsigned)c < 0x20 || c == 0x7f;
+}
+
+int __iscntrl_l(int c, locale_t l)
+{
+	return iscntrl(c);
+}
+
+weak_alias(__iscntrl_l, iscntrl_l);
libc/musl/src/ctype/isdigit.c
@@ -0,0 +1,14 @@
+#include <ctype.h>
+#undef isdigit
+
+int isdigit(int c)
+{
+	return (unsigned)c-'0' < 10;
+}
+
+int __isdigit_l(int c, locale_t l)
+{
+	return isdigit(c);
+}
+
+weak_alias(__isdigit_l, isdigit_l);
libc/musl/src/ctype/isgraph.c
@@ -0,0 +1,14 @@
+#include <ctype.h>
+#undef isgraph
+
+int isgraph(int c)
+{
+	return (unsigned)c-0x21 < 0x5e;
+}
+
+int __isgraph_l(int c, locale_t l)
+{
+	return isgraph(c);
+}
+
+weak_alias(__isgraph_l, isgraph_l);
libc/musl/src/ctype/islower.c
@@ -0,0 +1,14 @@
+#include <ctype.h>
+#undef islower
+
+int islower(int c)
+{
+	return (unsigned)c-'a' < 26;
+}
+
+int __islower_l(int c, locale_t l)
+{
+	return islower(c);
+}
+
+weak_alias(__islower_l, islower_l);
libc/musl/src/ctype/isprint.c
@@ -0,0 +1,14 @@
+#include <ctype.h>
+#undef isprint
+
+int isprint(int c)
+{
+	return (unsigned)c-0x20 < 0x5f;
+}
+
+int __isprint_l(int c, locale_t l)
+{
+	return isprint(c);
+}
+
+weak_alias(__isprint_l, isprint_l);
libc/musl/src/ctype/ispunct.c
@@ -0,0 +1,13 @@
+#include <ctype.h>
+
+int ispunct(int c)
+{
+	return isgraph(c) && !isalnum(c);
+}
+
+int __ispunct_l(int c, locale_t l)
+{
+	return ispunct(c);
+}
+
+weak_alias(__ispunct_l, ispunct_l);
libc/musl/src/ctype/isspace.c
@@ -0,0 +1,14 @@
+#include <ctype.h>
+#undef isspace
+
+int isspace(int c)
+{
+	return c == ' ' || (unsigned)c-'\t' < 5;
+}
+
+int __isspace_l(int c, locale_t l)
+{
+	return isspace(c);
+}
+
+weak_alias(__isspace_l, isspace_l);
libc/musl/src/ctype/isupper.c
@@ -0,0 +1,14 @@
+#include <ctype.h>
+#undef isupper
+
+int isupper(int c)
+{
+	return (unsigned)c-'A' < 26;
+}
+
+int __isupper_l(int c, locale_t l)
+{
+	return isupper(c);
+}
+
+weak_alias(__isupper_l, isupper_l);
libc/musl/src/ctype/iswalnum.c
@@ -0,0 +1,13 @@
+#include <wctype.h>
+
+int iswalnum(wint_t wc)
+{
+	return iswdigit(wc) || iswalpha(wc);
+}
+
+int __iswalnum_l(wint_t c, locale_t l)
+{
+	return iswalnum(c);
+}
+
+weak_alias(__iswalnum_l, iswalnum_l);
libc/musl/src/ctype/iswalpha.c
@@ -0,0 +1,21 @@
+#include <wctype.h>
+
+static const unsigned char table[] = {
+#include "alpha.h"
+};
+
+int iswalpha(wint_t wc)
+{
+	if (wc<0x20000U)
+		return (table[table[wc>>8]*32+((wc&255)>>3)]>>(wc&7))&1;
+	if (wc<0x2fffeU)
+		return 1;
+	return 0;
+}
+
+int __iswalpha_l(wint_t c, locale_t l)
+{
+	return iswalpha(c);
+}
+
+weak_alias(__iswalpha_l, iswalpha_l);
libc/musl/src/ctype/iswblank.c
@@ -0,0 +1,14 @@
+#include <wctype.h>
+#include <ctype.h>
+
+int iswblank(wint_t wc)
+{
+	return isblank(wc);
+}
+
+int __iswblank_l(wint_t c, locale_t l)
+{
+	return iswblank(c);
+}
+
+weak_alias(__iswblank_l, iswblank_l);
libc/musl/src/ctype/iswcntrl.c
@@ -0,0 +1,16 @@
+#include <wctype.h>
+
+int iswcntrl(wint_t wc)
+{
+	return (unsigned)wc < 32
+	    || (unsigned)(wc-0x7f) < 33
+	    || (unsigned)(wc-0x2028) < 2
+	    || (unsigned)(wc-0xfff9) < 3;
+}
+
+int __iswcntrl_l(wint_t c, locale_t l)
+{
+	return iswcntrl(c);
+}
+
+weak_alias(__iswcntrl_l, iswcntrl_l);
libc/musl/src/ctype/iswctype.c
@@ -0,0 +1,75 @@
+#include <wctype.h>
+#include <string.h>
+
+#define WCTYPE_ALNUM  1
+#define WCTYPE_ALPHA  2
+#define WCTYPE_BLANK  3
+#define WCTYPE_CNTRL  4
+#define WCTYPE_DIGIT  5
+#define WCTYPE_GRAPH  6
+#define WCTYPE_LOWER  7
+#define WCTYPE_PRINT  8
+#define WCTYPE_PUNCT  9
+#define WCTYPE_SPACE  10
+#define WCTYPE_UPPER  11
+#define WCTYPE_XDIGIT 12
+
+int iswctype(wint_t wc, wctype_t type)
+{
+	switch (type) {
+	case WCTYPE_ALNUM:
+		return iswalnum(wc);
+	case WCTYPE_ALPHA:
+		return iswalpha(wc);
+	case WCTYPE_BLANK:
+		return iswblank(wc);
+	case WCTYPE_CNTRL:
+		return iswcntrl(wc);
+	case WCTYPE_DIGIT:
+		return iswdigit(wc);
+	case WCTYPE_GRAPH:
+		return iswgraph(wc);
+	case WCTYPE_LOWER:
+		return iswlower(wc);
+	case WCTYPE_PRINT:
+		return iswprint(wc);
+	case WCTYPE_PUNCT:
+		return iswpunct(wc);
+	case WCTYPE_SPACE:
+		return iswspace(wc);
+	case WCTYPE_UPPER:
+		return iswupper(wc);
+	case WCTYPE_XDIGIT:
+		return iswxdigit(wc);
+	}
+	return 0;
+}
+
+wctype_t wctype(const char *s)
+{
+	int i;
+	const char *p;
+	/* order must match! */
+	static const char names[] =
+		"alnum\0" "alpha\0" "blank\0"
+		"cntrl\0" "digit\0" "graph\0"
+		"lower\0" "print\0" "punct\0"
+		"space\0" "upper\0" "xdigit";
+	for (i=1, p=names; *p; i++, p+=6)
+		if (*s == *p && !strcmp(s, p))
+			return i;
+	return 0;
+}
+
+int __iswctype_l(wint_t c, wctype_t t, locale_t l)
+{
+	return iswctype(c, t);
+}
+
+wctype_t __wctype_l(const char *s, locale_t l)
+{
+	return wctype(s);
+}
+
+weak_alias(__iswctype_l, iswctype_l);
+weak_alias(__wctype_l, wctype_l);
libc/musl/src/ctype/iswdigit.c
@@ -0,0 +1,15 @@
+#include <wctype.h>
+
+#undef iswdigit
+
+int iswdigit(wint_t wc)
+{
+	return (unsigned)wc-'0' < 10;
+}
+
+int __iswdigit_l(wint_t c, locale_t l)
+{
+	return iswdigit(c);
+}
+
+weak_alias(__iswdigit_l, iswdigit_l);
libc/musl/src/ctype/iswgraph.c
@@ -0,0 +1,14 @@
+#include <wctype.h>
+
+int iswgraph(wint_t wc)
+{
+	/* ISO C defines this function as: */
+	return !iswspace(wc) && iswprint(wc);
+}
+
+int __iswgraph_l(wint_t c, locale_t l)
+{
+	return iswgraph(c);
+}
+
+weak_alias(__iswgraph_l, iswgraph_l);
libc/musl/src/ctype/iswlower.c
@@ -0,0 +1,13 @@
+#include <wctype.h>
+
+int iswlower(wint_t wc)
+{
+	return towupper(wc) != wc;
+}
+
+int __iswlower_l(wint_t c, locale_t l)
+{
+	return iswlower(c);
+}
+
+weak_alias(__iswlower_l, iswlower_l);
libc/musl/src/ctype/iswprint.c
@@ -0,0 +1,26 @@
+#include <wctype.h>
+
+/* Consider all legal codepoints as printable except for:
+ * - C0 and C1 control characters
+ * - U+2028 and U+2029 (line/para break)
+ * - U+FFF9 through U+FFFB (interlinear annotation controls)
+ * The following code is optimized heavily to make hot paths for the
+ * expected printable characters. */
+
+int iswprint(wint_t wc)
+{
+	if (wc < 0xffU)
+		return (wc+1 & 0x7f) >= 0x21;
+	if (wc < 0x2028U || wc-0x202aU < 0xd800-0x202a || wc-0xe000U < 0xfff9-0xe000)
+		return 1;
+	if (wc-0xfffcU > 0x10ffff-0xfffc || (wc&0xfffe)==0xfffe)
+		return 0;
+	return 1;
+}
+
+int __iswprint_l(wint_t c, locale_t l)
+{
+	return iswprint(c);
+}
+
+weak_alias(__iswprint_l, iswprint_l);
libc/musl/src/ctype/iswpunct.c
@@ -0,0 +1,19 @@
+#include <wctype.h>
+
+static const unsigned char table[] = {
+#include "punct.h"
+};
+
+int iswpunct(wint_t wc)
+{
+	if (wc<0x20000U)
+		return (table[table[wc>>8]*32+((wc&255)>>3)]>>(wc&7))&1;
+	return 0;
+}
+
+int __iswpunct_l(wint_t c, locale_t l)
+{
+	return iswpunct(c);
+}
+
+weak_alias(__iswpunct_l, iswpunct_l);
libc/musl/src/ctype/iswspace.c
@@ -0,0 +1,24 @@
+#include <wchar.h>
+#include <wctype.h>
+
+/* Our definition of whitespace is the Unicode White_Space property,
+ * minus non-breaking spaces (U+00A0, U+2007, and U+202F) and script-
+ * specific characters with non-blank glyphs (U+1680 and U+180E). */
+
+int iswspace(wint_t wc)
+{
+	static const wchar_t spaces[] = {
+		' ', '\t', '\n', '\r', 11, 12,  0x0085,
+		0x2000, 0x2001, 0x2002, 0x2003, 0x2004, 0x2005,
+		0x2006, 0x2008, 0x2009, 0x200a,
+		0x2028, 0x2029, 0x205f, 0x3000, 0
+	};
+	return wc && wcschr(spaces, wc);
+}
+
+int __iswspace_l(wint_t c, locale_t l)
+{
+	return iswspace(c);
+}
+
+weak_alias(__iswspace_l, iswspace_l);
libc/musl/src/ctype/iswupper.c
@@ -0,0 +1,13 @@
+#include <wctype.h>
+
+int iswupper(wint_t wc)
+{
+	return towlower(wc) != wc;
+}
+
+int __iswupper_l(wint_t c, locale_t l)
+{
+	return iswupper(c);
+}
+
+weak_alias(__iswupper_l, iswupper_l);
libc/musl/src/ctype/iswxdigit.c
@@ -0,0 +1,13 @@
+#include <wctype.h>
+
+int iswxdigit(wint_t wc)
+{
+	return (unsigned)(wc-'0') < 10 || (unsigned)((wc|32)-'a') < 6;
+}
+
+int __iswxdigit_l(wint_t c, locale_t l)
+{
+	return iswxdigit(c);
+}
+
+weak_alias(__iswxdigit_l, iswxdigit_l);
libc/musl/src/ctype/isxdigit.c
@@ -0,0 +1,13 @@
+#include <ctype.h>
+
+int isxdigit(int c)
+{
+	return isdigit(c) || ((unsigned)c|32)-'a' < 6;
+}
+
+int __isxdigit_l(int c, locale_t l)
+{
+	return isxdigit(c);
+}
+
+weak_alias(__isxdigit_l, isxdigit_l);
libc/musl/src/ctype/nonspacing.h
@@ -0,0 +1,81 @@
+16,16,16,18,19,20,21,22,23,24,25,26,27,28,29,30,31,16,16,32,16,16,16,33,34,35,
+36,37,38,39,16,16,40,16,16,16,16,16,16,16,16,16,16,16,41,42,16,16,43,16,16,16,
+16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,
+16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,
+16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,
+16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,
+16,16,16,16,16,16,16,16,16,16,44,16,45,46,47,48,16,16,16,16,16,16,16,16,16,16,
+16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,
+16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,
+16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,49,16,16,50,
+51,16,52,53,54,16,16,16,16,16,16,55,16,16,16,16,16,56,57,58,59,60,61,62,63,16,
+16,64,16,65,66,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,
+16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,
+16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,
+16,16,16,67,68,16,16,16,69,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,
+16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,
+16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,
+16,16,16,16,16,16,16,70,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,
+16,16,71,72,16,16,16,16,16,16,16,73,16,16,16,16,16,74,16,16,16,16,16,16,16,75,
+76,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,
+16,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,
+255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+255,255,255,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,248,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,254,255,255,255,255,191,182,0,0,0,0,0,0,0,63,0,255,23,0,0,0,0,0,248,255,
+255,0,0,1,0,0,0,0,0,0,0,0,0,0,0,192,191,159,61,0,0,0,128,2,0,0,0,255,255,255,
+7,0,0,0,0,0,0,0,0,0,0,192,255,1,0,0,0,0,0,0,248,15,0,0,0,192,251,239,62,0,0,0,
+0,0,14,0,0,0,0,0,0,0,0,0,0,0,0,0,0,240,255,255,255,255,
+255,7,0,0,0,0,0,0,20,254,33,254,0,12,0,0,0,2,0,0,0,0,0,0,16,30,32,0,0,12,0,0,
+0,6,0,0,0,0,0,0,16,134,57,2,0,0,0,35,0,6,0,0,0,0,0,0,16,190,33,0,0,12,0,0,252,
+2,0,0,0,0,0,0,144,30,32,64,0,12,0,0,0,4,0,0,0,0,0,0,0,1,32,0,0,0,0,0,0,1,0,0,
+0,0,0,0,192,193,61,96,0,12,0,0,0,2,0,0,0,0,0,0,144,64,48,0,0,12,0,0,0,3,0,0,0,
+0,0,0,24,30,32,0,0,12,0,0,0,0,0,0,0,0,0,0,0,0,4,92,0,0,0,0,0,0,0,0,0,0,0,242,
+7,128,127,0,0,0,0,0,0,0,0,0,0,0,0,242,27,0,63,0,0,0,0,0,0,0,0,0,3,0,0,160,2,0,
+0,0,0,0,0,254,127,223,224,255,254,255,255,255,31,64,0,0,0,0,0,0,0,0,0,0,0,0,
+224,253,102,0,0,0,195,1,0,30,0,100,32,0,32,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,224,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,28,0,
+0,0,28,0,0,0,12,0,0,0,12,0,0,0,0,0,0,0,176,63,64,254,15,32,0,0,0,0,0,120,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,96,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,135,1,4,14,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,128,9,0,0,0,0,0,0,64,127,
+229,31,248,159,0,0,0,0,0,0,255,127,0,0,0,0,0,0,0,0,15,0,0,0,0,0,208,23,4,0,0,
+0,0,248,15,0,3,0,0,0,60,59,0,0,0,0,0,0,64,163,3,0,0,0,0,0,0,240,207,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,247,255,253,33,16,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,255,
+251,0,248,0,0,0,124,0,0,0,0,0,0,223,255,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,
+255,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,128,3,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,128,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,0,0,0,0,
+0,60,0,0,0,0,0,0,0,0,0,0,0,0,0,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,128,247,63,0,0,0,192,0,0,0,0,0,0,0,0,0,0,3,0,68,8,0,0,96,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,48,0,0,0,255,255,3,0,0,0,0,0,192,63,0,0,128,255,3,0,0,
+0,0,0,7,0,0,0,0,0,200,19,0,0,0,0,32,0,0,0,0,0,0,0,0,126,102,0,8,16,0,0,0,0,0,
+16,0,0,0,0,0,0,157,193,2,0,0,0,0,48,64,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,32,33,0,0,0,0,0,64,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,0,0,255,255,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,128,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,14,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,32,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,192,7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,110,240,0,0,0,0,0,135,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,96,0,0,
+0,2,0,0,0,0,0,0,255,127,0,0,0,0,0,0,128,3,0,0,0,0,0,120,38,0,0,0,0,0,0,0,0,7,
+0,0,0,128,239,31,0,0,0,0,0,0,0,8,0,3,0,0,0,0,0,192,127,0,28,0,0,0,0,0,0,0,0,0,
+0,0,128,211,64,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,128,248,7,0,0,3,0,0,0,0,
+0,0,16,1,0,0,0,192,31,31,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,
+92,0,0,0,0,0,0,0,0,0,0,0,0,0,248,133,13,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,60,176,1,0,0,48,0,0,0,0,0,0,0,0,0,0,248,167,1,0,0,0,0,0,0,
+0,0,0,0,0,0,40,191,0,0,0,0,0,0,0,0,0,0,0,0,224,188,15,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,126,6,0,0,0,0,248,121,128,0,126,14,0,0,0,0,0,252,127,3,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,127,191,0,0,0,0,0,0,0,0,0,0,252,255,255,252,109,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,126,180,191,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,31,0,0,0,0,0,0,0,127,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,128,7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+96,15,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,128,3,248,255,231,15,0,0,
+0,60,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,28,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,
+255,255,255,255,127,248,255,255,255,255,255,31,32,0,16,0,0,248,254,255,0,0,0,
+0,0,0,0,0,0,0,127,255,255,249,219,7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,127,0,0,0,0,0,0,
+0,0,0,0,0,0,0,240,7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
libc/musl/src/ctype/punct.h
@@ -0,0 +1,129 @@
+18,16,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,16,16,34,35,16,36,37,38,39,
+40,41,42,43,16,44,45,46,17,17,47,17,17,17,17,17,17,48,49,50,51,52,53,54,55,17,
+16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,56,
+16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,
+16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,
+16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,
+16,16,16,16,16,16,16,16,57,16,58,59,60,61,62,63,16,16,16,16,16,16,16,16,16,16,
+16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,
+16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,64,16,16,16,16,16,16,16,16,16,
+16,16,16,16,16,16,16,16,16,16,16,16,16,16,65,16,16,66,16,67,68,
+69,16,70,71,72,16,73,16,16,74,75,76,77,78,16,79,16,80,81,82,83,84,85,86,87,88,
+16,89,16,90,91,16,16,16,16,16,16,92,16,16,16,16,16,16,16,16,16,16,16,16,16,16,
+16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,
+16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,
+16,16,16,93,94,16,16,16,95,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,
+16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,
+16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,
+16,16,16,16,16,16,16,96,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,
+16,97,98,99,100,16,16,101,102,17,17,103,16,16,16,16,16,16,16,16,16,16,16,16,
+16,104,105,16,16,16,16,106,16,107,108,109,17,17,17,110,111,112,113,16,16,16,
+16,16,
+16,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,
+255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+255,255,255,255,255,255,255,255,255,255,255,0,0,0,0,254,255,0,252,1,0,0,248,1,
+0,0,120,0,0,0,0,255,251,223,251,0,0,128,0,0,0,128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,60,0,252,255,224,175,255,255,255,255,255,255,255,255,
+255,255,223,255,255,255,255,255,32,64,176,0,0,0,0,0,0,0,0,0,0,0,0,0,64,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,252,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,252,0,0,0,0,0,230,254,255,255,255,0,64,73,0,0,0,0,0,24,0,255,255,0,216,
+0,0,0,0,0,0,0,1,0,60,0,0,0,0,0,0,0,0,0,0,0,0,16,224,1,30,0,
+96,255,191,0,0,0,0,0,0,255,7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,248,207,3,
+0,0,0,3,0,32,255,127,0,0,0,78,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,7,252,0,0,0,0,0,
+0,0,0,0,16,0,32,30,0,48,0,1,0,0,0,0,0,0,0,0,16,0,32,0,0,0,0,252,47,0,0,0,0,0,
+0,0,16,0,32,0,0,0,0,0,0,0,0,0,0,0,0,0,16,0,32,0,0,0,0,3,224,0,0,0,0,0,0,0,16,
+0,32,0,0,0,0,253,0,0,0,0,0,0,0,0,0,0,32,0,0,0,0,255,7,0,0,0,0,0,0,0,0,0,32,0,
+0,0,0,0,255,0,0,0,0,0,0,0,16,0,32,0,0,0,0,0,0,0,0,0,0,0,0,0,24,0,160,0,127,0,
+0,255,3,0,0,0,0,0,0,0,0,0,4,0,0,0,0,16,0,0,0,0,0,0,128,0,128,192,223,0,12,0,0,
+0,0,0,0,0,0,0,0,0,0,0,31,0,0,0,0,0,
+0,254,255,255,255,0,252,255,255,0,0,0,0,0,0,0,0,252,0,0,0,0,0,0,192,255,223,
+255,7,0,0,0,0,0,0,0,0,0,0,128,6,0,252,0,0,24,62,0,0,128,191,0,204,0,0,0,0,0,0,
+0,0,0,0,0,8,0,0,0,0,0,0,0,0,0,0,0,96,255,255,255,31,0,0,255,3,0,0,0,0,0,0,0,0,
+0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,96,0,0,1,0,0,24,0,0,0,0,0,0,0,0,0,56,0,0,0,0,16,0,0,0,112,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,48,0,0,254,127,47,0,0,255,3,255,127,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,14,49,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,196,255,255,255,
+255,0,0,0,192,0,0,0,0,0,0,0,0,1,0,224,159,0,0,0,0,127,63,255,127,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,16,0,16,0,0,252,255,255,255,31,0,0,0,0,0,12,0,0,0,0,0,0,64,0,
+12,240,0,0,0,0,0,0,192,248,0,0,0,0,0,0,0,192,0,0,0,0,0,0,0,0,255,0,255,255,
+255,33,144,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,
+127,0,224,251,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,160,3,224,0,224,0,
+224,0,96,128,248,255,255,255,252,255,255,255,255,255,127,223,255,241,127,255,
+127,0,0,255,255,255,255,0,0,255,255,255,255,1,0,123,3,208,193,175,66,0,12,31,
+188,255,255,0,0,0,0,0,14,255,255,255,255,255,255,255,255,255,255,255,255,255,
+255,255,255,255,255,127,0,0,0,255,7,0,0,255,255,255,255,255,255,255,255,255,
+255,63,0,0,0,0,0,0,252,255,
+255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,207,255,255,255,
+63,255,255,255,255,227,255,253,7,0,0,240,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,224,135,3,254,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,128,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,127,255,255,255,3,0,0,0,0,0,0,
+255,255,255,251,255,255,255,255,255,255,255,255,255,255,15,0,255,255,255,255,
+255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+255,255,255,63,0,0,0,255,15,30,255,255,255,1,252,193,224,0,0,0,0,0,0,0,0,0,0,
+0,30,1,0,0,0,0,0,0,0,0,0,0,8,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,0,0,
+0,0,255,255,255,255,15,0,0,0,255,255,255,127,255,255,255,255,255,255,255,255,
+255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+127,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,
+255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,127,0,0,0,
+0,0,0,192,0,224,0,0,0,0,0,0,0,0,0,0,0,128,15,112,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+255,0,255,255,127,0,3,0,0,0,0,0,0,0,0,0,0,0,0,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+68,8,0,0,0,15,255,3,0,0,0,0,0,0,240,0,0,0,0,0,0,0,0,0,16,192,0,0,255,255,3,23,
+0,0,0,0,0,248,0,0,0,0,8,128,0,0,0,0,0,0,0,0,0,0,8,0,255,63,0,192,32,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,240,0,0,128,59,0,0,0,0,0,0,0,128,2,0,0,192,0,0,67,0,0,0,0,0,
+0,0,0,0,0,0,0,8,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,56,0,
+0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,128,0,0,0,0,0,2,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,252,255,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,192,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,48,255,255,255,3,255,255,255,255,255,255,247,
+255,127,15,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,128,254,255,0,252,1,0,0,248,1,0,
+0,248,63,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,127,127,0,48,135,255,255,255,255,255,
+143,255,0,0,0,0,0,0,224,255,255,127,255,15,1,0,0,0,0,0,255,255,255,255,255,63,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,
+15,0,0,0,0,15,0,0,0,0,0,0,0,0,0,0,0,0,0,0,128,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+128,255,0,0,128,255,0,0,0,0,128,255,0,0,0,0,0,0,0,0,0,248,0,0,192,143,0,0,0,
+128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,48,255,255,252,255,255,255,255,255,0,0,0,0,
+0,0,0,135,255,0,255,1,0,0,0,224,0,0,0,224,0,0,0,0,0,1,0,0,96,248,127,0,0,0,0,
+0,0,0,0,254,0,0,0,255,0,0,0,255,0,0,0,30,0,254,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,252,0,0,0,0,0,0,0,0,0,0,0,
+0,255,255,255,127,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,192,63,252,255,63,0,0,128,3,0,0,0,0,0,0,254,3,0,0,0,0,0,0,0,
+0,0,0,0,0,0,24,0,15,0,0,0,0,0,56,0,0,0,0,0,0,0,0,0,225,63,0,232,254,255,31,0,
+0,0,0,0,0,0,96,63,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,6,0,0,0,0,0,0,0,0,
+0,16,0,32,0,0,192,31,31,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,68,
+248,0,40,0,0,0,0,0,0,0,0,0,0,0,0,76,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,128,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,128,14,0,0,0,255,31,
+0,0,0,0,0,0,0,0,192,0,0,0,0,0,0,0,0,0,0,0,0,0,0,8,0,252,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,252,7,0,0,0,0,0,0,
+0,24,128,255,0,0,0,0,0,0,0,0,0,0,223,7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+128,62,0,0,252,255,31,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,52,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,31,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,192,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,63,0,0,0,0,0,0,0,128,255,48,0,0,248,3,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,128,7,0,0,0,0,0,0,0,0,0,0,0,
+0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,176,15,0,0,0,0,0,0,0,0,0,0,0,255,255,
+255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+255,255,255,255,255,255,255,255,255,63,0,255,255,255,255,127,254,255,255,255,
+255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+255,1,0,0,255,255,255,255,255,255,255,255,63,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,255,255,255,255,255,255,255,255,255,255,127,0,255,255,3,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,
+0,8,0,0,0,8,0,0,32,0,0,0,32,0,0,128,0,0,0,128,0,0,0,2,0,0,0,2,0,0,8,0,0,0,0,0,
+0,0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,15,0,
+248,254,255,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,128,255,127,0,0,0,0,0,0,0,0,
+0,0,0,0,0,112,7,0,192,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3,0,255,255,255,255,255,15,255,
+255,255,255,255,255,255,255,255,255,255,255,15,0,255,127,254,255,254,255,254,
+255,255,255,63,0,255,31,255,255,255,127,0,0,0,252,0,0,0,12,0,0,0,252,255,255,
+255,31,0,0,0,0,0,0,192,255,255,255,7,0,255,255,255,255,255,15,255,1,3,0,63,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,255,255,255,255,
+255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,31,0,255,31,
+255,1,255,255,255,255,255,255,255,255,255,255,255,255,255,255,15,0,255,255,
+255,255,255,255,255,255,255,255,31,0,0,0,0,
+0,255,15,255,255,255,255,255,255,255,0,255,3,255,255,255,255,255,0,255,255,
+255,63,0,0,0,0,0,0,0,0,0,0,255,15,255,255,255,255,255,127,255,31,255,255,255,
+15,0,0,255,255,255,0,0,0,0,0,1,0,255,255,127,0,0,0,
libc/musl/src/ctype/toascii.c
@@ -0,0 +1,7 @@
+#include <ctype.h>
+
+/* nonsense function that should NEVER be used! */
+int toascii(int c)
+{
+	return c & 0x7f;
+}
libc/musl/src/ctype/tolower.c
@@ -0,0 +1,14 @@
+#include <ctype.h>
+
+int tolower(int c)
+{
+	if (isupper(c)) return c | 32;
+	return c;
+}
+
+int __tolower_l(int c, locale_t l)
+{
+	return tolower(c);
+}
+
+weak_alias(__tolower_l, tolower_l);
libc/musl/src/ctype/toupper.c
@@ -0,0 +1,14 @@
+#include <ctype.h>
+
+int toupper(int c)
+{
+	if (islower(c)) return c & 0x5f;
+	return c;
+}
+
+int __toupper_l(int c, locale_t l)
+{
+	return toupper(c);
+}
+
+weak_alias(__toupper_l, toupper_l);
libc/musl/src/ctype/towctrans.c
@@ -0,0 +1,318 @@
+#include <ctype.h>
+#include <stddef.h>
+#include <wctype.h>
+
+#define CASEMAP(u1,u2,l) { (u1), (l)-(u1), (u2)-(u1)+1 }
+#define CASELACE(u1,u2) CASEMAP((u1),(u2),(u1)+1)
+
+static const struct {
+	unsigned short upper;
+	signed char lower;
+	unsigned char len;
+} casemaps[] = {
+	CASEMAP(0xc0,0xde,0xe0),
+
+	CASELACE(0x0100,0x012e),
+	CASELACE(0x0132,0x0136),
+	CASELACE(0x0139,0x0147),
+	CASELACE(0x014a,0x0176),
+	CASELACE(0x0179,0x017d),
+
+	CASELACE(0x370,0x372),
+	CASEMAP(0x391,0x3a1,0x3b1),
+	CASEMAP(0x3a3,0x3ab,0x3c3),
+	CASEMAP(0x400,0x40f,0x450),
+	CASEMAP(0x410,0x42f,0x430),
+
+	CASELACE(0x460,0x480),
+	CASELACE(0x48a,0x4be),
+	CASELACE(0x4c1,0x4cd),
+	CASELACE(0x4d0,0x50e),
+
+	CASELACE(0x514,0x52e),
+	CASEMAP(0x531,0x556,0x561),
+
+	CASELACE(0x01a0,0x01a4),
+	CASELACE(0x01b3,0x01b5),
+	CASELACE(0x01cd,0x01db),
+	CASELACE(0x01de,0x01ee),
+	CASELACE(0x01f8,0x021e),
+	CASELACE(0x0222,0x0232),
+	CASELACE(0x03d8,0x03ee),
+
+	CASELACE(0x1e00,0x1e94),
+	CASELACE(0x1ea0,0x1efe),
+
+	CASEMAP(0x1f08,0x1f0f,0x1f00),
+	CASEMAP(0x1f18,0x1f1d,0x1f10),
+	CASEMAP(0x1f28,0x1f2f,0x1f20),
+	CASEMAP(0x1f38,0x1f3f,0x1f30),
+	CASEMAP(0x1f48,0x1f4d,0x1f40),
+
+	CASEMAP(0x1f68,0x1f6f,0x1f60),
+	CASEMAP(0x1f88,0x1f8f,0x1f80),
+	CASEMAP(0x1f98,0x1f9f,0x1f90),
+	CASEMAP(0x1fa8,0x1faf,0x1fa0),
+	CASEMAP(0x1fb8,0x1fb9,0x1fb0),
+	CASEMAP(0x1fba,0x1fbb,0x1f70),
+	CASEMAP(0x1fc8,0x1fcb,0x1f72),
+	CASEMAP(0x1fd8,0x1fd9,0x1fd0),
+	CASEMAP(0x1fda,0x1fdb,0x1f76),
+	CASEMAP(0x1fe8,0x1fe9,0x1fe0),
+	CASEMAP(0x1fea,0x1feb,0x1f7a),
+	CASEMAP(0x1ff8,0x1ff9,0x1f78),
+	CASEMAP(0x1ffa,0x1ffb,0x1f7c),
+
+	CASEMAP(0x13f0,0x13f5,0x13f8),
+	CASELACE(0xa698,0xa69a),
+	CASELACE(0xa796,0xa79e),
+
+	CASELACE(0x246,0x24e),
+	CASELACE(0x510,0x512),
+	CASEMAP(0x2160,0x216f,0x2170),
+	CASEMAP(0x2c00,0x2c2e,0x2c30),
+	CASELACE(0x2c67,0x2c6b),
+	CASELACE(0x2c80,0x2ce2),
+	CASELACE(0x2ceb,0x2ced),
+
+	CASELACE(0xa640,0xa66c),
+	CASELACE(0xa680,0xa696),
+
+	CASELACE(0xa722,0xa72e),
+	CASELACE(0xa732,0xa76e),
+	CASELACE(0xa779,0xa77b),
+	CASELACE(0xa77e,0xa786),
+
+	CASELACE(0xa790,0xa792),
+	CASELACE(0xa7a0,0xa7a8),
+
+	CASELACE(0xa7b4,0xa7b6),
+
+	CASEMAP(0xff21,0xff3a,0xff41),
+	{ 0,0,0 }
+};
+
+static const unsigned short pairs[][2] = {
+	{ 'I',    0x0131 },
+	{ 'S',    0x017f },
+	{ 0x0130, 'i'    },
+	{ 0x0178, 0x00ff },
+	{ 0x0181, 0x0253 },
+	{ 0x0182, 0x0183 },
+	{ 0x0184, 0x0185 },
+	{ 0x0186, 0x0254 },
+	{ 0x0187, 0x0188 },
+	{ 0x0189, 0x0256 },
+	{ 0x018a, 0x0257 },
+	{ 0x018b, 0x018c },
+	{ 0x018e, 0x01dd },
+	{ 0x018f, 0x0259 },
+	{ 0x0190, 0x025b },
+	{ 0x0191, 0x0192 },
+	{ 0x0193, 0x0260 },
+	{ 0x0194, 0x0263 },
+	{ 0x0196, 0x0269 },
+	{ 0x0197, 0x0268 },
+	{ 0x0198, 0x0199 },
+	{ 0x019c, 0x026f },
+	{ 0x019d, 0x0272 },
+	{ 0x019f, 0x0275 },
+	{ 0x01a6, 0x0280 },
+	{ 0x01a7, 0x01a8 },
+	{ 0x01a9, 0x0283 },
+	{ 0x01ac, 0x01ad },
+	{ 0x01ae, 0x0288 },
+	{ 0x01af, 0x01b0 },
+	{ 0x01b1, 0x028a },
+	{ 0x01b2, 0x028b },
+	{ 0x01b7, 0x0292 },
+	{ 0x01b8, 0x01b9 },
+	{ 0x01bc, 0x01bd },
+	{ 0x01c4, 0x01c6 },
+	{ 0x01c4, 0x01c5 },
+	{ 0x01c5, 0x01c6 },
+	{ 0x01c7, 0x01c9 },
+	{ 0x01c7, 0x01c8 },
+	{ 0x01c8, 0x01c9 },
+	{ 0x01ca, 0x01cc },
+	{ 0x01ca, 0x01cb },
+	{ 0x01cb, 0x01cc },
+	{ 0x01f1, 0x01f3 },
+	{ 0x01f1, 0x01f2 },
+	{ 0x01f2, 0x01f3 },
+	{ 0x01f4, 0x01f5 },
+	{ 0x01f6, 0x0195 },
+	{ 0x01f7, 0x01bf },
+	{ 0x0220, 0x019e },
+	{ 0x0386, 0x03ac },
+	{ 0x0388, 0x03ad },
+	{ 0x0389, 0x03ae },
+	{ 0x038a, 0x03af },
+	{ 0x038c, 0x03cc },
+	{ 0x038e, 0x03cd },
+	{ 0x038f, 0x03ce },
+	{ 0x0399, 0x0345 },
+	{ 0x0399, 0x1fbe },
+	{ 0x03a3, 0x03c2 },
+	{ 0x03f7, 0x03f8 },
+	{ 0x03fa, 0x03fb },
+	{ 0x1e60, 0x1e9b },
+	{ 0x1e9e, 0xdf },
+
+	{ 0x1f59, 0x1f51 },
+	{ 0x1f5b, 0x1f53 },
+	{ 0x1f5d, 0x1f55 },
+	{ 0x1f5f, 0x1f57 },
+	{ 0x1fbc, 0x1fb3 },
+	{ 0x1fcc, 0x1fc3 },
+	{ 0x1fec, 0x1fe5 },
+	{ 0x1ffc, 0x1ff3 },
+
+	{ 0x23a, 0x2c65 },
+	{ 0x23b, 0x23c },
+	{ 0x23d, 0x19a },
+	{ 0x23e, 0x2c66 },
+	{ 0x241, 0x242 },
+	{ 0x243, 0x180 },
+	{ 0x244, 0x289 },
+	{ 0x245, 0x28c },
+	{ 0x3f4, 0x3b8 },
+	{ 0x3f9, 0x3f2 },
+	{ 0x3fd, 0x37b },
+	{ 0x3fe, 0x37c },
+	{ 0x3ff, 0x37d },
+	{ 0x4c0, 0x4cf },
+
+	{ 0x2126, 0x3c9 },
+	{ 0x212a, 'k' },
+	{ 0x212b, 0xe5 },
+	{ 0x2132, 0x214e },
+	{ 0x2183, 0x2184 },
+	{ 0x2c60, 0x2c61 },
+	{ 0x2c62, 0x26b },
+	{ 0x2c63, 0x1d7d },
+	{ 0x2c64, 0x27d },
+	{ 0x2c6d, 0x251 },
+	{ 0x2c6e, 0x271 },
+	{ 0x2c6f, 0x250 },
+	{ 0x2c70, 0x252 },
+	{ 0x2c72, 0x2c73 },
+	{ 0x2c75, 0x2c76 },
+	{ 0x2c7e, 0x23f },
+	{ 0x2c7f, 0x240 },
+	{ 0x2cf2, 0x2cf3 },
+
+	{ 0xa77d, 0x1d79 },
+	{ 0xa78b, 0xa78c },
+	{ 0xa78d, 0x265 },
+	{ 0xa7aa, 0x266 },
+
+	{ 0x10c7, 0x2d27 },
+	{ 0x10cd, 0x2d2d },
+
+	/* bogus greek 'symbol' letters */
+	{ 0x376, 0x377 },
+	{ 0x39c, 0xb5 },
+	{ 0x392, 0x3d0 },
+	{ 0x398, 0x3d1 },
+	{ 0x3a6, 0x3d5 },
+	{ 0x3a0, 0x3d6 },
+	{ 0x39a, 0x3f0 },
+	{ 0x3a1, 0x3f1 },
+	{ 0x395, 0x3f5 },
+	{ 0x3cf, 0x3d7 },
+
+	{ 0xa7ab, 0x25c },
+	{ 0xa7ac, 0x261 },
+	{ 0xa7ad, 0x26c },
+	{ 0xa7ae, 0x26a },
+	{ 0xa7b0, 0x29e },
+	{ 0xa7b1, 0x287 },
+	{ 0xa7b2, 0x29d },
+	{ 0xa7b3, 0xab53 },
+
+	/* special cyrillic lowercase forms */
+	{ 0x412, 0x1c80 },
+	{ 0x414, 0x1c81 },
+	{ 0x41e, 0x1c82 },
+	{ 0x421, 0x1c83 },
+	{ 0x422, 0x1c84 },
+	{ 0x422, 0x1c85 },
+	{ 0x42a, 0x1c86 },
+	{ 0x462, 0x1c87 },
+	{ 0xa64a, 0x1c88 },
+
+	{ 0,0 }
+};
+
+
+static wchar_t __towcase(wchar_t wc, int lower)
+{
+	int i;
+	int lmul = 2*lower-1;
+	int lmask = lower-1;
+	/* no letters with case in these large ranges */
+	if (!iswalpha(wc)
+	 || (unsigned)wc - 0x0600 <= 0x0fff-0x0600
+	 || (unsigned)wc - 0x2e00 <= 0xa63f-0x2e00
+	 || (unsigned)wc - 0xa800 <= 0xab52-0xa800
+	 || (unsigned)wc - 0xabc0 <= 0xfeff-0xabc0)
+		return wc;
+	/* special case because the diff between upper/lower is too big */
+	if (lower && (unsigned)wc - 0x10a0 < 0x2e)
+		if (wc>0x10c5 && wc != 0x10c7 && wc != 0x10cd) return wc;
+		else return wc + 0x2d00 - 0x10a0;
+	if (!lower && (unsigned)wc - 0x2d00 < 0x26)
+		if (wc>0x2d25 && wc != 0x2d27 && wc != 0x2d2d) return wc;
+		else return wc + 0x10a0 - 0x2d00;
+	if (lower && (unsigned)wc - 0x13a0 < 0x50)
+		return wc + 0xab70 - 0x13a0;
+	if (!lower && (unsigned)wc - 0xab70 < 0x50)
+		return wc + 0x13a0 - 0xab70;
+	for (i=0; casemaps[i].len; i++) {
+		int base = casemaps[i].upper + (lmask & casemaps[i].lower);
+		if ((unsigned)wc-base < casemaps[i].len) {
+			if (casemaps[i].lower == 1)
+				return wc + lower - ((wc-casemaps[i].upper)&1);
+			return wc + lmul*casemaps[i].lower;
+		}
+	}
+	for (i=0; pairs[i][1-lower]; i++) {
+		if (pairs[i][1-lower] == wc)
+			return pairs[i][lower];
+	}
+	if ((unsigned)wc - (0x10428 - 0x28*lower) < 0x28)
+		return wc - 0x28 + 0x50*lower;
+	if ((unsigned)wc - (0x104d8 - 0x28*lower) < 0x24)
+		return wc - 0x28 + 0x50*lower;
+	if ((unsigned)wc - (0x10cc0 - 0x40*lower) < 0x33)
+		return wc - 0x40 + 0x80*lower;
+	if ((unsigned)wc - (0x118c0 - 0x20*lower) < 0x20)
+		return wc - 0x20 + 0x40*lower;
+	if ((unsigned)wc - (0x1e922 - 0x22*lower) < 0x22)
+		return wc - 0x22 + 0x44*lower;
+	return wc;
+}
+
+wint_t towupper(wint_t wc)
+{
+	return (unsigned)wc < 128 ? toupper(wc) : __towcase(wc, 0);
+}
+
+wint_t towlower(wint_t wc)
+{
+	return (unsigned)wc < 128 ? tolower(wc) : __towcase(wc, 1);
+}
+
+wint_t __towupper_l(wint_t c, locale_t l)
+{
+	return towupper(c);
+}
+
+wint_t __towlower_l(wint_t c, locale_t l)
+{
+	return towlower(c);
+}
+
+weak_alias(__towupper_l, towupper_l);
+weak_alias(__towlower_l, towlower_l);
libc/musl/src/ctype/wcswidth.c
@@ -0,0 +1,8 @@
+#include <wchar.h>
+
+int wcswidth(const wchar_t *wcs, size_t n)
+{
+	int l=0, k=0;
+	for (; n-- && *wcs && (k = wcwidth(*wcs)) >= 0; l+=k, wcs++);
+	return (k < 0) ? k : l;
+}
libc/musl/src/ctype/wctrans.c
@@ -0,0 +1,29 @@
+#include <wctype.h>
+#include <string.h>
+
+wctrans_t wctrans(const char *class)
+{
+	if (!strcmp(class, "toupper")) return (wctrans_t)1;
+	if (!strcmp(class, "tolower")) return (wctrans_t)2;
+	return 0;
+}
+
+wint_t towctrans(wint_t wc, wctrans_t trans)
+{
+	if (trans == (wctrans_t)1) return towupper(wc);
+	if (trans == (wctrans_t)2) return towlower(wc);
+	return wc;
+}
+
+wctrans_t __wctrans_l(const char *s, locale_t l)
+{
+	return wctrans(s);
+}
+
+wint_t __towctrans_l(wint_t c, wctrans_t t, locale_t l)
+{
+	return towctrans(c, t);
+}
+
+weak_alias(__wctrans_l, wctrans_l);
+weak_alias(__towctrans_l, towctrans_l);
libc/musl/src/ctype/wcwidth.c
@@ -0,0 +1,29 @@
+#include <wchar.h>
+
+static const unsigned char table[] = {
+#include "nonspacing.h"
+};
+
+static const unsigned char wtable[] = {
+#include "wide.h"
+};
+
+int wcwidth(wchar_t wc)
+{
+	if (wc < 0xffU)
+		return (wc+1 & 0x7f) >= 0x21 ? 1 : wc ? -1 : 0;
+	if ((wc & 0xfffeffffU) < 0xfffe) {
+		if ((table[table[wc>>8]*32+((wc&255)>>3)]>>(wc&7))&1)
+			return 0;
+		if ((wtable[wtable[wc>>8]*32+((wc&255)>>3)]>>(wc&7))&1)
+			return 2;
+		return 1;
+	}
+	if ((wc & 0xfffe) == 0xfffe)
+		return -1;
+	if (wc-0x20000U < 0x20000)
+		return 2;
+	if (wc == 0xe0001 || wc-0xe0020U < 0x5f || wc-0xe0100 < 0xef)
+		return 0;
+	return 1;
+}
libc/musl/src/ctype/wide.h
@@ -0,0 +1,63 @@
+16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,18,16,16,16,16,16,16,16,16,
+16,16,16,16,16,16,16,16,16,19,16,20,21,22,16,16,16,23,16,16,24,25,26,27,28,17,
+17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,29,
+17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,
+17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,
+17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,
+17,17,17,17,17,17,17,17,30,16,16,16,16,31,16,16,17,17,17,17,17,17,17,17,17,17,
+17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,
+17,17,17,17,17,17,17,32,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,
+16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,17,17,16,16,16,33,
+34,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,
+16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,
+16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,
+16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,
+16,16,16,16,16,16,16,16,35,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,
+17,17,17,17,17,17,36,17,17,37,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,
+16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,17,38,39,16,16,
+16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,
+16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,
+16,16,16,16,16,16,16,40,41,42,43,44,45,46,16,16,47,16,16,16,16,16,
+16,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,
+255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+255,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,12,0,6,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,30,9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,96,0,0,48,0,0,0,0,0,0,255,15,0,0,0,0,128,0,0,8,
+0,2,12,0,96,48,64,16,0,0,4,44,36,32,12,0,0,0,1,0,0,0,80,184,0,0,0,0,0,0,0,224,
+0,0,0,1,128,0,0,0,0,0,0,0,0,0,0,0,24,0,0,0,0,0,0,33,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,251,255,255,255,255,255,255,255,
+255,255,255,15,0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+255,255,255,255,255,255,255,255,255,255,255,63,0,0,0,255,15,255,255,255,255,
+255,255,255,127,254,255,255,255,255,255,255,255,255,255,127,254,255,255,255,
+255,255,255,255,255,255,255,255,255,224,255,255,255,255,127,254,255,255,255,
+255,255,255,255,255,255,255,127,255,255,255,255,255,7,255,255,255,255,15,0,
+255,255,255,255,255,127,255,255,255,255,255,0,255,255,255,255,255,255,255,255,
+255,255,255,255,255,255,255,255,255,255,255,255,255,127,255,255,255,255,255,
+255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,0,
+0,0,0,0,0,0,0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+255,31,255,255,255,255,255,255,127,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,
+255,255,31,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+255,15,0,0,0,0,0,0,0,0,0,0,0,0,0,255,3,0,0,255,255,255,255,247,255,127,15,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,254,255,255,255,255,255,255,255,255,255,255,
+255,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,127,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,3,0,0,0,255,255,255,255,255,255,255,255,255,255,255,
+255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,31,0,
+0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+255,255,255,255,255,255,255,255,255,255,255,7,0,255,255,255,127,0,0,0,0,0,0,0,
+0,0,0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+255,255,255,255,255,255,255,255,255,255,255,255,
+15,16,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,128,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,64,254,7,0,0,0,0,0,0,0,0,0,0,0,0,7,0,255,255,255,
+255,255,15,255,1,3,0,63,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,
+1,224,191,255,255,255,255,255,255,255,255,223,255,255,15,0,255,255,255,255,
+255,135,15,0,255,255,17,255,255,255,255,255,255,255,255,127,253,255,255,255,
+255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+159,255,255,255,255,255,255,255,63,0,120,255,255,255,0,0,4,0,0,96,0,16,0,0,0,
+0,0,0,0,0,0,0,248,255,255,255,255,255,255,255,255,255,255,0,0,0,0,0,0,255,255,
+255,255,255,255,255,255,63,16,7,0,0,24,240,1,0,0,255,255,255,255,255,127,255,
+31,255,255,255,15,0,0,255,255,255,0,0,0,0,0,1,0,255,255,127,0,0,
+0,
libc/musl/src/dirent/__dirent.h
@@ -0,0 +1,11 @@
+struct __dirstream
+{
+	off_t tell;
+	int fd;
+	int buf_pos;
+	int buf_end;
+	volatile int lock[1];
+	/* Any changes to this struct must preserve the property:
+	 * offsetof(struct __dirent, buf) % sizeof(off_t) == 0 */
+	char buf[2048];
+};
libc/musl/src/dirent/alphasort.c
@@ -0,0 +1,9 @@
+#include <string.h>
+#include <dirent.h>
+
+int alphasort(const struct dirent **a, const struct dirent **b)
+{
+	return strcoll((*a)->d_name, (*b)->d_name);
+}
+
+weak_alias(alphasort, alphasort64);
libc/musl/src/dirent/closedir.c
@@ -0,0 +1,11 @@
+#include <dirent.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include "__dirent.h"
+
+int closedir(DIR *dir)
+{
+	int ret = close(dir->fd);
+	free(dir);
+	return ret;
+}
libc/musl/src/dirent/dirfd.c
@@ -0,0 +1,7 @@
+#include <dirent.h>
+#include "__dirent.h"
+
+int dirfd(DIR *d)
+{
+	return d->fd;
+}
libc/musl/src/dirent/fdopendir.c
@@ -0,0 +1,27 @@
+#include <dirent.h>
+#include <fcntl.h>
+#include <sys/stat.h>
+#include <errno.h>
+#include <stdlib.h>
+#include "__dirent.h"
+
+DIR *fdopendir(int fd)
+{
+	DIR *dir;
+	struct stat st;
+
+	if (fstat(fd, &st) < 0) {
+		return 0;
+	}
+	if (!S_ISDIR(st.st_mode)) {
+		errno = ENOTDIR;
+		return 0;
+	}
+	if (!(dir = calloc(1, sizeof *dir))) {
+		return 0;
+	}
+
+	fcntl(fd, F_SETFD, FD_CLOEXEC);
+	dir->fd = fd;
+	return dir;
+}
libc/musl/src/dirent/opendir.c
@@ -0,0 +1,21 @@
+#define _GNU_SOURCE
+#include <dirent.h>
+#include <fcntl.h>
+#include <stdlib.h>
+#include "__dirent.h"
+#include "syscall.h"
+
+DIR *opendir(const char *name)
+{
+	int fd;
+	DIR *dir;
+
+	if ((fd = open(name, O_RDONLY|O_DIRECTORY|O_CLOEXEC)) < 0)
+		return 0;
+	if (!(dir = calloc(1, sizeof *dir))) {
+		__syscall(SYS_close, fd);
+		return 0;
+	}
+	dir->fd = fd;
+	return dir;
+}
libc/musl/src/dirent/readdir.c
@@ -0,0 +1,29 @@
+#include <dirent.h>
+#include <errno.h>
+#include <stddef.h>
+#include "__dirent.h"
+#include "syscall.h"
+
+typedef char dirstream_buf_alignment_check[1-2*(int)(
+	offsetof(struct __dirstream, buf) % sizeof(off_t))];
+
+struct dirent *readdir(DIR *dir)
+{
+	struct dirent *de;
+	
+	if (dir->buf_pos >= dir->buf_end) {
+		int len = __syscall(SYS_getdents, dir->fd, dir->buf, sizeof dir->buf);
+		if (len <= 0) {
+			if (len < 0 && len != -ENOENT) errno = -len;
+			return 0;
+		}
+		dir->buf_end = len;
+		dir->buf_pos = 0;
+	}
+	de = (void *)(dir->buf + dir->buf_pos);
+	dir->buf_pos += de->d_reclen;
+	dir->tell = de->d_off;
+	return de;
+}
+
+weak_alias(readdir, readdir64);
libc/musl/src/dirent/readdir_r.c
@@ -0,0 +1,29 @@
+#include <dirent.h>
+#include <errno.h>
+#include <string.h>
+#include "__dirent.h"
+#include "lock.h"
+
+int readdir_r(DIR *restrict dir, struct dirent *restrict buf, struct dirent **restrict result)
+{
+	struct dirent *de;
+	int errno_save = errno;
+	int ret;
+	
+	LOCK(dir->lock);
+	errno = 0;
+	de = readdir(dir);
+	if ((ret = errno)) {
+		UNLOCK(dir->lock);
+		return ret;
+	}
+	errno = errno_save;
+	if (de) memcpy(buf, de, de->d_reclen);
+	else buf = NULL;
+
+	UNLOCK(dir->lock);
+	*result = buf;
+	return 0;
+}
+
+weak_alias(readdir_r, readdir64_r);
libc/musl/src/dirent/rewinddir.c
@@ -0,0 +1,13 @@
+#include <dirent.h>
+#include <unistd.h>
+#include "__dirent.h"
+#include "lock.h"
+
+void rewinddir(DIR *dir)
+{
+	LOCK(dir->lock);
+	lseek(dir->fd, 0, SEEK_SET);
+	dir->buf_pos = dir->buf_end = 0;
+	dir->tell = 0;
+	UNLOCK(dir->lock);
+}
libc/musl/src/dirent/scandir.c
@@ -0,0 +1,47 @@
+#include <dirent.h>
+#include <string.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include <errno.h>
+#include <stddef.h>
+
+int scandir(const char *path, struct dirent ***res,
+	int (*sel)(const struct dirent *),
+	int (*cmp)(const struct dirent **, const struct dirent **))
+{
+	DIR *d = opendir(path);
+	struct dirent *de, **names=0, **tmp;
+	size_t cnt=0, len=0;
+	int old_errno = errno;
+
+	if (!d) return -1;
+
+	while ((errno=0), (de = readdir(d))) {
+		if (sel && !sel(de)) continue;
+		if (cnt >= len) {
+			len = 2*len+1;
+			if (len > SIZE_MAX/sizeof *names) break;
+			tmp = realloc(names, len * sizeof *names);
+			if (!tmp) break;
+			names = tmp;
+		}
+		names[cnt] = malloc(de->d_reclen);
+		if (!names[cnt]) break;
+		memcpy(names[cnt++], de, de->d_reclen);
+	}
+
+	closedir(d);
+
+	if (errno) {
+		if (names) while (cnt-->0) free(names[cnt]);
+		free(names);
+		return -1;
+	}
+	errno = old_errno;
+
+	if (cmp) qsort(names, cnt, sizeof *names, (int (*)(const void *, const void *))cmp);
+	*res = names;
+	return cnt;
+}
+
+weak_alias(scandir, scandir64);
libc/musl/src/dirent/seekdir.c
@@ -0,0 +1,12 @@
+#include <dirent.h>
+#include <unistd.h>
+#include "__dirent.h"
+#include "lock.h"
+
+void seekdir(DIR *dir, long off)
+{
+	LOCK(dir->lock);
+	dir->tell = lseek(dir->fd, off, SEEK_SET);
+	dir->buf_pos = dir->buf_end = 0;
+	UNLOCK(dir->lock);
+}
libc/musl/src/dirent/telldir.c
@@ -0,0 +1,7 @@
+#include <dirent.h>
+#include "__dirent.h"
+
+long telldir(DIR *dir)
+{
+	return dir->tell;
+}
libc/musl/src/dirent/versionsort.c
@@ -0,0 +1,11 @@
+#define _GNU_SOURCE
+#include <string.h>
+#include <dirent.h>
+
+int versionsort(const struct dirent **a, const struct dirent **b)
+{
+	return strverscmp((*a)->d_name, (*b)->d_name);
+}
+
+#undef versionsort64
+weak_alias(versionsort, versionsort64);
libc/musl/src/env/__environ.c
@@ -0,0 +1,6 @@
+#include <unistd.h>
+
+char **__environ = 0;
+weak_alias(__environ, ___environ);
+weak_alias(__environ, _environ);
+weak_alias(__environ, environ);
libc/musl/src/env/__init_tls.c
@@ -0,0 +1,147 @@
+#include <elf.h>
+#include <limits.h>
+#include <sys/mman.h>
+#include <string.h>
+#include <stddef.h>
+#include "pthread_impl.h"
+#include "libc.h"
+#include "atomic.h"
+#include "syscall.h"
+
+int __init_tp(void *p)
+{
+	pthread_t td = p;
+	td->self = td;
+	int r = __set_thread_area(TP_ADJ(p));
+	if (r < 0) return -1;
+	if (!r) libc.can_do_threads = 1;
+	td->detach_state = DT_JOINABLE;
+	td->tid = __syscall(SYS_set_tid_address, &td->detach_state);
+	td->locale = &libc.global_locale;
+	td->robust_list.head = &td->robust_list.head;
+	return 0;
+}
+
+static struct builtin_tls {
+	char c;
+	struct pthread pt;
+	void *space[16];
+} builtin_tls[1];
+#define MIN_TLS_ALIGN offsetof(struct builtin_tls, pt)
+
+static struct tls_module main_tls;
+
+void *__copy_tls(unsigned char *mem)
+{
+	pthread_t td;
+	struct tls_module *p;
+	size_t i;
+	uintptr_t *dtv;
+
+#ifdef TLS_ABOVE_TP
+	dtv = (uintptr_t*)(mem + libc.tls_size) - (libc.tls_cnt + 1);
+
+	mem += -((uintptr_t)mem + sizeof(struct pthread)) & (libc.tls_align-1);
+	td = (pthread_t)mem;
+	mem += sizeof(struct pthread);
+
+	for (i=1, p=libc.tls_head; p; i++, p=p->next) {
+		dtv[i] = (uintptr_t)(mem + p->offset) + DTP_OFFSET;
+		memcpy(mem + p->offset, p->image, p->len);
+	}
+#else
+	dtv = (uintptr_t *)mem;
+
+	mem += libc.tls_size - sizeof(struct pthread);
+	mem -= (uintptr_t)mem & (libc.tls_align-1);
+	td = (pthread_t)mem;
+
+	for (i=1, p=libc.tls_head; p; i++, p=p->next) {
+		dtv[i] = (uintptr_t)(mem - p->offset) + DTP_OFFSET;
+		memcpy(mem - p->offset, p->image, p->len);
+	}
+#endif
+	dtv[0] = libc.tls_cnt;
+	td->dtv = td->dtv_copy = dtv;
+	return td;
+}
+
+#if ULONG_MAX == 0xffffffff
+typedef Elf32_Phdr Phdr;
+#else
+typedef Elf64_Phdr Phdr;
+#endif
+
+extern weak hidden const size_t _DYNAMIC[];
+
+static void static_init_tls(size_t *aux)
+{
+	unsigned char *p;
+	size_t n;
+	Phdr *phdr, *tls_phdr=0;
+	size_t base = 0;
+	void *mem;
+
+	for (p=(void *)aux[AT_PHDR],n=aux[AT_PHNUM]; n; n--,p+=aux[AT_PHENT]) {
+		phdr = (void *)p;
+		if (phdr->p_type == PT_PHDR)
+			base = aux[AT_PHDR] - phdr->p_vaddr;
+		if (phdr->p_type == PT_DYNAMIC && _DYNAMIC)
+			base = (size_t)_DYNAMIC - phdr->p_vaddr;
+		if (phdr->p_type == PT_TLS)
+			tls_phdr = phdr;
+		if (phdr->p_type == PT_GNU_STACK &&
+		    phdr->p_memsz > __default_stacksize)
+			__default_stacksize =
+				phdr->p_memsz < DEFAULT_STACK_MAX ?
+				phdr->p_memsz : DEFAULT_STACK_MAX;
+	}
+
+	if (tls_phdr) {
+		main_tls.image = (void *)(base + tls_phdr->p_vaddr);
+		main_tls.len = tls_phdr->p_filesz;
+		main_tls.size = tls_phdr->p_memsz;
+		main_tls.align = tls_phdr->p_align;
+		libc.tls_cnt = 1;
+		libc.tls_head = &main_tls;
+	}
+
+	main_tls.size += (-main_tls.size - (uintptr_t)main_tls.image)
+		& (main_tls.align-1);
+#ifdef TLS_ABOVE_TP
+	main_tls.offset = GAP_ABOVE_TP;
+	main_tls.offset += -GAP_ABOVE_TP & (main_tls.align-1);
+#else
+	main_tls.offset = main_tls.size;
+#endif
+	if (main_tls.align < MIN_TLS_ALIGN) main_tls.align = MIN_TLS_ALIGN;
+
+	libc.tls_align = main_tls.align;
+	libc.tls_size = 2*sizeof(void *) + sizeof(struct pthread)
+#ifdef TLS_ABOVE_TP
+		+ main_tls.offset
+#endif
+		+ main_tls.size + main_tls.align
+		+ MIN_TLS_ALIGN-1 & -MIN_TLS_ALIGN;
+
+	if (libc.tls_size > sizeof builtin_tls) {
+#ifndef SYS_mmap2
+#define SYS_mmap2 SYS_mmap
+#endif
+		mem = (void *)__syscall(
+			SYS_mmap2,
+			0, libc.tls_size, PROT_READ|PROT_WRITE,
+			MAP_ANONYMOUS|MAP_PRIVATE, -1, 0);
+		/* -4095...-1 cast to void * will crash on dereference anyway,
+		 * so don't bloat the init code checking for error codes and
+		 * explicitly calling a_crash(). */
+	} else {
+		mem = builtin_tls;
+	}
+
+	/* Failure to initialize thread pointer is always fatal. */
+	if (__init_tp(__copy_tls(mem)) < 0)
+		a_crash();
+}
+
+weak_alias(static_init_tls, __init_tls);
libc/musl/src/env/__libc_start_main.c
@@ -0,0 +1,96 @@
+#include <elf.h>
+#include <poll.h>
+#include <fcntl.h>
+#include <signal.h>
+#include <unistd.h>
+#include "syscall.h"
+#include "atomic.h"
+#include "libc.h"
+
+static void dummy(void) {}
+weak_alias(dummy, _init);
+
+extern weak hidden void (*const __init_array_start)(void), (*const __init_array_end)(void);
+
+static void dummy1(void *p) {}
+weak_alias(dummy1, __init_ssp);
+
+#define AUX_CNT 38
+
+#ifdef __GNUC__
+__attribute__((__noinline__))
+#endif
+void __init_libc(char **envp, char *pn)
+{
+	size_t i, *auxv, aux[AUX_CNT] = { 0 };
+	__environ = envp;
+	for (i=0; envp[i]; i++);
+	libc.auxv = auxv = (void *)(envp+i+1);
+	for (i=0; auxv[i]; i+=2) if (auxv[i]<AUX_CNT) aux[auxv[i]] = auxv[i+1];
+	__hwcap = aux[AT_HWCAP];
+	__sysinfo = aux[AT_SYSINFO];
+	libc.page_size = aux[AT_PAGESZ];
+
+	if (!pn) pn = (void*)aux[AT_EXECFN];
+	if (!pn) pn = "";
+	__progname = __progname_full = pn;
+	for (i=0; pn[i]; i++) if (pn[i]=='/') __progname = pn+i+1;
+
+	__init_tls(aux);
+	__init_ssp((void *)aux[AT_RANDOM]);
+
+	if (aux[AT_UID]==aux[AT_EUID] && aux[AT_GID]==aux[AT_EGID]
+		&& !aux[AT_SECURE]) return;
+
+	struct pollfd pfd[3] = { {.fd=0}, {.fd=1}, {.fd=2} };
+	int r =
+#ifdef SYS_poll
+	__syscall(SYS_poll, pfd, 3, 0);
+#else
+	__syscall(SYS_ppoll, pfd, 3, &(struct timespec){0}, 0, _NSIG/8);
+#endif
+	if (r<0) a_crash();
+	for (i=0; i<3; i++) if (pfd[i].revents&POLLNVAL)
+		if (__sys_open("/dev/null", O_RDWR)<0)
+			a_crash();
+	libc.secure = 1;
+}
+
+static void libc_start_init(void)
+{
+	_init();
+	uintptr_t a = (uintptr_t)&__init_array_start;
+	for (; a<(uintptr_t)&__init_array_end; a+=sizeof(void(*)()))
+		(*(void (**)(void))a)();
+}
+
+weak_alias(libc_start_init, __libc_start_init);
+
+typedef int lsm2_fn(int (*)(int,char **,char **), int, char **);
+static lsm2_fn libc_start_main_stage2;
+
+int __libc_start_main(int (*main)(int,char **,char **), int argc, char **argv)
+{
+	char **envp = argv+argc+1;
+
+	/* External linkage, and explicit noinline attribute if available,
+	 * are used to prevent the stack frame used during init from
+	 * persisting for the entire process lifetime. */
+	__init_libc(envp, argv[0]);
+
+	/* Barrier against hoisting application code or anything using ssp
+	 * or thread pointer prior to its initialization above. */
+	lsm2_fn *stage2 = libc_start_main_stage2;
+	__asm__ ( "" : "+r"(stage2) : : "memory" );
+	return stage2(main, argc, argv);
+}
+
+static int libc_start_main_stage2(int (*main)(int,char **,char **), int argc, char **argv)
+{
+	char **envp = argv+argc+1;
+	__libc_start_init();
+
+	/* Pass control to the application */
+	exit(main(argc, argv, envp));
+	return 0;
+}
libc/musl/src/env/__reset_tls.c
@@ -0,0 +1,15 @@
+#include <string.h>
+#include "pthread_impl.h"
+#include "libc.h"
+
+void __reset_tls()
+{
+	pthread_t self = __pthread_self();
+	struct tls_module *p;
+	size_t i, n = self->dtv[0];
+	if (n) for (p=libc.tls_head, i=1; i<=n; i++, p=p->next) {
+		char *mem = (char *)(self->dtv[i] - DTP_OFFSET);
+		memcpy(mem, p->image, p->len);
+		memset(mem+p->len, 0, p->size - p->len);
+	}
+}
libc/musl/src/env/__stack_chk_fail.c
@@ -0,0 +1,22 @@
+#include <string.h>
+#include <stdint.h>
+#include "pthread_impl.h"
+
+uintptr_t __stack_chk_guard;
+
+void __init_ssp(void *entropy)
+{
+	if (entropy) memcpy(&__stack_chk_guard, entropy, sizeof(uintptr_t));
+	else __stack_chk_guard = (uintptr_t)&__stack_chk_guard * 1103515245;
+
+	__pthread_self()->CANARY = __stack_chk_guard;
+}
+
+void __stack_chk_fail(void)
+{
+	a_crash();
+}
+
+hidden void __stack_chk_fail_local(void);
+
+weak_alias(__stack_chk_fail, __stack_chk_fail_local);
libc/musl/src/env/clearenv.c
@@ -0,0 +1,14 @@
+#define _GNU_SOURCE
+#include <stdlib.h>
+#include <unistd.h>
+
+static void dummy(char *old, char *new) {}
+weak_alias(dummy, __env_rm_add);
+
+int clearenv()
+{
+	char **e = __environ;
+	__environ = 0;
+	if (e) while (*e) __env_rm_add(*e++, 0);
+	return 0;
+}
libc/musl/src/env/getenv.c
@@ -0,0 +1,13 @@
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+char *getenv(const char *name)
+{
+	size_t l = __strchrnul(name, '=') - name;
+	if (l && !name[l] && __environ)
+		for (char **e = __environ; *e; e++)
+			if (!strncmp(name, *e, l) && l[*e] == '=')
+				return *e + l+1;
+	return 0;
+}
libc/musl/src/env/putenv.c
@@ -0,0 +1,46 @@
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+static void dummy(char *old, char *new) {}
+weak_alias(dummy, __env_rm_add);
+
+int __putenv(char *s, size_t l, char *r)
+{
+	size_t i=0;
+	if (__environ) {
+		for (char **e = __environ; *e; e++, i++)
+			if (!strncmp(s, *e, l+1)) {
+				char *tmp = *e;
+				*e = s;
+				__env_rm_add(tmp, r);
+				return 0;
+			}
+	}
+	static char **oldenv;
+	char **newenv;
+	if (__environ == oldenv) {
+		newenv = realloc(oldenv, sizeof *newenv * (i+2));
+		if (!newenv) goto oom;
+	} else {
+		newenv = malloc(sizeof *newenv * (i+2));
+		if (!newenv) goto oom;
+		if (i) memcpy(newenv, __environ, sizeof *newenv * i);
+		free(oldenv);
+	}
+	newenv[i] = s;
+	newenv[i+1] = 0;
+	__environ = oldenv = newenv;
+	if (r) __env_rm_add(0, r);
+	return 0;
+oom:
+	free(r);
+	return -1;
+}
+
+int putenv(char *s)
+{
+	size_t l = __strchrnul(s, '=') - s;
+	if (!l || !s[l]) return unsetenv(s);
+	return __putenv(s, l, 0);
+}
libc/musl/src/env/setenv.c
@@ -0,0 +1,42 @@
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+
+void __env_rm_add(char *old, char *new)
+{
+	static char **env_alloced;
+	static size_t env_alloced_n;
+	for (size_t i=0; i < env_alloced_n; i++)
+		if (env_alloced[i] == old) {
+			env_alloced[i] = new;
+			free(old);
+			return;
+		} else if (!env_alloced[i] && new) {
+			env_alloced[i] = new;
+			new = 0;
+		}
+	if (!new) return;
+	char **t = realloc(env_alloced, sizeof *t * (env_alloced_n+1));
+	if (!t) return;
+	(env_alloced = t)[env_alloced_n++] = new;
+}
+
+int setenv(const char *var, const char *value, int overwrite)
+{
+	char *s;
+	size_t l1, l2;
+
+	if (!var || !(l1 = __strchrnul(var, '=') - var) || var[l1]) {
+		errno = EINVAL;
+		return -1;
+	}
+	if (!overwrite && getenv(var)) return 0;
+
+	l2 = strlen(value);
+	s = malloc(l1+l2+2);
+	if (!s) return -1;
+	memcpy(s, var, l1);
+	s[l1] = '=';
+	memcpy(s+l1+1, value, l2+1);
+	return __putenv(s, l1, s);
+}
libc/musl/src/env/unsetenv.c
@@ -0,0 +1,28 @@
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include <unistd.h>
+
+static void dummy(char *old, char *new) {}
+weak_alias(dummy, __env_rm_add);
+
+int unsetenv(const char *name)
+{
+	size_t l = __strchrnul(name, '=') - name;
+	if (!l || name[l]) {
+		errno = EINVAL;
+		return -1;
+	}
+	if (__environ) {
+		char **e = __environ, **eo = e;
+		for (; *e; e++)
+			if (!strncmp(name, *e, l) && l[*e] == '=')
+				__env_rm_add(*e, 0);
+			else if (eo != e)
+				*eo++ = *e;
+			else
+				eo++;
+		if (eo != e) *eo = 0;
+	}
+	return 0;
+}
libc/musl/src/errno/__errno_location.c
@@ -0,0 +1,9 @@
+#include <errno.h>
+#include "pthread_impl.h"
+
+int *__errno_location(void)
+{
+	return &__pthread_self()->errno_val;
+}
+
+weak_alias(__errno_location, ___errno_location);
libc/musl/src/errno/__strerror.h
@@ -0,0 +1,105 @@
+/* This file is sorted such that 'errors' which represent exceptional
+ * conditions under which a correct program may fail come first, followed
+ * by messages that indicate an incorrect program or system failure. The
+ * macro E() along with double-inclusion is used to ensure that ordering
+ * of the strings remains synchronized. */
+
+E(EILSEQ,       "Illegal byte sequence")
+E(EDOM,         "Domain error")
+E(ERANGE,       "Result not representable")
+
+E(ENOTTY,       "Not a tty")
+E(EACCES,       "Permission denied")
+E(EPERM,        "Operation not permitted")
+E(ENOENT,       "No such file or directory")
+E(ESRCH,        "No such process")
+E(EEXIST,       "File exists")
+
+E(EOVERFLOW,    "Value too large for data type")
+E(ENOSPC,       "No space left on device")
+E(ENOMEM,       "Out of memory")
+
+E(EBUSY,        "Resource busy")
+E(EINTR,        "Interrupted system call")
+E(EAGAIN,       "Resource temporarily unavailable")
+E(ESPIPE,       "Invalid seek")
+
+E(EXDEV,        "Cross-device link")
+E(EROFS,        "Read-only file system")
+E(ENOTEMPTY,    "Directory not empty")
+
+E(ECONNRESET,   "Connection reset by peer")
+E(ETIMEDOUT,    "Operation timed out")
+E(ECONNREFUSED, "Connection refused")
+E(EHOSTDOWN,    "Host is down")
+E(EHOSTUNREACH, "Host is unreachable")
+E(EADDRINUSE,   "Address in use")
+
+E(EPIPE,        "Broken pipe")
+E(EIO,          "I/O error")
+E(ENXIO,        "No such device or address")
+E(ENOTBLK,      "Block device required")
+E(ENODEV,       "No such device")
+E(ENOTDIR,      "Not a directory")
+E(EISDIR,       "Is a directory")
+E(ETXTBSY,      "Text file busy")
+E(ENOEXEC,      "Exec format error")
+
+E(EINVAL,       "Invalid argument")
+
+E(E2BIG,        "Argument list too long")
+E(ELOOP,        "Symbolic link loop")
+E(ENAMETOOLONG, "Filename too long")
+E(ENFILE,       "Too many open files in system")
+E(EMFILE,       "No file descriptors available")
+E(EBADF,        "Bad file descriptor")
+E(ECHILD,       "No child process")
+E(EFAULT,       "Bad address")
+E(EFBIG,        "File too large")
+E(EMLINK,       "Too many links")
+E(ENOLCK,       "No locks available")
+
+E(EDEADLK,      "Resource deadlock would occur")
+E(ENOTRECOVERABLE, "State not recoverable")
+E(EOWNERDEAD,   "Previous owner died")
+E(ECANCELED,    "Operation canceled")
+E(ENOSYS,       "Function not implemented")
+E(ENOMSG,       "No message of desired type")
+E(EIDRM,        "Identifier removed")
+E(ENOSTR,       "Device not a stream")
+E(ENODATA,      "No data available")
+E(ETIME,        "Device timeout")
+E(ENOSR,        "Out of streams resources")
+E(ENOLINK,      "Link has been severed")
+E(EPROTO,       "Protocol error")
+E(EBADMSG,      "Bad message")
+E(EBADFD,       "File descriptor in bad state")
+E(ENOTSOCK,     "Not a socket")
+E(EDESTADDRREQ, "Destination address required")
+E(EMSGSIZE,     "Message too large")
+E(EPROTOTYPE,   "Protocol wrong type for socket")
+E(ENOPROTOOPT,  "Protocol not available")
+E(EPROTONOSUPPORT,"Protocol not supported")
+E(ESOCKTNOSUPPORT,"Socket type not supported")
+E(ENOTSUP,      "Not supported")
+E(EPFNOSUPPORT, "Protocol family not supported")
+E(EAFNOSUPPORT, "Address family not supported by protocol")
+E(EADDRNOTAVAIL,"Address not available")
+E(ENETDOWN,     "Network is down")
+E(ENETUNREACH,  "Network unreachable")
+E(ENETRESET,    "Connection reset by network")
+E(ECONNABORTED, "Connection aborted")
+E(ENOBUFS,      "No buffer space available")
+E(EISCONN,      "Socket is connected")
+E(ENOTCONN,     "Socket not connected")
+E(ESHUTDOWN,    "Cannot send after socket shutdown")
+E(EALREADY,     "Operation already in progress")
+E(EINPROGRESS,  "Operation in progress")
+E(ESTALE,       "Stale file handle")
+E(EREMOTEIO,    "Remote I/O error")
+E(EDQUOT,       "Quota exceeded")
+E(ENOMEDIUM,    "No medium found")
+E(EMEDIUMTYPE,  "Wrong medium type")
+E(EMULTIHOP,    "Multihop attempted")
+
+E(0,            "No error information")
libc/musl/src/errno/strerror.c
@@ -0,0 +1,36 @@
+#include <errno.h>
+#include <string.h>
+#include "locale_impl.h"
+
+#define E(a,b) ((unsigned char)a),
+static const unsigned char errid[] = {
+#include "__strerror.h"
+};
+
+#undef E
+#define E(a,b) b "\0"
+static const char errmsg[] =
+#include "__strerror.h"
+;
+
+char *__strerror_l(int e, locale_t loc)
+{
+	const char *s;
+	int i;
+	/* mips has one error code outside of the 8-bit range due to a
+	 * historical typo, so we just remap it. */
+	if (EDQUOT==1133) {
+		if (e==109) e=-1;
+		else if (e==EDQUOT) e=109;
+	}
+	for (i=0; errid[i] && errid[i] != e; i++);
+	for (s=errmsg; i; s++, i--) for (; *s; s++);
+	return (char *)LCTRANS(s, LC_MESSAGES, loc);
+}
+
+char *strerror(int e)
+{
+	return __strerror_l(e, CURRENT_LOCALE);
+}
+
+weak_alias(__strerror_l, strerror_l);
libc/musl/src/exit/arm/__aeabi_atexit.c
@@ -0,0 +1,6 @@
+int __cxa_atexit(void (*func)(void *), void *arg, void *dso);
+
+int __aeabi_atexit (void *obj, void (*func) (void *), void *d)
+{
+	return __cxa_atexit (func, obj, d);
+}
libc/musl/src/exit/_Exit.c
@@ -0,0 +1,8 @@
+#include <stdlib.h>
+#include "syscall.h"
+
+_Noreturn void _Exit(int ec)
+{
+	__syscall(SYS_exit_group, ec);
+	for (;;) __syscall(SYS_exit, ec);
+}
libc/musl/src/exit/abort.c
@@ -0,0 +1,32 @@
+#include <stdlib.h>
+#include <signal.h>
+#include "syscall.h"
+#include "pthread_impl.h"
+#include "atomic.h"
+#include "lock.h"
+#include "ksigaction.h"
+
+hidden volatile int __abort_lock[1];
+
+_Noreturn void abort(void)
+{
+	raise(SIGABRT);
+
+	/* If there was a SIGABRT handler installed and it returned, or if
+	 * SIGABRT was blocked or ignored, take an AS-safe lock to prevent
+	 * sigaction from installing a new SIGABRT handler, uninstall any
+	 * handler that may be present, and re-raise the signal to generate
+	 * the default action of abnormal termination. */
+	__block_all_sigs(0);
+	LOCK(__abort_lock);
+	__syscall(SYS_rt_sigaction, SIGABRT,
+		&(struct k_sigaction){.handler = SIG_DFL}, 0, _NSIG/8);
+	__syscall(SYS_tkill, __pthread_self()->tid, SIGABRT);
+	__syscall(SYS_rt_sigprocmask, SIG_UNBLOCK,
+		&(long[_NSIG/(8*sizeof(long))]){1UL<<(SIGABRT-1)}, 0, _NSIG/8);
+
+	/* Beyond this point should be unreachable. */
+	a_crash();
+	raise(SIGKILL);
+	_Exit(127);
+}
libc/musl/src/exit/assert.c
@@ -0,0 +1,9 @@
+#include <stdio.h>
+#include <stdlib.h>
+
+_Noreturn void __assert_fail(const char *expr, const char *file, int line, const char *func)
+{
+	fprintf(stderr, "Assertion failed: %s (%s: %s: %d)\n", expr, file, func, line);
+	fflush(NULL);
+	abort();
+}
libc/musl/src/exit/at_quick_exit.c
@@ -0,0 +1,31 @@
+#include <stdlib.h>
+#include "libc.h"
+#include "lock.h"
+
+#define COUNT 32
+
+static void (*funcs[COUNT])(void);
+static int count;
+static volatile int lock[1];
+
+void __funcs_on_quick_exit()
+{
+	void (*func)(void);
+	LOCK(lock);
+	while (count > 0) {
+		func = funcs[--count];
+		UNLOCK(lock);
+		func();
+		LOCK(lock);
+	}
+}
+
+int at_quick_exit(void (*func)(void))
+{
+	int r = 0;
+	LOCK(lock);
+	if (count == 32) r = -1;
+	else funcs[count++] = func;
+	UNLOCK(lock);
+	return r;
+}
libc/musl/src/exit/atexit.c
@@ -0,0 +1,72 @@
+#include <stdlib.h>
+#include <stdint.h>
+#include "libc.h"
+#include "lock.h"
+
+/* Ensure that at least 32 atexit handlers can be registered without malloc */
+#define COUNT 32
+
+static struct fl
+{
+	struct fl *next;
+	void (*f[COUNT])(void *);
+	void *a[COUNT];
+} builtin, *head;
+
+static int slot;
+static volatile int lock[1];
+
+void __funcs_on_exit()
+{
+	void (*func)(void *), *arg;
+	LOCK(lock);
+	for (; head; head=head->next, slot=COUNT) while(slot-->0) {
+		func = head->f[slot];
+		arg = head->a[slot];
+		UNLOCK(lock);
+		func(arg);
+		LOCK(lock);
+	}
+}
+
+void __cxa_finalize(void *dso)
+{
+}
+
+int __cxa_atexit(void (*func)(void *), void *arg, void *dso)
+{
+	LOCK(lock);
+
+	/* Defer initialization of head so it can be in BSS */
+	if (!head) head = &builtin;
+
+	/* If the current function list is full, add a new one */
+	if (slot==COUNT) {
+		struct fl *new_fl = calloc(sizeof(struct fl), 1);
+		if (!new_fl) {
+			UNLOCK(lock);
+			return -1;
+		}
+		new_fl->next = head;
+		head = new_fl;
+		slot = 0;
+	}
+
+	/* Append function to the list. */
+	head->f[slot] = func;
+	head->a[slot] = arg;
+	slot++;
+
+	UNLOCK(lock);
+	return 0;
+}
+
+static void call(void *p)
+{
+	((void (*)(void))(uintptr_t)p)();
+}
+
+int atexit(void (*func)(void))
+{
+	return __cxa_atexit(call, (void *)(uintptr_t)func, 0);
+}
libc/musl/src/exit/exit.c
@@ -0,0 +1,33 @@
+#include <stdlib.h>
+#include <stdint.h>
+#include "libc.h"
+
+static void dummy()
+{
+}
+
+/* atexit.c and __stdio_exit.c override these. the latter is linked
+ * as a consequence of linking either __toread.c or __towrite.c. */
+weak_alias(dummy, __funcs_on_exit);
+weak_alias(dummy, __stdio_exit);
+weak_alias(dummy, _fini);
+
+extern weak hidden void (*const __fini_array_start)(void), (*const __fini_array_end)(void);
+
+static void libc_exit_fini(void)
+{
+	uintptr_t a = (uintptr_t)&__fini_array_end;
+	for (; a>(uintptr_t)&__fini_array_start; a-=sizeof(void(*)()))
+		(*(void (**)())(a-sizeof(void(*)())))();
+	_fini();
+}
+
+weak_alias(libc_exit_fini, __libc_exit_fini);
+
+_Noreturn void exit(int code)
+{
+	__funcs_on_exit();
+	__libc_exit_fini();
+	__stdio_exit();
+	_Exit(code);
+}
libc/musl/src/exit/quick_exit.c
@@ -0,0 +1,11 @@
+#include <stdlib.h>
+#include "libc.h"
+
+static void dummy() { }
+weak_alias(dummy, __funcs_on_quick_exit);
+
+_Noreturn void quick_exit(int code)
+{
+	__funcs_on_quick_exit();
+	_Exit(code);
+}
libc/musl/src/fcntl/creat.c
@@ -0,0 +1,8 @@
+#include <fcntl.h>
+
+int creat(const char *filename, mode_t mode)
+{
+	return open(filename, O_CREAT|O_WRONLY|O_TRUNC, mode);
+}
+
+weak_alias(creat, creat64);
libc/musl/src/fcntl/fcntl.c
@@ -0,0 +1,48 @@
+#define _GNU_SOURCE
+#include <fcntl.h>
+#include <stdarg.h>
+#include <errno.h>
+#include "syscall.h"
+
+int fcntl(int fd, int cmd, ...)
+{
+	unsigned long arg;
+	va_list ap;
+	va_start(ap, cmd);
+	arg = va_arg(ap, unsigned long);
+	va_end(ap);
+	if (cmd == F_SETFL) arg |= O_LARGEFILE;
+	if (cmd == F_SETLKW) return syscall_cp(SYS_fcntl, fd, cmd, (void *)arg);
+	if (cmd == F_GETOWN) {
+		struct f_owner_ex ex;
+		int ret = __syscall(SYS_fcntl, fd, F_GETOWN_EX, &ex);
+		if (ret == -EINVAL) return __syscall(SYS_fcntl, fd, cmd, (void *)arg);
+		if (ret) return __syscall_ret(ret);
+		return ex.type == F_OWNER_PGRP ? -ex.pid : ex.pid;
+	}
+	if (cmd == F_DUPFD_CLOEXEC) {
+		int ret = __syscall(SYS_fcntl, fd, F_DUPFD_CLOEXEC, arg);
+		if (ret != -EINVAL) {
+			if (ret >= 0)
+				__syscall(SYS_fcntl, ret, F_SETFD, FD_CLOEXEC);
+			return __syscall_ret(ret);
+		}
+		ret = __syscall(SYS_fcntl, fd, F_DUPFD_CLOEXEC, 0);
+		if (ret != -EINVAL) {
+			if (ret >= 0) __syscall(SYS_close, ret);
+			return __syscall_ret(-EINVAL);
+		}
+		ret = __syscall(SYS_fcntl, fd, F_DUPFD, arg);
+		if (ret >= 0) __syscall(SYS_fcntl, ret, F_SETFD, FD_CLOEXEC);
+		return __syscall_ret(ret);
+	}
+	switch (cmd) {
+	case F_SETLK:
+	case F_GETLK:
+	case F_GETOWN_EX:
+	case F_SETOWN_EX:
+		return syscall(SYS_fcntl, fd, cmd, (void *)arg);
+	default:
+		return syscall(SYS_fcntl, fd, cmd, arg);
+	}
+}
libc/musl/src/fcntl/open.c
@@ -0,0 +1,23 @@
+#include <fcntl.h>
+#include <stdarg.h>
+#include "syscall.h"
+
+int open(const char *filename, int flags, ...)
+{
+	mode_t mode = 0;
+
+	if ((flags & O_CREAT) || (flags & O_TMPFILE) == O_TMPFILE) {
+		va_list ap;
+		va_start(ap, flags);
+		mode = va_arg(ap, mode_t);
+		va_end(ap);
+	}
+
+	int fd = __sys_open_cp(filename, flags, mode);
+	if (fd>=0 && (flags & O_CLOEXEC))
+		__syscall(SYS_fcntl, fd, F_SETFD, FD_CLOEXEC);
+
+	return __syscall_ret(fd);
+}
+
+weak_alias(open, open64);
libc/musl/src/fcntl/openat.c
@@ -0,0 +1,19 @@
+#include <fcntl.h>
+#include <stdarg.h>
+#include "syscall.h"
+
+int openat(int fd, const char *filename, int flags, ...)
+{
+	mode_t mode = 0;
+
+	if ((flags & O_CREAT) || (flags & O_TMPFILE) == O_TMPFILE) {
+		va_list ap;
+		va_start(ap, flags);
+		mode = va_arg(ap, mode_t);
+		va_end(ap);
+	}
+
+	return syscall_cp(SYS_openat, fd, filename, flags|O_LARGEFILE, mode);
+}
+
+weak_alias(openat, openat64);
libc/musl/src/fcntl/posix_fadvise.c
@@ -0,0 +1,18 @@
+#include <fcntl.h>
+#include "syscall.h"
+
+int posix_fadvise(int fd, off_t base, off_t len, int advice)
+{
+#if defined(SYSCALL_FADVISE_6_ARG)
+	/* Some archs, at least arm and powerpc, have the syscall
+	 * arguments reordered to avoid needing 7 argument registers
+	 * due to 64-bit argument alignment. */
+	return -__syscall(SYS_fadvise, fd, advice,
+		__SYSCALL_LL_E(base), __SYSCALL_LL_E(len));
+#else
+	return -__syscall(SYS_fadvise, fd, __SYSCALL_LL_O(base),
+		__SYSCALL_LL_E(len), advice);
+#endif
+}
+
+weak_alias(posix_fadvise, posix_fadvise64);
libc/musl/src/fcntl/posix_fallocate.c
@@ -0,0 +1,10 @@
+#include <fcntl.h>
+#include "syscall.h"
+
+int posix_fallocate(int fd, off_t base, off_t len)
+{
+	return -__syscall(SYS_fallocate, fd, 0, __SYSCALL_LL_E(base),
+		__SYSCALL_LL_E(len));
+}
+
+weak_alias(posix_fallocate, posix_fallocate64);
libc/musl/src/fenv/aarch64/fenv.s
@@ -0,0 +1,68 @@
+.global fegetround
+.type fegetround,%function
+fegetround:
+	mrs x0, fpcr
+	and w0, w0, #0xc00000
+	ret
+
+.global __fesetround
+.hidden __fesetround
+.type __fesetround,%function
+__fesetround:
+	mrs x1, fpcr
+	bic w1, w1, #0xc00000
+	orr w1, w1, w0
+	msr fpcr, x1
+	mov w0, #0
+	ret
+
+.global fetestexcept
+.type fetestexcept,%function
+fetestexcept:
+	and w0, w0, #0x1f
+	mrs x1, fpsr
+	and w0, w0, w1
+	ret
+
+.global feclearexcept
+.type feclearexcept,%function
+feclearexcept:
+	and w0, w0, #0x1f
+	mrs x1, fpsr
+	bic w1, w1, w0
+	msr fpsr, x1
+	mov w0, #0
+	ret
+
+.global feraiseexcept
+.type feraiseexcept,%function
+feraiseexcept:
+	and w0, w0, #0x1f
+	mrs x1, fpsr
+	orr w1, w1, w0
+	msr fpsr, x1
+	mov w0, #0
+	ret
+
+.global fegetenv
+.type fegetenv,%function
+fegetenv:
+	mrs x1, fpcr
+	mrs x2, fpsr
+	stp w1, w2, [x0]
+	mov w0, #0
+	ret
+
+// TODO preserve some bits
+.global fesetenv
+.type fesetenv,%function
+fesetenv:
+	mov x1, #0
+	mov x2, #0
+	cmn x0, #1
+	b.eq 1f
+	ldp w1, w2, [x0]
+1:	msr fpcr, x1
+	msr fpsr, x2
+	mov w0, #0
+	ret
libc/musl/src/fenv/arm/fenv-hf.S
@@ -0,0 +1,70 @@
+#if __ARM_PCS_VFP
+
+.syntax unified
+.fpu vfp
+
+.global fegetround
+.type fegetround,%function
+fegetround:
+	fmrx r0, fpscr
+	and r0, r0, #0xc00000
+	bx lr
+
+.global __fesetround
+.hidden __fesetround
+.type __fesetround,%function
+__fesetround:
+	fmrx r3, fpscr
+	bic r3, r3, #0xc00000
+	orr r3, r3, r0
+	fmxr fpscr, r3
+	mov r0, #0
+	bx lr
+
+.global fetestexcept
+.type fetestexcept,%function
+fetestexcept:
+	and r0, r0, #0x1f
+	fmrx r3, fpscr
+	and r0, r0, r3
+	bx lr
+
+.global feclearexcept
+.type feclearexcept,%function
+feclearexcept:
+	and r0, r0, #0x1f
+	fmrx r3, fpscr
+	bic r3, r3, r0
+	fmxr fpscr, r3
+	mov r0, #0
+	bx lr
+
+.global feraiseexcept
+.type feraiseexcept,%function
+feraiseexcept:
+	and r0, r0, #0x1f
+	fmrx r3, fpscr
+	orr r3, r3, r0
+	fmxr fpscr, r3
+	mov r0, #0
+	bx lr
+
+.global fegetenv
+.type fegetenv,%function
+fegetenv:
+	fmrx r3, fpscr
+	str r3, [r0]
+	mov r0, #0
+	bx lr
+
+.global fesetenv
+.type fesetenv,%function
+fesetenv:
+	cmn r0, #1
+	moveq r3, #0
+	ldrne r3, [r0]
+	fmxr fpscr, r3
+	mov r0, #0
+	bx lr
+
+#endif
libc/musl/src/fenv/arm/fenv.c
@@ -0,0 +1,3 @@
+#if !__ARM_PCS_VFP
+#include "../fenv.c"
+#endif
libc/musl/src/fenv/i386/fenv.s
@@ -0,0 +1,164 @@
+.hidden __hwcap
+
+.global feclearexcept
+.type feclearexcept,@function
+feclearexcept:	
+	mov 4(%esp),%ecx
+	and $0x3f,%ecx
+	fnstsw %ax
+		# consider sse fenv as well if the cpu has XMM capability
+	call 1f
+1:	addl $__hwcap-1b,(%esp)
+	pop %edx
+	testl $0x02000000,(%edx)
+	jz 2f
+		# maintain exceptions in the sse mxcsr, clear x87 exceptions
+	test %eax,%ecx
+	jz 1f
+	fnclex
+1:	push %edx
+	stmxcsr (%esp)
+	pop %edx
+	and $0x3f,%eax
+	or %eax,%edx
+	test %edx,%ecx
+	jz 1f
+	not %ecx
+	and %ecx,%edx
+	push %edx
+	ldmxcsr (%esp)
+	pop %edx
+1:	xor %eax,%eax
+	ret
+		# only do the expensive x87 fenv load/store when needed
+2:	test %eax,%ecx
+	jz 1b
+	not %ecx
+	and %ecx,%eax
+	test $0x3f,%eax
+	jz 1f
+	fnclex
+	jmp 1b
+1:	sub $32,%esp
+	fnstenv (%esp)
+	mov %al,4(%esp)
+	fldenv (%esp)
+	add $32,%esp
+	xor %eax,%eax
+	ret
+
+.global feraiseexcept
+.type feraiseexcept,@function
+feraiseexcept:	
+	mov 4(%esp),%eax
+	and $0x3f,%eax
+	sub $32,%esp
+	fnstenv (%esp)
+	or %al,4(%esp)
+	fldenv (%esp)
+	add $32,%esp
+	xor %eax,%eax
+	ret
+
+.global __fesetround
+.hidden __fesetround
+.type __fesetround,@function
+__fesetround:
+	mov 4(%esp),%ecx
+	push %eax
+	xor %eax,%eax
+	fnstcw (%esp)
+	andb $0xf3,1(%esp)
+	or %ch,1(%esp)
+	fldcw (%esp)
+		# consider sse fenv as well if the cpu has XMM capability
+	call 1f
+1:	addl $__hwcap-1b,(%esp)
+	pop %edx
+	testl $0x02000000,(%edx)
+	jz 1f
+	stmxcsr (%esp)
+	shl $3,%ch
+	andb $0x9f,1(%esp)
+	or %ch,1(%esp)
+	ldmxcsr (%esp)
+1:	pop %ecx
+	ret
+
+.global fegetround
+.type fegetround,@function
+fegetround:
+	push %eax
+	fnstcw (%esp)
+	pop %eax
+	and $0xc00,%eax
+	ret
+
+.global fegetenv
+.type fegetenv,@function
+fegetenv:
+	mov 4(%esp),%ecx
+	xor %eax,%eax
+	fnstenv (%ecx)
+		# consider sse fenv as well if the cpu has XMM capability
+	call 1f
+1:	addl $__hwcap-1b,(%esp)
+	pop %edx
+	testl $0x02000000,(%edx)
+	jz 1f
+	push %eax
+	stmxcsr (%esp)
+	pop %edx
+	and $0x3f,%edx
+	or %edx,4(%ecx)
+1:	ret
+
+.global fesetenv
+.type fesetenv,@function
+fesetenv:
+	mov 4(%esp),%ecx
+	xor %eax,%eax
+	inc %ecx
+	jz 1f
+	fldenv -1(%ecx)
+	movl -1(%ecx),%ecx
+	jmp 2f
+1:	push %eax
+	push %eax
+	push %eax
+	push %eax
+	pushl $0xffff
+	push %eax
+	pushl $0x37f
+	fldenv (%esp)
+	add $28,%esp
+		# consider sse fenv as well if the cpu has XMM capability
+2:	call 1f
+1:	addl $__hwcap-1b,(%esp)
+	pop %edx
+	testl $0x02000000,(%edx)
+	jz 1f
+		# mxcsr := same rounding mode, cleared exceptions, default mask
+	and $0xc00,%ecx
+	shl $3,%ecx
+	or $0x1f80,%ecx
+	mov %ecx,4(%esp)
+	ldmxcsr 4(%esp)
+1:	ret
+
+.global fetestexcept
+.type fetestexcept,@function
+fetestexcept:
+	mov 4(%esp),%ecx
+	and $0x3f,%ecx
+	fnstsw %ax
+		# consider sse fenv as well if the cpu has XMM capability
+	call 1f
+1:	addl $__hwcap-1b,(%esp)
+	pop %edx
+	testl $0x02000000,(%edx)
+	jz 1f
+	stmxcsr 4(%esp)
+	or 4(%esp),%eax
+1:	and %ecx,%eax
+	ret
libc/musl/src/fenv/m68k/fenv.c
@@ -0,0 +1,85 @@
+#include <fenv.h>
+#include <features.h>
+
+#if __HAVE_68881__ || __mcffpu__
+
+static unsigned getsr()
+{
+	unsigned v;
+	__asm__ __volatile__ ("fmove.l %%fpsr,%0" : "=dm"(v));
+	return v;
+}
+
+static void setsr(unsigned v)
+{
+	__asm__ __volatile__ ("fmove.l %0,%%fpsr" : : "dm"(v));
+}
+
+static unsigned getcr()
+{
+	unsigned v;
+	__asm__ __volatile__ ("fmove.l %%fpcr,%0" : "=dm"(v));
+	return v;
+}
+
+static void setcr(unsigned v)
+{
+	__asm__ __volatile__ ("fmove.l %0,%%fpcr" : : "dm"(v));
+}
+
+int feclearexcept(int mask)
+{
+	if (mask & ~FE_ALL_EXCEPT) return -1;
+	setsr(getsr() & ~mask);
+	return 0;
+}
+
+int feraiseexcept(int mask)
+{
+	if (mask & ~FE_ALL_EXCEPT) return -1;
+	setsr(getsr() | mask);
+	return 0;
+}
+
+int fetestexcept(int mask)
+{
+	return getsr() & mask;
+}
+
+int fegetround(void)
+{
+	return getcr() & FE_UPWARD;
+}
+
+hidden int __fesetround(int r)
+{
+	setcr((getcr() & ~FE_UPWARD) | r);
+	return 0;
+}
+
+int fegetenv(fenv_t *envp)
+{
+	envp->__control_register = getcr();
+	envp->__status_register = getsr();
+	__asm__ __volatile__ ("fmove.l %%fpiar,%0"
+		: "=dm"(envp->__instruction_address));
+	return 0;
+}
+
+int fesetenv(const fenv_t *envp)
+{
+	static const fenv_t default_env = { 0 };
+	if (envp == FE_DFL_ENV)
+		envp = &default_env;
+	setcr(envp->__control_register);
+	setsr(envp->__status_register);
+	__asm__ __volatile__ ("fmove.l %0,%%fpiar"
+		: : "dm"(envp->__instruction_address));
+	return 0;
+}
+
+#else
+
+#include "../fenv.c"
+
+#endif
libc/musl/src/fenv/mips/fenv-sf.c
@@ -0,0 +1,3 @@
+#ifdef __mips_soft_float
+#include "../fenv.c"
+#endif
libc/musl/src/fenv/mips/fenv.S
@@ -0,0 +1,72 @@
+#ifndef __mips_soft_float
+
+.set noreorder
+
+.global feclearexcept
+.type  feclearexcept,@function
+feclearexcept:
+	and     $4, $4, 0x7c
+	cfc1    $5, $31
+	or      $5, $5, $4
+	xor     $5, $5, $4
+	ctc1    $5, $31
+	jr      $ra
+	li      $2, 0
+
+.global feraiseexcept
+.type  feraiseexcept,@function
+feraiseexcept:
+	and     $4, $4, 0x7c
+	cfc1    $5, $31
+	or      $5, $5, $4
+	ctc1    $5, $31
+	jr      $ra
+	li      $2, 0
+
+.global fetestexcept
+.type  fetestexcept,@function
+fetestexcept:
+	and     $4, $4, 0x7c
+	cfc1    $2, $31
+	jr      $ra
+	and     $2, $2, $4
+
+.global fegetround
+.type  fegetround,@function
+fegetround:
+	cfc1    $2, $31
+	jr      $ra
+	andi    $2, $2, 3
+
+.global __fesetround
+.hidden __fesetround
+.type __fesetround,@function
+__fesetround:
+	cfc1    $5, $31
+	li      $6, -4
+	and     $5, $5, $6
+	or      $5, $5, $4
+	ctc1    $5, $31
+	jr      $ra
+	li      $2, 0
+
+.global fegetenv
+.type  fegetenv,@function
+fegetenv:
+	cfc1    $5, $31
+	sw      $5, 0($4)
+	jr      $ra
+	li      $2, 0
+
+.global fesetenv
+.type  fesetenv,@function
+fesetenv:
+	addiu   $5, $4, 1
+	beq     $5, $0, 1f
+	 nop
+	lw      $5, 0($4)
+1:	ctc1    $5, $31
+	jr      $ra
+	li      $2, 0
+
+#endif
libc/musl/src/fenv/mips64/fenv-sf.c
@@ -0,0 +1,3 @@
+#ifdef __mips_soft_float
+#include "../fenv.c"
+#endif
libc/musl/src/fenv/mips64/fenv.S
@@ -0,0 +1,72 @@
+#ifndef __mips_soft_float
+
+.set	noreorder
+
+.global	feclearexcept
+.type	feclearexcept,@function
+feclearexcept:
+	and	$4, $4, 0x7c
+	cfc1	$5, $31
+	or	$5, $5, $4
+	xor	$5, $5, $4
+	ctc1	$5, $31
+	jr	$ra
+	li	$2, 0
+
+.global	feraiseexcept
+.type	feraiseexcept,@function
+feraiseexcept:
+	and	$4, $4, 0x7c
+	cfc1	$5, $31
+	or	$5, $5, $4
+	ctc1	$5, $31
+	jr	$ra
+	li	$2, 0
+
+.global	fetestexcept
+.type	fetestexcept,@function
+fetestexcept:
+	and	$4, $4, 0x7c
+	cfc1	$2, $31
+	jr	$ra
+	and	$2, $2, $4
+
+.global	fegetround
+.type	fegetround,@function
+fegetround:
+	cfc1	$2, $31
+	jr	$ra
+	andi	$2, $2, 3
+
+.global	__fesetround
+.hidden __fesetround
+.type	__fesetround,@function
+__fesetround:
+	cfc1	$5, $31
+	li	$6, -4
+	and	$5, $5, $6
+	or	$5, $5, $4
+	ctc1	$5, $31
+	jr	$ra
+	li	$2, 0
+
+.global	fegetenv
+.type	fegetenv,@function
+fegetenv:
+	cfc1	$5, $31
+	sw	$5, 0($4)
+	jr	$ra
+	li	$2, 0
+
+.global	fesetenv
+.type	fesetenv,@function
+fesetenv:
+	daddiu	$5, $4, 1
+	beq	$5, $0, 1f
+	nop
+	lw	$5, 0($4)
+1:	ctc1	$5, $31
+	jr	$ra
+	li	$2, 0
+
+#endif
libc/musl/src/fenv/mipsn32/fenv-sf.c
@@ -0,0 +1,3 @@
+#ifdef __mips_soft_float
+#include "../fenv.c"
+#endif
libc/musl/src/fenv/mipsn32/fenv.S
@@ -0,0 +1,71 @@
+#ifndef __mips_soft_float
+
+.set	noreorder
+.global	feclearexcept
+.type	feclearexcept,@function
+feclearexcept:
+	and	$4, $4, 0x7c
+	cfc1	$5, $31
+	or	$5, $5, $4
+	xor	$5, $5, $4
+	ctc1	$5, $31
+	jr	$ra
+	li	$2, 0
+
+.global feraiseexcept
+.type  feraiseexcept,@function
+feraiseexcept:
+	and	$4, $4, 0x7c
+	cfc1	$5, $31
+	or	$5, $5, $4
+	ctc1	$5, $31
+	jr	$ra
+	li	$2, 0
+
+.global fetestexcept
+.type  fetestexcept,@function
+fetestexcept:
+	and	$4, $4, 0x7c
+	cfc1	$2, $31
+	jr	$ra
+	and	$2, $2, $4
+
+.global fegetround
+.type  fegetround,@function
+fegetround:
+	cfc1	$2, $31
+	jr	$ra
+	andi	$2, $2, 3
+
+.global __fesetround
+.hidden __fesetround
+.type __fesetround,@function
+__fesetround:
+	cfc1	$5, $31
+	li	$6, -4
+	and	$5, $5, $6
+	or	$5, $5, $4
+	ctc1	$5, $31
+	jr	$ra
+	li	$2, 0
+
+.global fegetenv
+.type  fegetenv,@function
+fegetenv:
+	cfc1	$5, $31
+	sw	$5, 0($4)
+	jr	$ra
+	li	$2, 0
+
+.global fesetenv
+.type  fesetenv,@function
+fesetenv:
+	addiu   $5, $4, 1
+	beq	$5, $0, 1f
+	nop
+	lw	$5, 0($4)
+1:	ctc1	$5, $31
+	jr	$ra
+	li	$2, 0
+
+#endif
libc/musl/src/fenv/powerpc/fenv-sf.c
@@ -0,0 +1,3 @@
+#ifdef _SOFT_FLOAT
+#include "../fenv.c"
+#endif
libc/musl/src/fenv/powerpc/fenv.S
@@ -0,0 +1,130 @@
+#ifndef _SOFT_FLOAT
+.global feclearexcept
+.type feclearexcept,@function
+feclearexcept:
+	andis. 3,3,0x3e00
+	/* if (r3 & FE_INVALID) r3 |= all_invalid_flags */
+	andis. 0,3,0x2000
+	stwu 1,-16(1)
+	beq- 0,1f
+	oris 3,3,0x01f8
+	ori  3,3,0x0700
+1:
+	/*
+	 * note: fpscr contains various fpu status and control
+	 * flags and we dont check if r3 may alter other flags
+	 * than the exception related ones
+	 * ufpscr &= ~r3
+	 */
+	mffs 0
+	stfd 0,8(1)
+	lwz 9,12(1)
+	andc 9,9,3
+	stw 9,12(1)
+	lfd 0,8(1)
+	mtfsf 255,0
+
+	/* return 0 */
+	li 3,0
+	addi 1,1,16
+	blr
+
+.global feraiseexcept
+.type feraiseexcept,@function
+feraiseexcept:
+	andis. 3,3,0x3e00
+	/* if (r3 & FE_INVALID) r3 |= software_invalid_flag */
+	andis. 0,3,0x2000
+	stwu 1,-16(1)
+	beq- 0,1f
+	ori 3,3,0x0400
+1:
+	/* fpscr |= r3 */
+	mffs 0
+	stfd 0,8(1)
+	lwz 9,12(1)
+	or 9,9,3
+	stw 9,12(1)
+	lfd 0,8(1)
+	mtfsf 255,0
+
+	/* return 0 */
+	li 3,0
+	addi 1,1,16
+	blr
+
+.global fetestexcept
+.type fetestexcept,@function
+fetestexcept:
+	andis. 3,3,0x3e00
+	/* return r3 & fpscr */
+	stwu 1,-16(1)
+	mffs 0
+	stfd 0,8(1)
+	lwz 9,12(1)
+	addi 1,1,16
+	and 3,3,9
+	blr
+
+.global fegetround
+.type fegetround,@function
+fegetround:
+	/* return fpscr & 3 */
+	stwu 1,-16(1)
+	mffs 0
+	stfd 0,8(1)
+	lwz 3,12(1)
+	addi 1,1,16
+	clrlwi 3,3,30
+	blr
+
+.global __fesetround
+.hidden __fesetround
+.type __fesetround,@function
+__fesetround:
+	/*
+	 * note: invalid input is not checked, r3 < 4 must hold
+	 * fpscr = (fpscr & -4U) | r3
+	 */
+	stwu 1,-16(1)
+	mffs 0
+	stfd 0,8(1)
+	lwz 9,12(1)
+	clrrwi 9,9,2
+	or 9,9,3
+	stw 9,12(1)
+	lfd 0,8(1)
+	mtfsf 255,0
+
+	/* return 0 */
+	li 3,0
+	addi 1,1,16
+	blr
+
+.global fegetenv
+.type fegetenv,@function
+fegetenv:
+	/* *r3 = fpscr */
+	mffs 0
+	stfd 0,0(3)
+	/* return 0 */
+	li 3,0
+	blr
+
+.global fesetenv
+.type fesetenv,@function
+fesetenv:
+	cmpwi 3, -1
+	bne 1f
+	mflr 4
+	bl 2f
+	.zero 8
+2:	mflr 3
+	mtlr 4
+1:	/* fpscr = *r3 */
+	lfd 0,0(3)
+	mtfsf 255,0
+	/* return 0 */
+	li 3,0
+	blr
+#endif
libc/musl/src/fenv/powerpc64/fenv.c
@@ -0,0 +1,69 @@
+#define _GNU_SOURCE
+#include <fenv.h>
+#include <features.h>
+
+static inline double get_fpscr_f(void)
+{
+	double d;
+	__asm__ __volatile__("mffs %0" : "=d"(d));
+	return d;
+}
+
+static inline long get_fpscr(void)
+{
+	return (union {double f; long i;}) {get_fpscr_f()}.i;
+}
+
+static inline void set_fpscr_f(double fpscr)
+{
+	__asm__ __volatile__("mtfsf 255, %0" : : "d"(fpscr));
+}
+
+static void set_fpscr(long fpscr)
+{
+	set_fpscr_f((union {long i; double f;}) {fpscr}.f);
+}
+
+int feclearexcept(int mask)
+{
+	mask &= FE_ALL_EXCEPT;
+	if (mask & FE_INVALID) mask |= FE_ALL_INVALID;
+	set_fpscr(get_fpscr() & ~mask);
+	return 0;
+}
+
+int feraiseexcept(int mask)
+{
+	mask &= FE_ALL_EXCEPT;
+	if (mask & FE_INVALID) mask |= FE_INVALID_SOFTWARE;
+	set_fpscr(get_fpscr() | mask);
+	return 0;
+}
+
+int fetestexcept(int mask)
+{
+	return get_fpscr() & mask & FE_ALL_EXCEPT;
+}
+
+int fegetround(void)
+{
+	return get_fpscr() & 3;
+}
+
+hidden int __fesetround(int r)
+{
+	set_fpscr(get_fpscr() & ~3L | r);
+	return 0;
+}
+
+int fegetenv(fenv_t *envp)
+{
+	*envp = get_fpscr_f();
+	return 0;
+}
+
+int fesetenv(const fenv_t *envp)
+{
+	set_fpscr_f(envp != FE_DFL_ENV ? *envp : 0);
+	return 0;
+}
libc/musl/src/fenv/s390x/fenv.c
@@ -0,0 +1,56 @@
+#include <fenv.h>
+#include <features.h>
+
+static inline unsigned get_fpc(void)
+{
+	unsigned fpc;
+	__asm__ __volatile__("efpc %0" : "=r"(fpc));
+	return fpc;
+}
+
+static inline void set_fpc(unsigned fpc)
+{
+	__asm__ __volatile__("sfpc %0" :: "r"(fpc));
+}
+
+int feclearexcept(int mask)
+{
+	mask &= FE_ALL_EXCEPT;
+	set_fpc(get_fpc() & ~mask);
+	return 0;
+}
+
+int feraiseexcept(int mask)
+{
+	mask &= FE_ALL_EXCEPT;
+	set_fpc(get_fpc() | mask);
+	return 0;
+}
+
+int fetestexcept(int mask)
+{
+	return get_fpc() & mask & FE_ALL_EXCEPT;
+}
+
+int fegetround(void)
+{
+	return get_fpc() & 3;
+}
+
+hidden int __fesetround(int r)
+{
+	set_fpc(get_fpc() & ~3L | r);
+	return 0;
+}
+
+int fegetenv(fenv_t *envp)
+{
+	*envp = get_fpc();
+	return 0;
+}
+
+int fesetenv(const fenv_t *envp)
+{
+	set_fpc(envp != FE_DFL_ENV ? *envp : 0);
+	return 0;
+}
libc/musl/src/fenv/sh/fenv-nofpu.c
@@ -0,0 +1,3 @@
+#if !__SH_FPU_ANY__ && !__SH4__
+#include "../fenv.c"
+#endif
libc/musl/src/fenv/sh/fenv.S
@@ -0,0 +1,79 @@
+#if __SH_FPU_ANY__ || __SH4__
+
+.global fegetround
+.type   fegetround, @function
+fegetround:
+	sts fpscr, r0
+	rts
+	 and #3, r0
+
+.global __fesetround
+.hidden __fesetround
+.type   __fesetround, @function
+__fesetround:
+	sts fpscr, r0
+	or  r4, r0
+	lds r0, fpscr
+	rts
+	 mov #0, r0
+
+.global fetestexcept
+.type   fetestexcept, @function
+fetestexcept:
+	sts fpscr, r0
+	and r4, r0
+	rts
+	 and #0x7c, r0
+
+.global feclearexcept
+.type   feclearexcept, @function
+feclearexcept:
+	mov r4, r0
+	and #0x7c, r0
+	not r0, r4
+	sts fpscr, r0
+	and r4, r0
+	lds r0, fpscr
+	rts
+	 mov #0, r0
+
+.global feraiseexcept
+.type   feraiseexcept, @function
+feraiseexcept:
+	mov r4, r0
+	and #0x7c, r0
+	sts fpscr, r4
+	or  r4, r0
+	lds r0, fpscr
+	rts
+	 mov #0, r0
+
+.global fegetenv
+.type   fegetenv, @function
+fegetenv:
+	sts fpscr, r0
+	mov.l r0, @r4
+	rts
+	 mov #0, r0
+
+.global fesetenv
+.type   fesetenv, @function
+fesetenv:
+	mov r4, r0
+	cmp/eq #-1, r0
+	bf 1f
+
+	! the default environment is complicated by the fact that we need to
+	! preserve the current precision bit, which we do not know a priori
+	sts fpscr, r0
+	mov #8, r1
+	swap.w r1, r1
+	bra 2f
+	 and r1, r0
+
+1:	mov.l @r4, r0      ! non-default environment
+2:	lds r0, fpscr
+	rts
+	 mov #0, r0
+
+#endif
libc/musl/src/fenv/x32/fenv.s
@@ -0,0 +1,98 @@
+.global feclearexcept
+.type feclearexcept,@function
+feclearexcept:
+		# maintain exceptions in the sse mxcsr, clear x87 exceptions
+	mov %edi,%ecx
+	and $0x3f,%ecx
+	fnstsw %ax
+	test %eax,%ecx
+	jz 1f
+	fnclex
+1:	stmxcsr -8(%esp)
+	and $0x3f,%eax
+	or %eax,-8(%esp)
+	test %ecx,-8(%esp)
+	jz 1f
+	not %ecx
+	and %ecx,-8(%esp)
+	ldmxcsr -8(%esp)
+1:	xor %eax,%eax
+	ret
+
+.global feraiseexcept
+.type feraiseexcept,@function
+feraiseexcept:
+	and $0x3f,%edi
+	stmxcsr -8(%esp)
+	or %edi,-8(%esp)
+	ldmxcsr -8(%esp)
+	xor %eax,%eax
+	ret
+
+.global __fesetround
+.hidden __fesetround
+.type __fesetround,@function
+__fesetround:
+	push %rax
+	xor %eax,%eax
+	mov %edi,%ecx
+	fnstcw (%esp)
+	andb $0xf3,1(%esp)
+	or %ch,1(%esp)
+	fldcw (%esp)
+	stmxcsr (%esp)
+	shl $3,%ch
+	andb $0x9f,1(%esp)
+	or %ch,1(%esp)
+	ldmxcsr (%esp)
+	pop %rcx
+	ret
+
+.global fegetround
+.type fegetround,@function
+fegetround:
+	push %rax
+	stmxcsr (%esp)
+	pop %rax
+	shr $3,%eax
+	and $0xc00,%eax
+	ret
+
+.global fegetenv
+.type fegetenv,@function
+fegetenv:
+	xor %eax,%eax
+	fnstenv (%edi)
+	stmxcsr 28(%edi)
+	ret
+
+.global fesetenv
+.type fesetenv,@function
+fesetenv:
+	xor %eax,%eax
+	inc %edi
+	jz 1f
+	fldenv -1(%edi)
+	ldmxcsr 27(%edi)
+	ret
+1:	push %rax
+	push %rax
+	pushq $0xffff
+	pushq $0x37f
+	fldenv (%esp)
+	pushq $0x1f80
+	ldmxcsr (%esp)
+	add $40,%esp
+	ret
+
+.global fetestexcept
+.type fetestexcept,@function
+fetestexcept:
+	and $0x3f,%edi
+	push %rax
+	stmxcsr (%esp)
+	pop %rsi
+	fnstsw %ax
+	or %esi,%eax
+	and %edi,%eax
+	ret
libc/musl/src/fenv/x86_64/fenv.s
@@ -0,0 +1,98 @@
+.global feclearexcept
+.type feclearexcept,@function
+feclearexcept:
+		# maintain exceptions in the sse mxcsr, clear x87 exceptions
+	mov %edi,%ecx
+	and $0x3f,%ecx
+	fnstsw %ax
+	test %eax,%ecx
+	jz 1f
+	fnclex
+1:	stmxcsr -8(%rsp)
+	and $0x3f,%eax
+	or %eax,-8(%rsp)
+	test %ecx,-8(%rsp)
+	jz 1f
+	not %ecx
+	and %ecx,-8(%rsp)
+	ldmxcsr -8(%rsp)
+1:	xor %eax,%eax
+	ret
+
+.global feraiseexcept
+.type feraiseexcept,@function
+feraiseexcept:
+	and $0x3f,%edi
+	stmxcsr -8(%rsp)
+	or %edi,-8(%rsp)
+	ldmxcsr -8(%rsp)
+	xor %eax,%eax
+	ret
+
+.global __fesetround
+.hidden __fesetround
+.type __fesetround,@function
+__fesetround:
+	push %rax
+	xor %eax,%eax
+	mov %edi,%ecx
+	fnstcw (%rsp)
+	andb $0xf3,1(%rsp)
+	or %ch,1(%rsp)
+	fldcw (%rsp)
+	stmxcsr (%rsp)
+	shl $3,%ch
+	andb $0x9f,1(%rsp)
+	or %ch,1(%rsp)
+	ldmxcsr (%rsp)
+	pop %rcx
+	ret
+
+.global fegetround
+.type fegetround,@function
+fegetround:
+	push %rax
+	stmxcsr (%rsp)
+	pop %rax
+	shr $3,%eax
+	and $0xc00,%eax
+	ret
+
+.global fegetenv
+.type fegetenv,@function
+fegetenv:
+	xor %eax,%eax
+	fnstenv (%rdi)
+	stmxcsr 28(%rdi)
+	ret
+
+.global fesetenv
+.type fesetenv,@function
+fesetenv:
+	xor %eax,%eax
+	inc %rdi
+	jz 1f
+	fldenv -1(%rdi)
+	ldmxcsr 27(%rdi)
+	ret
+1:	push %rax
+	push %rax
+	pushq $0xffff
+	pushq $0x37f
+	fldenv (%rsp)
+	pushq $0x1f80
+	ldmxcsr (%rsp)
+	add $40,%rsp
+	ret
+
+.global fetestexcept
+.type fetestexcept,@function
+fetestexcept:
+	and $0x3f,%edi
+	push %rax
+	stmxcsr (%rsp)
+	pop %rsi
+	fnstsw %ax
+	or %esi,%eax
+	and %edi,%eax
+	ret
libc/musl/src/fenv/__flt_rounds.c
@@ -0,0 +1,19 @@
+#include <float.h>
+#include <fenv.h>
+
+int __flt_rounds()
+{
+	switch (fegetround()) {
+#ifdef FE_TOWARDZERO
+	case FE_TOWARDZERO: return 0;
+#endif
+	case FE_TONEAREST: return 1;
+#ifdef FE_UPWARD
+	case FE_UPWARD: return 2;
+#endif
+#ifdef FE_DOWNWARD
+	case FE_DOWNWARD: return 3;
+#endif
+	}
+	return -1;
+}
libc/musl/src/fenv/fegetexceptflag.c
@@ -0,0 +1,7 @@
+#include <fenv.h>
+
+int fegetexceptflag(fexcept_t *fp, int mask)
+{
+	*fp = fetestexcept(mask);
+	return 0;
+}
libc/musl/src/fenv/feholdexcept.c
@@ -0,0 +1,8 @@
+#include <fenv.h>
+
+int feholdexcept(fenv_t *envp)
+{
+	fegetenv(envp);
+	feclearexcept(FE_ALL_EXCEPT);
+	return 0;
+}
libc/musl/src/fenv/fenv.c
@@ -0,0 +1,38 @@
+#include <fenv.h>
+
+/* Dummy functions for archs lacking fenv implementation */
+
+int feclearexcept(int mask)
+{
+	return 0;
+}
+
+int feraiseexcept(int mask)
+{
+	return 0;
+}
+
+int fetestexcept(int mask)
+{
+	return 0;
+}
+
+int fegetround(void)
+{
+	return FE_TONEAREST;
+}
+
+int __fesetround(int r)
+{
+	return 0;
+}
+
+int fegetenv(fenv_t *envp)
+{
+	return 0;
+}
+
+int fesetenv(const fenv_t *envp)
+{
+	return 0;
+}
libc/musl/src/fenv/fesetexceptflag.c
@@ -0,0 +1,8 @@
+#include <fenv.h>
+
+int fesetexceptflag(const fexcept_t *fp, int mask)
+{
+	feclearexcept(~*fp & mask);
+	feraiseexcept(*fp & mask);
+	return 0;
+}
libc/musl/src/fenv/fesetround.c
@@ -0,0 +1,23 @@
+#include <fenv.h>
+#include <features.h>
+
+/* __fesetround wrapper for arch independent argument check */
+
+hidden int __fesetround(int);
+
+int fesetround(int r)
+{
+	if (r != FE_TONEAREST
+#ifdef FE_DOWNWARD
+		&& r != FE_DOWNWARD
+#endif
+#ifdef FE_UPWARD
+		&& r != FE_UPWARD
+#endif
+#ifdef FE_TOWARDZERO
+		&& r != FE_TOWARDZERO
+#endif
+	)
+		return -1;
+	return __fesetround(r);
+}
libc/musl/src/fenv/feupdateenv.c
@@ -0,0 +1,9 @@
+#include <fenv.h>
+
+int feupdateenv(const fenv_t *envp)
+{
+	int ex = fetestexcept(FE_ALL_EXCEPT);
+	fesetenv(envp);
+	feraiseexcept(ex);
+	return 0;
+}
libc/musl/src/include/arpa/inet.h
@@ -0,0 +1,8 @@
+#ifndef ARPA_INET_H
+#define ARPA_INET_H
+
+#include_next "arpa/inet.h"
+
+hidden int __inet_aton(const char *, struct in_addr *);
+
+#endif
libc/musl/src/include/sys/auxv.h
@@ -0,0 +1,10 @@
+#ifndef SYS_AUXV_H
+#define SYS_AUXV_H
+
+#include_next "sys/auxv.h"
+
+#include <features.h>
+
+hidden unsigned long __getauxval(unsigned long);
+
+#endif
libc/musl/src/include/sys/mman.h
@@ -0,0 +1,20 @@
+#ifndef SYS_MMAN_H
+#define SYS_MMAN_H
+
+#include_next "sys/mman.h"
+
+hidden void __vm_wait(void);
+hidden void __vm_lock(void);
+hidden void __vm_unlock(void);
+
+hidden void *__mmap(void *, size_t, int, int, int, off_t);
+hidden int __munmap(void *, size_t);
+hidden void *__mremap(void *, size_t, size_t, int, ...);
+hidden int __madvise(void *, size_t, int);
+hidden int __mprotect(void *, size_t, int);
+
+hidden const unsigned char *__map_file(const char *, size_t *);
+
+hidden char *__shm_mapname(const char *, char *);
+
+#endif
libc/musl/src/include/sys/sysinfo.h
@@ -0,0 +1,9 @@
+#ifndef SYS_SYSINFO_H
+#define SYS_SYSINFO_H
+
+#include_next "sys/sysinfo.h"
+#include <features.h>
+
+hidden int __lsysinfo(struct sysinfo *);
+
+#endif
libc/musl/src/include/sys/time.h
@@ -0,0 +1,8 @@
+#ifndef SYS_TIME_H
+#define SYS_TIME_H
+
+#include_next "sys/time.h"
+
+hidden int __futimesat(int, const char *, const struct timeval [2]);
+
+#endif
libc/musl/src/include/crypt.h
@@ -0,0 +1,16 @@
+#ifndef CRYPT_H
+#define CRYPT_H
+
+#include_next "crypt.h"
+
+#include <features.h>
+
+hidden char *__crypt_r(const char *, const char *, struct crypt_data *);
+
+hidden char *__crypt_des(const char *, const char *, char *);
+hidden char *__crypt_md5(const char *, const char *, char *);
+hidden char *__crypt_blowfish(const char *, const char *, char *);
+hidden char *__crypt_sha256(const char *, const char *, char *);
+hidden char *__crypt_sha512(const char *, const char *, char *);
+
+#endif
libc/musl/src/include/errno.h
@@ -0,0 +1,11 @@
+#ifndef ERRNO_H
+#define ERRNO_H
+
+#include_next "errno.h"
+
+hidden int *___errno_location(void);
+
+#undef errno
+#define errno (*___errno_location())
+
+#endif
libc/musl/src/include/langinfo.h
@@ -0,0 +1,8 @@
+#ifndef LANGINFO_H
+#define LANGINFO_H
+
+#include_next "langinfo.h"
+
+char *__nl_langinfo_l(nl_item, locale_t);
+
+#endif
libc/musl/src/include/pthread.h
@@ -0,0 +1,22 @@
+#ifndef PTHREAD_H
+#define PTHREAD_H
+
+#include_next "pthread.h"
+
+hidden int __pthread_once(pthread_once_t *, void (*)(void));
+hidden void __pthread_testcancel(void);
+hidden int __pthread_setcancelstate(int, int *);
+hidden int __pthread_create(pthread_t *restrict, const pthread_attr_t *restrict, void *(*)(void *), void *restrict);
+hidden _Noreturn void __pthread_exit(void *);
+hidden int __pthread_join(pthread_t, void **);
+hidden int __pthread_mutex_lock(pthread_mutex_t *);
+hidden int __pthread_mutex_trylock(pthread_mutex_t *);
+hidden int __pthread_mutex_trylock_owner(pthread_mutex_t *);
+hidden int __pthread_mutex_timedlock(pthread_mutex_t *restrict, const struct timespec *restrict);
+hidden int __pthread_mutex_unlock(pthread_mutex_t *);
+hidden int __private_cond_signal(pthread_cond_t *, int);
+hidden int __pthread_cond_timedwait(pthread_cond_t *restrict, pthread_mutex_t *restrict, const struct timespec *restrict);
+hidden int __pthread_key_create(pthread_key_t *, void (*)(void *));
+hidden int __pthread_key_delete(pthread_key_t);
+
+#endif
libc/musl/src/include/resolv.h
@@ -0,0 +1,12 @@
+#ifndef RESOLV_H
+#define RESOLV_H
+
+#include_next "resolv.h"
+
+hidden int __dn_expand(const unsigned char *, const unsigned char *, const unsigned char *, char *, int);
+
+hidden int __res_mkquery(int, const char *, int, int, const unsigned char *, int, const unsigned char*, unsigned char *, int);
+hidden int __res_send(const unsigned char *, int, unsigned char *, int);
+hidden int __res_msend(int, const unsigned char *const *, const int *, unsigned char *const *, int *, int);
+
+#endif
libc/musl/src/include/signal.h
@@ -0,0 +1,14 @@
+#ifndef SIGNAL_H
+#define SIGNAL_H
+
+#include_next "signal.h"
+
+hidden int __sigaction(int, const struct sigaction *, struct sigaction *);
+
+hidden void __block_all_sigs(void *);
+hidden void __block_app_sigs(void *);
+hidden void __restore_sigs(void *);
+
+hidden void __get_handler_set(sigset_t *);
+
+#endif
libc/musl/src/include/stdio.h
@@ -0,0 +1,18 @@
+#ifndef STDIO_H
+#define STDIO_H
+
+#include_next "stdio.h"
+
+#undef stdin
+#undef stdout
+#undef stderr
+
+extern hidden FILE __stdin_FILE;
+extern hidden FILE __stdout_FILE;
+extern hidden FILE __stderr_FILE;
+
+#define stdin (&__stdin_FILE)
+#define stdout (&__stdout_FILE)
+#define stderr (&__stderr_FILE)
+
+#endif
libc/musl/src/include/stdlib.h
@@ -0,0 +1,12 @@
+#ifndef STDLIB_H
+#define STDLIB_H
+
+#include_next "stdlib.h"
+
+hidden int __putenv(char *, size_t, char *);
+hidden void __env_rm_add(char *, char *);
+hidden int __mkostemps(char *, int, int);
+hidden int __ptsname_r(int, char *, size_t);
+hidden char *__randname(char *);
+
+#endif
libc/musl/src/include/string.h
@@ -0,0 +1,11 @@
+#ifndef STRING_H
+#define STRING_H
+
+#include_next "string.h"
+
+hidden void *__memrchr(const void *, int, size_t);
+hidden char *__stpcpy(char *, const char *);
+hidden char *__stpncpy(char *, const char *, size_t);
+hidden char *__strchrnul(const char *, int);
+
+#endif
libc/musl/src/include/time.h
@@ -0,0 +1,14 @@
+#ifndef TIME_H
+#define TIME_H
+
+#include_next "time.h"
+
+hidden int __clock_gettime(clockid_t, struct timespec *);
+
+hidden char *__asctime_r(const struct tm *, char *);
+hidden struct tm *__gmtime_r(const time_t *restrict, struct tm *restrict);
+hidden struct tm *__localtime_r(const time_t *restrict, struct tm *restrict);
+
+hidden size_t __strftime_l(char *restrict, size_t, const char *restrict, const struct tm *restrict, locale_t);
+
+#endif
libc/musl/src/include/unistd.h
@@ -0,0 +1,13 @@
+#ifndef UNISTD_H
+#define UNISTD_H
+
+#include_next "unistd.h"
+
+extern char **__environ;
+
+hidden int __dup3(int, int, int);
+hidden int __mkostemps(char *, int, int);
+hidden int __execvpe(const char *, char *const *, char *const *);
+hidden int __aio_close(int);
+
+#endif
libc/musl/src/internal/aarch64/syscall.s
@@ -0,0 +1,14 @@
+.global __syscall
+.hidden __syscall
+.type __syscall,%function
+__syscall:
+	uxtw x8,w0
+	mov x0,x1
+	mov x1,x2
+	mov x2,x3
+	mov x3,x4
+	mov x4,x5
+	mov x5,x6
+	mov x6,x7
+	svc 0
+	ret
libc/musl/src/internal/arm/syscall.s
@@ -0,0 +1,15 @@
+.syntax unified
+.global __syscall
+.hidden __syscall
+.type __syscall,%function
+__syscall:
+	mov ip,sp
+	stmfd sp!,{r4,r5,r6,r7}
+	mov r7,r0
+	mov r0,r1
+	mov r1,r2
+	mov r2,r3
+	ldmfd ip,{r3,r4,r5,r6}
+	svc 0
+	ldmfd sp!,{r4,r5,r6,r7}
+	bx lr
libc/musl/src/internal/i386/syscall.s
@@ -0,0 +1,78 @@
+.hidden __sysinfo
+
+# The calling convention for __vsyscall has the syscall number
+# and 5 args arriving as:  eax, edx, ecx, edi, esi, 4(%esp).
+# This ensures that the inline asm in the C code never has to touch
+# ebx or ebp (which are unavailable in PIC and frame-pointer-using
+# code, respectively), and optimizes for size/simplicity in the caller.
+
+.global __vsyscall
+.hidden __vsyscall
+.type __vsyscall,@function
+__vsyscall:
+	push %edi
+	push %ebx
+	mov %edx,%ebx
+	mov %edi,%edx
+	mov 12(%esp),%edi
+	push %eax
+	call 1f
+2:	mov %ebx,%edx
+	pop %ebx
+	pop %ebx
+	pop %edi
+	ret
+
+1:	mov (%esp),%eax
+	add $[__sysinfo-2b],%eax
+	mov (%eax),%eax
+	test %eax,%eax
+	jz 1f
+	push %eax
+	mov 8(%esp),%eax
+	ret                     # tail call to kernel vsyscall entry
+1:	mov 4(%esp),%eax
+	int $128
+	ret
+
+# The __vsyscall6 entry point is used only for 6-argument syscalls.
+# Instead of passing the 5th argument on the stack, a pointer to the
+# 5th and 6th arguments is passed. This is ugly, but there are no
+# register constraints the inline asm could use that would make it
+# possible to pass two arguments on the stack.
+
+.global __vsyscall6
+.hidden __vsyscall6
+.type __vsyscall6,@function
+__vsyscall6:
+	push %ebp
+	push %eax
+	mov 12(%esp), %ebp
+	mov (%ebp), %eax
+	mov 4(%ebp), %ebp
+	push %eax
+	mov 4(%esp),%eax
+	call __vsyscall
+	pop %ebp
+	pop %ebp
+	pop %ebp
+	ret
+
+.global __syscall
+.hidden __syscall
+.type __syscall,@function
+__syscall:
+	lea 24(%esp),%eax
+	push %esi
+	push %edi
+	push %eax
+	mov 16(%esp),%eax
+	mov 20(%esp),%edx
+	mov 24(%esp),%ecx
+	mov 28(%esp),%edi
+	mov 32(%esp),%esi
+	call __vsyscall6
+	pop %edi
+	pop %edi
+	pop %esi
+	ret
libc/musl/src/internal/m68k/syscall.s
@@ -0,0 +1,9 @@
+.global __syscall
+.hidden __syscall
+.type __syscall,%function
+__syscall:
+	movem.l %d2-%d5,-(%sp)
+	movem.l 20(%sp),%d0-%d5/%a0
+	trap #0
+	movem.l (%sp)+,%d2-%d5
+	rts
libc/musl/src/internal/microblaze/syscall.s
@@ -0,0 +1,14 @@
+.global __syscall
+.hidden __syscall
+.type   __syscall,@function
+__syscall:
+	addi    r12, r5, 0              # Save the system call number
+	add     r5, r6, r0              # Shift the arguments, arg1
+	add     r6, r7, r0              # arg2
+	add     r7, r8, r0              # arg3
+	add     r8, r9, r0              # arg4
+	add     r9, r10, r0             # arg5
+	lwi     r10, r1, 28             # Get arg6.
+	brki    r14, 0x8                # syscall
+	rtsd    r15, 8
+	nop
libc/musl/src/internal/mips/syscall.s
@@ -0,0 +1,26 @@
+.set    noreorder
+
+.global __syscall
+.hidden __syscall
+.type   __syscall,@function
+__syscall:
+	move    $2, $4
+	move    $4, $5
+	move    $5, $6
+	move    $6, $7
+	lw      $7, 16($sp)
+	lw      $8, 20($sp)
+	lw      $9, 24($sp)
+	lw      $10,28($sp)
+	subu    $sp, $sp, 32
+	sw      $8, 16($sp)
+	sw      $9, 20($sp)
+	sw      $10,24($sp)
+	sw      $2 ,28($sp)
+	lw      $2, 28($sp)
+	syscall
+	beq     $7, $0, 1f
+	addu    $sp, $sp, 32
+	subu    $2, $0, $2
+1:	jr      $ra
+	nop
libc/musl/src/internal/mips64/syscall.s
@@ -0,0 +1,19 @@
+.set	noreorder
+.global	__syscall
+.hidden	__syscall
+.type	__syscall,@function
+__syscall:
+	move	$2, $4
+	move	$4, $5
+	move	$5, $6
+	move	$6, $7
+	move	$7, $8
+	move	$8, $9
+	move	$9, $10
+	move	$10, $11
+	syscall
+	beq	$7, $0, 1f
+	nop
+	dsubu	$2, $0, $2
+1:	jr	$ra
+	nop
libc/musl/src/internal/mipsn32/syscall.s
@@ -0,0 +1,19 @@
+.set	noreorder
+.global	__syscall
+.hidden	__syscall
+.type	__syscall,@function
+__syscall:
+	move	$2, $4
+	move	$4, $5
+	move	$5, $6
+	move	$6, $7
+	move	$7, $8
+	move	$8, $9
+	move	$9, $10
+	move	$10, $11
+	syscall
+	beq	$7, $0, 1f
+	nop
+	subu	$2, $0, $2
+1:	jr	$ra
+	nop
libc/musl/src/internal/or1k/syscall.s
@@ -0,0 +1,14 @@
+.global __syscall
+.hidden __syscall
+.type   __syscall,@function
+__syscall:
+	l.ori	r11, r3, 0
+	l.lwz	r3, 0(r1)
+	l.lwz	r4, 4(r1)
+	l.lwz	r5, 8(r1)
+	l.lwz	r6, 12(r1)
+	l.lwz	r7, 16(r1)
+	l.lwz	r8, 20(r1)
+	l.sys	1
+	l.jr	r9
+	 l.nop
libc/musl/src/internal/powerpc/syscall.s
@@ -0,0 +1,19 @@
+	.global __syscall
+	.hidden __syscall
+	.type   __syscall,@function
+__syscall:
+	mr      0, 3                  # Save the system call number
+	mr      3, 4                  # Shift the arguments: arg1
+	mr      4, 5                  # arg2
+	mr      5, 6                  # arg3
+	mr      6, 7                  # arg4
+	mr      7, 8                  # arg5
+	mr      8, 9                  # arg6
+	sc
+	bnslr+ # return if not summary overflow
+	#else error:
+	# return negated value.
+	neg 3, 3
+	blr
+	.end    __syscall
+	.size   __syscall, .-__syscall
libc/musl/src/internal/powerpc64/syscall.s
@@ -0,0 +1,17 @@
+	.global __syscall
+	.hidden __syscall
+	.type   __syscall,@function
+__syscall:
+	mr      0, 3                  # Save the system call number
+	mr      3, 4                  # Shift the arguments: arg1
+	mr      4, 5                  # arg2
+	mr      5, 6                  # arg3
+	mr      6, 7                  # arg4
+	mr      7, 8                  # arg5
+	mr      8, 9                  # arg6
+	sc
+	bnslr+       # return if not summary overflow
+	neg     3, 3 # otherwise error: return negated value.
+	blr
+	.end    __syscall
+	.size   __syscall, .-__syscall
libc/musl/src/internal/s390x/syscall.s
@@ -0,0 +1,15 @@
+.global __syscall
+.hidden __syscall
+.type   __syscall, %function
+__syscall:
+	stg %r7, 56(%r15)
+	lgr %r1, %r2
+	lgr %r2, %r3
+	lgr %r3, %r4
+	lgr %r4, %r5
+	lgr %r5, %r6
+	lg  %r6, 160(%r15)
+	lg  %r7, 168(%r15)
+	svc 0
+	lg  %r7, 56(%r15)
+	br  %r14
libc/musl/src/internal/sh/__shcall.c
@@ -0,0 +1,6 @@
+#include <features.h>
+
+hidden int __shcall(void *arg, int (*func)(void *))
+{
+	return func(arg);
+}
libc/musl/src/internal/sh/syscall.s
@@ -0,0 +1,23 @@
+.global __syscall
+.hidden __syscall
+.type   __syscall, @function
+__syscall:
+	! The kernel syscall entry point documents that the trap number indicates
+	! the number of arguments being passed, but it then ignores that information.
+	! Since we do not actually know how many arguments are being passed, we will
+	! say there are six, since that is the maximum we support here.
+	mov r4, r3
+	mov r5, r4
+	mov r6, r5
+	mov r7, r6
+	mov.l @r15, r7
+	mov.l @(4,r15), r0
+	mov.l @(8,r15), r1
+	trapa #31
+	or r0, r0
+	or r0, r0
+	or r0, r0
+	or r0, r0
+	or r0, r0
+	rts
+	 nop
libc/musl/src/internal/x32/syscall.s
@@ -0,0 +1,13 @@
+.global __syscall
+.hidden __syscall
+.type __syscall,@function
+__syscall:
+	movq %rdi,%rax
+	movq %rsi,%rdi
+	movq %rdx,%rsi
+	movq %rcx,%rdx
+	movq %r8,%r10
+	movq %r9,%r8
+	movq 8(%rsp),%r9
+	syscall
+	ret
libc/musl/src/internal/x86_64/syscall.s
@@ -0,0 +1,13 @@
+.global __syscall
+.hidden __syscall
+.type __syscall,@function
+__syscall:
+	movq %rdi,%rax
+	movq %rsi,%rdi
+	movq %rdx,%rsi
+	movq %rcx,%rdx
+	movq %r8,%r10
+	movq %r9,%r8
+	movq 8(%rsp),%r9
+	syscall
+	ret
libc/musl/src/internal/atomic.h
@@ -0,0 +1,318 @@
+#ifndef _ATOMIC_H
+#define _ATOMIC_H
+
+#include <stdint.h>
+
+#include "atomic_arch.h"
+
+#ifdef a_ll
+
+#ifndef a_pre_llsc
+#define a_pre_llsc()
+#endif
+
+#ifndef a_post_llsc
+#define a_post_llsc()
+#endif
+
+#ifndef a_cas
+#define a_cas a_cas
+static inline int a_cas(volatile int *p, int t, int s)
+{
+	int old;
+	a_pre_llsc();
+	do old = a_ll(p);
+	while (old==t && !a_sc(p, s));
+	a_post_llsc();
+	return old;
+}
+#endif
+
+#ifndef a_swap
+#define a_swap a_swap
+static inline int a_swap(volatile int *p, int v)
+{
+	int old;
+	a_pre_llsc();
+	do old = a_ll(p);
+	while (!a_sc(p, v));
+	a_post_llsc();
+	return old;
+}
+#endif
+
+#ifndef a_fetch_add
+#define a_fetch_add a_fetch_add
+static inline int a_fetch_add(volatile int *p, int v)
+{
+	int old;
+	a_pre_llsc();
+	do old = a_ll(p);
+	while (!a_sc(p, (unsigned)old + v));
+	a_post_llsc();
+	return old;
+}
+#endif
+
+#ifndef a_fetch_and
+#define a_fetch_and a_fetch_and
+static inline int a_fetch_and(volatile int *p, int v)
+{
+	int old;
+	a_pre_llsc();
+	do old = a_ll(p);
+	while (!a_sc(p, old & v));
+	a_post_llsc();
+	return old;
+}
+#endif
+
+#ifndef a_fetch_or
+#define a_fetch_or a_fetch_or
+static inline int a_fetch_or(volatile int *p, int v)
+{
+	int old;
+	a_pre_llsc();
+	do old = a_ll(p);
+	while (!a_sc(p, old | v));
+	a_post_llsc();
+	return old;
+}
+#endif
+
+#endif
+
+#ifdef a_ll_p
+
+#ifndef a_cas_p
+#define a_cas_p a_cas_p
+static inline void *a_cas_p(volatile void *p, void *t, void *s)
+{
+	void *old;
+	a_pre_llsc();
+	do old = a_ll_p(p);
+	while (old==t && !a_sc_p(p, s));
+	a_post_llsc();
+	return old;
+}
+#endif
+
+#endif
+
+#ifndef a_cas
+#error missing definition of a_cas
+#endif
+
+#ifndef a_swap
+#define a_swap a_swap
+static inline int a_swap(volatile int *p, int v)
+{
+	int old;
+	do old = *p;
+	while (a_cas(p, old, v) != old);
+	return old;
+}
+#endif
+
+#ifndef a_fetch_add
+#define a_fetch_add a_fetch_add
+static inline int a_fetch_add(volatile int *p, int v)
+{
+	int old;
+	do old = *p;
+	while (a_cas(p, old, (unsigned)old+v) != old);
+	return old;
+}
+#endif
+
+#ifndef a_fetch_and
+#define a_fetch_and a_fetch_and
+static inline int a_fetch_and(volatile int *p, int v)
+{
+	int old;
+	do old = *p;
+	while (a_cas(p, old, old&v) != old);
+	return old;
+}
+#endif
+#ifndef a_fetch_or
+#define a_fetch_or a_fetch_or
+static inline int a_fetch_or(volatile int *p, int v)
+{
+	int old;
+	do old = *p;
+	while (a_cas(p, old, old|v) != old);
+	return old;
+}
+#endif
+
+#ifndef a_and
+#define a_and a_and
+static inline void a_and(volatile int *p, int v)
+{
+	a_fetch_and(p, v);
+}
+#endif
+
+#ifndef a_or
+#define a_or a_or
+static inline void a_or(volatile int *p, int v)
+{
+	a_fetch_or(p, v);
+}
+#endif
+
+#ifndef a_inc
+#define a_inc a_inc
+static inline void a_inc(volatile int *p)
+{
+	a_fetch_add(p, 1);
+}
+#endif
+
+#ifndef a_dec
+#define a_dec a_dec
+static inline void a_dec(volatile int *p)
+{
+	a_fetch_add(p, -1);
+}
+#endif
+
+#ifndef a_store
+#define a_store a_store
+static inline void a_store(volatile int *p, int v)
+{
+#ifdef a_barrier
+	a_barrier();
+	*p = v;
+	a_barrier();
+#else
+	a_swap(p, v);
+#endif
+}
+#endif
+
+#ifndef a_barrier
+#define a_barrier a_barrier
+static void a_barrier()
+{
+	volatile int tmp = 0;
+	a_cas(&tmp, 0, 0);
+}
+#endif
+
+#ifndef a_spin
+#define a_spin a_barrier
+#endif
+
+#ifndef a_and_64
+#define a_and_64 a_and_64
+static inline void a_and_64(volatile uint64_t *p, uint64_t v)
+{
+	union { uint64_t v; uint32_t r[2]; } u = { v };
+	if (u.r[0]+1) a_and((int *)p, u.r[0]);
+	if (u.r[1]+1) a_and((int *)p+1, u.r[1]);
+}
+#endif
+
+#ifndef a_or_64
+#define a_or_64 a_or_64
+static inline void a_or_64(volatile uint64_t *p, uint64_t v)
+{
+	union { uint64_t v; uint32_t r[2]; } u = { v };
+	if (u.r[0]) a_or((int *)p, u.r[0]);
+	if (u.r[1]) a_or((int *)p+1, u.r[1]);
+}
+#endif
+
+#ifndef a_cas_p
+typedef char a_cas_p_undefined_but_pointer_not_32bit[-sizeof(char) == 0xffffffff ? 1 : -1];
+#define a_cas_p a_cas_p
+static inline void *a_cas_p(volatile void *p, void *t, void *s)
+{
+	return (void *)a_cas((volatile int *)p, (int)t, (int)s);
+}
+#endif
+
+#ifndef a_or_l
+#define a_or_l a_or_l
+static inline void a_or_l(volatile void *p, long v)
+{
+	if (sizeof(long) == sizeof(int)) a_or(p, v);
+	else a_or_64(p, v);
+}
+#endif
+
+#ifndef a_crash
+#define a_crash a_crash
+static inline void a_crash()
+{
+	*(volatile char *)0=0;
+}
+#endif
+
+#ifndef a_ctz_32
+#define a_ctz_32 a_ctz_32
+static inline int a_ctz_32(uint32_t x)
+{
+#ifdef a_clz_32
+	return 31-a_clz_32(x&-x);
+#else
+	static const char debruijn32[32] = {
+		0, 1, 23, 2, 29, 24, 19, 3, 30, 27, 25, 11, 20, 8, 4, 13,
+		31, 22, 28, 18, 26, 10, 7, 12, 21, 17, 9, 6, 16, 5, 15, 14
+	};
+	return debruijn32[(x&-x)*0x076be629 >> 27];
+#endif
+}
+#endif
+
+#ifndef a_ctz_64
+#define a_ctz_64 a_ctz_64
+static inline int a_ctz_64(uint64_t x)
+{
+	static const char debruijn64[64] = {
+		0, 1, 2, 53, 3, 7, 54, 27, 4, 38, 41, 8, 34, 55, 48, 28,
+		62, 5, 39, 46, 44, 42, 22, 9, 24, 35, 59, 56, 49, 18, 29, 11,
+		63, 52, 6, 26, 37, 40, 33, 47, 61, 45, 43, 21, 23, 58, 17, 10,
+		51, 25, 36, 32, 60, 20, 57, 16, 50, 31, 19, 15, 30, 14, 13, 12
+	};
+	if (sizeof(long) < 8) {
+		uint32_t y = x;
+		if (!y) {
+			y = x>>32;
+			return 32 + a_ctz_32(y);
+		}
+		return a_ctz_32(y);
+	}
+	return debruijn64[(x&-x)*0x022fdd63cc95386dull >> 58];
+}
+#endif
+
+static inline int a_ctz_l(unsigned long x)
+{
+	return (sizeof(long) < 8) ? a_ctz_32(x) : a_ctz_64(x);
+}
+
+#ifndef a_clz_64
+#define a_clz_64 a_clz_64
+static inline int a_clz_64(uint64_t x)
+{
+#ifdef a_clz_32
+	if (x>>32)
+		return a_clz_32(x>>32);
+	return a_clz_32(x) + 32;
+#else
+	uint32_t y;
+	int r;
+	if (x>>32) y=x>>32, r=0; else y=x, r=32;
+	if (y>>16) y>>=16; else r |= 16;
+	if (y>>8) y>>=8; else r |= 8;
+	if (y>>4) y>>=4; else r |= 4;
+	if (y>>2) y>>=2; else r |= 2;
+	return r | !(y>>1);
+#endif
+}
+#endif
+
+#endif
libc/musl/src/internal/dynlink.h
@@ -0,0 +1,108 @@
+#ifndef _INTERNAL_RELOC_H
+#define _INTERNAL_RELOC_H
+
+#include <features.h>
+#include <elf.h>
+#include <stdint.h>
+#include <stddef.h>
+#include <stdarg.h>
+
+#if UINTPTR_MAX == 0xffffffff
+typedef Elf32_Ehdr Ehdr;
+typedef Elf32_Phdr Phdr;
+typedef Elf32_Sym Sym;
+#define R_TYPE(x) ((x)&255)
+#define R_SYM(x) ((x)>>8)
+#define R_INFO ELF32_R_INFO
+#else
+typedef Elf64_Ehdr Ehdr;
+typedef Elf64_Phdr Phdr;
+typedef Elf64_Sym Sym;
+#define R_TYPE(x) ((x)&0x7fffffff)
+#define R_SYM(x) ((x)>>32)
+#define R_INFO ELF64_R_INFO
+#endif
+
+/* These enum constants provide unmatchable default values for
+ * any relocation type the arch does not use. */
+enum {
+	REL_NONE = 0,
+	REL_SYMBOLIC = -100,
+	REL_GOT,
+	REL_PLT,
+	REL_RELATIVE,
+	REL_OFFSET,
+	REL_OFFSET32,
+	REL_COPY,
+	REL_SYM_OR_REL,
+	REL_DTPMOD,
+	REL_DTPOFF,
+	REL_TPOFF,
+	REL_TPOFF_NEG,
+	REL_TLSDESC,
+	REL_FUNCDESC,
+	REL_FUNCDESC_VAL,
+};
+
+struct fdpic_loadseg {
+	uintptr_t addr, p_vaddr, p_memsz;
+};
+
+struct fdpic_loadmap {
+	unsigned short version, nsegs;
+	struct fdpic_loadseg segs[];
+};
+
+struct fdpic_dummy_loadmap {
+	unsigned short version, nsegs;
+	struct fdpic_loadseg segs[1];
+};
+
+#include "reloc.h"
+
+#ifndef FDPIC_CONSTDISP_FLAG
+#define FDPIC_CONSTDISP_FLAG 0
+#endif
+
+#ifndef DL_FDPIC
+#define DL_FDPIC 0
+#endif
+
+#ifndef DL_NOMMU_SUPPORT
+#define DL_NOMMU_SUPPORT 0
+#endif
+
+#if !DL_FDPIC
+#define IS_RELATIVE(x,s) ( \
+	(R_TYPE(x) == REL_RELATIVE) || \
+	(R_TYPE(x) == REL_SYM_OR_REL && !R_SYM(x)) )
+#else
+#define IS_RELATIVE(x,s) ( ( \
+	(R_TYPE(x) == REL_FUNCDESC_VAL) || \
+	(R_TYPE(x) == REL_SYMBOLIC) ) \
+	&& (((s)[R_SYM(x)].st_info & 0xf) == STT_SECTION) )
+#endif
+
+#ifndef NEED_MIPS_GOT_RELOCS
+#define NEED_MIPS_GOT_RELOCS 0
+#endif
+
+#ifndef DT_DEBUG_INDIRECT
+#define DT_DEBUG_INDIRECT 0
+#endif
+
+#define AUX_CNT 32
+#define DYN_CNT 32
+
+typedef void (*stage2_func)(unsigned char *, size_t *);
+typedef _Noreturn void (*stage3_func)(size_t *);
+
+hidden void *__dlsym(void *restrict, const char *restrict, void *restrict);
+
+hidden void __dl_seterr(const char *, ...);
+hidden int __dl_invalid_handle(void *);
+hidden void __dl_vseterr(const char *, va_list);
+
+hidden ptrdiff_t __tlsdesc_static(), __tlsdesc_dynamic();
+
+#endif
libc/musl/src/internal/fdpic_crt.h
@@ -0,0 +1,28 @@
+#include <stdint.h>
+#include <features.h>
+
+hidden void *__fdpic_fixup(void *map, uintptr_t *a, uintptr_t *z)
+{
+	/* If map is a null pointer, the program was loaded by a
+	 * non-FDPIC-aware ELF loader, and fixups are not needed,
+	 * but the value for the GOT pointer is. */
+	if (!map) return (void *)z[-1];
+
+	struct {
+		unsigned short version, nsegs;
+		struct fdpic_loadseg {
+			uintptr_t addr, p_vaddr, p_memsz;
+		} segs[];
+	} *lm = map;
+	int nsegs = lm->nsegs, rseg = 0, vseg = 0;
+	for (;;) {
+		while (*a-lm->segs[rseg].p_vaddr >= lm->segs[rseg].p_memsz)
+			if (++rseg == nsegs) rseg = 0;
+		uintptr_t *r = (uintptr_t *)
+			(*a + lm->segs[rseg].addr - lm->segs[rseg].p_vaddr);
+		if (++a == z) return r;
+		while (*r-lm->segs[vseg].p_vaddr >= lm->segs[vseg].p_memsz)
+			if (++vseg == nsegs) vseg = 0;
+		*r += lm->segs[vseg].addr - lm->segs[vseg].p_vaddr;
+	}
+}
libc/musl/src/internal/floatscan.c
@@ -0,0 +1,510 @@
+#include <stdint.h>
+#include <stdio.h>
+#include <math.h>
+#include <float.h>
+#include <limits.h>
+#include <errno.h>
+#include <ctype.h>
+
+#include "shgetc.h"
+#include "floatscan.h"
+
+#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024
+
+#define LD_B1B_DIG 2
+#define LD_B1B_MAX 9007199, 254740991
+#define KMAX 128
+
+#elif LDBL_MANT_DIG == 64 && LDBL_MAX_EXP == 16384
+
+#define LD_B1B_DIG 3
+#define LD_B1B_MAX 18, 446744073, 709551615
+#define KMAX 2048
+
+#elif LDBL_MANT_DIG == 113 && LDBL_MAX_EXP == 16384
+
+#define LD_B1B_DIG 4
+#define LD_B1B_MAX 10384593, 717069655, 257060992, 658440191
+#define KMAX 2048
+
+#else
+#error Unsupported long double representation
+#endif
+
+#define MASK (KMAX-1)
+
+#define CONCAT2(x,y) x ## y
+#define CONCAT(x,y) CONCAT2(x,y)
+
+static long long scanexp(FILE *f, int pok)
+{
+	int c;
+	int x;
+	long long y;
+	int neg = 0;
+	
+	c = shgetc(f);
+	if (c=='+' || c=='-') {
+		neg = (c=='-');
+		c = shgetc(f);
+		if (c-'0'>=10U && pok) shunget(f);
+	}
+	if (c-'0'>=10U) {
+		shunget(f);
+		return LLONG_MIN;
+	}
+	for (x=0; c-'0'<10U && x<INT_MAX/10; c = shgetc(f))
+		x = 10*x + c-'0';
+	for (y=x; c-'0'<10U && y<LLONG_MAX/100; c = shgetc(f))
+		y = 10*y + c-'0';
+	for (; c-'0'<10U; c = shgetc(f));
+	shunget(f);
+	return neg ? -y : y;
+}
+
+
+static long double decfloat(FILE *f, int c, int bits, int emin, int sign, int pok)
+{
+	uint32_t x[KMAX];
+	static const uint32_t th[] = { LD_B1B_MAX };
+	int i, j, k, a, z;
+	long long lrp=0, dc=0;
+	long long e10=0;
+	int lnz = 0;
+	int gotdig = 0, gotrad = 0;
+	int rp;
+	int e2;
+	int emax = -emin-bits+3;
+	int denormal = 0;
+	long double y;
+	long double frac=0;
+	long double bias=0;
+	static const int p10s[] = { 10, 100, 1000, 10000,
+		100000, 1000000, 10000000, 100000000 };
+
+	j=0;
+	k=0;
+
+	/* Don't let leading zeros consume buffer space */
+	for (; c=='0'; c = shgetc(f)) gotdig=1;
+	if (c=='.') {
+		gotrad = 1;
+		for (c = shgetc(f); c=='0'; c = shgetc(f)) gotdig=1, lrp--;
+	}
+
+	x[0] = 0;
+	for (; c-'0'<10U || c=='.'; c = shgetc(f)) {
+		if (c == '.') {
+			if (gotrad) break;
+			gotrad = 1;
+			lrp = dc;
+		} else if (k < KMAX-3) {
+			dc++;
+			if (c!='0') lnz = dc;
+			if (j) x[k] = x[k]*10 + c-'0';
+			else x[k] = c-'0';
+			if (++j==9) {
+				k++;
+				j=0;
+			}
+			gotdig=1;
+		} else {
+			dc++;
+			if (c!='0') {
+				lnz = (KMAX-4)*9;
+				x[KMAX-4] |= 1;
+			}
+		}
+	}
+	if (!gotrad) lrp=dc;
+
+	if (gotdig && (c|32)=='e') {
+		e10 = scanexp(f, pok);
+		if (e10 == LLONG_MIN) {
+			if (pok) {
+				shunget(f);
+			} else {
+				shlim(f, 0);
+				return 0;
+			}
+			e10 = 0;
+		}
+		lrp += e10;
+	} else if (c>=0) {
+		shunget(f);
+	}
+	if (!gotdig) {
+		errno = EINVAL;
+		shlim(f, 0);
+		return 0;
+	}
+
+	/* Handle zero specially to avoid nasty special cases later */
+	if (!x[0]) return sign * 0.0;
+
+	/* Optimize small integers (w/no exponent) and over/under-flow */
+	if (lrp==dc && dc<10 && (bits>30 || x[0]>>bits==0))
+		return sign * (long double)x[0];
+	if (lrp > -emin/2) {
+		errno = ERANGE;
+		return sign * LDBL_MAX * LDBL_MAX;
+	}
+	if (lrp < emin-2*LDBL_MANT_DIG) {
+		errno = ERANGE;
+		return sign * LDBL_MIN * LDBL_MIN;
+	}
+
+	/* Align incomplete final B1B digit */
+	if (j) {
+		for (; j<9; j++) x[k]*=10;
+		k++;
+		j=0;
+	}
+
+	a = 0;
+	z = k;
+	e2 = 0;
+	rp = lrp;
+
+	/* Optimize small to mid-size integers (even in exp. notation) */
+	if (lnz<9 && lnz<=rp && rp < 18) {
+		if (rp == 9) return sign * (long double)x[0];
+		if (rp < 9) return sign * (long double)x[0] / p10s[8-rp];
+		int bitlim = bits-3*(int)(rp-9);
+		if (bitlim>30 || x[0]>>bitlim==0)
+			return sign * (long double)x[0] * p10s[rp-10];
+	}
+
+	/* Drop trailing zeros */
+	for (; !x[z-1]; z--);
+
+	/* Align radix point to B1B digit boundary */
+	if (rp % 9) {
+		int rpm9 = rp>=0 ? rp%9 : rp%9+9;
+		int p10 = p10s[8-rpm9];
+		uint32_t carry = 0;
+		for (k=a; k!=z; k++) {
+			uint32_t tmp = x[k] % p10;
+			x[k] = x[k]/p10 + carry;
+			carry = 1000000000/p10 * tmp;
+			if (k==a && !x[k]) {
+				a = (a+1 & MASK);
+				rp -= 9;
+			}
+		}
+		if (carry) x[z++] = carry;
+		rp += 9-rpm9;
+	}
+
+	/* Upscale until desired number of bits are left of radix point */
+	while (rp < 9*LD_B1B_DIG || (rp == 9*LD_B1B_DIG && x[a]<th[0])) {
+		uint32_t carry = 0;
+		e2 -= 29;
+		for (k=(z-1 & MASK); ; k=(k-1 & MASK)) {
+			uint64_t tmp = ((uint64_t)x[k] << 29) + carry;
+			if (tmp > 1000000000) {
+				carry = tmp / 1000000000;
+				x[k] = tmp % 1000000000;
+			} else {
+				carry = 0;
+				x[k] = tmp;
+			}
+			if (k==(z-1 & MASK) && k!=a && !x[k]) z = k;
+			if (k==a) break;
+		}
+		if (carry) {
+			rp += 9;
+			a = (a-1 & MASK);
+			if (a == z) {
+				z = (z-1 & MASK);
+				x[z-1 & MASK] |= x[z];
+			}
+			x[a] = carry;
+		}
+	}
+
+	/* Downscale until exactly number of bits are left of radix point */
+	for (;;) {
+		uint32_t carry = 0;
+		int sh = 1;
+		for (i=0; i<LD_B1B_DIG; i++) {
+			k = (a+i & MASK);
+			if (k == z || x[k] < th[i]) {
+				i=LD_B1B_DIG;
+				break;
+			}
+			if (x[a+i & MASK] > th[i]) break;
+		}
+		if (i==LD_B1B_DIG && rp==9*LD_B1B_DIG) break;
+		/* FIXME: find a way to compute optimal sh */
+		if (rp > 9+9*LD_B1B_DIG) sh = 9;
+		e2 += sh;
+		for (k=a; k!=z; k=(k+1 & MASK)) {
+			uint32_t tmp = x[k] & (1<<sh)-1;
+			x[k] = (x[k]>>sh) + carry;
+			carry = (1000000000>>sh) * tmp;
+			if (k==a && !x[k]) {
+				a = (a+1 & MASK);
+				i--;
+				rp -= 9;
+			}
+		}
+		if (carry) {
+			if ((z+1 & MASK) != a) {
+				x[z] = carry;
+				z = (z+1 & MASK);
+			} else x[z-1 & MASK] |= 1;
+		}
+	}
+
+	/* Assemble desired bits into floating point variable */
+	for (y=i=0; i<LD_B1B_DIG; i++) {
+		if ((a+i & MASK)==z) x[(z=(z+1 & MASK))-1] = 0;
+		y = 1000000000.0L * y + x[a+i & MASK];
+	}
+
+	y *= sign;
+
+	/* Limit precision for denormal results */
+	if (bits > LDBL_MANT_DIG+e2-emin) {
+		bits = LDBL_MANT_DIG+e2-emin;
+		if (bits<0) bits=0;
+		denormal = 1;
+	}
+
+	/* Calculate bias term to force rounding, move out lower bits */
+	if (bits < LDBL_MANT_DIG) {
+		bias = copysignl(scalbn(1, 2*LDBL_MANT_DIG-bits-1), y);
+		frac = fmodl(y, scalbn(1, LDBL_MANT_DIG-bits));
+		y -= frac;
+		y += bias;
+	}
+
+	/* Process tail of decimal input so it can affect rounding */
+	if ((a+i & MASK) != z) {
+		uint32_t t = x[a+i & MASK];
+		if (t < 500000000 && (t || (a+i+1 & MASK) != z))
+			frac += 0.25*sign;
+		else if (t > 500000000)
+			frac += 0.75*sign;
+		else if (t == 500000000) {
+			if ((a+i+1 & MASK) == z)
+				frac += 0.5*sign;
+			else
+				frac += 0.75*sign;
+		}
+		if (LDBL_MANT_DIG-bits >= 2 && !fmodl(frac, 1))
+			frac++;
+	}
+
+	y += frac;
+	y -= bias;
+
+	if ((e2+LDBL_MANT_DIG & INT_MAX) > emax-5) {
+		if (fabs(y) >= CONCAT(0x1p, LDBL_MANT_DIG)) {
+			if (denormal && bits==LDBL_MANT_DIG+e2-emin)
+				denormal = 0;
+			y *= 0.5;
+			e2++;
+		}
+		if (e2+LDBL_MANT_DIG>emax || (denormal && frac))
+			errno = ERANGE;
+	}
+
+	return scalbnl(y, e2);
+}
+
+static long double hexfloat(FILE *f, int bits, int emin, int sign, int pok)
+{
+	uint32_t x = 0;
+	long double y = 0;
+	long double scale = 1;
+	long double bias = 0;
+	int gottail = 0, gotrad = 0, gotdig = 0;
+	long long rp = 0;
+	long long dc = 0;
+	long long e2 = 0;
+	int d;
+	int c;
+
+	c = shgetc(f);
+
+	/* Skip leading zeros */
+	for (; c=='0'; c = shgetc(f)) gotdig = 1;
+
+	if (c=='.') {
+		gotrad = 1;
+		c = shgetc(f);
+		/* Count zeros after the radix point before significand */
+		for (rp=0; c=='0'; c = shgetc(f), rp--) gotdig = 1;
+	}
+
+	for (; c-'0'<10U || (c|32)-'a'<6U || c=='.'; c = shgetc(f)) {
+		if (c=='.') {
+			if (gotrad) break;
+			rp = dc;
+			gotrad = 1;
+		} else {
+			gotdig = 1;
+			if (c > '9') d = (c|32)+10-'a';
+			else d = c-'0';
+			if (dc<8) {
+				x = x*16 + d;
+			} else if (dc < LDBL_MANT_DIG/4+1) {
+				y += d*(scale/=16);
+			} else if (d && !gottail) {
+				y += 0.5*scale;
+				gottail = 1;
+			}
+			dc++;
+		}
+	}
+	if (!gotdig) {
+		shunget(f);
+		if (pok) {
+			shunget(f);
+			if (gotrad) shunget(f);
+		} else {
+			shlim(f, 0);
+		}
+		return sign * 0.0;
+	}
+	if (!gotrad) rp = dc;
+	while (dc<8) x *= 16, dc++;
+	if ((c|32)=='p') {
+		e2 = scanexp(f, pok);
+		if (e2 == LLONG_MIN) {
+			if (pok) {
+				shunget(f);
+			} else {
+				shlim(f, 0);
+				return 0;
+			}
+			e2 = 0;
+		}
+	} else {
+		shunget(f);
+	}
+	e2 += 4*rp - 32;
+
+	if (!x) return sign * 0.0;
+	if (e2 > -emin) {
+		errno = ERANGE;
+		return sign * LDBL_MAX * LDBL_MAX;
+	}
+	if (e2 < emin-2*LDBL_MANT_DIG) {
+		errno = ERANGE;
+		return sign * LDBL_MIN * LDBL_MIN;
+	}
+
+	while (x < 0x80000000) {
+		if (y>=0.5) {
+			x += x + 1;
+			y += y - 1;
+		} else {
+			x += x;
+			y += y;
+		}
+		e2--;
+	}
+
+	if (bits > 32+e2-emin) {
+		bits = 32+e2-emin;
+		if (bits<0) bits=0;
+	}
+
+	if (bits < LDBL_MANT_DIG)
+		bias = copysignl(scalbn(1, 32+LDBL_MANT_DIG-bits-1), sign);
+
+	if (bits<32 && y && !(x&1)) x++, y=0;
+
+	y = bias + sign*(long double)x + sign*y;
+	y -= bias;
+
+	if (!y) errno = ERANGE;
+
+	return scalbnl(y, e2);
+}
+
+long double __floatscan(FILE *f, int prec, int pok)
+{
+	int sign = 1;
+	size_t i;
+	int bits;
+	int emin;
+	int c;
+
+	switch (prec) {
+	case 0:
+		bits = FLT_MANT_DIG;
+		emin = FLT_MIN_EXP-bits;
+		break;
+	case 1:
+		bits = DBL_MANT_DIG;
+		emin = DBL_MIN_EXP-bits;
+		break;
+	case 2:
+		bits = LDBL_MANT_DIG;
+		emin = LDBL_MIN_EXP-bits;
+		break;
+	default:
+		return 0;
+	}
+
+	while (isspace((c=shgetc(f))));
+
+	if (c=='+' || c=='-') {
+		sign -= 2*(c=='-');
+		c = shgetc(f);
+	}
+
+	for (i=0; i<8 && (c|32)=="infinity"[i]; i++)
+		if (i<7) c = shgetc(f);
+	if (i==3 || i==8 || (i>3 && pok)) {
+		if (i!=8) {
+			shunget(f);
+			if (pok) for (; i>3; i--) shunget(f);
+		}
+		return sign * INFINITY;
+	}
+	if (!i) for (i=0; i<3 && (c|32)=="nan"[i]; i++)
+		if (i<2) c = shgetc(f);
+	if (i==3) {
+		if (shgetc(f) != '(') {
+			shunget(f);
+			return NAN;
+		}
+		for (i=1; ; i++) {
+			c = shgetc(f);
+			if (c-'0'<10U || c-'A'<26U || c-'a'<26U || c=='_')
+				continue;
+			if (c==')') return NAN;
+			shunget(f);
+			if (!pok) {
+				errno = EINVAL;
+				shlim(f, 0);
+				return 0;
+			}
+			while (i--) shunget(f);
+			return NAN;
+		}
+		return NAN;
+	}
+
+	if (i) {
+		shunget(f);
+		errno = EINVAL;
+		shlim(f, 0);
+		return 0;
+	}
+
+	if (c=='0') {
+		c = shgetc(f);
+		if ((c|32) == 'x')
+			return hexfloat(f, bits, emin, sign, pok);
+		shunget(f);
+		c = '0';
+	}
+
+	return decfloat(f, c, bits, emin, sign, pok);
+}
libc/musl/src/internal/floatscan.h
@@ -0,0 +1,8 @@
+#ifndef FLOATSCAN_H
+#define FLOATSCAN_H
+
+#include <stdio.h>
+
+hidden long double __floatscan(FILE *, int, int);
+
+#endif
libc/musl/src/internal/futex.h
@@ -0,0 +1,19 @@
+#ifndef _INTERNAL_FUTEX_H
+#define _INTERNAL_FUTEX_H
+
+#define FUTEX_WAIT		0
+#define FUTEX_WAKE		1
+#define FUTEX_FD		2
+#define FUTEX_REQUEUE		3
+#define FUTEX_CMP_REQUEUE	4
+#define FUTEX_WAKE_OP		5
+#define FUTEX_LOCK_PI		6
+#define FUTEX_UNLOCK_PI		7
+#define FUTEX_TRYLOCK_PI	8
+#define FUTEX_WAIT_BITSET	9
+
+#define FUTEX_PRIVATE 128
+
+#define FUTEX_CLOCK_REALTIME 256
+
+#endif
libc/musl/src/internal/intscan.c
@@ -0,0 +1,100 @@
+#include <limits.h>
+#include <errno.h>
+#include <ctype.h>
+#include "shgetc.h"
+
+/* Lookup table for digit values. -1==255>=36 -> invalid */
+static const unsigned char table[] = { -1,
+-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,-1,-1,-1,-1,-1,-1,
+-1,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,
+25,26,27,28,29,30,31,32,33,34,35,-1,-1,-1,-1,-1,
+-1,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,
+25,26,27,28,29,30,31,32,33,34,35,-1,-1,-1,-1,-1,
+-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+};
+
+unsigned long long __intscan(FILE *f, unsigned base, int pok, unsigned long long lim)
+{
+	const unsigned char *val = table+1;
+	int c, neg=0;
+	unsigned x;
+	unsigned long long y;
+	if (base > 36 || base == 1) {
+		errno = EINVAL;
+		return 0;
+	}
+	while (isspace((c=shgetc(f))));
+	if (c=='+' || c=='-') {
+		neg = -(c=='-');
+		c = shgetc(f);
+	}
+	if ((base == 0 || base == 16) && c=='0') {
+		c = shgetc(f);
+		if ((c|32)=='x') {
+			c = shgetc(f);
+			if (val[c]>=16) {
+				shunget(f);
+				if (pok) shunget(f);
+				else shlim(f, 0);
+				return 0;
+			}
+			base = 16;
+		} else if (base == 0) {
+			base = 8;
+		}
+	} else {
+		if (base == 0) base = 10;
+		if (val[c] >= base) {
+			shunget(f);
+			shlim(f, 0);
+			errno = EINVAL;
+			return 0;
+		}
+	}
+	if (base == 10) {
+		for (x=0; c-'0'<10U && x<=UINT_MAX/10-1; c=shgetc(f))
+			x = x*10 + (c-'0');
+		for (y=x; c-'0'<10U && y<=ULLONG_MAX/10 && 10*y<=ULLONG_MAX-(c-'0'); c=shgetc(f))
+			y = y*10 + (c-'0');
+		if (c-'0'>=10U) goto done;
+	} else if (!(base & base-1)) {
+		int bs = "\0\1\2\4\7\3\6\5"[(0x17*base)>>5&7];
+		for (x=0; val[c]<base && x<=UINT_MAX/32; c=shgetc(f))
+			x = x<<bs | val[c];
+		for (y=x; val[c]<base && y<=ULLONG_MAX>>bs; c=shgetc(f))
+			y = y<<bs | val[c];
+	} else {
+		for (x=0; val[c]<base && x<=UINT_MAX/36-1; c=shgetc(f))
+			x = x*base + val[c];
+		for (y=x; val[c]<base && y<=ULLONG_MAX/base && base*y<=ULLONG_MAX-val[c]; c=shgetc(f))
+			y = y*base + val[c];
+	}
+	if (val[c]<base) {
+		for (; val[c]<base; c=shgetc(f));
+		errno = ERANGE;
+		y = lim;
+		if (lim&1) neg = 0;
+	}
+done:
+	shunget(f);
+	if (y>=lim) {
+		if (!(lim&1) && !neg) {
+			errno = ERANGE;
+			return lim-1;
+		} else if (y>lim) {
+			errno = ERANGE;
+			return lim;
+		}
+	}
+	return (y^neg)-neg;
+}
libc/musl/src/internal/intscan.h
@@ -0,0 +1,8 @@
+#ifndef INTSCAN_H
+#define INTSCAN_H
+
+#include <stdio.h>
+
+hidden unsigned long long __intscan(FILE *, unsigned, int, unsigned long long);
+
+#endif
libc/musl/src/internal/ksigaction.h
@@ -0,0 +1,13 @@
+#include <features.h>
+
+/* This is the structure used for the rt_sigaction syscall on most archs,
+ * but it can be overridden by a file with the same name in the top-level
+ * arch dir for a given arch, if necessary. */
+struct k_sigaction {
+	void (*handler)(int);
+	unsigned long flags;
+	void (*restorer)(void);
+	unsigned mask[2];
+};
+
+hidden void __restore(), __restore_rt();
libc/musl/src/internal/libc.c
@@ -0,0 +1,10 @@
+#include "libc.h"
+
+struct __libc __libc;
+
+size_t __hwcap;
+size_t __sysinfo;
+char *__progname=0, *__progname_full=0;
+
+weak_alias(__progname, program_invocation_short_name);
+weak_alias(__progname_full, program_invocation_name);
libc/musl/src/internal/libm.h
@@ -0,0 +1,199 @@
+/* origin: FreeBSD /usr/src/lib/msun/src/math_private.h */
+/*
+ * ====================================================
+ * 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.
+ * ====================================================
+ */
+
+#ifndef _LIBM_H
+#define _LIBM_H
+
+#include <stdint.h>
+#include <float.h>
+#include <math.h>
+#include <complex.h>
+#include <endian.h>
+
+#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024
+#elif LDBL_MANT_DIG == 64 && LDBL_MAX_EXP == 16384 && __BYTE_ORDER == __LITTLE_ENDIAN
+union ldshape {
+	long double f;
+	struct {
+		uint64_t m;
+		uint16_t se;
+	} i;
+};
+#elif LDBL_MANT_DIG == 64 && LDBL_MAX_EXP == 16384 && __BYTE_ORDER == __BIG_ENDIAN
+/* This is the m68k variant of 80-bit long double, and this definition only works
+ * on archs where the alignment requirement of uint64_t is <= 4. */
+union ldshape {
+	long double f;
+	struct {
+		uint16_t se;
+		uint16_t pad;
+		uint64_t m;
+	} i;
+};
+#elif LDBL_MANT_DIG == 113 && LDBL_MAX_EXP == 16384 && __BYTE_ORDER == __LITTLE_ENDIAN
+union ldshape {
+	long double f;
+	struct {
+		uint64_t lo;
+		uint32_t mid;
+		uint16_t top;
+		uint16_t se;
+	} i;
+	struct {
+		uint64_t lo;
+		uint64_t hi;
+	} i2;
+};
+#elif LDBL_MANT_DIG == 113 && LDBL_MAX_EXP == 16384 && __BYTE_ORDER == __BIG_ENDIAN
+union ldshape {
+	long double f;
+	struct {
+		uint16_t se;
+		uint16_t top;
+		uint32_t mid;
+		uint64_t lo;
+	} i;
+	struct {
+		uint64_t hi;
+		uint64_t lo;
+	} i2;
+};
+#else
+#error Unsupported long double representation
+#endif
+
+#define FORCE_EVAL(x) do {                        \
+	if (sizeof(x) == sizeof(float)) {         \
+		volatile float __x;               \
+		__x = (x);                        \
+	} else if (sizeof(x) == sizeof(double)) { \
+		volatile double __x;              \
+		__x = (x);                        \
+	} else {                                  \
+		volatile long double __x;         \
+		__x = (x);                        \
+	}                                         \
+} while(0)
+
+/* Get two 32 bit ints from a double.  */
+#define EXTRACT_WORDS(hi,lo,d)                    \
+do {                                              \
+  union {double f; uint64_t i;} __u;              \
+  __u.f = (d);                                    \
+  (hi) = __u.i >> 32;                             \
+  (lo) = (uint32_t)__u.i;                         \
+} while (0)
+
+/* Get the more significant 32 bit int from a double.  */
+#define GET_HIGH_WORD(hi,d)                       \
+do {                                              \
+  union {double f; uint64_t i;} __u;              \
+  __u.f = (d);                                    \
+  (hi) = __u.i >> 32;                             \
+} while (0)
+
+/* Get the less significant 32 bit int from a double.  */
+#define GET_LOW_WORD(lo,d)                        \
+do {                                              \
+  union {double f; uint64_t i;} __u;              \
+  __u.f = (d);                                    \
+  (lo) = (uint32_t)__u.i;                         \
+} while (0)
+
+/* Set a double from two 32 bit ints.  */
+#define INSERT_WORDS(d,hi,lo)                     \
+do {                                              \
+  union {double f; uint64_t i;} __u;              \
+  __u.i = ((uint64_t)(hi)<<32) | (uint32_t)(lo);  \
+  (d) = __u.f;                                    \
+} while (0)
+
+/* Set the more significant 32 bits of a double from an int.  */
+#define SET_HIGH_WORD(d,hi)                       \
+do {                                              \
+  union {double f; uint64_t i;} __u;              \
+  __u.f = (d);                                    \
+  __u.i &= 0xffffffff;                            \
+  __u.i |= (uint64_t)(hi) << 32;                  \
+  (d) = __u.f;                                    \
+} while (0)
+
+/* Set the less significant 32 bits of a double from an int.  */
+#define SET_LOW_WORD(d,lo)                        \
+do {                                              \
+  union {double f; uint64_t i;} __u;              \
+  __u.f = (d);                                    \
+  __u.i &= 0xffffffff00000000ull;                 \
+  __u.i |= (uint32_t)(lo);                        \
+  (d) = __u.f;                                    \
+} while (0)
+
+/* Get a 32 bit int from a float.  */
+#define GET_FLOAT_WORD(w,d)                       \
+do {                                              \
+  union {float f; uint32_t i;} __u;               \
+  __u.f = (d);                                    \
+  (w) = __u.i;                                    \
+} while (0)
+
+/* Set a float from a 32 bit int.  */
+#define SET_FLOAT_WORD(d,w)                       \
+do {                                              \
+  union {float f; uint32_t i;} __u;               \
+  __u.i = (w);                                    \
+  (d) = __u.f;                                    \
+} while (0)
+
+#undef __CMPLX
+#undef CMPLX
+#undef CMPLXF
+#undef CMPLXL
+
+#define __CMPLX(x, y, t) \
+	((union { _Complex t __z; t __xy[2]; }){.__xy = {(x),(y)}}.__z)
+
+#define CMPLX(x, y) __CMPLX(x, y, double)
+#define CMPLXF(x, y) __CMPLX(x, y, float)
+#define CMPLXL(x, y) __CMPLX(x, y, long double)
+
+/* fdlibm kernel functions */
+
+hidden int    __rem_pio2_large(double*,double*,int,int,int);
+
+hidden int    __rem_pio2(double,double*);
+hidden double __sin(double,double,int);
+hidden double __cos(double,double);
+hidden double __tan(double,double,int);
+hidden double __expo2(double);
+hidden double complex __ldexp_cexp(double complex,int);
+
+hidden int    __rem_pio2f(float,double*);
+hidden float  __sindf(double);
+hidden float  __cosdf(double);
+hidden float  __tandf(double,int);
+hidden float  __expo2f(float);
+hidden float complex __ldexp_cexpf(float complex,int);
+
+hidden int __rem_pio2l(long double, long double *);
+hidden long double __sinl(long double, long double, int);
+hidden long double __cosl(long double, long double);
+hidden long double __tanl(long double, long double, int);
+
+/* polynomial evaluation */
+hidden long double __polevll(long double, const long double *, int);
+hidden long double __p1evll(long double, const long double *, int);
+
+extern int __signgam;
+hidden double __lgamma_r(double, int *);
+hidden float __lgammaf_r(float, int *);
+
+#endif
libc/musl/src/internal/locale_impl.h
@@ -0,0 +1,45 @@
+#ifndef _LOCALE_IMPL_H
+#define _LOCALE_IMPL_H
+
+#include <locale.h>
+#include <stdlib.h>
+#include "libc.h"
+#include "pthread_impl.h"
+
+#define LOCALE_NAME_MAX 23
+
+struct __locale_map {
+	const void *map;
+	size_t map_size;
+	char name[LOCALE_NAME_MAX+1];
+	const struct __locale_map *next;
+};
+
+extern hidden const struct __locale_map __c_dot_utf8;
+extern hidden const struct __locale_struct __c_locale;
+extern hidden const struct __locale_struct __c_dot_utf8_locale;
+
+hidden const struct __locale_map *__get_locale(int, const char *);
+hidden const char *__mo_lookup(const void *, size_t, const char *);
+hidden const char *__lctrans(const char *, const struct __locale_map *);
+hidden const char *__lctrans_cur(const char *);
+hidden const char *__lctrans_impl(const char *, const struct __locale_map *);
+hidden int __loc_is_allocated(locale_t);
+hidden char *__gettextdomain(void);
+
+#define LOC_MAP_FAILED ((const struct __locale_map *)-1)
+
+#define LCTRANS(msg, lc, loc) __lctrans(msg, (loc)->cat[(lc)])
+#define LCTRANS_CUR(msg) __lctrans_cur(msg)
+
+#define C_LOCALE ((locale_t)&__c_locale)
+#define UTF8_LOCALE ((locale_t)&__c_dot_utf8_locale)
+
+#define CURRENT_LOCALE (__pthread_self()->locale)
+
+#define CURRENT_UTF8 (!!__pthread_self()->locale->cat[LC_CTYPE])
+
+#undef MB_CUR_MAX
+#define MB_CUR_MAX (CURRENT_UTF8 ? 4 : 1)
+
+#endif
libc/musl/src/internal/lock.h
@@ -0,0 +1,9 @@
+#ifndef LOCK_H
+#define LOCK_H
+
+hidden void __lock(volatile int *);
+hidden void __unlock(volatile int *);
+#define LOCK(x) __lock(x)
+#define UNLOCK(x) __unlock(x)
+
+#endif
libc/musl/src/internal/malloc_impl.h
@@ -0,0 +1,46 @@
+#ifndef MALLOC_IMPL_H
+#define MALLOC_IMPL_H
+
+#include <sys/mman.h>
+
+hidden void *__expand_heap(size_t *);
+
+hidden void __malloc_donate(char *, char *);
+
+hidden void *__memalign(size_t, size_t);
+
+struct chunk {
+	size_t psize, csize;
+	struct chunk *next, *prev;
+};
+
+struct bin {
+	volatile int lock[2];
+	struct chunk *head;
+	struct chunk *tail;
+};
+
+#define SIZE_ALIGN (4*sizeof(size_t))
+#define SIZE_MASK (-SIZE_ALIGN)
+#define OVERHEAD (2*sizeof(size_t))
+#define MMAP_THRESHOLD (0x1c00*SIZE_ALIGN)
+#define DONTCARE 16
+#define RECLAIM 163840
+
+#define CHUNK_SIZE(c) ((c)->csize & -2)
+#define CHUNK_PSIZE(c) ((c)->psize & -2)
+#define PREV_CHUNK(c) ((struct chunk *)((char *)(c) - CHUNK_PSIZE(c)))
+#define NEXT_CHUNK(c) ((struct chunk *)((char *)(c) + CHUNK_SIZE(c)))
+#define MEM_TO_CHUNK(p) (struct chunk *)((char *)(p) - OVERHEAD)
+#define CHUNK_TO_MEM(c) (void *)((char *)(c) + OVERHEAD)
+#define BIN_TO_CHUNK(i) (MEM_TO_CHUNK(&mal.bins[i].head))
+
+#define C_INUSE  ((size_t)1)
+
+#define IS_MMAPPED(c) !((c)->csize & (C_INUSE))
+
+hidden void __bin_chunk(struct chunk *);
+
+hidden extern int __malloc_replaced;
+
+#endif
libc/musl/src/internal/procfdname.c
@@ -0,0 +1,15 @@
+#include "syscall.h"
+
+void __procfdname(char *buf, unsigned fd)
+{
+	unsigned i, j;
+	for (i=0; (buf[i] = "/proc/self/fd/"[i]); i++);
+	if (!fd) {
+		buf[i] = '0';
+		buf[i+1] = 0;
+		return;
+	}
+	for (j=fd; j; j/=10, i++);
+	buf[i] = 0;
+	for (; fd; fd/=10) buf[--i] = '0' + fd%10;
+}
libc/musl/src/internal/pthread_impl.h
@@ -0,0 +1,198 @@
+#ifndef _PTHREAD_IMPL_H
+#define _PTHREAD_IMPL_H
+
+#include <pthread.h>
+#include <signal.h>
+#include <errno.h>
+#include <limits.h>
+#include <sys/mman.h>
+#include "libc.h"
+#include "syscall.h"
+#include "atomic.h"
+#include "futex.h"
+
+#define pthread __pthread
+
+struct pthread {
+	/* Part 1 -- these fields may be external or
+	 * internal (accessed via asm) ABI. Do not change. */
+	struct pthread *self;
+	uintptr_t *dtv;
+	void *unused1, *unused2;
+	uintptr_t sysinfo;
+	uintptr_t canary, canary2;
+
+	/* Part 2 -- implementation details, non-ABI. */
+	int tid;
+	int errno_val;
+	volatile int detach_state;
+	volatile int cancel;
+	volatile unsigned char canceldisable, cancelasync;
+	unsigned char tsd_used:1;
+	unsigned char unblock_cancel:1;
+	unsigned char dlerror_flag:1;
+	unsigned char *map_base;
+	size_t map_size;
+	void *stack;
+	size_t stack_size;
+	size_t guard_size;
+	void *start_arg;
+	void *(*start)(void *);
+	void *result;
+	struct __ptcb *cancelbuf;
+	void **tsd;
+	struct {
+		volatile void *volatile head;
+		long off;
+		volatile void *volatile pending;
+	} robust_list;
+	volatile int timer_id;
+	locale_t locale;
+	volatile int killlock[1];
+	char *dlerror_buf;
+	void *stdio_locks;
+
+	/* Part 3 -- the positions of these fields relative to
+	 * the end of the structure is external and internal ABI. */
+	uintptr_t canary_at_end;
+	uintptr_t *dtv_copy;
+};
+
+struct start_sched_args {
+	void *start_arg;
+	void *(*start_fn)(void *);
+	sigset_t mask;
+	pthread_attr_t *attr;
+	volatile int futex;
+};
+
+enum {
+	DT_EXITED = 0,
+	DT_EXITING,
+	DT_JOINABLE,
+	DT_DETACHED,
+	DT_DYNAMIC,
+};
+
+struct __timer {
+	int timerid;
+	pthread_t thread;
+};
+
+#define __SU (sizeof(size_t)/sizeof(int))
+
+#define _a_stacksize __u.__s[0]
+#define _a_guardsize __u.__s[1]
+#define _a_stackaddr __u.__s[2]
+#define _a_detach __u.__i[3*__SU+0]
+#define _a_sched __u.__i[3*__SU+1]
+#define _a_policy __u.__i[3*__SU+2]
+#define _a_prio __u.__i[3*__SU+3]
+#define _m_type __u.__i[0]
+#define _m_lock __u.__vi[1]
+#define _m_waiters __u.__vi[2]
+#define _m_prev __u.__p[3]
+#define _m_next __u.__p[4]
+#define _m_count __u.__i[5]
+#define _c_shared __u.__p[0]
+#define _c_seq __u.__vi[2]
+#define _c_waiters __u.__vi[3]
+#define _c_clock __u.__i[4]
+#define _c_lock __u.__vi[8]
+#define _c_head __u.__p[1]
+#define _c_tail __u.__p[5]
+#define _rw_lock __u.__vi[0]
+#define _rw_waiters __u.__vi[1]
+#define _rw_shared __u.__i[2]
+#define _b_lock __u.__vi[0]
+#define _b_waiters __u.__vi[1]
+#define _b_limit __u.__i[2]
+#define _b_count __u.__vi[3]
+#define _b_waiters2 __u.__vi[4]
+#define _b_inst __u.__p[3]
+
+#include "pthread_arch.h"
+
+#ifndef CANARY
+#define CANARY canary
+#endif
+
+#ifndef DTP_OFFSET
+#define DTP_OFFSET 0
+#endif
+
+#ifndef tls_mod_off_t
+#define tls_mod_off_t size_t
+#endif
+
+#define SIGTIMER 32
+#define SIGCANCEL 33
+#define SIGSYNCCALL 34
+
+#define SIGALL_SET ((sigset_t *)(const unsigned long long [2]){ -1,-1 })
+#define SIGPT_SET \
+	((sigset_t *)(const unsigned long [_NSIG/8/sizeof(long)]){ \
+	[sizeof(long)==4] = 3UL<<(32*(sizeof(long)>4)) })
+#define SIGTIMER_SET \
+	((sigset_t *)(const unsigned long [_NSIG/8/sizeof(long)]){ \
+	 0x80000000 })
+
+void *__tls_get_addr(tls_mod_off_t *);
+hidden void *__tls_get_new(tls_mod_off_t *);
+hidden int __init_tp(void *);
+hidden void *__copy_tls(unsigned char *);
+hidden void __reset_tls();
+
+hidden void __dl_thread_cleanup(void);
+hidden void __testcancel();
+hidden void __do_cleanup_push(struct __ptcb *);
+hidden void __do_cleanup_pop(struct __ptcb *);
+hidden void __pthread_tsd_run_dtors();
+
+hidden void __pthread_key_delete_synccall(void (*)(void *), void *);
+hidden int __pthread_key_delete_impl(pthread_key_t);
+
+extern hidden volatile int __block_new_threads;
+extern hidden volatile size_t __pthread_tsd_size;
+extern hidden void *__pthread_tsd_main[];
+extern hidden volatile int __aio_fut;
+extern hidden volatile int __eintr_valid_flag;
+
+hidden int __clone(int (*)(void *), void *, int, void *, ...);
+hidden int __set_thread_area(void *);
+hidden int __libc_sigaction(int, const struct sigaction *, struct sigaction *);
+hidden void __unmapself(void *, size_t);
+
+hidden int __timedwait(volatile int *, int, clockid_t, const struct timespec *, int);
+hidden int __timedwait_cp(volatile int *, int, clockid_t, const struct timespec *, int);
+hidden void __wait(volatile int *, volatile int *, int, int);
+static inline void __wake(volatile void *addr, int cnt, int priv)
+{
+	if (priv) priv = FUTEX_PRIVATE;
+	if (cnt<0) cnt = INT_MAX;
+	__syscall(SYS_futex, addr, FUTEX_WAKE|priv, cnt) != -ENOSYS ||
+	__syscall(SYS_futex, addr, FUTEX_WAKE, cnt);
+}
+static inline void __futexwait(volatile void *addr, int val, int priv)
+{
+	if (priv) priv = FUTEX_PRIVATE;
+	__syscall(SYS_futex, addr, FUTEX_WAIT|priv, val, 0) != -ENOSYS ||
+	__syscall(SYS_futex, addr, FUTEX_WAIT, val, 0);
+}
+
+hidden void __acquire_ptc(void);
+hidden void __release_ptc(void);
+hidden void __inhibit_ptc(void);
+
+extern hidden unsigned __default_stacksize;
+extern hidden unsigned __default_guardsize;
+
+#define DEFAULT_STACK_SIZE 131072
+#define DEFAULT_GUARD_SIZE 8192
+
+#define DEFAULT_STACK_MAX (8<<20)
+#define DEFAULT_GUARD_MAX (1<<20)
+
+#define __ATTRP_C11_THREAD ((void*)(uintptr_t)-1)
+
+#endif
libc/musl/src/internal/shgetc.c
@@ -0,0 +1,36 @@
+#include "shgetc.h"
+
+/* The shcnt field stores the number of bytes read so far, offset by
+ * the value of buf-rpos at the last function call (__shlim or __shgetc),
+ * so that between calls the inline shcnt macro can add rpos-buf to get
+ * the actual count. */
+
+void __shlim(FILE *f, off_t lim)
+{
+	f->shlim = lim;
+	f->shcnt = f->buf - f->rpos;
+	/* If lim is nonzero, rend must be a valid pointer. */
+	if (lim && f->rend - f->rpos > lim)
+		f->shend = f->rpos + lim;
+	else
+		f->shend = f->rend;
+}
+
+int __shgetc(FILE *f)
+{
+	int c;
+	off_t cnt = shcnt(f);
+	if (f->shlim && cnt >= f->shlim || (c=__uflow(f)) < 0) {
+		f->shcnt = f->buf - f->rpos + cnt;
+		f->shend = 0;
+		return EOF;
+	}
+	cnt++;
+	if (f->shlim && f->rend - f->rpos > f->shlim - cnt)
+		f->shend = f->rpos + (f->shlim - cnt);
+	else
+		f->shend = f->rend;
+	f->shcnt = f->buf - f->rpos + cnt;
+	if (f->rpos[-1] != c) f->rpos[-1] = c;
+	return c;
+}
libc/musl/src/internal/shgetc.h
@@ -0,0 +1,32 @@
+#include "stdio_impl.h"
+
+/* Scan helper "stdio" functions for use by scanf-family and strto*-family
+ * functions. These accept either a valid stdio FILE, or a minimal pseudo
+ * FILE whose buffer pointers point into a null-terminated string. In the
+ * latter case, the sh_fromstring macro should be used to setup the FILE;
+ * the rest of the structure can be left uninitialized.
+ *
+ * To begin using these functions, shlim must first be called on the FILE
+ * to set a field width limit, or 0 for no limit. For string pseudo-FILEs,
+ * a nonzero limit is not valid and produces undefined behavior. After that,
+ * shgetc, shunget, and shcnt are valid as long as no other stdio functions
+ * are called on the stream.
+ *
+ * When used with a real FILE object, shunget has only one byte of pushback
+ * available. Further shunget (up to a limit of the stdio UNGET buffer size)
+ * will adjust the position but will not restore the data to be read again.
+ * This functionality is needed for the wcsto*-family functions, where it's
+ * okay because the FILE will be discarded immediately anyway. When used
+ * with string pseudo-FILEs, shunget has unlimited pushback, back to the
+ * beginning of the string. */
+
+hidden void __shlim(FILE *, off_t);
+hidden int __shgetc(FILE *);
+
+#define shcnt(f) ((f)->shcnt + ((f)->rpos - (f)->buf))
+#define shlim(f, lim) __shlim((f), (lim))
+#define shgetc(f) (((f)->rpos != (f)->shend) ? *(f)->rpos++ : __shgetc(f))
+#define shunget(f) ((f)->shend ? (void)(f)->rpos-- : (void)0)
+
+#define sh_fromstring(f, s) \
+	((f)->buf = (f)->rpos = (void *)(s), (f)->rend = (void*)-1)
libc/musl/src/internal/stdio_impl.h
@@ -0,0 +1,114 @@
+#ifndef _STDIO_IMPL_H
+#define _STDIO_IMPL_H
+
+#include <stdio.h>
+#include "syscall.h"
+
+#define UNGET 8
+
+#define FFINALLOCK(f) ((f)->lock>=0 ? __lockfile((f)) : 0)
+#define FLOCK(f) int __need_unlock = ((f)->lock>=0 ? __lockfile((f)) : 0)
+#define FUNLOCK(f) do { if (__need_unlock) __unlockfile((f)); } while (0)
+
+#define F_PERM 1
+#define F_NORD 4
+#define F_NOWR 8
+#define F_EOF 16
+#define F_ERR 32
+#define F_SVB 64
+#define F_APP 128
+
+struct _IO_FILE {
+	unsigned flags;
+	unsigned char *rpos, *rend;
+	int (*close)(FILE *);
+	unsigned char *wend, *wpos;
+	unsigned char *mustbezero_1;
+	unsigned char *wbase;
+	size_t (*read)(FILE *, unsigned char *, size_t);
+	size_t (*write)(FILE *, const unsigned char *, size_t);
+	off_t (*seek)(FILE *, off_t, int);
+	unsigned char *buf;
+	size_t buf_size;
+	FILE *prev, *next;
+	int fd;
+	int pipe_pid;
+	long lockcount;
+	int mode;
+	volatile int lock;
+	int lbf;
+	void *cookie;
+	off_t off;
+	char *getln_buf;
+	void *mustbezero_2;
+	unsigned char *shend;
+	off_t shlim, shcnt;
+	FILE *prev_locked, *next_locked;
+	struct __locale_struct *locale;
+};
+
+extern hidden FILE *volatile __stdin_used;
+extern hidden FILE *volatile __stdout_used;
+extern hidden FILE *volatile __stderr_used;
+
+hidden int __lockfile(FILE *);
+hidden void __unlockfile(FILE *);
+
+hidden size_t __stdio_read(FILE *, unsigned char *, size_t);
+hidden size_t __stdio_write(FILE *, const unsigned char *, size_t);
+hidden size_t __stdout_write(FILE *, const unsigned char *, size_t);
+hidden off_t __stdio_seek(FILE *, off_t, int);
+hidden int __stdio_close(FILE *);
+
+hidden size_t __string_read(FILE *, unsigned char *, size_t);
+
+hidden int __toread(FILE *);
+hidden int __towrite(FILE *);
+
+hidden void __stdio_exit(void);
+hidden void __stdio_exit_needed(void);
+
+#if defined(__PIC__) && (100*__GNUC__+__GNUC_MINOR__ >= 303)
+__attribute__((visibility("protected")))
+#endif
+int __overflow(FILE *, int), __uflow(FILE *);
+
+hidden int __fseeko(FILE *, off_t, int);
+hidden int __fseeko_unlocked(FILE *, off_t, int);
+hidden off_t __ftello(FILE *);
+hidden off_t __ftello_unlocked(FILE *);
+hidden size_t __fwritex(const unsigned char *, size_t, FILE *);
+hidden int __putc_unlocked(int, FILE *);
+
+hidden FILE *__fdopen(int, const char *);
+hidden int __fmodeflags(const char *);
+
+hidden FILE *__ofl_add(FILE *f);
+hidden FILE **__ofl_lock(void);
+hidden void __ofl_unlock(void);
+
+struct __pthread;
+hidden void __register_locked_file(FILE *, struct __pthread *);
+hidden void __unlist_locked_file(FILE *);
+hidden void __do_orphaned_stdio_locks(void);
+
+#define MAYBE_WAITERS 0x40000000
+
+hidden void __getopt_msg(const char *, const char *, const char *, size_t);
+
+#define feof(f) ((f)->flags & F_EOF)
+#define ferror(f) ((f)->flags & F_ERR)
+
+#define getc_unlocked(f) \
+	( ((f)->rpos != (f)->rend) ? *(f)->rpos++ : __uflow((f)) )
+
+#define putc_unlocked(c, f) \
+	( (((unsigned char)(c)!=(f)->lbf && (f)->wpos!=(f)->wend)) \
+	? *(f)->wpos++ = (unsigned char)(c) \
+	: __overflow((f),(unsigned char)(c)) )
+
+/* Caller-allocated FILE * operations */
+hidden FILE *__fopen_rb_ca(const char *, FILE *, unsigned char *, size_t);
+hidden int __fclose_ca(FILE *);
+
+#endif
libc/musl/src/internal/syscall.c
libc/musl/src/internal/syscall.h
@@ -0,0 +1,251 @@
+#ifndef _INTERNAL_SYSCALL_H
+#define _INTERNAL_SYSCALL_H
+
+#include <features.h>
+#include <sys/syscall.h>
+#include "syscall_arch.h"
+
+#ifndef SYSCALL_RLIM_INFINITY
+#define SYSCALL_RLIM_INFINITY (~0ULL)
+#endif
+
+#ifndef SYSCALL_MMAP2_UNIT
+#define SYSCALL_MMAP2_UNIT 4096ULL
+#endif
+
+#ifndef __SYSCALL_LL_PRW
+#define __SYSCALL_LL_PRW(x) __SYSCALL_LL_O(x)
+#endif
+
+#ifndef __scc
+#define __scc(X) ((long) (X))
+typedef long syscall_arg_t;
+#endif
+
+hidden long __syscall_ret(unsigned long), __syscall(syscall_arg_t, ...),
+	__syscall_cp(syscall_arg_t, syscall_arg_t, syscall_arg_t, syscall_arg_t,
+	             syscall_arg_t, syscall_arg_t, syscall_arg_t);
+
+#ifdef SYSCALL_NO_INLINE
+#define __syscall0(n) (__syscall)(n)
+#define __syscall1(n,a) (__syscall)(n,__scc(a))
+#define __syscall2(n,a,b) (__syscall)(n,__scc(a),__scc(b))
+#define __syscall3(n,a,b,c) (__syscall)(n,__scc(a),__scc(b),__scc(c))
+#define __syscall4(n,a,b,c,d) (__syscall)(n,__scc(a),__scc(b),__scc(c),__scc(d))
+#define __syscall5(n,a,b,c,d,e) (__syscall)(n,__scc(a),__scc(b),__scc(c),__scc(d),__scc(e))
+#define __syscall6(n,a,b,c,d,e,f) (__syscall)(n,__scc(a),__scc(b),__scc(c),__scc(d),__scc(e),__scc(f))
+#else
+#define __syscall1(n,a) __syscall1(n,__scc(a))
+#define __syscall2(n,a,b) __syscall2(n,__scc(a),__scc(b))
+#define __syscall3(n,a,b,c) __syscall3(n,__scc(a),__scc(b),__scc(c))
+#define __syscall4(n,a,b,c,d) __syscall4(n,__scc(a),__scc(b),__scc(c),__scc(d))
+#define __syscall5(n,a,b,c,d,e) __syscall5(n,__scc(a),__scc(b),__scc(c),__scc(d),__scc(e))
+#define __syscall6(n,a,b,c,d,e,f) __syscall6(n,__scc(a),__scc(b),__scc(c),__scc(d),__scc(e),__scc(f))
+#endif
+#define __syscall7(n,a,b,c,d,e,f,g) (__syscall)(n,__scc(a),__scc(b),__scc(c),__scc(d),__scc(e),__scc(f),__scc(g))
+
+#define __SYSCALL_NARGS_X(a,b,c,d,e,f,g,h,n,...) n
+#define __SYSCALL_NARGS(...) __SYSCALL_NARGS_X(__VA_ARGS__,7,6,5,4,3,2,1,0,)
+#define __SYSCALL_CONCAT_X(a,b) a##b
+#define __SYSCALL_CONCAT(a,b) __SYSCALL_CONCAT_X(a,b)
+#define __SYSCALL_DISP(b,...) __SYSCALL_CONCAT(b,__SYSCALL_NARGS(__VA_ARGS__))(__VA_ARGS__)
+
+#define __syscall(...) __SYSCALL_DISP(__syscall,__VA_ARGS__)
+#define syscall(...) __syscall_ret(__syscall(__VA_ARGS__))
+
+#define socketcall __socketcall
+#define socketcall_cp __socketcall_cp
+
+#define __syscall_cp0(n) (__syscall_cp)(n,0,0,0,0,0,0)
+#define __syscall_cp1(n,a) (__syscall_cp)(n,__scc(a),0,0,0,0,0)
+#define __syscall_cp2(n,a,b) (__syscall_cp)(n,__scc(a),__scc(b),0,0,0,0)
+#define __syscall_cp3(n,a,b,c) (__syscall_cp)(n,__scc(a),__scc(b),__scc(c),0,0,0)
+#define __syscall_cp4(n,a,b,c,d) (__syscall_cp)(n,__scc(a),__scc(b),__scc(c),__scc(d),0,0)
+#define __syscall_cp5(n,a,b,c,d,e) (__syscall_cp)(n,__scc(a),__scc(b),__scc(c),__scc(d),__scc(e),0)
+#define __syscall_cp6(n,a,b,c,d,e,f) (__syscall_cp)(n,__scc(a),__scc(b),__scc(c),__scc(d),__scc(e),__scc(f))
+
+#define __syscall_cp(...) __SYSCALL_DISP(__syscall_cp,__VA_ARGS__)
+#define syscall_cp(...) __syscall_ret(__syscall_cp(__VA_ARGS__))
+
+#ifndef SYSCALL_USE_SOCKETCALL
+#define __socketcall(nm,a,b,c,d,e,f) syscall(SYS_##nm, a, b, c, d, e, f)
+#define __socketcall_cp(nm,a,b,c,d,e,f) syscall_cp(SYS_##nm, a, b, c, d, e, f)
+#else
+#define __socketcall(nm,a,b,c,d,e,f) syscall(SYS_socketcall, __SC_##nm, \
+    ((long [6]){ (long)a, (long)b, (long)c, (long)d, (long)e, (long)f }))
+#define __socketcall_cp(nm,a,b,c,d,e,f) syscall_cp(SYS_socketcall, __SC_##nm, \
+    ((long [6]){ (long)a, (long)b, (long)c, (long)d, (long)e, (long)f }))
+#endif
+
+/* fixup legacy 16-bit junk */
+
+#ifdef SYS_getuid32
+#undef SYS_lchown
+#undef SYS_getuid
+#undef SYS_getgid
+#undef SYS_geteuid
+#undef SYS_getegid
+#undef SYS_setreuid
+#undef SYS_setregid
+#undef SYS_getgroups
+#undef SYS_setgroups
+#undef SYS_fchown
+#undef SYS_setresuid
+#undef SYS_getresuid
+#undef SYS_setresgid
+#undef SYS_getresgid
+#undef SYS_chown
+#undef SYS_setuid
+#undef SYS_setgid
+#undef SYS_setfsuid
+#undef SYS_setfsgid
+#define SYS_lchown SYS_lchown32
+#define SYS_getuid SYS_getuid32
+#define SYS_getgid SYS_getgid32
+#define SYS_geteuid SYS_geteuid32
+#define SYS_getegid SYS_getegid32
+#define SYS_setreuid SYS_setreuid32
+#define SYS_setregid SYS_setregid32
+#define SYS_getgroups SYS_getgroups32
+#define SYS_setgroups SYS_setgroups32
+#define SYS_fchown SYS_fchown32
+#define SYS_setresuid SYS_setresuid32
+#define SYS_getresuid SYS_getresuid32
+#define SYS_setresgid SYS_setresgid32
+#define SYS_getresgid SYS_getresgid32
+#define SYS_chown SYS_chown32
+#define SYS_setuid SYS_setuid32
+#define SYS_setgid SYS_setgid32
+#define SYS_setfsuid SYS_setfsuid32
+#define SYS_setfsgid SYS_setfsgid32
+#endif
+
+
+/* fixup legacy 32-bit-vs-lfs64 junk */
+
+#ifdef SYS_fcntl64
+#undef SYS_fcntl
+#define SYS_fcntl SYS_fcntl64
+#endif
+
+#ifdef SYS_getdents64
+#undef SYS_getdents
+#define SYS_getdents SYS_getdents64
+#endif
+
+#ifdef SYS_ftruncate64
+#undef SYS_ftruncate
+#undef SYS_truncate
+#define SYS_ftruncate SYS_ftruncate64
+#define SYS_truncate SYS_truncate64
+#endif
+
+#ifdef SYS_stat64
+#undef SYS_stat
+#define SYS_stat SYS_stat64
+#endif
+
+#ifdef SYS_fstat64
+#undef SYS_fstat
+#define SYS_fstat SYS_fstat64
+#endif
+
+#ifdef SYS_lstat64
+#undef SYS_lstat
+#define SYS_lstat SYS_lstat64
+#endif
+
+#ifdef SYS_statfs64
+#undef SYS_statfs
+#define SYS_statfs SYS_statfs64
+#endif
+
+#ifdef SYS_fstatfs64
+#undef SYS_fstatfs
+#define SYS_fstatfs SYS_fstatfs64
+#endif
+
+#if defined(SYS_newfstatat)
+#undef SYS_fstatat
+#define SYS_fstatat SYS_newfstatat
+#elif defined(SYS_fstatat64)
+#undef SYS_fstatat
+#define SYS_fstatat SYS_fstatat64
+#endif
+
+#ifdef SYS_ugetrlimit
+#undef SYS_getrlimit
+#define SYS_getrlimit SYS_ugetrlimit
+#endif
+
+#ifdef SYS__newselect
+#undef SYS_select
+#define SYS_select SYS__newselect
+#endif
+
+#ifdef SYS_pread64
+#undef SYS_pread
+#undef SYS_pwrite
+#define SYS_pread SYS_pread64
+#define SYS_pwrite SYS_pwrite64
+#endif
+
+#ifdef SYS_fadvise64_64
+#undef SYS_fadvise
+#define SYS_fadvise SYS_fadvise64_64
+#elif defined(SYS_fadvise64)
+#undef SYS_fadvise
+#define SYS_fadvise SYS_fadvise64
+#endif
+
+#ifdef SYS_sendfile64
+#undef SYS_sendfile
+#define SYS_sendfile SYS_sendfile64
+#endif
+
+/* socketcall calls */
+
+#define __SC_socket      1
+#define __SC_bind        2
+#define __SC_connect     3
+#define __SC_listen      4
+#define __SC_accept      5
+#define __SC_getsockname 6
+#define __SC_getpeername 7
+#define __SC_socketpair  8
+#define __SC_send        9
+#define __SC_recv        10
+#define __SC_sendto      11
+#define __SC_recvfrom    12
+#define __SC_shutdown    13
+#define __SC_setsockopt  14
+#define __SC_getsockopt  15
+#define __SC_sendmsg     16
+#define __SC_recvmsg     17
+#define __SC_accept4     18
+#define __SC_recvmmsg    19
+#define __SC_sendmmsg    20
+
+#ifdef SYS_open
+#define __sys_open2(x,pn,fl) __syscall2(SYS_open, pn, (fl)|O_LARGEFILE)
+#define __sys_open3(x,pn,fl,mo) __syscall3(SYS_open, pn, (fl)|O_LARGEFILE, mo)
+#define __sys_open_cp2(x,pn,fl) __syscall_cp2(SYS_open, pn, (fl)|O_LARGEFILE)
+#define __sys_open_cp3(x,pn,fl,mo) __syscall_cp3(SYS_open, pn, (fl)|O_LARGEFILE, mo)
+#else
+#define __sys_open2(x,pn,fl) __syscall3(SYS_openat, AT_FDCWD, pn, (fl)|O_LARGEFILE)
+#define __sys_open3(x,pn,fl,mo) __syscall4(SYS_openat, AT_FDCWD, pn, (fl)|O_LARGEFILE, mo)
+#define __sys_open_cp2(x,pn,fl) __syscall_cp3(SYS_openat, AT_FDCWD, pn, (fl)|O_LARGEFILE)
+#define __sys_open_cp3(x,pn,fl,mo) __syscall_cp4(SYS_openat, AT_FDCWD, pn, (fl)|O_LARGEFILE, mo)
+#endif
+
+#define __sys_open(...) __SYSCALL_DISP(__sys_open,,__VA_ARGS__)
+#define sys_open(...) __syscall_ret(__sys_open(__VA_ARGS__))
+
+#define __sys_open_cp(...) __SYSCALL_DISP(__sys_open_cp,,__VA_ARGS__)
+#define sys_open_cp(...) __syscall_ret(__sys_open_cp(__VA_ARGS__))
+
+hidden void __procfdname(char __buf[static 15+3*sizeof(int)], unsigned);
+
+hidden void *__vdsosym(const char *, const char *);
+
+#endif
libc/musl/src/internal/syscall_ret.c
@@ -0,0 +1,11 @@
+#include <errno.h>
+#include "syscall.h"
+
+long __syscall_ret(unsigned long r)
+{
+	if (r > -4096UL) {
+		errno = -r;
+		return -1;
+	}
+	return r;
+}
libc/musl/src/internal/vdso.c
@@ -0,0 +1,93 @@
+#include <elf.h>
+#include <link.h>
+#include <limits.h>
+#include <stdint.h>
+#include <string.h>
+#include "libc.h"
+#include "syscall.h"
+
+#ifdef VDSO_USEFUL
+
+#if ULONG_MAX == 0xffffffff
+typedef Elf32_Ehdr Ehdr;
+typedef Elf32_Phdr Phdr;
+typedef Elf32_Sym Sym;
+typedef Elf32_Verdef Verdef;
+typedef Elf32_Verdaux Verdaux;
+#else
+typedef Elf64_Ehdr Ehdr;
+typedef Elf64_Phdr Phdr;
+typedef Elf64_Sym Sym;
+typedef Elf64_Verdef Verdef;
+typedef Elf64_Verdaux Verdaux;
+#endif
+
+static int checkver(Verdef *def, int vsym, const char *vername, char *strings)
+{
+	vsym &= 0x7fff;
+	for (;;) {
+		if (!(def->vd_flags & VER_FLG_BASE)
+		  && (def->vd_ndx & 0x7fff) == vsym)
+			break;
+		if (def->vd_next == 0)
+			return 0;
+		def = (Verdef *)((char *)def + def->vd_next);
+	}
+	Verdaux *aux = (Verdaux *)((char *)def + def->vd_aux);
+	return !strcmp(vername, strings + aux->vda_name);
+}
+
+#define OK_TYPES (1<<STT_NOTYPE | 1<<STT_OBJECT | 1<<STT_FUNC | 1<<STT_COMMON)
+#define OK_BINDS (1<<STB_GLOBAL | 1<<STB_WEAK | 1<<STB_GNU_UNIQUE)
+
+void *__vdsosym(const char *vername, const char *name)
+{
+	size_t i;
+	for (i=0; libc.auxv[i] != AT_SYSINFO_EHDR; i+=2)
+		if (!libc.auxv[i]) return 0;
+	if (!libc.auxv[i+1]) return 0;
+	Ehdr *eh = (void *)libc.auxv[i+1];
+	Phdr *ph = (void *)((char *)eh + eh->e_phoff);
+	size_t *dynv=0, base=-1;
+	for (i=0; i<eh->e_phnum; i++, ph=(void *)((char *)ph+eh->e_phentsize)) {
+		if (ph->p_type == PT_LOAD)
+			base = (size_t)eh + ph->p_offset - ph->p_vaddr;
+		else if (ph->p_type == PT_DYNAMIC)
+			dynv = (void *)((char *)eh + ph->p_offset);
+	}
+	if (!dynv || base==(size_t)-1) return 0;
+
+	char *strings = 0;
+	Sym *syms = 0;
+	Elf_Symndx *hashtab = 0;
+	uint16_t *versym = 0;
+	Verdef *verdef = 0;
+	
+	for (i=0; dynv[i]; i+=2) {
+		void *p = (void *)(base + dynv[i+1]);
+		switch(dynv[i]) {
+		case DT_STRTAB: strings = p; break;
+		case DT_SYMTAB: syms = p; break;
+		case DT_HASH: hashtab = p; break;
+		case DT_VERSYM: versym = p; break;
+		case DT_VERDEF: verdef = p; break;
+		}
+	}	
+
+	if (!strings || !syms || !hashtab) return 0;
+	if (!verdef) versym = 0;
+
+	for (i=0; i<hashtab[1]; i++) {
+		if (!(1<<(syms[i].st_info&0xf) & OK_TYPES)) continue;
+		if (!(1<<(syms[i].st_info>>4) & OK_BINDS)) continue;
+		if (!syms[i].st_shndx) continue;
+		if (strcmp(name, strings+syms[i].st_name)) continue;
+		if (versym && !checkver(verdef, versym[i], vername, strings))
+			continue;
+		return (void *)(base + syms[i].st_value);
+	}
+
+	return 0;
+}
+
+#endif
libc/musl/src/internal/version.c
@@ -0,0 +1,4 @@
+#include "version.h"
+#include "libc.h"
+
+const char __libc_version[] = VERSION;
libc/musl/src/internal/version.h
@@ -0,0 +1,1 @@
+#define VERSION "1.1.21"
libc/musl/src/ipc/ftok.c
@@ -0,0 +1,10 @@
+#include <sys/ipc.h>
+#include <sys/stat.h>
+
+key_t ftok(const char *path, int id)
+{
+	struct stat st;
+	if (stat(path, &st) < 0) return -1;
+
+	return ((st.st_ino & 0xffff) | ((st.st_dev & 0xff) << 16) | ((id & 0xffu) << 24));
+}
libc/musl/src/ipc/ipc.h
@@ -0,0 +1,12 @@
+#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
libc/musl/src/ipc/msgctl.c
@@ -0,0 +1,34 @@
+#include <sys/msg.h>
+#include <endian.h>
+#include "syscall.h"
+#include "ipc.h"
+
+#if __BYTE_ORDER != __BIG_ENDIAN
+#undef SYSCALL_IPC_BROKEN_MODE
+#endif
+
+int msgctl(int q, int cmd, struct msqid_ds *buf)
+{
+#ifdef SYSCALL_IPC_BROKEN_MODE
+	struct msqid_ds tmp;
+	if (cmd == IPC_SET) {
+		tmp = *buf;
+		tmp.msg_perm.mode *= 0x10000U;
+		buf = &tmp;
+	}
+#endif
+#ifdef SYS_msgctl
+	int r = __syscall(SYS_msgctl, q, cmd | IPC_64, buf);
+#else
+	int r = __syscall(SYS_ipc, IPCOP_msgctl, q, cmd | IPC_64, 0, buf, 0);
+#endif
+#ifdef SYSCALL_IPC_BROKEN_MODE
+	if (r >= 0) switch (cmd) {
+	case IPC_STAT:
+	case MSG_STAT:
+	case MSG_STAT_ANY:
+		buf->msg_perm.mode >>= 16;
+	}
+#endif
+	return __syscall_ret(r);
+}
libc/musl/src/ipc/msgget.c
@@ -0,0 +1,12 @@
+#include <sys/msg.h>
+#include "syscall.h"
+#include "ipc.h"
+
+int msgget(key_t k, int flag)
+{
+#ifdef SYS_msgget
+	return syscall(SYS_msgget, k, flag);
+#else
+	return syscall(SYS_ipc, IPCOP_msgget, k, flag);
+#endif
+}
libc/musl/src/ipc/msgrcv.c
@@ -0,0 +1,12 @@
+#include <sys/msg.h>
+#include "syscall.h"
+#include "ipc.h"
+
+ssize_t msgrcv(int q, void *m, size_t len, long type, int flag)
+{
+#ifdef SYS_msgrcv
+	return syscall_cp(SYS_msgrcv, q, m, len, type, flag);
+#else
+	return syscall_cp(SYS_ipc, IPCOP_msgrcv, q, len, flag, ((long[]){ (long)m, type }));
+#endif
+}
libc/musl/src/ipc/msgsnd.c
@@ -0,0 +1,12 @@
+#include <sys/msg.h>
+#include "syscall.h"
+#include "ipc.h"
+
+int msgsnd(int q, const void *m, size_t len, int flag)
+{
+#ifdef SYS_msgsnd
+	return syscall_cp(SYS_msgsnd, q, m, len, flag);
+#else
+	return syscall_cp(SYS_ipc, IPCOP_msgsnd, q, len, flag, m);
+#endif
+}
libc/musl/src/ipc/semctl.c
@@ -0,0 +1,50 @@
+#include <sys/sem.h>
+#include <stdarg.h>
+#include <endian.h>
+#include "syscall.h"
+#include "ipc.h"
+
+#if __BYTE_ORDER != __BIG_ENDIAN
+#undef SYSCALL_IPC_BROKEN_MODE
+#endif
+
+union semun {
+	int val;
+	struct semid_ds *buf;
+	unsigned short *array;
+};
+
+int semctl(int id, int num, int cmd, ...)
+{
+	union semun arg = {0};
+	va_list ap;
+	switch (cmd) {
+	case SETVAL: case GETALL: case SETALL: case IPC_STAT: case IPC_SET:
+	case IPC_INFO: case SEM_INFO: case SEM_STAT:
+		va_start(ap, cmd);
+		arg = va_arg(ap, union semun);
+		va_end(ap);
+	}
+#ifdef SYSCALL_IPC_BROKEN_MODE
+	struct semid_ds tmp;
+	if (cmd == IPC_SET) {
+		tmp = *arg.buf;
+		tmp.sem_perm.mode *= 0x10000U;
+		arg.buf = &tmp;
+	}
+#endif
+#ifdef SYS_semctl
+	int r = __syscall(SYS_semctl, id, num, cmd | IPC_64, arg.buf);
+#else
+	int r = __syscall(SYS_ipc, IPCOP_semctl, id, num, cmd | IPC_64, &arg.buf);
+#endif
+#ifdef SYSCALL_IPC_BROKEN_MODE
+	if (r >= 0) switch (cmd) {
+	case IPC_STAT:
+	case SEM_STAT:
+	case SEM_STAT_ANY:
+		arg.buf->sem_perm.mode >>= 16;
+	}
+#endif
+	return __syscall_ret(r);
+}
libc/musl/src/ipc/semget.c
@@ -0,0 +1,19 @@
+#include <sys/sem.h>
+#include <limits.h>
+#include <errno.h>
+#include "syscall.h"
+#include "ipc.h"
+
+int semget(key_t key, int n, int fl)
+{
+	/* The kernel uses the wrong type for the sem_nsems member
+	 * of struct semid_ds, and thus might not check that the
+	 * n fits in the correct (per POSIX) userspace type, so
+	 * we have to check here. */
+	if (n > USHRT_MAX) return __syscall_ret(-EINVAL);
+#ifdef SYS_semget
+	return syscall(SYS_semget, key, n, fl);
+#else
+	return syscall(SYS_ipc, IPCOP_semget, key, n, fl);
+#endif
+}
libc/musl/src/ipc/semop.c
@@ -0,0 +1,12 @@
+#include <sys/sem.h>
+#include "syscall.h"
+#include "ipc.h"
+
+int semop(int id, struct sembuf *buf, size_t n)
+{
+#ifdef SYS_semop
+	return syscall(SYS_semop, id, buf, n);
+#else
+	return syscall(SYS_ipc, IPCOP_semop, id, n, 0, buf);
+#endif
+}
libc/musl/src/ipc/semtimedop.c
@@ -0,0 +1,13 @@
+#define _GNU_SOURCE
+#include <sys/sem.h>
+#include "syscall.h"
+#include "ipc.h"
+
+int semtimedop(int id, struct sembuf *buf, size_t n, const struct timespec *ts)
+{
+#ifdef SYS_semtimedop
+	return syscall(SYS_semtimedop, id, buf, n, ts);
+#else
+	return syscall(SYS_ipc, IPCOP_semtimedop, id, n, 0, buf, ts);
+#endif
+}
libc/musl/src/ipc/shmat.c
@@ -0,0 +1,17 @@
+#include <sys/shm.h>
+#include "syscall.h"
+#include "ipc.h"
+
+#ifdef SYS_shmat
+void *shmat(int id, const void *addr, int flag)
+{
+	return (void *)syscall(SYS_shmat, id, addr, flag);
+}
+#else
+void *shmat(int id, const void *addr, int flag)
+{
+	unsigned long ret;
+	ret = syscall(SYS_ipc, IPCOP_shmat, id, flag, &addr, addr);
+	return (ret > -(unsigned long)SHMLBA) ? (void *)ret : (void *)addr;
+}
+#endif
libc/musl/src/ipc/shmctl.c
@@ -0,0 +1,34 @@
+#include <sys/shm.h>
+#include <endian.h>
+#include "syscall.h"
+#include "ipc.h"
+
+#if __BYTE_ORDER != __BIG_ENDIAN
+#undef SYSCALL_IPC_BROKEN_MODE
+#endif
+
+int shmctl(int id, int cmd, struct shmid_ds *buf)
+{
+#ifdef SYSCALL_IPC_BROKEN_MODE
+	struct shmid_ds tmp;
+	if (cmd == IPC_SET) {
+		tmp = *buf;
+		tmp.shm_perm.mode *= 0x10000U;
+		buf = &tmp;
+	}
+#endif
+#ifdef SYS_shmctl
+	int r = __syscall(SYS_shmctl, id, cmd | IPC_64, buf);
+#else
+	int r = __syscall(SYS_ipc, IPCOP_shmctl, id, cmd | IPC_64, 0, buf, 0);
+#endif
+#ifdef SYSCALL_IPC_BROKEN_MODE
+	if (r >= 0) switch (cmd) {
+	case IPC_STAT:
+	case SHM_STAT:
+	case SHM_STAT_ANY:
+		buf->shm_perm.mode >>= 16;
+	}
+#endif
+	return __syscall_ret(r);
+}
libc/musl/src/ipc/shmdt.c
@@ -0,0 +1,12 @@
+#include <sys/shm.h>
+#include "syscall.h"
+#include "ipc.h"
+
+int shmdt(const void *addr)
+{
+#ifdef SYS_shmdt
+	return syscall(SYS_shmdt, addr);
+#else
+	return syscall(SYS_ipc, IPCOP_shmdt, 0, 0, 0, addr);
+#endif
+}
libc/musl/src/ipc/shmget.c
@@ -0,0 +1,14 @@
+#include <sys/shm.h>
+#include <stdint.h>
+#include "syscall.h"
+#include "ipc.h"
+
+int shmget(key_t key, size_t size, int flag)
+{
+	if (size > PTRDIFF_MAX) size = SIZE_MAX;
+#ifdef SYS_shmget
+	return syscall(SYS_shmget, key, size, flag);
+#else
+	return syscall(SYS_ipc, IPCOP_shmget, key, size, flag);
+#endif
+}
libc/musl/src/ldso/aarch64/dlsym.s
@@ -0,0 +1,6 @@
+.global dlsym
+.hidden __dlsym
+.type dlsym,%function
+dlsym:
+	mov x2,x30
+	b __dlsym
libc/musl/src/ldso/aarch64/tlsdesc.s
@@ -0,0 +1,95 @@
+// size_t __tlsdesc_static(size_t *a)
+// {
+// 	return a[1];
+// }
+.global __tlsdesc_static
+.hidden __tlsdesc_static
+.type __tlsdesc_static,@function
+__tlsdesc_static:
+	ldr x0,[x0,#8]
+	ret
+
+.hidden __tls_get_new
+
+// size_t __tlsdesc_dynamic(size_t *a)
+// {
+// 	struct {size_t modidx,off;} *p = (void*)a[1];
+// 	size_t *dtv = *(size_t**)(tp - 8);
+// 	if (p->modidx <= dtv[0])
+// 		return dtv[p->modidx] + p->off - tp;
+// 	return __tls_get_new(p) - tp;
+// }
+.global __tlsdesc_dynamic
+.hidden __tlsdesc_dynamic
+.type __tlsdesc_dynamic,@function
+__tlsdesc_dynamic:
+	stp x1,x2,[sp,#-32]!
+	stp x3,x4,[sp,#16]
+	mrs x1,tpidr_el0      // tp
+	ldr x0,[x0,#8]        // p
+	ldr x2,[x0]           // p->modidx
+	ldr x3,[x1,#-8]       // dtv
+	ldr x4,[x3]           // dtv[0]
+	cmp x2,x4
+	b.hi 1f
+	ldr x2,[x3,x2,lsl #3] // dtv[p->modidx]
+	ldr x0,[x0,#8]        // p->off
+	add x0,x0,x2
+2:	sub x0,x0,x1
+	ldp x3,x4,[sp,#16]
+	ldp x1,x2,[sp],#32
+	ret
+
+	// save all registers __tls_get_new may clobber
+	// update sp in two steps because offset must be in [-512,509]
+1:	stp x29,x30,[sp,#-160]!
+	stp x5,x6,[sp,#16]
+	stp x7,x8,[sp,#32]
+	stp x9,x10,[sp,#48]
+	stp x11,x12,[sp,#64]
+	stp x13,x14,[sp,#80]
+	stp x15,x16,[sp,#96]
+	stp x17,x18,[sp,#112]
+	stp q0,q1,[sp,#128]
+	stp q2,q3,[sp,#-480]!
+	stp q4,q5,[sp,#32]
+	stp q6,q7,[sp,#64]
+	stp q8,q9,[sp,#96]
+	stp q10,q11,[sp,#128]
+	stp q12,q13,[sp,#160]
+	stp q14,q15,[sp,#192]
+	stp q16,q17,[sp,#224]
+	stp q18,q19,[sp,#256]
+	stp q20,q21,[sp,#288]
+	stp q22,q23,[sp,#320]
+	stp q24,q25,[sp,#352]
+	stp q26,q27,[sp,#384]
+	stp q28,q29,[sp,#416]
+	stp q30,q31,[sp,#448]
+	bl __tls_get_new
+	mrs x1,tpidr_el0
+	ldp q4,q5,[sp,#32]
+	ldp q6,q7,[sp,#64]
+	ldp q8,q9,[sp,#96]
+	ldp q10,q11,[sp,#128]
+	ldp q12,q13,[sp,#160]
+	ldp q14,q15,[sp,#192]
+	ldp q16,q17,[sp,#224]
+	ldp q18,q19,[sp,#256]
+	ldp q20,q21,[sp,#288]
+	ldp q22,q23,[sp,#320]
+	ldp q24,q25,[sp,#352]
+	ldp q26,q27,[sp,#384]
+	ldp q28,q29,[sp,#416]
+	ldp q30,q31,[sp,#448]
+	ldp q2,q3,[sp],#480
+	ldp x5,x6,[sp,#16]
+	ldp x7,x8,[sp,#32]
+	ldp x9,x10,[sp,#48]
+	ldp x11,x12,[sp,#64]
+	ldp x13,x14,[sp,#80]
+	ldp x15,x16,[sp,#96]
+	ldp x17,x18,[sp,#112]
+	ldp q0,q1,[sp,#128]
+	ldp x29,x30,[sp],#160
+	b 2b
libc/musl/src/ldso/arm/dlsym.s
@@ -0,0 +1,8 @@
+.syntax unified
+.text
+.global dlsym
+.hidden __dlsym
+.type dlsym,%function
+dlsym:
+	mov r2,lr
+	b __dlsym
libc/musl/src/ldso/arm/find_exidx.c
@@ -0,0 +1,42 @@
+#define _GNU_SOURCE
+#include <link.h>
+#include <stdint.h>
+
+struct find_exidx_data {
+	uintptr_t pc, exidx_start;
+	int exidx_len;
+};
+
+static int find_exidx(struct dl_phdr_info *info, size_t size, void *ptr)
+{
+	struct find_exidx_data *data = ptr;
+	const ElfW(Phdr) *phdr = info->dlpi_phdr;
+	uintptr_t addr, exidx_start = 0;
+	int i, match = 0, exidx_len = 0;
+
+	for (i = info->dlpi_phnum; i > 0; i--, phdr++) {
+		addr = info->dlpi_addr + phdr->p_vaddr;
+		switch (phdr->p_type) {
+		case PT_LOAD:
+			match |= data->pc >= addr && data->pc < addr + phdr->p_memsz;
+			break;
+		case PT_ARM_EXIDX:
+			exidx_start = addr;
+			exidx_len = phdr->p_memsz;
+			break;
+		}
+	}
+	data->exidx_start = exidx_start;
+	data->exidx_len = exidx_len;
+	return match;
+}
+
+uintptr_t __gnu_Unwind_Find_exidx(uintptr_t pc, int *pcount)
+{
+	struct find_exidx_data data;
+	data.pc = pc;
+	if (dl_iterate_phdr(find_exidx, &data) <= 0)
+		return 0;
+	*pcount = data.exidx_len / 8;
+	return data.exidx_start;
+}
libc/musl/src/ldso/arm/tlsdesc.S
@@ -0,0 +1,72 @@
+.syntax unified
+
+.text
+.global __tlsdesc_static
+.hidden __tlsdesc_static
+.type __tlsdesc_static,%function
+__tlsdesc_static:
+	ldr r0,[r0]
+	bx lr
+
+.hidden __tls_get_new
+
+.global __tlsdesc_dynamic
+.hidden __tlsdesc_dynamic
+.type __tlsdesc_dynamic,%function
+__tlsdesc_dynamic:
+	push {r2,r3,ip,lr}
+	ldr r1,[r0]
+	ldr r2,[r1,#4]  // r2 = offset
+	ldr r1,[r1]     // r1 = modid
+
+#if ((__ARM_ARCH_6K__ || __ARM_ARCH_6KZ__ || __ARM_ARCH_6ZK__) && !__thumb__) \
+ || __ARM_ARCH_7A__ || __ARM_ARCH_7R__ || __ARM_ARCH >= 7
+	mrc p15,0,r0,c13,c0,3
+#else
+	ldr r0,1f
+	add r0,r0,pc
+	ldr r0,[r0]
+2:
+#if __ARM_ARCH >= 5
+	blx r0          // r0 = tp
+#else
+	mov lr,pc
+	bx r0
+#endif
+#endif
+	ldr r3,[r0,#-4] // r3 = dtv
+	ldr ip,[r3]     // ip = dtv slot count
+	cmp r1,ip
+	bhi 3f
+	ldr ip,[r3,r1,LSL #2]
+	sub r0,ip,r0
+	add r0,r0,r2    // r0 = r3[r1]-r0+r2
+4:
+#if __ARM_ARCH >= 5
+	pop {r2,r3,ip,pc}
+#else
+	pop {r2,r3,ip,lr}
+	bx lr
+#endif
+
+3:
+#if __ARM_PCS_VFP || !__SOFTFP__
+	.fpu vfp
+	vpush {d0-d7}
+#endif
+	push {r0-r3}
+	add r0,sp,#4
+	bl __tls_get_new
+	pop {r1-r3,ip}
+#if __ARM_PCS_VFP || !__SOFTFP__
+	vpop {d0-d7}
+#endif
+	sub r0,r0,r1    // r0 = retval-tp
+	b 4b
+
+#if ((__ARM_ARCH_6K__ || __ARM_ARCH_6KZ__ || __ARM_ARCH_6ZK__) && !__thumb__) \
+ || __ARM_ARCH_7A__ || __ARM_ARCH_7R__ || __ARM_ARCH >= 7
+#else
+	.align 2
+1:	.word __a_gettp_ptr - 2b
+#endif
libc/musl/src/ldso/i386/dlsym.s
@@ -0,0 +1,11 @@
+.text
+.global dlsym
+.hidden __dlsym
+.type dlsym,@function
+dlsym:
+	push (%esp)
+	push 12(%esp)
+	push 12(%esp)
+	call __dlsym
+	add $12,%esp
+	ret
libc/musl/src/ldso/i386/tlsdesc.s
@@ -0,0 +1,31 @@
+.text
+.global __tlsdesc_static
+.hidden __tlsdesc_static
+.type __tlsdesc_static,@function
+__tlsdesc_static:
+	mov 4(%eax),%eax
+	ret
+
+.hidden __tls_get_new
+
+.global __tlsdesc_dynamic
+.hidden __tlsdesc_dynamic
+.type __tlsdesc_dynamic,@function
+__tlsdesc_dynamic:
+	mov 4(%eax),%eax
+	push %edx
+	mov %gs:4,%edx
+	push %ecx
+	mov (%eax),%ecx
+	cmp %ecx,(%edx)
+	jc 1f
+	mov 4(%eax),%eax
+	add (%edx,%ecx,4),%eax
+2:	pop %ecx
+	sub %gs:0,%eax
+	pop %edx
+	ret
+1:	push %eax
+	call __tls_get_new
+	pop %ecx
+	jmp 2b
libc/musl/src/ldso/m68k/dlsym.s
@@ -0,0 +1,12 @@
+.text
+.global dlsym
+.hidden __dlsym
+.type dlsym,@function
+dlsym:
+	move.l (%sp),-(%sp)
+	move.l 12(%sp),-(%sp)
+	move.l 12(%sp),-(%sp)
+	lea __dlsym-.-8,%a1
+	jsr (%pc,%a1)
+	add.l #12,%sp
+	rts
libc/musl/src/ldso/microblaze/dlsym.s
@@ -0,0 +1,6 @@
+.global dlsym
+.hidden __dlsym
+.type   dlsym,@function
+dlsym:
+	brid    __dlsym
+	add     r7, r15, r0
libc/musl/src/ldso/mips/dlsym.s
@@ -0,0 +1,17 @@
+.set noreorder
+.global dlsym
+.hidden __dlsym
+.type dlsym,@function
+dlsym:
+	lui $gp, %hi(_gp_disp)
+	addiu $gp, %lo(_gp_disp)
+	addu $gp, $gp, $25
+	move $6, $ra
+	lw $25, %call16(__dlsym)($gp)
+	addiu $sp, $sp, -16
+	sw $ra, 12($sp)
+	jalr $25
+	nop
+	lw $ra, 12($sp)
+	jr $ra
+	addiu $sp, $sp, 16
libc/musl/src/ldso/mips64/dlsym.s
@@ -0,0 +1,17 @@
+.set	noreorder
+.global	dlsym
+.hidden	__dlsym
+.type	dlsym,@function
+dlsym:
+	lui	$3, %hi(%neg(%gp_rel(dlsym)))
+	daddiu	$3, $3, %lo(%neg(%gp_rel(dlsym)))
+	daddu	$3, $3, $25
+	move	$6, $ra
+	ld	$25, %got_disp(__dlsym)($3)
+	daddiu	$sp, $sp, -32
+	sd	$ra, 24($sp)
+	jalr	$25
+	nop
+	ld	$ra, 24($sp)
+	jr	$ra
+	daddiu	$sp, $sp, 32
libc/musl/src/ldso/mipsn32/dlsym.s
@@ -0,0 +1,17 @@
+.set	noreorder
+.global	dlsym
+.hidden	__dlsym
+.type	dlsym,@function
+dlsym:
+	lui	$3, %hi(%neg(%gp_rel(dlsym)))
+	addiu	$3, $3, %lo(%neg(%gp_rel(dlsym)))
+	addu	$3, $3, $25
+	move	$6, $ra
+	lw	$25, %got_disp(__dlsym)($3)
+	addiu	$sp, $sp, -32
+	sd	$ra, 16($sp)
+	jalr	$25
+	nop
+	ld	$ra, 16($sp)
+	jr	$ra
+	addiu	$sp, $sp, 32
libc/musl/src/ldso/or1k/dlsym.s
@@ -0,0 +1,6 @@
+.global dlsym
+.hidden __dlsym
+.type   dlsym,@function
+dlsym:
+	l.j	__dlsym
+	 l.ori	r5, r9, 0
libc/musl/src/ldso/powerpc/dlsym.s
@@ -0,0 +1,9 @@
+	.text
+	.global dlsym
+	.hidden __dlsym
+	.type   dlsym,@function
+dlsym:
+	mflr    5                      # The return address is arg3.
+	b       __dlsym
+	.end    dlsym
+	.size   dlsym, .-dlsym
libc/musl/src/ldso/powerpc64/dlsym.s
@@ -0,0 +1,12 @@
+	.text
+	.global dlsym
+	.hidden __dlsym
+	.type   dlsym,@function
+dlsym:
+	addis   2, 12, .TOC.-dlsym@ha
+	addi    2,  2, .TOC.-dlsym@l
+	.localentry dlsym,.-dlsym
+	mflr    5                      # The return address is arg3.
+	b       __dlsym
+	.end    dlsym
+	.size   dlsym, .-dlsym
libc/musl/src/ldso/s390x/dlsym.s
@@ -0,0 +1,6 @@
+	.global dlsym
+	.hidden __dlsym
+	.type   dlsym,@function
+dlsym:
+	lgr %r4, %r14
+	jg __dlsym
libc/musl/src/ldso/sh/dlsym.s
@@ -0,0 +1,11 @@
+.text
+.global dlsym
+.hidden __dlsym
+.type   dlsym, @function
+dlsym:
+	mov.l L1, r0
+1:	braf  r0
+	 mov.l @r15, r6
+
+.align 2
+L1:	.long __dlsym@PLT-(1b+4-.)
libc/musl/src/ldso/x32/dlsym.s
@@ -0,0 +1,7 @@
+.text
+.global dlsym
+.hidden __dlsym
+.type dlsym,@function
+dlsym:
+	mov (%rsp),%rdx
+	jmp __dlsym
libc/musl/src/ldso/x86_64/dlsym.s
@@ -0,0 +1,7 @@
+.text
+.global dlsym
+.hidden __dlsym
+.type dlsym,@function
+dlsym:
+	mov (%rsp),%rdx
+	jmp __dlsym
libc/musl/src/ldso/x86_64/tlsdesc.s
@@ -0,0 +1,44 @@
+.text
+.global __tlsdesc_static
+.hidden __tlsdesc_static
+.type __tlsdesc_static,@function
+__tlsdesc_static:
+	mov 8(%rax),%rax
+	ret
+
+.hidden __tls_get_new
+
+.global __tlsdesc_dynamic
+.hidden __tlsdesc_dynamic
+.type __tlsdesc_dynamic,@function
+__tlsdesc_dynamic:
+	mov 8(%rax),%rax
+	push %rdx
+	mov %fs:8,%rdx
+	push %rcx
+	mov (%rax),%rcx
+	cmp %rcx,(%rdx)
+	jc 1f
+	mov 8(%rax),%rax
+	add (%rdx,%rcx,8),%rax
+2:	pop %rcx
+	sub %fs:0,%rax
+	pop %rdx
+	ret
+1:	push %rdi
+	push %rdi
+	push %rsi
+	push %r8
+	push %r9
+	push %r10
+	push %r11
+	mov %rax,%rdi
+	call __tls_get_new
+	pop %r11
+	pop %r10
+	pop %r9
+	pop %r8
+	pop %rsi
+	pop %rdi
+	pop %rdi
+	jmp 2b
libc/musl/src/ldso/__dlsym.c
@@ -0,0 +1,10 @@
+#include <dlfcn.h>
+#include "dynlink.h"
+
+static void *stub_dlsym(void *restrict p, const char *restrict s, void *restrict ra)
+{
+	__dl_seterr("Symbol not found: %s", s);
+	return 0;
+}
+
+weak_alias(stub_dlsym, __dlsym);
libc/musl/src/ldso/dl_iterate_phdr.c
@@ -0,0 +1,46 @@
+#include <elf.h>
+#include <link.h>
+#include "libc.h"
+
+#define AUX_CNT 38
+
+extern weak hidden const size_t _DYNAMIC[];
+
+static int static_dl_iterate_phdr(int(*callback)(struct dl_phdr_info *info, size_t size, void *data), void *data)
+{
+	unsigned char *p;
+	ElfW(Phdr) *phdr, *tls_phdr=0;
+	size_t base = 0;
+	size_t n;
+	struct dl_phdr_info info;
+	size_t i, aux[AUX_CNT] = {0};
+
+	for (i=0; libc.auxv[i]; i+=2)
+		if (libc.auxv[i]<AUX_CNT) aux[libc.auxv[i]] = libc.auxv[i+1];
+
+	for (p=(void *)aux[AT_PHDR],n=aux[AT_PHNUM]; n; n--,p+=aux[AT_PHENT]) {
+		phdr = (void *)p;
+		if (phdr->p_type == PT_PHDR)
+			base = aux[AT_PHDR] - phdr->p_vaddr;
+		if (phdr->p_type == PT_DYNAMIC && _DYNAMIC)
+			base = (size_t)_DYNAMIC - phdr->p_vaddr;
+		if (phdr->p_type == PT_TLS)
+			tls_phdr = phdr;
+	}
+	info.dlpi_addr  = base;
+	info.dlpi_name  = "/proc/self/exe";
+	info.dlpi_phdr  = (void *)aux[AT_PHDR];
+	info.dlpi_phnum = aux[AT_PHNUM];
+	info.dlpi_adds  = 0;
+	info.dlpi_subs  = 0;
+	if (tls_phdr) {
+		info.dlpi_tls_modid = 1;
+		info.dlpi_tls_data = (void *)(base + tls_phdr->p_vaddr);
+	} else {
+		info.dlpi_tls_modid = 0;
+		info.dlpi_tls_data = 0;
+	}
+	return (callback)(&info, sizeof (info), data);
+}
+
+weak_alias(static_dl_iterate_phdr, dl_iterate_phdr);
libc/musl/src/ldso/dladdr.c
@@ -0,0 +1,9 @@
+#define _GNU_SOURCE
+#include <dlfcn.h>
+
+static int stub_dladdr(const void *addr, Dl_info *info)
+{
+	return 0;
+}
+
+weak_alias(stub_dladdr, dladdr);
libc/musl/src/ldso/dlclose.c
@@ -0,0 +1,7 @@
+#include <dlfcn.h>
+#include "dynlink.h"
+
+int dlclose(void *p)
+{
+	return __dl_invalid_handle(p);
+}
libc/musl/src/ldso/dlerror.c
@@ -0,0 +1,59 @@
+#include <dlfcn.h>
+#include <stdlib.h>
+#include <stdarg.h>
+#include "pthread_impl.h"
+#include "dynlink.h"
+
+char *dlerror()
+{
+	pthread_t self = __pthread_self();
+	if (!self->dlerror_flag) return 0;
+	self->dlerror_flag = 0;
+	char *s = self->dlerror_buf;
+	if (s == (void *)-1)
+		return "Dynamic linker failed to allocate memory for error message";
+	else
+		return s;
+}
+
+void __dl_thread_cleanup(void)
+{
+	pthread_t self = __pthread_self();
+	if (self->dlerror_buf != (void *)-1)
+		free(self->dlerror_buf);
+}
+
+hidden void __dl_vseterr(const char *fmt, va_list ap)
+{
+	va_list ap2;
+	va_copy(ap2, ap);
+	pthread_t self = __pthread_self();
+	if (self->dlerror_buf != (void *)-1)
+		free(self->dlerror_buf);
+	size_t len = vsnprintf(0, 0, fmt, ap2);
+	va_end(ap2);
+	char *buf = malloc(len+1);
+	if (buf) {
+		vsnprintf(buf, len+1, fmt, ap);
+	} else {
+		buf = (void *)-1;	
+	}
+	self->dlerror_buf = buf;
+	self->dlerror_flag = 1;
+}
+
+hidden void __dl_seterr(const char *fmt, ...)
+{
+	va_list ap;
+	va_start(ap, fmt);
+	__dl_vseterr(fmt, ap);
+	va_end(ap);
+}
+
+static int stub_invalid_handle(void *h)
+{
+	__dl_seterr("Invalid library handle %p", (void *)h);
+	return 1;
+}
+
+weak_alias(stub_invalid_handle, __dl_invalid_handle);
libc/musl/src/ldso/dlinfo.c
@@ -0,0 +1,14 @@
+#define _GNU_SOURCE
+#include <dlfcn.h>
+#include "dynlink.h"
+
+int dlinfo(void *dso, int req, void *res)
+{
+	if (__dl_invalid_handle(dso)) return -1;
+	if (req != RTLD_DI_LINKMAP) {
+		__dl_seterr("Unsupported request %d", req);
+		return -1;
+	}
+	*(struct link_map **)res = dso;
+	return 0;
+}
libc/musl/src/ldso/dlopen.c
@@ -0,0 +1,10 @@
+#include <dlfcn.h>
+#include "dynlink.h"
+
+static void *stub_dlopen(const char *file, int mode)
+{
+	__dl_seterr("Dynamic loading not supported");
+	return 0;
+}
+
+weak_alias(stub_dlopen, dlopen);
libc/musl/src/ldso/dlsym.c
@@ -0,0 +1,7 @@
+#include <dlfcn.h>
+#include "dynlink.h"
+
+void *dlsym(void *restrict p, const char *restrict s)
+{
+	return __dlsym(p, s, 0);
+}
libc/musl/src/ldso/tlsdesc.c
@@ -0,0 +1,9 @@
+#include <stddef.h>
+#include <dynlink.h>
+
+ptrdiff_t __tlsdesc_static()
+{
+	return 0;
+}
+
+weak_alias(__tlsdesc_static, __tlsdesc_dynamic);
libc/musl/src/legacy/cuserid.c
@@ -0,0 +1,14 @@
+#define _GNU_SOURCE
+#include <pwd.h>
+#include <stdio.h>
+#include <unistd.h>
+
+char *cuserid(char *buf)
+{
+	struct passwd pw, *ppw;
+	long pwb[256];
+	if (getpwuid_r(geteuid(), &pw, (void *)pwb, sizeof pwb, &ppw))
+		return 0;
+	snprintf(buf, L_cuserid, "%s", pw.pw_name);
+	return buf;
+}
libc/musl/src/legacy/daemon.c
@@ -0,0 +1,33 @@
+#define _GNU_SOURCE
+#include <fcntl.h>
+#include <unistd.h>
+
+int daemon(int nochdir, int noclose)
+{
+	if (!nochdir && chdir("/"))
+		return -1;
+	if (!noclose) {
+		int fd, failed = 0;
+		if ((fd = open("/dev/null", O_RDWR)) < 0) return -1;
+		if (dup2(fd, 0) < 0 || dup2(fd, 1) < 0 || dup2(fd, 2) < 0)
+			failed++;
+		if (fd > 2) close(fd);
+		if (failed) return -1;
+	}
+
+	switch(fork()) {
+	case 0: break;
+	case -1: return -1;
+	default: _exit(0);
+	}
+
+	if (setsid() < 0) return -1;
+
+	switch(fork()) {
+	case 0: break;
+	case -1: return -1;
+	default: _exit(0);
+	}
+
+	return 0;
+}
libc/musl/src/legacy/err.c
@@ -0,0 +1,67 @@
+#include <err.h>
+#include <stdio.h>
+#include <stdarg.h>
+#include <stdlib.h>
+
+extern char *__progname;
+
+void vwarn(const char *fmt, va_list ap)
+{
+	fprintf (stderr, "%s: ", __progname);
+	if (fmt) {
+		vfprintf(stderr, fmt, ap);
+		fputs (": ", stderr);
+	}
+	perror(0);
+}
+
+void vwarnx(const char *fmt, va_list ap)
+{
+	fprintf (stderr, "%s: ", __progname);
+	if (fmt) vfprintf(stderr, fmt, ap);
+	putc('\n', stderr);
+}
+
+_Noreturn void verr(int status, const char *fmt, va_list ap)
+{
+	vwarn(fmt, ap);
+	exit(status);
+}
+
+_Noreturn void verrx(int status, const char *fmt, va_list ap)
+{
+	vwarnx(fmt, ap);
+	exit(status);
+}
+
+void warn(const char *fmt, ...)
+{
+	va_list ap;
+	va_start(ap, fmt);
+	vwarn(fmt, ap);
+	va_end(ap);
+}
+
+void warnx(const char *fmt, ...)
+{
+	va_list ap;
+	va_start(ap, fmt);
+	vwarnx(fmt, ap);
+	va_end(ap);
+}
+
+_Noreturn void err(int status, const char *fmt, ...)
+{
+	va_list ap;
+	va_start(ap, fmt);
+	verr(status, fmt, ap);
+	va_end(ap);
+}
+
+_Noreturn void errx(int status, const char *fmt, ...)
+{
+	va_list ap;
+	va_start(ap, fmt);
+	verrx(status, fmt, ap);
+	va_end(ap);
+}
libc/musl/src/legacy/euidaccess.c
@@ -0,0 +1,10 @@
+#define _GNU_SOURCE
+#include <unistd.h>
+#include <fcntl.h>
+
+int euidaccess(const char *filename, int amode)
+{
+	return faccessat(AT_FDCWD, filename, amode, AT_EACCESS);
+}
+
+weak_alias(euidaccess, eaccess);
libc/musl/src/legacy/ftw.c
@@ -0,0 +1,11 @@
+#include <ftw.h>
+
+int ftw(const char *path, int (*fn)(const char *, const struct stat *, int), int fd_limit)
+{
+	/* The following cast assumes that calling a function with one
+	 * argument more than it needs behaves as expected. This is
+	 * actually undefined, but works on all real-world machines. */
+	return nftw(path, (int (*)())fn, fd_limit, FTW_PHYS);
+}
+
+weak_alias(ftw, ftw64);
libc/musl/src/legacy/futimes.c
@@ -0,0 +1,14 @@
+#define _GNU_SOURCE
+#include <sys/stat.h>
+#include <sys/time.h>
+
+int futimes(int fd, const struct timeval tv[2])
+{
+	struct timespec times[2];
+	if (!tv) return futimens(fd, 0);
+	times[0].tv_sec  = tv[0].tv_sec;
+	times[0].tv_nsec = tv[0].tv_usec * 1000;
+	times[1].tv_sec  = tv[1].tv_sec;
+	times[1].tv_nsec = tv[1].tv_usec * 1000;
+	return futimens(fd, times);
+}
libc/musl/src/legacy/getdtablesize.c
@@ -0,0 +1,11 @@
+#define _GNU_SOURCE
+#include <unistd.h>
+#include <limits.h>
+#include <sys/resource.h>
+
+int getdtablesize(void)
+{
+	struct rlimit rl;
+	getrlimit(RLIMIT_NOFILE, &rl);
+	return rl.rlim_cur < INT_MAX ? rl.rlim_cur : INT_MAX;
+}
libc/musl/src/legacy/getloadavg.c
@@ -0,0 +1,14 @@
+#define _GNU_SOURCE
+#include <stdlib.h>
+#include <sys/sysinfo.h>
+
+int getloadavg(double *a, int n)
+{
+	struct sysinfo si;
+	if (n <= 0) return n ? -1 : 0;
+	sysinfo(&si);
+	if (n > 3) n = 3;
+	for (int i=0; i<n; i++)
+		a[i] = 1.0/(1<<SI_LOAD_SHIFT) * si.loads[i];
+	return n;
+}
libc/musl/src/legacy/getpagesize.c
@@ -0,0 +1,8 @@
+#define _GNU_SOURCE
+#include <unistd.h>
+#include "libc.h"
+
+int getpagesize(void)
+{
+	return PAGE_SIZE;
+}
libc/musl/src/legacy/getpass.c
@@ -0,0 +1,40 @@
+#define _GNU_SOURCE
+#include <stdio.h>
+#include <termios.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <string.h>
+
+char *getpass(const char *prompt)
+{
+	int fd;
+	struct termios s, t;
+	ssize_t l;
+	static char password[128];
+
+	if ((fd = open("/dev/tty", O_RDWR|O_NOCTTY|O_CLOEXEC)) < 0) return 0;
+
+	tcgetattr(fd, &t);
+	s = t;
+	t.c_lflag &= ~(ECHO|ISIG);
+	t.c_lflag |= ICANON;
+	t.c_iflag &= ~(INLCR|IGNCR);
+	t.c_iflag |= ICRNL;
+	tcsetattr(fd, TCSAFLUSH, &t);
+	tcdrain(fd);
+
+	dprintf(fd, "%s", prompt);
+
+	l = read(fd, password, sizeof password);
+	if (l >= 0) {
+		if (l > 0 && password[l-1] == '\n' || l==sizeof password) l--;
+		password[l] = 0;
+	}
+
+	tcsetattr(fd, TCSAFLUSH, &s);
+
+	dprintf(fd, "\n");
+	close(fd);
+
+	return l<0 ? 0 : password;
+}
libc/musl/src/legacy/getusershell.c
@@ -0,0 +1,32 @@
+#define _GNU_SOURCE
+#include <stdio.h>
+#include <unistd.h>
+
+static const char defshells[] = "/bin/sh\n/bin/csh\n";
+
+static char *line;
+static size_t linesize;
+static FILE *f;
+
+void endusershell(void)
+{
+	if (f) fclose(f);
+	f = 0;
+}
+
+void setusershell(void)
+{
+	if (!f) f = fopen("/etc/shells", "rbe");
+	if (!f) f = fmemopen((void *)defshells, sizeof defshells - 1, "rb");
+}
+
+char *getusershell(void)
+{
+	ssize_t l;
+	if (!f) setusershell();
+	if (!f) return 0;
+	l = getline(&line, &linesize, f);
+	if (l <= 0) return 0;
+	if (line[l-1]=='\n') line[l-1]=0;
+	return line;
+}
libc/musl/src/legacy/isastream.c
@@ -0,0 +1,7 @@
+#include <stropts.h>
+#include <fcntl.h>
+
+int isastream(int fd)
+{
+	return fcntl(fd, F_GETFD) < 0 ? -1 : 0;
+}
libc/musl/src/legacy/lutimes.c
@@ -0,0 +1,14 @@
+#define _GNU_SOURCE
+#include <sys/stat.h>
+#include <sys/time.h>
+#include <fcntl.h>
+
+int lutimes(const char *filename, const struct timeval tv[2])
+{
+	struct timespec times[2];
+	times[0].tv_sec  = tv[0].tv_sec;
+	times[0].tv_nsec = tv[0].tv_usec * 1000;
+	times[1].tv_sec  = tv[1].tv_sec;
+	times[1].tv_nsec = tv[1].tv_usec * 1000;
+	return utimensat(AT_FDCWD, filename, times, AT_SYMLINK_NOFOLLOW);
+}
libc/musl/src/legacy/ulimit.c
@@ -0,0 +1,19 @@
+#include <sys/resource.h>
+#include <ulimit.h>
+#include <stdarg.h>
+
+long ulimit(int cmd, ...)
+{
+	struct rlimit rl;
+	getrlimit(RLIMIT_FSIZE, &rl);
+	if (cmd == UL_SETFSIZE) {
+		long val;
+		va_list ap;
+		va_start(ap, cmd);
+		val = va_arg(ap, long);
+		va_end(ap);
+		rl.rlim_cur = 512ULL * val;
+		if (setrlimit(RLIMIT_FSIZE, &rl)) return -1;
+	}
+	return rl.rlim_cur / 512;
+}
libc/musl/src/legacy/utmpx.c
@@ -0,0 +1,52 @@
+#define _GNU_SOURCE
+#include <utmpx.h>
+#include <stddef.h>
+#include <errno.h>
+
+void endutxent(void)
+{
+}
+
+void setutxent(void)
+{
+}
+
+struct utmpx *getutxent(void)
+{
+	return NULL;
+}
+
+struct utmpx *getutxid(const struct utmpx *ut)
+{
+	return NULL;
+}
+
+struct utmpx *getutxline(const struct utmpx *ut)
+{
+	return NULL;
+}
+
+struct utmpx *pututxline(const struct utmpx *ut)
+{
+	return NULL;
+}
+
+void updwtmpx(const char *f, const struct utmpx *u)
+{
+}
+
+static int __utmpxname(const char *f)
+{
+	errno = ENOTSUP;
+	return -1;
+}
+
+weak_alias(endutxent, endutent);
+weak_alias(setutxent, setutent);
+weak_alias(getutxent, getutent);
+weak_alias(getutxid, getutid);
+weak_alias(getutxline, getutline);
+weak_alias(pututxline, pututline);
+weak_alias(updwtmpx, updwtmp);
+weak_alias(__utmpxname, utmpname);
+weak_alias(__utmpxname, utmpxname);
libc/musl/src/legacy/valloc.c
@@ -0,0 +1,8 @@
+#define _BSD_SOURCE
+#include <stdlib.h>
+#include "libc.h"
+
+void *valloc(size_t size)
+{
+	return memalign(PAGE_SIZE, size);
+}
libc/musl/src/linux/x32/sysinfo.c
@@ -0,0 +1,49 @@
+#include <sys/sysinfo.h>
+#include "syscall.h"
+
+#define klong long long
+#define kulong unsigned long long
+
+struct kernel_sysinfo {
+	klong uptime;
+	kulong loads[3];
+	kulong totalram;
+	kulong freeram;
+	kulong sharedram;
+	kulong bufferram;
+	kulong totalswap;
+	kulong freeswap;
+	short procs;
+	short pad;
+	kulong totalhigh;
+	kulong freehigh;
+	unsigned mem_unit;
+};
+
+int __lsysinfo(struct sysinfo *info)
+{
+	struct kernel_sysinfo tmp;
+	int ret = syscall(SYS_sysinfo, &tmp);
+	if(ret == -1) return ret;
+	info->uptime = tmp.uptime;
+	info->loads[0] = tmp.loads[0];
+	info->loads[1] = tmp.loads[1];
+	info->loads[2] = tmp.loads[2];
+	kulong shifts;
+	kulong max = tmp.totalram | tmp.totalswap;
+	__asm__("bsr %1,%0" : "=r"(shifts) : "r"(max));
+	shifts = shifts >= 32 ? shifts - 31 : 0;
+	info->totalram = tmp.totalram >> shifts;
+	info->freeram = tmp.freeram >> shifts;
+	info->sharedram = tmp.sharedram >> shifts;
+	info->bufferram = tmp.bufferram >> shifts;
+	info->totalswap = tmp.totalswap >> shifts;
+	info->freeswap = tmp.freeswap >> shifts;
+	info->procs = tmp.procs ;
+	info->totalhigh = tmp.totalhigh >> shifts;
+	info->freehigh = tmp.freehigh >> shifts;
+	info->mem_unit = (tmp.mem_unit ? tmp.mem_unit : 1) << shifts;
+	return ret;
+}
+
+weak_alias(__lsysinfo, sysinfo);
libc/musl/src/linux/adjtime.c
@@ -0,0 +1,27 @@
+#define _GNU_SOURCE
+#include <sys/time.h>
+#include <sys/timex.h>
+#include <errno.h>
+#include "syscall.h"
+
+int adjtime(const struct timeval *in, struct timeval *out)
+{
+	struct timex tx = { 0 };
+	if (in) {
+		if (in->tv_sec > 1000 || in->tv_usec > 1000000000) {
+			errno = EINVAL;
+			return -1;
+		}
+		tx.offset = in->tv_sec*1000000 + in->tv_usec;
+		tx.modes = ADJ_OFFSET_SINGLESHOT;
+	}
+	if (syscall(SYS_adjtimex, &tx) < 0) return -1;
+	if (out) {
+		out->tv_sec = tx.offset / 1000000;
+		if ((out->tv_usec = tx.offset % 1000000) < 0) {
+			out->tv_sec--;
+			out->tv_usec += 1000000;
+		}
+	}
+	return 0;
+}
libc/musl/src/linux/adjtimex.c
@@ -0,0 +1,7 @@
+#include <sys/timex.h>
+#include "syscall.h"
+
+int adjtimex(struct timex *tx)
+{
+	return syscall(SYS_adjtimex, tx);
+}
libc/musl/src/linux/arch_prctl.c
@@ -0,0 +1,7 @@
+#include "syscall.h"
+#ifdef SYS_arch_prctl
+int arch_prctl(int code, unsigned long addr)
+{
+	return syscall(SYS_arch_prctl, code, addr);
+}
+#endif
libc/musl/src/linux/brk.c
@@ -0,0 +1,9 @@
+#define _BSD_SOURCE
+#include <unistd.h>
+#include <errno.h>
+#include "syscall.h"
+
+int brk(void *end)
+{
+	return __syscall_ret(-ENOMEM);
+}
libc/musl/src/linux/cache.c
@@ -0,0 +1,17 @@
+#include "syscall.h"
+
+#ifdef SYS_cacheflush
+int _flush_cache(void *addr, int len, int op)
+{
+	return syscall(SYS_cacheflush, addr, len, op);
+}
+weak_alias(_flush_cache, cacheflush);
+#endif
+
+#ifdef SYS_cachectl
+int __cachectl(void *addr, int len, int op)
+{
+	return syscall(SYS_cachectl, addr, len, op);
+}
+weak_alias(__cachectl, cachectl);
+#endif
libc/musl/src/linux/cap.c
@@ -0,0 +1,11 @@
+#include "syscall.h"
+
+int capset(void *a, void *b)
+{
+	return syscall(SYS_capset, a, b);
+}
+
+int capget(void *a, void *b)
+{
+	return syscall(SYS_capget, a, b);
+}
libc/musl/src/linux/chroot.c
@@ -0,0 +1,8 @@
+#define _GNU_SOURCE
+#include <unistd.h>
+#include "syscall.h"
+
+int chroot(const char *path)
+{
+	return syscall(SYS_chroot, path);
+}
libc/musl/src/linux/clock_adjtime.c
@@ -0,0 +1,7 @@
+#include <sys/timex.h>
+#include "syscall.h"
+
+int clock_adjtime (clockid_t clock_id, struct timex *utx)
+{
+	return syscall(SYS_clock_adjtime, clock_id, utx);
+}
libc/musl/src/linux/clone.c
@@ -0,0 +1,21 @@
+#define _GNU_SOURCE
+#include <stdarg.h>
+#include <unistd.h>
+#include <sched.h>
+#include "pthread_impl.h"
+#include "syscall.h"
+
+int clone(int (*func)(void *), void *stack, int flags, void *arg, ...)
+{
+	va_list ap;
+	pid_t *ptid, *ctid;
+	void  *tls;
+
+	va_start(ap, arg);
+	ptid = va_arg(ap, pid_t *);
+	tls  = va_arg(ap, void *);
+	ctid = va_arg(ap, pid_t *);
+	va_end(ap);
+
+	return __syscall_ret(__clone(func, stack, flags, arg, ptid, tls, ctid));
+}
libc/musl/src/linux/epoll.c
@@ -0,0 +1,37 @@
+#include <sys/epoll.h>
+#include <signal.h>
+#include <errno.h>
+#include "syscall.h"
+
+int epoll_create(int size)
+{
+	return epoll_create1(0);
+}
+
+int epoll_create1(int flags)
+{
+	int r = __syscall(SYS_epoll_create1, flags);
+#ifdef SYS_epoll_create
+	if (r==-ENOSYS && !flags) r = __syscall(SYS_epoll_create, 1);
+#endif
+	return __syscall_ret(r);
+}
+
+int epoll_ctl(int fd, int op, int fd2, struct epoll_event *ev)
+{
+	return syscall(SYS_epoll_ctl, fd, op, fd2, ev);
+}
+
+int epoll_pwait(int fd, struct epoll_event *ev, int cnt, int to, const sigset_t *sigs)
+{
+	int r = __syscall(SYS_epoll_pwait, fd, ev, cnt, to, sigs, _NSIG/8);
+#ifdef SYS_epoll_wait
+	if (r==-ENOSYS && !sigs) r = __syscall(SYS_epoll_wait, fd, ev, cnt, to);
+#endif
+	return __syscall_ret(r);
+}
+
+int epoll_wait(int fd, struct epoll_event *ev, int cnt, int to)
+{
+	return epoll_pwait(fd, ev, cnt, to, 0);
+}
libc/musl/src/linux/eventfd.c
@@ -0,0 +1,23 @@
+#include <sys/eventfd.h>
+#include <unistd.h>
+#include <errno.h>
+#include "syscall.h"
+
+int eventfd(unsigned int count, int flags)
+{
+	int r = __syscall(SYS_eventfd2, count, flags);
+#ifdef SYS_eventfd
+	if (r==-ENOSYS && !flags) r = __syscall(SYS_eventfd, count);
+#endif
+	return __syscall_ret(r);
+}
+
+int eventfd_read(int fd, eventfd_t *value)
+{
+	return (sizeof(*value) == read(fd, value, sizeof(*value))) ? 0 : -1;
+}
+
+int eventfd_write(int fd, eventfd_t value)
+{
+	return (sizeof(value) == write(fd, &value, sizeof(value))) ? 0 : -1;
+}
libc/musl/src/linux/fallocate.c
@@ -0,0 +1,12 @@
+#define _GNU_SOURCE
+#include <fcntl.h>
+#include "syscall.h"
+
+int fallocate(int fd, int mode, off_t base, off_t len)
+{
+	return syscall(SYS_fallocate, fd, mode, __SYSCALL_LL_E(base),
+		__SYSCALL_LL_E(len));
+}
+
+#undef fallocate64
+weak_alias(fallocate, fallocate64);
libc/musl/src/linux/fanotify.c
@@ -0,0 +1,14 @@
+#include "syscall.h"
+#include <sys/fanotify.h>
+
+int fanotify_init(unsigned flags, unsigned event_f_flags)
+{
+	return syscall(SYS_fanotify_init, flags, event_f_flags);
+}
+
+int fanotify_mark(int fanotify_fd, unsigned flags, unsigned long long mask,
+	          int dfd, const char *pathname)
+{
+	return syscall(SYS_fanotify_mark, fanotify_fd, flags, __SYSCALL_LL_E(mask), dfd, pathname);
+}
+
libc/musl/src/linux/flock.c
@@ -0,0 +1,7 @@
+#include <sys/file.h>
+#include "syscall.h"
+
+int flock(int fd, int op)
+{
+	return syscall(SYS_flock, fd, op);
+}
libc/musl/src/linux/getdents.c
@@ -0,0 +1,10 @@
+#define _BSD_SOURCE
+#include <dirent.h>
+#include "syscall.h"
+
+int getdents(int fd, struct dirent *buf, size_t len)
+{
+	return syscall(SYS_getdents, fd, buf, len);
+}
+
+weak_alias(getdents, getdents64);
libc/musl/src/linux/getrandom.c
@@ -0,0 +1,7 @@
+#include <sys/random.h>
+#include "syscall.h"
+
+ssize_t getrandom(void *buf, size_t buflen, unsigned flags)
+{
+	return syscall_cp(SYS_getrandom, buf, buflen, flags);
+}
libc/musl/src/linux/inotify.c
@@ -0,0 +1,26 @@
+#include <sys/inotify.h>
+#include <errno.h>
+#include "syscall.h"
+
+int inotify_init()
+{
+	return inotify_init1(0);
+}
+int inotify_init1(int flags)
+{
+	int r = __syscall(SYS_inotify_init1, flags);
+#ifdef SYS_inotify_init
+	if (r==-ENOSYS && !flags) r = __syscall(SYS_inotify_init);
+#endif
+	return __syscall_ret(r);
+}
+
+int inotify_add_watch(int fd, const char *pathname, uint32_t mask)
+{
+	return syscall(SYS_inotify_add_watch, fd, pathname, mask);
+}
+
+int inotify_rm_watch(int fd, int wd)
+{
+	return syscall(SYS_inotify_rm_watch, fd, wd);
+}
libc/musl/src/linux/ioperm.c
@@ -0,0 +1,10 @@
+#include "syscall.h"
+
+#ifdef SYS_ioperm
+#include <sys/io.h>
+
+int ioperm(unsigned long from, unsigned long num, int turn_on)
+{
+	return syscall(SYS_ioperm, from, num, turn_on);
+}
+#endif
libc/musl/src/linux/iopl.c
@@ -0,0 +1,10 @@
+#include "syscall.h"
+
+#ifdef SYS_iopl
+#include <sys/io.h>
+
+int iopl(int level)
+{
+	return syscall(SYS_iopl, level);
+}
+#endif
libc/musl/src/linux/klogctl.c
@@ -0,0 +1,7 @@
+#include <sys/klog.h>
+#include "syscall.h"
+
+int klogctl (int type, char *buf, int len)
+{
+	return syscall(SYS_syslog, type, buf, len);
+}
libc/musl/src/linux/memfd_create.c
@@ -0,0 +1,8 @@
+#define _GNU_SOURCE 1
+#include <sys/mman.h>
+#include "syscall.h"
+
+int memfd_create(const char *name, unsigned flags)
+{
+	return syscall(SYS_memfd_create, name, flags);
+}
libc/musl/src/linux/mlock2.c
@@ -0,0 +1,10 @@
+#define _GNU_SOURCE 1
+#include <sys/mman.h>
+#include "syscall.h"
+
+int mlock2(const void *addr, size_t len, unsigned flags)
+{
+	if (flags == 0)
+		return mlock(addr, len);
+	return syscall(SYS_mlock2, addr, len, flags);
+}
libc/musl/src/linux/module.c
@@ -0,0 +1,11 @@
+#include "syscall.h"
+
+int init_module(void *a, unsigned long b, const char *c)
+{
+	return syscall(SYS_init_module, a, b, c);
+}
+
+int delete_module(const char *a, unsigned b)
+{
+	return syscall(SYS_delete_module, a, b);
+}
libc/musl/src/linux/mount.c
@@ -0,0 +1,17 @@
+#include <sys/mount.h>
+#include "syscall.h"
+
+int mount(const char *special, const char *dir, const char *fstype, unsigned long flags, const void *data)
+{
+	return syscall(SYS_mount, special, dir, fstype, flags, data);
+}
+
+int umount(const char *special)
+{
+	return syscall(SYS_umount2, special, 0);
+}
+
+int umount2(const char *special, int flags)
+{
+	return syscall(SYS_umount2, special, flags);
+}
libc/musl/src/linux/name_to_handle_at.c
@@ -0,0 +1,10 @@
+#define _GNU_SOURCE
+#include <fcntl.h>
+#include "syscall.h"
+
+int name_to_handle_at(int dirfd, const char *pathname,
+	struct file_handle *handle, int *mount_id, int flags)
+{
+	return syscall(SYS_name_to_handle_at, dirfd,
+		pathname, handle, mount_id, flags);
+}
libc/musl/src/linux/open_by_handle_at.c
@@ -0,0 +1,8 @@
+#define _GNU_SOURCE
+#include <fcntl.h>
+#include "syscall.h"
+
+int open_by_handle_at(int mount_fd, struct file_handle *handle, int flags)
+{
+	return syscall(SYS_open_by_handle_at, mount_fd, handle, flags);
+}
libc/musl/src/linux/personality.c
@@ -0,0 +1,8 @@
+#include <sys/personality.h>
+#include "syscall.h"
+#ifdef SYS_personality
+int personality(unsigned long persona)
+{
+	return syscall(SYS_personality, persona);
+}
+#endif
libc/musl/src/linux/pivot_root.c
@@ -0,0 +1,6 @@
+#include "syscall.h"
+
+int pivot_root(const char *new, const char *old)
+{
+	return syscall(SYS_pivot_root, new, old);
+}
libc/musl/src/linux/ppoll.c
@@ -0,0 +1,10 @@
+#define _GNU_SOURCE
+#include <poll.h>
+#include <signal.h>
+#include "syscall.h"
+
+int ppoll(struct pollfd *fds, nfds_t n, const struct timespec *to, const sigset_t *mask)
+{
+	return syscall_cp(SYS_ppoll, fds, n,
+		to ? (struct timespec []){*to} : 0, mask, _NSIG/8);
+}
libc/musl/src/linux/prctl.c
@@ -0,0 +1,14 @@
+#include <sys/prctl.h>
+#include <stdarg.h>
+#include "syscall.h"
+
+int prctl(int op, ...)
+{
+	unsigned long x[4];
+	int i;
+	va_list ap;
+	va_start(ap, op);
+	for (i=0; i<4; i++) x[i] = va_arg(ap, unsigned long);
+	va_end(ap);
+	return syscall(SYS_prctl, op, x[0], x[1], x[2], x[3]);
+}
libc/musl/src/linux/prlimit.c
@@ -0,0 +1,26 @@
+#define _GNU_SOURCE
+#include <sys/resource.h>
+#include "syscall.h"
+
+#define FIX(x) do{ if ((x)>=SYSCALL_RLIM_INFINITY) (x)=RLIM_INFINITY; }while(0)
+
+int prlimit(pid_t pid, int resource, const struct rlimit *new_limit, struct rlimit *old_limit)
+{
+	struct rlimit tmp;
+	int r;
+	if (new_limit && SYSCALL_RLIM_INFINITY != RLIM_INFINITY) {
+		tmp = *new_limit;
+		FIX(tmp.rlim_cur);
+		FIX(tmp.rlim_max);
+		new_limit = &tmp;
+	}
+	r = syscall(SYS_prlimit64, pid, resource, new_limit, old_limit);
+	if (!r && old_limit && SYSCALL_RLIM_INFINITY != RLIM_INFINITY) {
+		FIX(old_limit->rlim_cur);
+		FIX(old_limit->rlim_max);
+	}
+	return r;
+}
+
+#undef prlimit64
+weak_alias(prlimit, prlimit64);
libc/musl/src/linux/process_vm.c
@@ -0,0 +1,13 @@
+#define _GNU_SOURCE
+#include <sys/uio.h>
+#include "syscall.h"
+
+ssize_t process_vm_writev(pid_t pid, const struct iovec *lvec, unsigned long liovcnt, const struct iovec *rvec, unsigned long riovcnt, unsigned long flags)
+{
+	return syscall(SYS_process_vm_writev, pid, lvec, liovcnt, rvec, riovcnt, flags);
+}
+
+ssize_t process_vm_readv(pid_t pid, const struct iovec *lvec, unsigned long liovcnt, const struct iovec *rvec, unsigned long riovcnt, unsigned long flags)
+{
+	return syscall(SYS_process_vm_readv, pid, lvec, liovcnt, rvec, riovcnt, flags);
+}
libc/musl/src/linux/ptrace.c
@@ -0,0 +1,29 @@
+#include <sys/ptrace.h>
+#include <stdarg.h>
+#include <unistd.h>
+#include "syscall.h"
+
+long ptrace(int req, ...)
+{
+	va_list ap;
+	pid_t pid;
+	void *addr, *data, *addr2 = 0;
+	long ret, result;
+
+	va_start(ap, req);
+	pid = va_arg(ap, pid_t);
+	addr = va_arg(ap, void *);
+	data = va_arg(ap, void *);
+	/* PTRACE_{READ,WRITE}{DATA,TEXT} (16...19) are specific to SPARC. */
+#ifdef PTRACE_READDATA
+	if ((unsigned)req - PTRACE_READDATA < 4)
+		addr2 = va_arg(ap, void *);
+#endif
+	va_end(ap);
+
+	if (req-1U < 3) data = &result;
+	ret = syscall(SYS_ptrace, req, pid, addr, data, addr2);
+
+	if (ret < 0 || req-1U >= 3) return ret;
+	return result;
+}
libc/musl/src/linux/quotactl.c
@@ -0,0 +1,7 @@
+#include <sys/quota.h>
+#include "syscall.h"
+
+int quotactl(int cmd, const char *special, int id, char *addr)
+{
+	return syscall(SYS_quotactl, cmd, special, id, addr);
+}
libc/musl/src/linux/readahead.c
@@ -0,0 +1,8 @@
+#define _GNU_SOURCE
+#include <fcntl.h>
+#include "syscall.h"
+
+ssize_t readahead(int fd, off_t pos, size_t len)
+{
+	return syscall(SYS_readahead, fd, __SYSCALL_LL_O(pos), len);
+}
libc/musl/src/linux/reboot.c
@@ -0,0 +1,7 @@
+#include <sys/reboot.h>
+#include "syscall.h"
+
+int reboot(int type)
+{
+	return syscall(SYS_reboot, 0xfee1dead, 672274793, type);
+}
libc/musl/src/linux/remap_file_pages.c
@@ -0,0 +1,8 @@
+#define _GNU_SOURCE
+#include <sys/mman.h>
+#include "syscall.h"
+
+int remap_file_pages(void *addr, size_t size, int prot, size_t pgoff, int flags)
+{
+	return syscall(SYS_remap_file_pages, addr, size, prot, pgoff, flags);
+}
libc/musl/src/linux/sbrk.c
@@ -0,0 +1,11 @@
+#define _BSD_SOURCE
+#include <unistd.h>
+#include <stdint.h>
+#include <errno.h>
+#include "syscall.h"
+
+void *sbrk(intptr_t inc)
+{
+	if (inc) return (void *)__syscall_ret(-ENOMEM);
+	return (void *)__syscall(SYS_brk, 0);
+}
libc/musl/src/linux/sendfile.c
@@ -0,0 +1,9 @@
+#include <sys/sendfile.h>
+#include "syscall.h"
+
+ssize_t sendfile(int out_fd, int in_fd, off_t *ofs, size_t count)
+{
+	return syscall(SYS_sendfile, out_fd, in_fd, ofs, count);
+}
+
+weak_alias(sendfile, sendfile64);
libc/musl/src/linux/setfsgid.c
@@ -0,0 +1,7 @@
+#include <sys/fsuid.h>
+#include "syscall.h"
+
+int setfsgid(gid_t gid)
+{
+	return syscall(SYS_setfsgid, gid);
+}
libc/musl/src/linux/setfsuid.c
@@ -0,0 +1,7 @@
+#include <sys/fsuid.h>
+#include "syscall.h"
+
+int setfsuid(uid_t uid)
+{
+	return syscall(SYS_setfsuid, uid);
+}
libc/musl/src/linux/setgroups.c
@@ -0,0 +1,8 @@
+#define _GNU_SOURCE
+#include <unistd.h>
+#include "syscall.h"
+
+int setgroups(size_t count, const gid_t list[])
+{
+	return syscall(SYS_setgroups, count, list);
+}
libc/musl/src/linux/sethostname.c
@@ -0,0 +1,8 @@
+#define _GNU_SOURCE
+#include <unistd.h>
+#include "syscall.h"
+
+int sethostname(const char *name, size_t len)
+{
+	return syscall(SYS_sethostname, name, len);
+}
libc/musl/src/linux/setns.c
@@ -0,0 +1,8 @@
+#define _GNU_SOURCE
+#include <sched.h>
+#include "syscall.h"
+
+int setns(int fd, int nstype)
+{
+	return syscall(SYS_setns, fd, nstype);
+}
libc/musl/src/linux/settimeofday.c
@@ -0,0 +1,8 @@
+#define _BSD_SOURCE
+#include <sys/time.h>
+#include "syscall.h"
+
+int settimeofday(const struct timeval *tv, const struct timezone *tz)
+{
+	return syscall(SYS_settimeofday, tv, 0);
+}
libc/musl/src/linux/signalfd.c
@@ -0,0 +1,21 @@
+#include <sys/signalfd.h>
+#include <signal.h>
+#include <errno.h>
+#include <fcntl.h>
+#include "syscall.h"
+
+int signalfd(int fd, const sigset_t *sigs, int flags)
+{
+	int ret = __syscall(SYS_signalfd4, fd, sigs, _NSIG/8, flags);
+#ifdef SYS_signalfd
+	if (ret != -ENOSYS) return __syscall_ret(ret);
+	ret = __syscall(SYS_signalfd, fd, sigs, _NSIG/8);
+	if (ret >= 0) {
+		if (flags & SFD_CLOEXEC)
+			__syscall(SYS_fcntl, ret, F_SETFD, FD_CLOEXEC);
+		if (flags & SFD_NONBLOCK)
+			__syscall(SYS_fcntl, ret, F_SETFL, O_NONBLOCK);
+	}
+#endif
+	return __syscall_ret(ret);
+}
libc/musl/src/linux/splice.c
@@ -0,0 +1,8 @@
+#define _GNU_SOURCE
+#include <fcntl.h>
+#include "syscall.h"
+
+ssize_t splice(int fd_in, off_t *off_in, int fd_out, off_t *off_out, size_t len, unsigned flags)
+{
+	return syscall(SYS_splice, fd_in, off_in, fd_out, off_out, len, flags);
+}
libc/musl/src/linux/stime.c
@@ -0,0 +1,9 @@
+#define _GNU_SOURCE
+#include <time.h>
+#include <sys/time.h>
+
+int stime(const time_t *t)
+{
+	struct timeval tv = { .tv_sec = *t, .tv_usec = 0 };
+	return settimeofday(&tv, (void *)0);
+}
libc/musl/src/linux/swap.c
@@ -0,0 +1,12 @@
+#include <sys/swap.h>
+#include "syscall.h"
+
+int swapon(const char *path, int flags)
+{
+	return syscall(SYS_swapon, path, flags);
+}
+
+int swapoff(const char *path)
+{
+	return syscall(SYS_swapoff, path);
+}
libc/musl/src/linux/sync_file_range.c
@@ -0,0 +1,17 @@
+#define _GNU_SOURCE
+#include <fcntl.h>
+#include <errno.h>
+#include "syscall.h"
+
+int sync_file_range(int fd, off_t pos, off_t len, unsigned flags)
+{
+#if defined(SYS_sync_file_range2)
+	return syscall(SYS_sync_file_range2, fd, flags,
+		__SYSCALL_LL_E(pos), __SYSCALL_LL_E(len));
+#elif defined(SYS_sync_file_range)
+	return syscall(SYS_sync_file_range, fd,
+		__SYSCALL_LL_O(pos), __SYSCALL_LL_E(len), flags);
+#else
+	return __syscall_ret(-ENOSYS);
+#endif
+}
libc/musl/src/linux/syncfs.c
@@ -0,0 +1,8 @@
+#define _GNU_SOURCE
+#include <unistd.h>
+#include "syscall.h"
+
+int syncfs(int fd)
+{
+	return syscall(SYS_syncfs, fd);
+}
libc/musl/src/linux/sysinfo.c
@@ -0,0 +1,9 @@
+#include <sys/sysinfo.h>
+#include "syscall.h"
+
+int __lsysinfo(struct sysinfo *info)
+{
+	return syscall(SYS_sysinfo, info);
+}
+
+weak_alias(__lsysinfo, sysinfo);
libc/musl/src/linux/tee.c
@@ -0,0 +1,8 @@
+#define _GNU_SOURCE
+#include <fcntl.h>
+#include "syscall.h"
+
+ssize_t tee(int src, int dest, size_t len, unsigned flags)
+{
+	return syscall(SYS_tee, src, dest, len, flags);
+}
libc/musl/src/linux/timerfd.c
@@ -0,0 +1,17 @@
+#include <sys/timerfd.h>
+#include "syscall.h"
+
+int timerfd_create(int clockid, int flags)
+{
+	return syscall(SYS_timerfd_create, clockid, flags);
+}
+
+int timerfd_settime(int fd, int flags, const struct itimerspec *new, struct itimerspec *old)
+{
+	return syscall(SYS_timerfd_settime, fd, flags, new, old);
+}
+
+int timerfd_gettime(int fd, struct itimerspec *cur)
+{
+	return syscall(SYS_timerfd_gettime, fd, cur);
+}
libc/musl/src/linux/unshare.c
@@ -0,0 +1,8 @@
+#define _GNU_SOURCE
+#include <sched.h>
+#include "syscall.h"
+
+int unshare(int flags)
+{
+	return syscall(SYS_unshare, flags);
+}
libc/musl/src/linux/utimes.c
@@ -0,0 +1,8 @@
+#include <sys/time.h>
+#include "fcntl.h"
+#include "syscall.h"
+
+int utimes(const char *path, const struct timeval times[2])
+{
+	return __futimesat(AT_FDCWD, path, times);
+}
libc/musl/src/linux/vhangup.c
@@ -0,0 +1,8 @@
+#define _GNU_SOURCE
+#include <unistd.h>
+#include "syscall.h"
+
+int vhangup(void)
+{
+	return syscall(SYS_vhangup);
+}
libc/musl/src/linux/vmsplice.c
@@ -0,0 +1,8 @@
+#define _GNU_SOURCE
+#include <fcntl.h>
+#include "syscall.h"
+
+ssize_t vmsplice(int fd, const struct iovec *iov, size_t cnt, unsigned flags)
+{
+	return syscall(SYS_vmsplice, fd, iov, cnt, flags);
+}
libc/musl/src/linux/wait3.c
@@ -0,0 +1,9 @@
+#define _GNU_SOURCE
+#include <sys/wait.h>
+#include <sys/resource.h>
+#include "syscall.h"
+
+pid_t wait3(int *status, int options, struct rusage *usage)
+{
+	return wait4(-1, status, options, usage);
+}
libc/musl/src/linux/wait4.c
@@ -0,0 +1,9 @@
+#define _GNU_SOURCE
+#include <sys/wait.h>
+#include <sys/resource.h>
+#include "syscall.h"
+
+pid_t wait4(pid_t pid, int *status, int options, struct rusage *usage)
+{
+	return syscall(SYS_wait4, pid, status, options, usage);
+}
libc/musl/src/linux/xattr.c
@@ -0,0 +1,62 @@
+#include <sys/xattr.h>
+#include "syscall.h"
+
+ssize_t getxattr(const char *path, const char *name, void *value, size_t size)
+{
+	return syscall(SYS_getxattr, path, name, value, size);
+}
+
+ssize_t lgetxattr(const char *path, const char *name, void *value, size_t size)
+{
+	return syscall(SYS_lgetxattr, path, name, value, size);
+}
+
+ssize_t fgetxattr(int filedes, const char *name, void *value, size_t size)
+{
+	return syscall(SYS_fgetxattr, filedes, name, value, size);
+}
+
+ssize_t listxattr(const char *path, char *list, size_t size)
+{
+	return syscall(SYS_listxattr, path, list, size);
+}
+
+ssize_t llistxattr(const char *path, char *list, size_t size)
+{
+	return syscall(SYS_llistxattr, path, list, size);
+}
+
+ssize_t flistxattr(int filedes, char *list, size_t size)
+{
+	return syscall(SYS_flistxattr, filedes, list, size);
+}
+
+int setxattr(const char *path, const char *name, const void *value, size_t size, int flags)
+{
+	return syscall(SYS_setxattr, path, name, value, size, flags);
+}
+
+int lsetxattr(const char *path, const char *name, const void *value, size_t size, int flags)
+{
+	return syscall(SYS_lsetxattr, path, name, value, size, flags);
+}
+
+int fsetxattr(int filedes, const char *name, const void *value, size_t size, int flags)
+{
+	return syscall(SYS_fsetxattr, filedes, name, value, size, flags);
+}
+
+int removexattr(const char *path, const char *name)
+{
+	return syscall(SYS_removexattr, path, name);
+}
+
+int lremovexattr(const char *path, const char *name)
+{
+	return syscall(SYS_lremovexattr, path, name);
+}
+
+int fremovexattr(int fd, const char *name)
+{
+	return syscall(SYS_fremovexattr, fd, name);
+}
libc/musl/src/locale/__lctrans.c
@@ -0,0 +1,19 @@
+#include <locale.h>
+#include "locale_impl.h"
+
+static const char *dummy(const char *msg, const struct __locale_map *lm)
+{
+	return msg;
+}
+
+weak_alias(dummy, __lctrans_impl);
+
+const char *__lctrans(const char *msg, const struct __locale_map *lm)
+{
+	return __lctrans_impl(msg, lm);
+}
+
+const char *__lctrans_cur(const char *msg)
+{
+	return __lctrans_impl(msg, CURRENT_LOCALE->cat[LC_MESSAGES]);
+}
libc/musl/src/locale/__mo_lookup.c
@@ -0,0 +1,42 @@
+#include <stdint.h>
+#include <string.h>
+
+static inline uint32_t swapc(uint32_t x, int c)
+{
+	return c ? x>>24 | x>>8&0xff00 | x<<8&0xff0000 | x<<24 : x;
+}
+
+const char *__mo_lookup(const void *p, size_t size, const char *s)
+{
+	const uint32_t *mo = p;
+	int sw = *mo - 0x950412de;
+	uint32_t b = 0, n = swapc(mo[2], sw);
+	uint32_t o = swapc(mo[3], sw);
+	uint32_t t = swapc(mo[4], sw);
+	if (n>=size/4 || o>=size-4*n || t>=size-4*n || ((o|t)%4))
+		return 0;
+	o/=4;
+	t/=4;
+	for (;;) {
+		uint32_t ol = swapc(mo[o+2*(b+n/2)], sw);
+		uint32_t os = swapc(mo[o+2*(b+n/2)+1], sw);
+		if (os >= size || ol >= size-os || ((char *)p)[os+ol])
+			return 0;
+		int sign = strcmp(s, (char *)p + os);
+		if (!sign) {
+			uint32_t tl = swapc(mo[t+2*(b+n/2)], sw);
+			uint32_t ts = swapc(mo[t+2*(b+n/2)+1], sw);
+			if (ts >= size || tl >= size-ts || ((char *)p)[ts+tl])
+				return 0;
+			return (char *)p + ts;
+		}
+		else if (n == 1) return 0;
+		else if (sign < 0)
+			n /= 2;
+		else {
+			b += n/2;
+			n -= n/2;
+		}
+	}
+	return 0;
+}
libc/musl/src/locale/big5.h
@@ -0,0 +1,1085 @@
+12288,65292,12289,12290,65294,8231,65307,65306,65311,65281,65072,8230,8229,
+65104,65105,65106,183,65108,65109,65110,65111,65372,8211,65073,8212,65075,
+9588,65076,65103,65288,65289,65077,65078,65371,65373,65079,65080,12308,12309,
+65081,65082,12304,12305,65083,65084,12298,12299,65085,65086,12296,12297,65087,
+65088,12300,12301,65089,65090,12302,12303,65091,65092,65113,65114,65115,65116,
+65117,65118,8216,8217,8220,8221,12317,12318,8245,8242,65283,65286,65290,8251,
+167,12291,9675,9679,9651,9650,9678,9734,9733,9671,9670,9633,9632,9661,9660,
+12963,8453,175,65507,65343,717,65097,65098,65101,65102,65099,65100,65119,
+65120,65121,65291,65293,215,247,177,8730,65308,65310,65309,8806,8807,8800,
+8734,8786,8801,65122,65123,65124,65125,65126,65374,8745,8746,8869,8736,8735,
+8895,13266,13265,8747,8750,8757,8756,9792,9794,8853,8857,8593,8595,8592,8594,
+8598,8599,8601,8600,8741,8739,65295,65340,8725,65128,65284,65509,12306,65504,
+65505,65285,65312,8451,8457,65129,65130,65131,13269,13212,13213,13214,13262,
+13217,13198,13199,13252,176,20825,20827,20830,20829,20833,20835,21991,29929,
+31950,9601,9602,9603,9604,9605,9606,9607,9608,9615,9614,9613,9612,9611,9610,
+9609,9532,9524,9516,9508,9500,9620,9472,9474,9621,9484,9488,9492,9496,9581,
+9582,9584,9583,9552,9566,9578,9569,9698,9699,9701,9700,9585,9586,9587,65296,
+65297,65298,65299,65300,65301,65302,65303,65304,65305,8544,8545,8546,8547,
+8548,8549,8550,8551,8552,8553,12321,
+12322,12323,12324,12325,12326,12327,12328,12329,21313,21316,21317,65313,65314,
+65315,65316,65317,65318,65319,65320,65321,65322,65323,65324,65325,65326,65327,
+65328,65329,65330,65331,65332,65333,65334,65335,65336,65337,65338,65345,65346,
+65347,65348,65349,65350,65351,65352,65353,65354,65355,65356,65357,65358,65359,
+65360,65361,65362,65363,65364,65365,65366,65367,65368,65369,65370,913,914,915,
+916,917,918,919,920,921,922,923,924,925,926,927,928,929,931,932,933,934,935,
+936,937,945,946,947,948,949,950,951,952,953,954,955,956,957,958,959,960,961,
+963,964,965,966,967,968,969,12549,12550,12551,12552,12553,12554,12555,12556,
+12557,12558,12559,12560,12561,12562,12563,12564,12565,12566,12567,12568,12569,
+12570,12571,12572,12573,12574,12575,12576,12577,12578,12579,12580,12581,12582,
+12583,12584,12585,729,713,714,711,715,9216,9217,9218,9219,9220,9221,9222,9223,
+9224,9225,9226,9227,9228,9229,9230,9231,9232,9233,9234,9235,9236,9237,9238,
+9239,9240,9241,9242,9243,9244,9245,9246,9247,9249,8364,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,19968,20057,19969,19971,20035,20061,20102,
+20108,20154,20799,20837,20843,20960,20992,20993,21147,21269,21313,21340,21448,
+19977,19979,19976,19978,20011,20024,20961,20037,20040,20063,20062,20110,20129,
+20800,20995,21242,21315,21449,21475,22303,
+22763,22805,22823,22899,23376,23377,23379,23544,23567,23586,23608,23665,24029,
+24037,24049,24050,24051,24062,24178,24318,24331,24339,25165,19985,19984,19981,
+20013,20016,20025,20043,23609,20104,20113,20117,20114,20116,20130,20161,20160,
+20163,20166,20167,20173,20170,20171,20164,20803,20801,20839,20845,20846,20844,
+20887,20982,20998,20999,21000,21243,21246,21247,21270,21305,21320,21319,21317,
+21342,21380,21451,21450,21453,22764,22825,22827,22826,22829,23380,23569,23588,
+23610,23663,24052,24187,24319,24340,24341,24515,25096,25142,25163,25166,25903,
+25991,26007,26020,26041,26085,26352,26376,26408,27424,27490,27513,27595,27604,
+27611,27663,27700,28779,29226,29238,29243,29255,29273,29275,29356,29579,19993,
+19990,19989,19988,19992,20027,20045,20047,20046,20197,20184,20180,20181,20182,
+20183,20195,20196,20185,20190,20805,20804,20873,20874,20908,20985,20986,20984,
+21002,21152,21151,21253,21254,21271,21277,20191,21322,21321,21345,21344,21359,
+21358,21435,21487,21476,21491,21484,21486,21481,21480,21500,21496,21493,21483,
+21478,21482,21490,21489,21488,21477,21485,21499,22235,22234,22806,22830,22833,
+22900,22902,23381,23427,23612,24040,24039,24038,24066,24067,24179,24188,24321,
+24344,24343,24517,25098,25171,25172,25170,25169,26021,26086,26414,26412,26410,
+26411,26413,27491,27597,27665,27664,27704,27713,27712,27710,29359,29572,29577,
+29916,29926,29976,29983,29992,29993,30000,30001,30002,30003,30091,30333,30382,
+30399,30446,30683,30690,30707,31034,31166,31348,31435,19998,19999,20050,20051,
+20073,20121,20132,20134,20133,20223,20233,20249,20234,
+20245,20237,20240,20241,20239,20210,20214,20219,20208,20211,20221,20225,20235,
+20809,20807,20806,20808,20840,20849,20877,20912,21015,21009,21010,21006,21014,
+21155,21256,21281,21280,21360,21361,21513,21519,21516,21514,21520,21505,21515,
+21508,21521,21517,21512,21507,21518,21510,21522,22240,22238,22237,22323,22320,
+22312,22317,22316,22319,22313,22809,22810,22839,22840,22916,22904,22915,22909,
+22905,22914,22913,23383,23384,23431,23432,23429,23433,23546,23574,23673,24030,
+24070,24182,24180,24335,24347,24537,24534,25102,25100,25101,25104,25187,25179,
+25176,25910,26089,26088,26092,26093,26354,26355,26377,26429,26420,26417,26421,
+27425,27492,27515,27670,27741,27735,27737,27743,27744,27728,27733,27745,27739,
+27725,27726,28784,29279,29277,30334,31481,31859,31992,32566,32650,32701,32769,
+32771,32780,32786,32819,32895,32905,32907,32908,33251,33258,33267,33276,33292,
+33307,33311,33390,33394,33406,34411,34880,34892,34915,35199,38433,20018,20136,
+20301,20303,20295,20311,20318,20276,20315,20309,20272,20304,20305,20285,20282,
+20280,20291,20308,20284,20294,20323,20316,20320,20271,20302,20278,20313,20317,
+20296,20314,20812,20811,20813,20853,20918,20919,21029,21028,21033,21034,21032,
+21163,21161,21162,21164,21283,21363,21365,21533,21549,21534,21566,21542,21582,
+21543,21574,21571,21555,21576,21570,21531,21545,21578,21561,21563,21560,21550,
+21557,21558,21536,21564,21568,21553,21547,21535,21548,22250,22256,22244,22251,
+22346,22353,22336,22349,22343,22350,22334,22352,22351,22331,22767,22846,22941,
+22930,22952,22942,22947,22937,22934,22925,22948,22931,
+22922,22949,23389,23388,23386,23387,23436,23435,23439,23596,23616,23617,23615,
+23614,23696,23697,23700,23692,24043,24076,24207,24199,24202,24311,24324,24351,
+24420,24418,24439,24441,24536,24524,24535,24525,24561,24555,24568,24554,25106,
+25105,25220,25239,25238,25216,25206,25225,25197,25226,25212,25214,25209,25203,
+25234,25199,25240,25198,25237,25235,25233,25222,25913,25915,25912,26097,26356,
+26463,26446,26447,26448,26449,26460,26454,26462,26441,26438,26464,26451,26455,
+27493,27599,27714,27742,27801,27777,27784,27785,27781,27803,27754,27770,27792,
+27760,27788,27752,27798,27794,27773,27779,27762,27774,27764,27782,27766,27789,
+27796,27800,27778,28790,28796,28797,28792,29282,29281,29280,29380,29378,29590,
+29996,29995,30007,30008,30338,30447,30691,31169,31168,31167,31350,31995,32597,
+32918,32915,32925,32920,32923,32922,32946,33391,33426,33419,33421,35211,35282,
+35328,35895,35910,35925,35997,36196,36208,36275,36523,36554,36763,36784,36802,
+36806,36805,36804,24033,37009,37026,37034,37030,37027,37193,37318,37324,38450,
+38446,38449,38442,38444,20006,20054,20083,20107,20123,20126,20139,20140,20335,
+20381,20365,20339,20351,20332,20379,20363,20358,20355,20336,20341,20360,20329,
+20347,20374,20350,20367,20369,20346,20820,20818,20821,20841,20855,20854,20856,
+20925,20989,21051,21048,21047,21050,21040,21038,21046,21057,21182,21179,21330,
+21332,21331,21329,21350,21367,21368,21369,21462,21460,21463,21619,21621,21654,
+21624,21653,21632,21627,21623,21636,21650,21638,21628,21648,21617,21622,21644,
+21658,21602,21608,21643,21629,21646,22266,22403,22391,
+22378,22377,22369,22374,22372,22396,22812,22857,22855,22856,22852,22868,22974,
+22971,22996,22969,22958,22993,22982,22992,22989,22987,22995,22986,22959,22963,
+22994,22981,23391,23396,23395,23447,23450,23448,23452,23449,23451,23578,23624,
+23621,23622,23735,23713,23736,23721,23723,23729,23731,24088,24090,24086,24085,
+24091,24081,24184,24218,24215,24220,24213,24214,24310,24358,24359,24361,24448,
+24449,24447,24444,24541,24544,24573,24565,24575,24591,24596,24623,24629,24598,
+24618,24597,24609,24615,24617,24619,24603,25110,25109,25151,25150,25152,25215,
+25289,25292,25284,25279,25282,25273,25298,25307,25259,25299,25300,25291,25288,
+25256,25277,25276,25296,25305,25287,25293,25269,25306,25265,25304,25302,25303,
+25286,25260,25294,25918,26023,26044,26106,26132,26131,26124,26118,26114,26126,
+26112,26127,26133,26122,26119,26381,26379,26477,26507,26517,26481,26524,26483,
+26487,26503,26525,26519,26479,26480,26495,26505,26494,26512,26485,26522,26515,
+26492,26474,26482,27427,27494,27495,27519,27667,27675,27875,27880,27891,27825,
+27852,27877,27827,27837,27838,27836,27874,27819,27861,27859,27832,27844,27833,
+27841,27822,27863,27845,27889,27839,27835,27873,27867,27850,27820,27887,27868,
+27862,27872,28821,28814,28818,28810,28825,29228,29229,29240,29256,29287,29289,
+29376,29390,29401,29399,29392,29609,29608,29599,29611,29605,30013,30109,30105,
+30106,30340,30402,30450,30452,30693,30717,31038,31040,31041,31177,31176,31354,
+31353,31482,31998,32596,32652,32651,32773,32954,32933,32930,32945,32929,32939,
+32937,32948,32938,32943,33253,33278,33293,33459,33437,
+33433,33453,33469,33439,33465,33457,33452,33445,33455,33464,33443,33456,33470,
+33463,34382,34417,21021,34920,36555,36814,36820,36817,37045,37048,37041,37046,
+37319,37329,38263,38272,38428,38464,38463,38459,38468,38466,38585,38632,38738,
+38750,20127,20141,20142,20449,20405,20399,20415,20448,20433,20431,20445,20419,
+20406,20440,20447,20426,20439,20398,20432,20420,20418,20442,20430,20446,20407,
+20823,20882,20881,20896,21070,21059,21066,21069,21068,21067,21063,21191,21193,
+21187,21185,21261,21335,21371,21402,21467,21676,21696,21672,21710,21705,21688,
+21670,21683,21703,21698,21693,21674,21697,21700,21704,21679,21675,21681,21691,
+21673,21671,21695,22271,22402,22411,22432,22435,22434,22478,22446,22419,22869,
+22865,22863,22862,22864,23004,23000,23039,23011,23016,23043,23013,23018,23002,
+23014,23041,23035,23401,23459,23462,23460,23458,23461,23553,23630,23631,23629,
+23627,23769,23762,24055,24093,24101,24095,24189,24224,24230,24314,24328,24365,
+24421,24456,24453,24458,24459,24455,24460,24457,24594,24605,24608,24613,24590,
+24616,24653,24688,24680,24674,24646,24643,24684,24683,24682,24676,25153,25308,
+25366,25353,25340,25325,25345,25326,25341,25351,25329,25335,25327,25324,25342,
+25332,25361,25346,25919,25925,26027,26045,26082,26149,26157,26144,26151,26159,
+26143,26152,26161,26148,26359,26623,26579,26609,26580,26576,26604,26550,26543,
+26613,26601,26607,26564,26577,26548,26586,26597,26552,26575,26590,26611,26544,
+26585,26594,26589,26578,27498,27523,27526,27573,27602,27607,27679,27849,27915,
+27954,27946,27969,27941,27916,27953,27934,27927,27963,
+27965,27966,27958,27931,27893,27961,27943,27960,27945,27950,27957,27918,27947,
+28843,28858,28851,28844,28847,28845,28856,28846,28836,29232,29298,29295,29300,
+29417,29408,29409,29623,29642,29627,29618,29645,29632,29619,29978,29997,30031,
+30028,30030,30027,30123,30116,30117,30114,30115,30328,30342,30343,30344,30408,
+30406,30403,30405,30465,30457,30456,30473,30475,30462,30460,30471,30684,30722,
+30740,30732,30733,31046,31049,31048,31047,31161,31162,31185,31186,31179,31359,
+31361,31487,31485,31869,32002,32005,32000,32009,32007,32004,32006,32568,32654,
+32703,32772,32784,32781,32785,32822,32982,32997,32986,32963,32964,32972,32993,
+32987,32974,32990,32996,32989,33268,33314,33511,33539,33541,33507,33499,33510,
+33540,33509,33538,33545,33490,33495,33521,33537,33500,33492,33489,33502,33491,
+33503,33519,33542,34384,34425,34427,34426,34893,34923,35201,35284,35336,35330,
+35331,35998,36000,36212,36211,36276,36557,36556,36848,36838,36834,36842,36837,
+36845,36843,36836,36840,37066,37070,37057,37059,37195,37194,37325,38274,38480,
+38475,38476,38477,38754,38761,38859,38893,38899,38913,39080,39131,39135,39318,
+39321,20056,20147,20492,20493,20515,20463,20518,20517,20472,20521,20502,20486,
+20540,20511,20506,20498,20497,20474,20480,20500,20520,20465,20513,20491,20505,
+20504,20467,20462,20525,20522,20478,20523,20489,20860,20900,20901,20898,20941,
+20940,20934,20939,21078,21084,21076,21083,21085,21290,21375,21407,21405,21471,
+21736,21776,21761,21815,21756,21733,21746,21766,21754,21780,21737,21741,21729,
+21769,21742,21738,21734,21799,21767,21757,21775,22275,
+22276,22466,22484,22475,22467,22537,22799,22871,22872,22874,23057,23064,23068,
+23071,23067,23059,23020,23072,23075,23081,23077,23052,23049,23403,23640,23472,
+23475,23478,23476,23470,23477,23481,23480,23556,23633,23637,23632,23789,23805,
+23803,23786,23784,23792,23798,23809,23796,24046,24109,24107,24235,24237,24231,
+24369,24466,24465,24464,24665,24675,24677,24656,24661,24685,24681,24687,24708,
+24735,24730,24717,24724,24716,24709,24726,25159,25331,25352,25343,25422,25406,
+25391,25429,25410,25414,25423,25417,25402,25424,25405,25386,25387,25384,25421,
+25420,25928,25929,26009,26049,26053,26178,26185,26191,26179,26194,26188,26181,
+26177,26360,26388,26389,26391,26657,26680,26696,26694,26707,26681,26690,26708,
+26665,26803,26647,26700,26705,26685,26612,26704,26688,26684,26691,26666,26693,
+26643,26648,26689,27530,27529,27575,27683,27687,27688,27686,27684,27888,28010,
+28053,28040,28039,28006,28024,28023,27993,28051,28012,28041,28014,27994,28020,
+28009,28044,28042,28025,28037,28005,28052,28874,28888,28900,28889,28872,28879,
+29241,29305,29436,29433,29437,29432,29431,29574,29677,29705,29678,29664,29674,
+29662,30036,30045,30044,30042,30041,30142,30149,30151,30130,30131,30141,30140,
+30137,30146,30136,30347,30384,30410,30413,30414,30505,30495,30496,30504,30697,
+30768,30759,30776,30749,30772,30775,30757,30765,30752,30751,30770,31061,31056,
+31072,31071,31062,31070,31069,31063,31066,31204,31203,31207,31199,31206,31209,
+31192,31364,31368,31449,31494,31505,31881,32033,32023,32011,32010,32032,32034,
+32020,32016,32021,32026,32028,32013,32025,32027,32570,
+32607,32660,32709,32705,32774,32792,32789,32793,32791,32829,32831,33009,33026,
+33008,33029,33005,33012,33030,33016,33011,33032,33021,33034,33020,33007,33261,
+33260,33280,33296,33322,33323,33320,33324,33467,33579,33618,33620,33610,33592,
+33616,33609,33589,33588,33615,33586,33593,33590,33559,33600,33585,33576,33603,
+34388,34442,34474,34451,34468,34473,34444,34467,34460,34928,34935,34945,34946,
+34941,34937,35352,35344,35342,35340,35349,35338,35351,35347,35350,35343,35345,
+35912,35962,35961,36001,36002,36215,36524,36562,36564,36559,36785,36865,36870,
+36855,36864,36858,36852,36867,36861,36869,36856,37013,37089,37085,37090,37202,
+37197,37196,37336,37341,37335,37340,37337,38275,38498,38499,38497,38491,38493,
+38500,38488,38494,38587,39138,39340,39592,39640,39717,39730,39740,20094,20602,
+20605,20572,20551,20547,20556,20570,20553,20581,20598,20558,20565,20597,20596,
+20599,20559,20495,20591,20589,20828,20885,20976,21098,21103,21202,21209,21208,
+21205,21264,21263,21273,21311,21312,21310,21443,26364,21830,21866,21862,21828,
+21854,21857,21827,21834,21809,21846,21839,21845,21807,21860,21816,21806,21852,
+21804,21859,21811,21825,21847,22280,22283,22281,22495,22533,22538,22534,22496,
+22500,22522,22530,22581,22519,22521,22816,22882,23094,23105,23113,23142,23146,
+23104,23100,23138,23130,23110,23114,23408,23495,23493,23492,23490,23487,23494,
+23561,23560,23559,23648,23644,23645,23815,23814,23822,23835,23830,23842,23825,
+23849,23828,23833,23844,23847,23831,24034,24120,24118,24115,24119,24247,24248,
+24246,24245,24254,24373,24375,24407,24428,24425,24427,
+24471,24473,24478,24472,24481,24480,24476,24703,24739,24713,24736,24744,24779,
+24756,24806,24765,24773,24763,24757,24796,24764,24792,24789,24774,24799,24760,
+24794,24775,25114,25115,25160,25504,25511,25458,25494,25506,25509,25463,25447,
+25496,25514,25457,25513,25481,25475,25499,25451,25512,25476,25480,25497,25505,
+25516,25490,25487,25472,25467,25449,25448,25466,25949,25942,25937,25945,25943,
+21855,25935,25944,25941,25940,26012,26011,26028,26063,26059,26060,26062,26205,
+26202,26212,26216,26214,26206,26361,21207,26395,26753,26799,26786,26771,26805,
+26751,26742,26801,26791,26775,26800,26755,26820,26797,26758,26757,26772,26781,
+26792,26783,26785,26754,27442,27578,27627,27628,27691,28046,28092,28147,28121,
+28082,28129,28108,28132,28155,28154,28165,28103,28107,28079,28113,28078,28126,
+28153,28088,28151,28149,28101,28114,28186,28085,28122,28139,28120,28138,28145,
+28142,28136,28102,28100,28074,28140,28095,28134,28921,28937,28938,28925,28911,
+29245,29309,29313,29468,29467,29462,29459,29465,29575,29701,29706,29699,29702,
+29694,29709,29920,29942,29943,29980,29986,30053,30054,30050,30064,30095,30164,
+30165,30133,30154,30157,30350,30420,30418,30427,30519,30526,30524,30518,30520,
+30522,30827,30787,30798,31077,31080,31085,31227,31378,31381,31520,31528,31515,
+31532,31526,31513,31518,31534,31890,31895,31893,32070,32067,32113,32046,32057,
+32060,32064,32048,32051,32068,32047,32066,32050,32049,32573,32670,32666,32716,
+32718,32722,32796,32842,32838,33071,33046,33059,33067,33065,33072,33060,33282,
+33333,33335,33334,33337,33678,33694,33688,33656,33698,
+33686,33725,33707,33682,33674,33683,33673,33696,33655,33659,33660,33670,33703,
+34389,24426,34503,34496,34486,34500,34485,34502,34507,34481,34479,34505,34899,
+34974,34952,34987,34962,34966,34957,34955,35219,35215,35370,35357,35363,35365,
+35377,35373,35359,35355,35362,35913,35930,36009,36012,36011,36008,36010,36007,
+36199,36198,36286,36282,36571,36575,36889,36877,36890,36887,36899,36895,36893,
+36880,36885,36894,36896,36879,36898,36886,36891,36884,37096,37101,37117,37207,
+37326,37365,37350,37347,37351,37357,37353,38281,38506,38517,38515,38520,38512,
+38516,38518,38519,38508,38592,38634,38633,31456,31455,38914,38915,39770,40165,
+40565,40575,40613,40635,20642,20621,20613,20633,20625,20608,20630,20632,20634,
+26368,20977,21106,21108,21109,21097,21214,21213,21211,21338,21413,21883,21888,
+21927,21884,21898,21917,21912,21890,21916,21930,21908,21895,21899,21891,21939,
+21934,21919,21822,21938,21914,21947,21932,21937,21886,21897,21931,21913,22285,
+22575,22570,22580,22564,22576,22577,22561,22557,22560,22777,22778,22880,23159,
+23194,23167,23186,23195,23207,23411,23409,23506,23500,23507,23504,23562,23563,
+23601,23884,23888,23860,23879,24061,24133,24125,24128,24131,24190,24266,24257,
+24258,24260,24380,24429,24489,24490,24488,24785,24801,24754,24758,24800,24860,
+24867,24826,24853,24816,24827,24820,24936,24817,24846,24822,24841,24832,24850,
+25119,25161,25507,25484,25551,25536,25577,25545,25542,25549,25554,25571,25552,
+25569,25558,25581,25582,25462,25588,25578,25563,25682,25562,25593,25950,25958,
+25954,25955,26001,26000,26031,26222,26224,26228,26230,
+26223,26257,26234,26238,26231,26366,26367,26399,26397,26874,26837,26848,26840,
+26839,26885,26847,26869,26862,26855,26873,26834,26866,26851,26827,26829,26893,
+26898,26894,26825,26842,26990,26875,27454,27450,27453,27544,27542,27580,27631,
+27694,27695,27692,28207,28216,28244,28193,28210,28263,28234,28192,28197,28195,
+28187,28251,28248,28196,28246,28270,28205,28198,28271,28212,28237,28218,28204,
+28227,28189,28222,28363,28297,28185,28238,28259,28228,28274,28265,28255,28953,
+28954,28966,28976,28961,28982,29038,28956,29260,29316,29312,29494,29477,29492,
+29481,29754,29738,29747,29730,29733,29749,29750,29748,29743,29723,29734,29736,
+29989,29990,30059,30058,30178,30171,30179,30169,30168,30174,30176,30331,30332,
+30358,30355,30388,30428,30543,30701,30813,30828,30831,31245,31240,31243,31237,
+31232,31384,31383,31382,31461,31459,31561,31574,31558,31568,31570,31572,31565,
+31563,31567,31569,31903,31909,32094,32080,32104,32085,32043,32110,32114,32097,
+32102,32098,32112,32115,21892,32724,32725,32779,32850,32901,33109,33108,33099,
+33105,33102,33081,33094,33086,33100,33107,33140,33298,33308,33769,33795,33784,
+33805,33760,33733,33803,33729,33775,33777,33780,33879,33802,33776,33804,33740,
+33789,33778,33738,33848,33806,33796,33756,33799,33748,33759,34395,34527,34521,
+34541,34516,34523,34532,34512,34526,34903,35009,35010,34993,35203,35222,35387,
+35424,35413,35422,35388,35393,35412,35419,35408,35398,35380,35386,35382,35414,
+35937,35970,36015,36028,36019,36029,36033,36027,36032,36020,36023,36022,36031,
+36024,36234,36229,36225,36302,36317,36299,36314,36305,
+36300,36315,36294,36603,36600,36604,36764,36910,36917,36913,36920,36914,36918,
+37122,37109,37129,37118,37219,37221,37327,37396,37397,37411,37385,37406,37389,
+37392,37383,37393,38292,38287,38283,38289,38291,38290,38286,38538,38542,38539,
+38525,38533,38534,38541,38514,38532,38593,38597,38596,38598,38599,38639,38642,
+38860,38917,38918,38920,39143,39146,39151,39145,39154,39149,39342,39341,40643,
+40653,40657,20098,20653,20661,20658,20659,20677,20670,20652,20663,20667,20655,
+20679,21119,21111,21117,21215,21222,21220,21218,21219,21295,21983,21992,21971,
+21990,21966,21980,21959,21969,21987,21988,21999,21978,21985,21957,21958,21989,
+21961,22290,22291,22622,22609,22616,22615,22618,22612,22635,22604,22637,22602,
+22626,22610,22603,22887,23233,23241,23244,23230,23229,23228,23219,23234,23218,
+23913,23919,24140,24185,24265,24264,24338,24409,24492,24494,24858,24847,24904,
+24863,24819,24859,24825,24833,24840,24910,24908,24900,24909,24894,24884,24871,
+24845,24838,24887,25121,25122,25619,25662,25630,25642,25645,25661,25644,25615,
+25628,25620,25613,25654,25622,25623,25606,25964,26015,26032,26263,26249,26247,
+26248,26262,26244,26264,26253,26371,27028,26989,26970,26999,26976,26964,26997,
+26928,27010,26954,26984,26987,26974,26963,27001,27014,26973,26979,26971,27463,
+27506,27584,27583,27603,27645,28322,28335,28371,28342,28354,28304,28317,28359,
+28357,28325,28312,28348,28346,28331,28369,28310,28316,28356,28372,28330,28327,
+28340,29006,29017,29033,29028,29001,29031,29020,29036,29030,29004,29029,29022,
+28998,29032,29014,29242,29266,29495,29509,29503,29502,
+29807,29786,29781,29791,29790,29761,29759,29785,29787,29788,30070,30072,30208,
+30192,30209,30194,30193,30202,30207,30196,30195,30430,30431,30555,30571,30566,
+30558,30563,30585,30570,30572,30556,30565,30568,30562,30702,30862,30896,30871,
+30872,30860,30857,30844,30865,30867,30847,31098,31103,31105,33836,31165,31260,
+31258,31264,31252,31263,31262,31391,31392,31607,31680,31584,31598,31591,31921,
+31923,31925,32147,32121,32145,32129,32143,32091,32622,32617,32618,32626,32681,
+32680,32676,32854,32856,32902,32900,33137,33136,33144,33125,33134,33139,33131,
+33145,33146,33126,33285,33351,33922,33911,33853,33841,33909,33894,33899,33865,
+33900,33883,33852,33845,33889,33891,33897,33901,33862,34398,34396,34399,34553,
+34579,34568,34567,34560,34558,34555,34562,34563,34566,34570,34905,35039,35028,
+35033,35036,35032,35037,35041,35018,35029,35026,35228,35299,35435,35442,35443,
+35430,35433,35440,35463,35452,35427,35488,35441,35461,35437,35426,35438,35436,
+35449,35451,35390,35432,35938,35978,35977,36042,36039,36040,36036,36018,36035,
+36034,36037,36321,36319,36328,36335,36339,36346,36330,36324,36326,36530,36611,
+36617,36606,36618,36767,36786,36939,36938,36947,36930,36948,36924,36949,36944,
+36935,36943,36942,36941,36945,36926,36929,37138,37143,37228,37226,37225,37321,
+37431,37463,37432,37437,37440,37438,37467,37451,37476,37457,37428,37449,37453,
+37445,37433,37439,37466,38296,38552,38548,38549,38605,38603,38601,38602,38647,
+38651,38649,38646,38742,38772,38774,38928,38929,38931,38922,38930,38924,39164,
+39156,39165,39166,39347,39345,39348,39649,40169,40578,
+40718,40723,40736,20711,20718,20709,20694,20717,20698,20693,20687,20689,20721,
+20686,20713,20834,20979,21123,21122,21297,21421,22014,22016,22043,22039,22013,
+22036,22022,22025,22029,22030,22007,22038,22047,22024,22032,22006,22296,22294,
+22645,22654,22659,22675,22666,22649,22661,22653,22781,22821,22818,22820,22890,
+22889,23265,23270,23273,23255,23254,23256,23267,23413,23518,23527,23521,23525,
+23526,23528,23522,23524,23519,23565,23650,23940,23943,24155,24163,24149,24151,
+24148,24275,24278,24330,24390,24432,24505,24903,24895,24907,24951,24930,24931,
+24927,24922,24920,24949,25130,25735,25688,25684,25764,25720,25695,25722,25681,
+25703,25652,25709,25723,25970,26017,26071,26070,26274,26280,26269,27036,27048,
+27029,27073,27054,27091,27083,27035,27063,27067,27051,27060,27088,27085,27053,
+27084,27046,27075,27043,27465,27468,27699,28467,28436,28414,28435,28404,28457,
+28478,28448,28460,28431,28418,28450,28415,28399,28422,28465,28472,28466,28451,
+28437,28459,28463,28552,28458,28396,28417,28402,28364,28407,29076,29081,29053,
+29066,29060,29074,29246,29330,29334,29508,29520,29796,29795,29802,29808,29805,
+29956,30097,30247,30221,30219,30217,30227,30433,30435,30596,30589,30591,30561,
+30913,30879,30887,30899,30889,30883,31118,31119,31117,31278,31281,31402,31401,
+31469,31471,31649,31637,31627,31605,31639,31645,31636,31631,31672,31623,31620,
+31929,31933,31934,32187,32176,32156,32189,32190,32160,32202,32180,32178,32177,
+32186,32162,32191,32181,32184,32173,32210,32199,32172,32624,32736,32737,32735,
+32862,32858,32903,33104,33152,33167,33160,33162,33151,
+33154,33255,33274,33287,33300,33310,33355,33993,33983,33990,33988,33945,33950,
+33970,33948,33995,33976,33984,34003,33936,33980,34001,33994,34623,34588,34619,
+34594,34597,34612,34584,34645,34615,34601,35059,35074,35060,35065,35064,35069,
+35048,35098,35055,35494,35468,35486,35491,35469,35489,35475,35492,35498,35493,
+35496,35480,35473,35482,35495,35946,35981,35980,36051,36049,36050,36203,36249,
+36245,36348,36628,36626,36629,36627,36771,36960,36952,36956,36963,36953,36958,
+36962,36957,36955,37145,37144,37150,37237,37240,37239,37236,37496,37504,37509,
+37528,37526,37499,37523,37532,37544,37500,37521,38305,38312,38313,38307,38309,
+38308,38553,38556,38555,38604,38610,38656,38780,38789,38902,38935,38936,39087,
+39089,39171,39173,39180,39177,39361,39599,39600,39654,39745,39746,40180,40182,
+40179,40636,40763,40778,20740,20736,20731,20725,20729,20738,20744,20745,20741,
+20956,21127,21128,21129,21133,21130,21232,21426,22062,22075,22073,22066,22079,
+22068,22057,22099,22094,22103,22132,22070,22063,22064,22656,22687,22686,22707,
+22684,22702,22697,22694,22893,23305,23291,23307,23285,23308,23304,23534,23532,
+23529,23531,23652,23653,23965,23956,24162,24159,24161,24290,24282,24287,24285,
+24291,24288,24392,24433,24503,24501,24950,24935,24942,24925,24917,24962,24956,
+24944,24939,24958,24999,24976,25003,24974,25004,24986,24996,24980,25006,25134,
+25705,25711,25721,25758,25778,25736,25744,25776,25765,25747,25749,25769,25746,
+25774,25773,25771,25754,25772,25753,25762,25779,25973,25975,25976,26286,26283,
+26292,26289,27171,27167,27112,27137,27166,27161,27133,
+27169,27155,27146,27123,27138,27141,27117,27153,27472,27470,27556,27589,27590,
+28479,28540,28548,28497,28518,28500,28550,28525,28507,28536,28526,28558,28538,
+28528,28516,28567,28504,28373,28527,28512,28511,29087,29100,29105,29096,29270,
+29339,29518,29527,29801,29835,29827,29822,29824,30079,30240,30249,30239,30244,
+30246,30241,30242,30362,30394,30436,30606,30599,30604,30609,30603,30923,30917,
+30906,30922,30910,30933,30908,30928,31295,31292,31296,31293,31287,31291,31407,
+31406,31661,31665,31684,31668,31686,31687,31681,31648,31692,31946,32224,32244,
+32239,32251,32216,32236,32221,32232,32227,32218,32222,32233,32158,32217,32242,
+32249,32629,32631,32687,32745,32806,33179,33180,33181,33184,33178,33176,34071,
+34109,34074,34030,34092,34093,34067,34065,34083,34081,34068,34028,34085,34047,
+34054,34690,34676,34678,34656,34662,34680,34664,34649,34647,34636,34643,34907,
+34909,35088,35079,35090,35091,35093,35082,35516,35538,35527,35524,35477,35531,
+35576,35506,35529,35522,35519,35504,35542,35533,35510,35513,35547,35916,35918,
+35948,36064,36062,36070,36068,36076,36077,36066,36067,36060,36074,36065,36205,
+36255,36259,36395,36368,36381,36386,36367,36393,36383,36385,36382,36538,36637,
+36635,36639,36649,36646,36650,36636,36638,36645,36969,36974,36968,36973,36983,
+37168,37165,37159,37169,37255,37257,37259,37251,37573,37563,37559,37610,37548,
+37604,37569,37555,37564,37586,37575,37616,37554,38317,38321,38660,38662,38663,
+38665,38752,38797,38795,38799,38945,38955,38940,39091,39178,39187,39186,39192,
+39389,39376,39391,39387,39377,39381,39378,39385,39607,
+39662,39663,39719,39749,39748,39799,39791,40198,40201,40195,40617,40638,40654,
+22696,40786,20754,20760,20756,20752,20757,20864,20906,20957,21137,21139,21235,
+22105,22123,22137,22121,22116,22136,22122,22120,22117,22129,22127,22124,22114,
+22134,22721,22718,22727,22725,22894,23325,23348,23416,23536,23566,24394,25010,
+24977,25001,24970,25037,25014,25022,25034,25032,25136,25797,25793,25803,25787,
+25788,25818,25796,25799,25794,25805,25791,25810,25812,25790,25972,26310,26313,
+26297,26308,26311,26296,27197,27192,27194,27225,27243,27224,27193,27204,27234,
+27233,27211,27207,27189,27231,27208,27481,27511,27653,28610,28593,28577,28611,
+28580,28609,28583,28595,28608,28601,28598,28582,28576,28596,29118,29129,29136,
+29138,29128,29141,29113,29134,29145,29148,29123,29124,29544,29852,29859,29848,
+29855,29854,29922,29964,29965,30260,30264,30266,30439,30437,30624,30622,30623,
+30629,30952,30938,30956,30951,31142,31309,31310,31302,31308,31307,31418,31705,
+31761,31689,31716,31707,31713,31721,31718,31957,31958,32266,32273,32264,32283,
+32291,32286,32285,32265,32272,32633,32690,32752,32753,32750,32808,33203,33193,
+33192,33275,33288,33368,33369,34122,34137,34120,34152,34153,34115,34121,34157,
+34154,34142,34691,34719,34718,34722,34701,34913,35114,35122,35109,35115,35105,
+35242,35238,35558,35578,35563,35569,35584,35548,35559,35566,35582,35585,35586,
+35575,35565,35571,35574,35580,35947,35949,35987,36084,36420,36401,36404,36418,
+36409,36405,36667,36655,36664,36659,36776,36774,36981,36980,36984,36978,36988,
+36986,37172,37266,37664,37686,37624,37683,37679,37666,
+37628,37675,37636,37658,37648,37670,37665,37653,37678,37657,38331,38567,38568,
+38570,38613,38670,38673,38678,38669,38675,38671,38747,38748,38758,38808,38960,
+38968,38971,38967,38957,38969,38948,39184,39208,39198,39195,39201,39194,39405,
+39394,39409,39608,39612,39675,39661,39720,39825,40213,40227,40230,40232,40210,
+40219,40664,40660,40845,40860,20778,20767,20769,20786,21237,22158,22144,22160,
+22149,22151,22159,22741,22739,22737,22734,23344,23338,23332,23418,23607,23656,
+23996,23994,23997,23992,24171,24396,24509,25033,25026,25031,25062,25035,25138,
+25140,25806,25802,25816,25824,25840,25830,25836,25841,25826,25837,25986,25987,
+26329,26326,27264,27284,27268,27298,27292,27355,27299,27262,27287,27280,27296,
+27484,27566,27610,27656,28632,28657,28639,28640,28635,28644,28651,28655,28544,
+28652,28641,28649,28629,28654,28656,29159,29151,29166,29158,29157,29165,29164,
+29172,29152,29237,29254,29552,29554,29865,29872,29862,29864,30278,30274,30284,
+30442,30643,30634,30640,30636,30631,30637,30703,30967,30970,30964,30959,30977,
+31143,31146,31319,31423,31751,31757,31742,31735,31756,31712,31968,31964,31966,
+31970,31967,31961,31965,32302,32318,32326,32311,32306,32323,32299,32317,32305,
+32325,32321,32308,32313,32328,32309,32319,32303,32580,32755,32764,32881,32882,
+32880,32879,32883,33222,33219,33210,33218,33216,33215,33213,33225,33214,33256,
+33289,33393,34218,34180,34174,34204,34193,34196,34223,34203,34183,34216,34186,
+34407,34752,34769,34739,34770,34758,34731,34747,34746,34760,34763,35131,35126,
+35140,35128,35133,35244,35598,35607,35609,35611,35594,
+35616,35613,35588,35600,35905,35903,35955,36090,36093,36092,36088,36091,36264,
+36425,36427,36424,36426,36676,36670,36674,36677,36671,36991,36989,36996,36993,
+36994,36992,37177,37283,37278,37276,37709,37762,37672,37749,37706,37733,37707,
+37656,37758,37740,37723,37744,37722,37716,38346,38347,38348,38344,38342,38577,
+38584,38614,38684,38686,38816,38867,38982,39094,39221,39425,39423,39854,39851,
+39850,39853,40251,40255,40587,40655,40670,40668,40669,40667,40766,40779,21474,
+22165,22190,22745,22744,23352,24413,25059,25139,25844,25842,25854,25862,25850,
+25851,25847,26039,26332,26406,27315,27308,27331,27323,27320,27330,27310,27311,
+27487,27512,27567,28681,28683,28670,28678,28666,28689,28687,29179,29180,29182,
+29176,29559,29557,29863,29887,29973,30294,30296,30290,30653,30655,30651,30652,
+30990,31150,31329,31330,31328,31428,31429,31787,31783,31786,31774,31779,31777,
+31975,32340,32341,32350,32346,32353,32338,32345,32584,32761,32763,32887,32886,
+33229,33231,33290,34255,34217,34253,34256,34249,34224,34234,34233,34214,34799,
+34796,34802,34784,35206,35250,35316,35624,35641,35628,35627,35920,36101,36441,
+36451,36454,36452,36447,36437,36544,36681,36685,36999,36995,37000,37291,37292,
+37328,37780,37770,37782,37794,37811,37806,37804,37808,37784,37786,37783,38356,
+38358,38352,38357,38626,38620,38617,38619,38622,38692,38819,38822,38829,38905,
+38989,38991,38988,38990,38995,39098,39230,39231,39229,39214,39333,39438,39617,
+39683,39686,39759,39758,39757,39882,39881,39933,39880,39872,40273,40285,40288,
+40672,40725,40748,20787,22181,22750,22751,22754,23541,
+40848,24300,25074,25079,25078,25077,25856,25871,26336,26333,27365,27357,27354,
+27347,28699,28703,28712,28698,28701,28693,28696,29190,29197,29272,29346,29560,
+29562,29885,29898,29923,30087,30086,30303,30305,30663,31001,31153,31339,31337,
+31806,31807,31800,31805,31799,31808,32363,32365,32377,32361,32362,32645,32371,
+32694,32697,32696,33240,34281,34269,34282,34261,34276,34277,34295,34811,34821,
+34829,34809,34814,35168,35167,35158,35166,35649,35676,35672,35657,35674,35662,
+35663,35654,35673,36104,36106,36476,36466,36487,36470,36460,36474,36468,36692,
+36686,36781,37002,37003,37297,37294,37857,37841,37855,37827,37832,37852,37853,
+37846,37858,37837,37848,37860,37847,37864,38364,38580,38627,38698,38695,38753,
+38876,38907,39006,39000,39003,39100,39237,39241,39446,39449,39693,39912,39911,
+39894,39899,40329,40289,40306,40298,40300,40594,40599,40595,40628,21240,22184,
+22199,22198,22196,22204,22756,23360,23363,23421,23542,24009,25080,25082,25880,
+25876,25881,26342,26407,27372,28734,28720,28722,29200,29563,29903,30306,30309,
+31014,31018,31020,31019,31431,31478,31820,31811,31821,31983,31984,36782,32381,
+32380,32386,32588,32768,33242,33382,34299,34297,34321,34298,34310,34315,34311,
+34314,34836,34837,35172,35258,35320,35696,35692,35686,35695,35679,35691,36111,
+36109,36489,36481,36485,36482,37300,37323,37912,37891,37885,38369,38704,39108,
+39250,39249,39336,39467,39472,39479,39477,39955,39949,40569,40629,40680,40751,
+40799,40803,40801,20791,20792,22209,22208,22210,22804,23660,24013,25084,25086,
+25885,25884,26005,26345,27387,27396,27386,27570,28748,
+29211,29351,29910,29908,30313,30675,31824,32399,32396,32700,34327,34349,34330,
+34851,34850,34849,34847,35178,35180,35261,35700,35703,35709,36115,36490,36493,
+36491,36703,36783,37306,37934,37939,37941,37946,37944,37938,37931,38370,38712,
+38713,38706,38911,39015,39013,39255,39493,39491,39488,39486,39631,39764,39761,
+39981,39973,40367,40372,40386,40376,40605,40687,40729,40796,40806,40807,20796,
+20795,22216,22218,22217,23423,24020,24018,24398,25087,25892,27402,27489,28753,
+28760,29568,29924,30090,30318,30316,31155,31840,31839,32894,32893,33247,35186,
+35183,35324,35712,36118,36119,36497,36499,36705,37192,37956,37969,37970,38717,
+38718,38851,38849,39019,39253,39509,39501,39634,39706,40009,39985,39998,39995,
+40403,40407,40756,40812,40810,40852,22220,24022,25088,25891,25899,25898,26348,
+27408,29914,31434,31844,31843,31845,32403,32406,32404,33250,34360,34367,34865,
+35722,37008,37007,37987,37984,37988,38760,39023,39260,39514,39515,39511,39635,
+39636,39633,40020,40023,40022,40421,40607,40692,22225,22761,25900,28766,30321,
+30322,30679,32592,32648,34870,34873,34914,35731,35730,35734,33399,36123,37312,
+37994,38722,38728,38724,38854,39024,39519,39714,39768,40031,40441,40442,40572,
+40573,40711,40823,40818,24307,27414,28771,31852,31854,34875,35264,36513,37313,
+38002,38000,39025,39262,39638,39715,40652,28772,30682,35738,38007,38857,39522,
+39525,32412,35740,36522,37317,38013,38014,38012,40055,40056,40695,35924,38015,
+40474,29224,39530,39729,40475,40478,31858,9312,9313,9314,9315,9316,9317,9318,
+9319,9320,9321,9332,9333,9334,9335,9336,
+9337,9338,9339,9340,9341,8560,8561,8562,8563,8564,8565,8566,8567,8568,8569,
+20022,20031,20101,20128,20866,20886,20907,21241,21304,21353,21430,22794,23424,
+24027,24186,24191,24308,24400,24417,25908,26080,30098,30326,36789,38582,168,
+710,12541,12542,12445,12446,0,0,12293,12294,12295,12540,65339,65341,10045,
+12353,12354,12355,12356,12357,12358,12359,12360,12361,12362,12363,12364,12365,
+12366,12367,12368,12369,12370,12371,12372,12373,12374,12375,12376,12377,12378,
+12379,12380,12381,12382,12383,12384,12385,12386,12387,12388,12389,12390,12391,
+12392,12393,12394,12395,12396,12397,12398,12399,12400,12401,12402,12403,12404,
+12405,12406,12407,12408,12409,12410,12411,12412,12413,12414,12415,12416,12417,
+12418,12419,12420,12421,12422,12423,12424,12425,12426,12427,12428,12429,12430,
+12431,12432,12433,12434,12435,12449,12450,12451,12452,12453,12454,12455,12456,
+12457,12458,12459,12460,12461,12462,12463,12464,12465,12466,12467,12468,12469,
+12470,12471,12472,12473,12474,12475,12476,12477,12478,12479,12480,12481,12482,
+12483,12484,12485,12486,12487,12488,12489,12490,12491,12492,12493,12494,12495,
+12496,12497,12498,12499,12500,12501,12502,12503,12504,12505,12506,12507,12508,
+12509,12510,12511,12512,12513,12514,12515,12516,12517,12518,12519,12520,12521,
+12522,12523,12524,12525,12526,12527,12528,12529,12530,12531,12532,12533,12534,
+1040,1041,1042,1043,1044,1045,1025,1046,1047,1048,1049,1050,1051,1052,1053,
+1054,1055,1056,1057,1058,1059,1060,1061,1062,1063,1064,1065,1066,1067,1068,
+1069,1070,
+1071,1072,1073,1074,1075,1076,1077,1105,1078,1079,1080,1081,1082,1083,1084,
+1085,1086,1087,1088,1089,1090,1091,1092,1093,1094,1095,1096,1097,1098,1099,
+1100,1101,1102,1103,8679,8632,8633,12751,204,20058,138,20994,17553,40880,
+20872,40881,30215,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,65506,65508,65287,65282,12849,8470,8481,12443,12444,11904,
+11908,11910,11911,11912,11914,11916,11917,11925,11932,11933,11941,11943,11946,
+11948,11950,11958,11964,11966,11974,11978,11980,11981,11983,11990,11991,11998,
+12003,0,0,0,643,592,603,596,629,339,248,331,650,618,20034,20060,20981,21274,
+21378,19975,19980,20039,20109,22231,64012,23662,24435,19983,20871,19982,20014,
+20115,20162,20169,20168,20888,21244,21356,21433,22304,22787,22828,23568,24063,
+26081,27571,27596,27668,29247,20017,20028,20200,20188,20201,20193,20189,20186,
+21004,21276,21324,22306,22307,22807,22831,23425,23428,23570,23611,23668,23667,
+24068,24192,24194,24521,25097,25168,27669,27702,27715,27711,27707,29358,29360,
+29578,31160,32906,38430,20238,20248,20268,20213,20244,20209,20224,20215,20232,
+20253,20226,20229,20258,20243,20228,20212,20242,20913,21011,21001,21008,21158,
+21282,21279,21325,21386,21511,22241,22239,22318,22314,22324,22844,22912,22908,
+22917,22907,22910,22903,22911,23382,23573,23589,23676,23674,23675,
+23678,24031,24181,24196,24322,24346,24436,24533,24532,24527,25180,25182,25188,
+25185,25190,25186,25177,25184,25178,25189,26095,26094,26430,26425,26424,26427,
+26426,26431,26428,26419,27672,27718,27730,27740,27727,27722,27732,27723,27724,
+28785,29278,29364,29365,29582,29994,30335,31349,32593,33400,33404,33408,33405,
+33407,34381,35198,37017,37015,37016,37019,37012,38434,38436,38432,38435,20310,
+20283,20322,20297,20307,20324,20286,20327,20306,20319,20289,20312,20269,20275,
+20287,20321,20879,20921,21020,21022,21025,21165,21166,21257,21347,21362,21390,
+21391,21552,21559,21546,21588,21573,21529,21532,21541,21528,21565,21583,21569,
+21544,21540,21575,22254,22247,22245,22337,22341,22348,22345,22347,22354,22790,
+22848,22950,22936,22944,22935,22926,22946,22928,22927,22951,22945,23438,23442,
+23592,23594,23693,23695,23688,23691,23689,23698,23690,23686,23699,23701,24032,
+24074,24078,24203,24201,24204,24200,24205,24325,24349,24440,24438,24530,24529,
+24528,24557,24552,24558,24563,24545,24548,24547,24570,24559,24567,24571,24576,
+24564,25146,25219,25228,25230,25231,25236,25223,25201,25211,25210,25200,25217,
+25224,25207,25213,25202,25204,25911,26096,26100,26099,26098,26101,26437,26439,
+26457,26453,26444,26440,26461,26445,26458,26443,27600,27673,27674,27768,27751,
+27755,27780,27787,27791,27761,27759,27753,27802,27757,27783,27797,27804,27750,
+27763,27749,27771,27790,28788,28794,29283,29375,29373,29379,29382,29377,29370,
+29381,29589,29591,29587,29588,29586,30010,30009,30100,30101,30337,31037,32820,
+32917,32921,32912,32914,32924,33424,33423,33413,33422,
+33425,33427,33418,33411,33412,35960,36809,36799,37023,37025,37029,37022,37031,
+37024,38448,38440,38447,38445,20019,20376,20348,20357,20349,20352,20359,20342,
+20340,20361,20356,20343,20300,20375,20330,20378,20345,20353,20344,20368,20380,
+20372,20382,20370,20354,20373,20331,20334,20894,20924,20926,21045,21042,21043,
+21062,21041,21180,21258,21259,21308,21394,21396,21639,21631,21633,21649,21634,
+21640,21611,21626,21630,21605,21612,21620,21606,21645,21615,21601,21600,21656,
+21603,21607,21604,22263,22265,22383,22386,22381,22379,22385,22384,22390,22400,
+22389,22395,22387,22388,22370,22376,22397,22796,22853,22965,22970,22991,22990,
+22962,22988,22977,22966,22972,22979,22998,22961,22973,22976,22984,22964,22983,
+23394,23397,23443,23445,23620,23623,23726,23716,23712,23733,23727,23720,23724,
+23711,23715,23725,23714,23722,23719,23709,23717,23734,23728,23718,24087,24084,
+24089,24360,24354,24355,24356,24404,24450,24446,24445,24542,24549,24621,24614,
+24601,24626,24587,24628,24586,24599,24627,24602,24606,24620,24610,24589,24592,
+24622,24595,24593,24588,24585,24604,25108,25149,25261,25268,25297,25278,25258,
+25270,25290,25262,25267,25263,25275,25257,25264,25272,25917,26024,26043,26121,
+26108,26116,26130,26120,26107,26115,26123,26125,26117,26109,26129,26128,26358,
+26378,26501,26476,26510,26514,26486,26491,26520,26502,26500,26484,26509,26508,
+26490,26527,26513,26521,26499,26493,26497,26488,26489,26516,27429,27520,27518,
+27614,27677,27795,27884,27883,27886,27865,27830,27860,27821,27879,27831,27856,
+27842,27834,27843,27846,27885,27890,27858,27869,27828,
+27786,27805,27776,27870,27840,27952,27853,27847,27824,27897,27855,27881,27857,
+28820,28824,28805,28819,28806,28804,28817,28822,28802,28826,28803,29290,29398,
+29387,29400,29385,29404,29394,29396,29402,29388,29393,29604,29601,29613,29606,
+29602,29600,29612,29597,29917,29928,30015,30016,30014,30092,30104,30383,30451,
+30449,30448,30453,30712,30716,30713,30715,30714,30711,31042,31039,31173,31352,
+31355,31483,31861,31997,32821,32911,32942,32931,32952,32949,32941,33312,33440,
+33472,33451,33434,33432,33435,33461,33447,33454,33468,33438,33466,33460,33448,
+33441,33449,33474,33444,33475,33462,33442,34416,34415,34413,34414,35926,36818,
+36811,36819,36813,36822,36821,36823,37042,37044,37039,37043,37040,38457,38461,
+38460,38458,38467,20429,20421,20435,20402,20425,20427,20417,20436,20444,20441,
+20411,20403,20443,20423,20438,20410,20416,20409,20460,21060,21065,21184,21186,
+21309,21372,21399,21398,21401,21400,21690,21665,21677,21669,21711,21699,33549,
+21687,21678,21718,21686,21701,21702,21664,21616,21692,21666,21694,21618,21726,
+21680,22453,22430,22431,22436,22412,22423,22429,22427,22420,22424,22415,22425,
+22437,22426,22421,22772,22797,22867,23009,23006,23022,23040,23025,23005,23034,
+23037,23036,23030,23012,23026,23031,23003,23017,23027,23029,23008,23038,23028,
+23021,23464,23628,23760,23768,23756,23767,23755,23771,23774,23770,23753,23751,
+23754,23766,23763,23764,23759,23752,23750,23758,23775,23800,24057,24097,24098,
+24099,24096,24100,24240,24228,24226,24219,24227,24229,24327,24366,24406,24454,
+24631,24633,24660,24690,24670,24645,24659,24647,24649,
+24667,24652,24640,24642,24671,24612,24644,24664,24678,24686,25154,25155,25295,
+25357,25355,25333,25358,25347,25323,25337,25359,25356,25336,25334,25344,25363,
+25364,25338,25365,25339,25328,25921,25923,26026,26047,26166,26145,26162,26165,
+26140,26150,26146,26163,26155,26170,26141,26164,26169,26158,26383,26384,26561,
+26610,26568,26554,26588,26555,26616,26584,26560,26551,26565,26603,26596,26591,
+26549,26573,26547,26615,26614,26606,26595,26562,26553,26574,26599,26608,26546,
+26620,26566,26605,26572,26542,26598,26587,26618,26569,26570,26563,26602,26571,
+27432,27522,27524,27574,27606,27608,27616,27680,27681,27944,27956,27949,27935,
+27964,27967,27922,27914,27866,27955,27908,27929,27962,27930,27921,27904,27933,
+27970,27905,27928,27959,27907,27919,27968,27911,27936,27948,27912,27938,27913,
+27920,28855,28831,28862,28849,28848,28833,28852,28853,28841,29249,29257,29258,
+29292,29296,29299,29294,29386,29412,29416,29419,29407,29418,29414,29411,29573,
+29644,29634,29640,29637,29625,29622,29621,29620,29675,29631,29639,29630,29635,
+29638,29624,29643,29932,29934,29998,30023,30024,30119,30122,30329,30404,30472,
+30467,30468,30469,30474,30455,30459,30458,30695,30696,30726,30737,30738,30725,
+30736,30735,30734,30729,30723,30739,31050,31052,31051,31045,31044,31189,31181,
+31183,31190,31182,31360,31358,31441,31488,31489,31866,31864,31865,31871,31872,
+31873,32003,32008,32001,32600,32657,32653,32702,32775,32782,32783,32788,32823,
+32984,32967,32992,32977,32968,32962,32976,32965,32995,32985,32988,32970,32981,
+32969,32975,32983,32998,32973,33279,33313,33428,33497,
+33534,33529,33543,33512,33536,33493,33594,33515,33494,33524,33516,33505,33522,
+33525,33548,33531,33526,33520,33514,33508,33504,33530,33523,33517,34423,34420,
+34428,34419,34881,34894,34919,34922,34921,35283,35332,35335,36210,36835,36833,
+36846,36832,37105,37053,37055,37077,37061,37054,37063,37067,37064,37332,37331,
+38484,38479,38481,38483,38474,38478,20510,20485,20487,20499,20514,20528,20507,
+20469,20468,20531,20535,20524,20470,20471,20503,20508,20512,20519,20533,20527,
+20529,20494,20826,20884,20883,20938,20932,20933,20936,20942,21089,21082,21074,
+21086,21087,21077,21090,21197,21262,21406,21798,21730,21783,21778,21735,21747,
+21732,21786,21759,21764,21768,21739,21777,21765,21745,21770,21755,21751,21752,
+21728,21774,21763,21771,22273,22274,22476,22578,22485,22482,22458,22470,22461,
+22460,22456,22454,22463,22471,22480,22457,22465,22798,22858,23065,23062,23085,
+23086,23061,23055,23063,23050,23070,23091,23404,23463,23469,23468,23555,23638,
+23636,23788,23807,23790,23793,23799,23808,23801,24105,24104,24232,24238,24234,
+24236,24371,24368,24423,24669,24666,24679,24641,24738,24712,24704,24722,24705,
+24733,24707,24725,24731,24727,24711,24732,24718,25113,25158,25330,25360,25430,
+25388,25412,25413,25398,25411,25572,25401,25419,25418,25404,25385,25409,25396,
+25432,25428,25433,25389,25415,25395,25434,25425,25400,25431,25408,25416,25930,
+25926,26054,26051,26052,26050,26186,26207,26183,26193,26386,26387,26655,26650,
+26697,26674,26675,26683,26699,26703,26646,26673,26652,26677,26667,26669,26671,
+26702,26692,26676,26653,26642,26644,26662,26664,26670,
+26701,26682,26661,26656,27436,27439,27437,27441,27444,27501,32898,27528,27622,
+27620,27624,27619,27618,27623,27685,28026,28003,28004,28022,27917,28001,28050,
+27992,28002,28013,28015,28049,28045,28143,28031,28038,27998,28007,28000,28055,
+28016,28028,27999,28034,28056,27951,28008,28043,28030,28032,28036,27926,28035,
+28027,28029,28021,28048,28892,28883,28881,28893,28875,32569,28898,28887,28882,
+28894,28896,28884,28877,28869,28870,28871,28890,28878,28897,29250,29304,29303,
+29302,29440,29434,29428,29438,29430,29427,29435,29441,29651,29657,29669,29654,
+29628,29671,29667,29673,29660,29650,29659,29652,29661,29658,29655,29656,29672,
+29918,29919,29940,29941,29985,30043,30047,30128,30145,30139,30148,30144,30143,
+30134,30138,30346,30409,30493,30491,30480,30483,30482,30499,30481,30485,30489,
+30490,30498,30503,30755,30764,30754,30773,30767,30760,30766,30763,30753,30761,
+30771,30762,30769,31060,31067,31055,31068,31059,31058,31057,31211,31212,31200,
+31214,31213,31210,31196,31198,31197,31366,31369,31365,31371,31372,31370,31367,
+31448,31504,31492,31507,31493,31503,31496,31498,31502,31497,31506,31876,31889,
+31882,31884,31880,31885,31877,32030,32029,32017,32014,32024,32022,32019,32031,
+32018,32015,32012,32604,32609,32606,32608,32605,32603,32662,32658,32707,32706,
+32704,32790,32830,32825,33018,33010,33017,33013,33025,33019,33024,33281,33327,
+33317,33587,33581,33604,33561,33617,33573,33622,33599,33601,33574,33564,33570,
+33602,33614,33563,33578,33544,33596,33613,33558,33572,33568,33591,33583,33577,
+33607,33605,33612,33619,33566,33580,33611,33575,33608,
+34387,34386,34466,34472,34454,34445,34449,34462,34439,34455,34438,34443,34458,
+34437,34469,34457,34465,34471,34453,34456,34446,34461,34448,34452,34883,34884,
+34925,34933,34934,34930,34944,34929,34943,34927,34947,34942,34932,34940,35346,
+35911,35927,35963,36004,36003,36214,36216,36277,36279,36278,36561,36563,36862,
+36853,36866,36863,36859,36868,36860,36854,37078,37088,37081,37082,37091,37087,
+37093,37080,37083,37079,37084,37092,37200,37198,37199,37333,37346,37338,38492,
+38495,38588,39139,39647,39727,20095,20592,20586,20577,20574,20576,20563,20555,
+20573,20594,20552,20557,20545,20571,20554,20578,20501,20549,20575,20585,20587,
+20579,20580,20550,20544,20590,20595,20567,20561,20944,21099,21101,21100,21102,
+21206,21203,21293,21404,21877,21878,21820,21837,21840,21812,21802,21841,21858,
+21814,21813,21808,21842,21829,21772,21810,21861,21838,21817,21832,21805,21819,
+21824,21835,22282,22279,22523,22548,22498,22518,22492,22516,22528,22509,22525,
+22536,22520,22539,22515,22479,22535,22510,22499,22514,22501,22508,22497,22542,
+22524,22544,22503,22529,22540,22513,22505,22512,22541,22532,22876,23136,23128,
+23125,23143,23134,23096,23093,23149,23120,23135,23141,23148,23123,23140,23127,
+23107,23133,23122,23108,23131,23112,23182,23102,23117,23097,23116,23152,23145,
+23111,23121,23126,23106,23132,23410,23406,23489,23488,23641,23838,23819,23837,
+23834,23840,23820,23848,23821,23846,23845,23823,23856,23826,23843,23839,23854,
+24126,24116,24241,24244,24249,24242,24243,24374,24376,24475,24470,24479,24714,
+24720,24710,24766,24752,24762,24787,24788,24783,24804,
+24793,24797,24776,24753,24795,24759,24778,24767,24771,24781,24768,25394,25445,
+25482,25474,25469,25533,25502,25517,25501,25495,25515,25486,25455,25479,25488,
+25454,25519,25461,25500,25453,25518,25468,25508,25403,25503,25464,25477,25473,
+25489,25485,25456,25939,26061,26213,26209,26203,26201,26204,26210,26392,26745,
+26759,26768,26780,26733,26734,26798,26795,26966,26735,26787,26796,26793,26741,
+26740,26802,26767,26743,26770,26748,26731,26738,26794,26752,26737,26750,26779,
+26774,26763,26784,26761,26788,26744,26747,26769,26764,26762,26749,27446,27443,
+27447,27448,27537,27535,27533,27534,27532,27690,28096,28075,28084,28083,28276,
+28076,28137,28130,28087,28150,28116,28160,28104,28128,28127,28118,28094,28133,
+28124,28125,28123,28148,28106,28093,28141,28144,28090,28117,28098,28111,28105,
+28112,28146,28115,28157,28119,28109,28131,28091,28922,28941,28919,28951,28916,
+28940,28912,28932,28915,28944,28924,28927,28934,28947,28928,28920,28918,28939,
+28930,28942,29310,29307,29308,29311,29469,29463,29447,29457,29464,29450,29448,
+29439,29455,29470,29576,29686,29688,29685,29700,29697,29693,29703,29696,29690,
+29692,29695,29708,29707,29684,29704,30052,30051,30158,30162,30159,30155,30156,
+30161,30160,30351,30345,30419,30521,30511,30509,30513,30514,30516,30515,30525,
+30501,30523,30517,30792,30802,30793,30797,30794,30796,30758,30789,30800,31076,
+31079,31081,31082,31075,31083,31073,31163,31226,31224,31222,31223,31375,31380,
+31376,31541,31559,31540,31525,31536,31522,31524,31539,31512,31530,31517,31537,
+31531,31533,31535,31538,31544,31514,31523,31892,31896,
+31894,31907,32053,32061,32056,32054,32058,32069,32044,32041,32065,32071,32062,
+32063,32074,32059,32040,32611,32661,32668,32669,32667,32714,32715,32717,32720,
+32721,32711,32719,32713,32799,32798,32795,32839,32835,32840,33048,33061,33049,
+33051,33069,33055,33068,33054,33057,33045,33063,33053,33058,33297,33336,33331,
+33338,33332,33330,33396,33680,33699,33704,33677,33658,33651,33700,33652,33679,
+33665,33685,33689,33653,33684,33705,33661,33667,33676,33693,33691,33706,33675,
+33662,33701,33711,33672,33687,33712,33663,33702,33671,33710,33654,33690,34393,
+34390,34495,34487,34498,34497,34501,34490,34480,34504,34489,34483,34488,34508,
+34484,34491,34492,34499,34493,34494,34898,34953,34965,34984,34978,34986,34970,
+34961,34977,34975,34968,34983,34969,34971,34967,34980,34988,34956,34963,34958,
+35202,35286,35289,35285,35376,35367,35372,35358,35897,35899,35932,35933,35965,
+36005,36221,36219,36217,36284,36290,36281,36287,36289,36568,36574,36573,36572,
+36567,36576,36577,36900,36875,36881,36892,36876,36897,37103,37098,37104,37108,
+37106,37107,37076,37099,37100,37097,37206,37208,37210,37203,37205,37356,37364,
+37361,37363,37368,37348,37369,37354,37355,37367,37352,37358,38266,38278,38280,
+38524,38509,38507,38513,38511,38591,38762,38916,39141,39319,20635,20629,20628,
+20638,20619,20643,20611,20620,20622,20637,20584,20636,20626,20610,20615,20831,
+20948,21266,21265,21412,21415,21905,21928,21925,21933,21879,22085,21922,21907,
+21896,21903,21941,21889,21923,21906,21924,21885,21900,21926,21887,21909,21921,
+21902,22284,22569,22583,22553,22558,22567,22563,22568,
+22517,22600,22565,22556,22555,22579,22591,22582,22574,22585,22584,22573,22572,
+22587,22881,23215,23188,23199,23162,23202,23198,23160,23206,23164,23205,23212,
+23189,23214,23095,23172,23178,23191,23171,23179,23209,23163,23165,23180,23196,
+23183,23187,23197,23530,23501,23499,23508,23505,23498,23502,23564,23600,23863,
+23875,23915,23873,23883,23871,23861,23889,23886,23893,23859,23866,23890,23869,
+23857,23897,23874,23865,23881,23864,23868,23858,23862,23872,23877,24132,24129,
+24408,24486,24485,24491,24777,24761,24780,24802,24782,24772,24852,24818,24842,
+24854,24837,24821,24851,24824,24828,24830,24769,24835,24856,24861,24848,24831,
+24836,24843,25162,25492,25521,25520,25550,25573,25576,25583,25539,25757,25587,
+25546,25568,25590,25557,25586,25589,25697,25567,25534,25565,25564,25540,25560,
+25555,25538,25543,25548,25547,25544,25584,25559,25561,25906,25959,25962,25956,
+25948,25960,25957,25996,26013,26014,26030,26064,26066,26236,26220,26235,26240,
+26225,26233,26218,26226,26369,26892,26835,26884,26844,26922,26860,26858,26865,
+26895,26838,26871,26859,26852,26870,26899,26896,26867,26849,26887,26828,26888,
+26992,26804,26897,26863,26822,26900,26872,26832,26877,26876,26856,26891,26890,
+26903,26830,26824,26845,26846,26854,26868,26833,26886,26836,26857,26901,26917,
+26823,27449,27451,27455,27452,27540,27543,27545,27541,27581,27632,27634,27635,
+27696,28156,28230,28231,28191,28233,28296,28220,28221,28229,28258,28203,28223,
+28225,28253,28275,28188,28211,28235,28224,28241,28219,28163,28206,28254,28264,
+28252,28257,28209,28200,28256,28273,28267,28217,28194,
+28208,28243,28261,28199,28280,28260,28279,28245,28281,28242,28262,28213,28214,
+28250,28960,28958,28975,28923,28974,28977,28963,28965,28962,28978,28959,28968,
+28986,28955,29259,29274,29320,29321,29318,29317,29323,29458,29451,29488,29474,
+29489,29491,29479,29490,29485,29478,29475,29493,29452,29742,29740,29744,29739,
+29718,29722,29729,29741,29745,29732,29731,29725,29737,29728,29746,29947,29999,
+30063,30060,30183,30170,30177,30182,30173,30175,30180,30167,30357,30354,30426,
+30534,30535,30532,30541,30533,30538,30542,30539,30540,30686,30700,30816,30820,
+30821,30812,30829,30833,30826,30830,30832,30825,30824,30814,30818,31092,31091,
+31090,31088,31234,31242,31235,31244,31236,31385,31462,31460,31562,31547,31556,
+31560,31564,31566,31552,31576,31557,31906,31902,31912,31905,32088,32111,32099,
+32083,32086,32103,32106,32079,32109,32092,32107,32082,32084,32105,32081,32095,
+32078,32574,32575,32613,32614,32674,32672,32673,32727,32849,32847,32848,33022,
+32980,33091,33098,33106,33103,33095,33085,33101,33082,33254,33262,33271,33272,
+33273,33284,33340,33341,33343,33397,33595,33743,33785,33827,33728,33768,33810,
+33767,33764,33788,33782,33808,33734,33736,33771,33763,33727,33793,33757,33765,
+33752,33791,33761,33739,33742,33750,33781,33737,33801,33807,33758,33809,33798,
+33730,33779,33749,33786,33735,33745,33770,33811,33731,33772,33774,33732,33787,
+33751,33762,33819,33755,33790,34520,34530,34534,34515,34531,34522,34538,34525,
+34539,34524,34540,34537,34519,34536,34513,34888,34902,34901,35002,35031,35001,
+35000,35008,35006,34998,35004,34999,35005,34994,35073,
+35017,35221,35224,35223,35293,35290,35291,35406,35405,35385,35417,35392,35415,
+35416,35396,35397,35410,35400,35409,35402,35404,35407,35935,35969,35968,36026,
+36030,36016,36025,36021,36228,36224,36233,36312,36307,36301,36295,36310,36316,
+36303,36309,36313,36296,36311,36293,36591,36599,36602,36601,36582,36590,36581,
+36597,36583,36584,36598,36587,36593,36588,36596,36585,36909,36916,36911,37126,
+37164,37124,37119,37116,37128,37113,37115,37121,37120,37127,37125,37123,37217,
+37220,37215,37218,37216,37377,37386,37413,37379,37402,37414,37391,37388,37376,
+37394,37375,37373,37382,37380,37415,37378,37404,37412,37401,37399,37381,37398,
+38267,38285,38284,38288,38535,38526,38536,38537,38531,38528,38594,38600,38595,
+38641,38640,38764,38768,38766,38919,39081,39147,40166,40697,20099,20100,20150,
+20669,20671,20678,20654,20676,20682,20660,20680,20674,20656,20673,20666,20657,
+20683,20681,20662,20664,20951,21114,21112,21115,21116,21955,21979,21964,21968,
+21963,21962,21981,21952,21972,21956,21993,21951,21970,21901,21967,21973,21986,
+21974,21960,22002,21965,21977,21954,22292,22611,22632,22628,22607,22605,22601,
+22639,22613,22606,22621,22617,22629,22619,22589,22627,22641,22780,23239,23236,
+23243,23226,23224,23217,23221,23216,23231,23240,23227,23238,23223,23232,23242,
+23220,23222,23245,23225,23184,23510,23512,23513,23583,23603,23921,23907,23882,
+23909,23922,23916,23902,23912,23911,23906,24048,24143,24142,24138,24141,24139,
+24261,24268,24262,24267,24263,24384,24495,24493,24823,24905,24906,24875,24901,
+24886,24882,24878,24902,24879,24911,24873,24896,25120,
+37224,25123,25125,25124,25541,25585,25579,25616,25618,25609,25632,25636,25651,
+25667,25631,25621,25624,25657,25655,25634,25635,25612,25638,25648,25640,25665,
+25653,25647,25610,25626,25664,25637,25639,25611,25575,25627,25646,25633,25614,
+25967,26002,26067,26246,26252,26261,26256,26251,26250,26265,26260,26232,26400,
+26982,26975,26936,26958,26978,26993,26943,26949,26986,26937,26946,26967,26969,
+27002,26952,26953,26933,26988,26931,26941,26981,26864,27000,26932,26985,26944,
+26991,26948,26998,26968,26945,26996,26956,26939,26955,26935,26972,26959,26961,
+26930,26962,26927,27003,26940,27462,27461,27459,27458,27464,27457,27547,64013,
+27643,27644,27641,27639,27640,28315,28374,28360,28303,28352,28319,28307,28308,
+28320,28337,28345,28358,28370,28349,28353,28318,28361,28343,28336,28365,28326,
+28367,28338,28350,28355,28380,28376,28313,28306,28302,28301,28324,28321,28351,
+28339,28368,28362,28311,28334,28323,28999,29012,29010,29027,29024,28993,29021,
+29026,29042,29048,29034,29025,28994,29016,28995,29003,29040,29023,29008,29011,
+28996,29005,29018,29263,29325,29324,29329,29328,29326,29500,29506,29499,29498,
+29504,29514,29513,29764,29770,29771,29778,29777,29783,29760,29775,29776,29774,
+29762,29766,29773,29780,29921,29951,29950,29949,29981,30073,30071,27011,30191,
+30223,30211,30199,30206,30204,30201,30200,30224,30203,30198,30189,30197,30205,
+30361,30389,30429,30549,30559,30560,30546,30550,30554,30569,30567,30548,30553,
+30573,30688,30855,30874,30868,30863,30852,30869,30853,30854,30881,30851,30841,
+30873,30848,30870,30843,31100,31106,31101,31097,31249,
+31256,31257,31250,31255,31253,31266,31251,31259,31248,31395,31394,31390,31467,
+31590,31588,31597,31604,31593,31602,31589,31603,31601,31600,31585,31608,31606,
+31587,31922,31924,31919,32136,32134,32128,32141,32127,32133,32122,32142,32123,
+32131,32124,32140,32148,32132,32125,32146,32621,32619,32615,32616,32620,32678,
+32677,32679,32731,32732,32801,33124,33120,33143,33116,33129,33115,33122,33138,
+26401,33118,33142,33127,33135,33092,33121,33309,33353,33348,33344,33346,33349,
+34033,33855,33878,33910,33913,33935,33933,33893,33873,33856,33926,33895,33840,
+33869,33917,33882,33881,33908,33907,33885,34055,33886,33847,33850,33844,33914,
+33859,33912,33842,33861,33833,33753,33867,33839,33858,33837,33887,33904,33849,
+33870,33868,33874,33903,33989,33934,33851,33863,33846,33843,33896,33918,33860,
+33835,33888,33876,33902,33872,34571,34564,34551,34572,34554,34518,34549,34637,
+34552,34574,34569,34561,34550,34573,34565,35030,35019,35021,35022,35038,35035,
+35034,35020,35024,35205,35227,35295,35301,35300,35297,35296,35298,35292,35302,
+35446,35462,35455,35425,35391,35447,35458,35460,35445,35459,35457,35444,35450,
+35900,35915,35914,35941,35940,35942,35974,35972,35973,36044,36200,36201,36241,
+36236,36238,36239,36237,36243,36244,36240,36242,36336,36320,36332,36337,36334,
+36304,36329,36323,36322,36327,36338,36331,36340,36614,36607,36609,36608,36613,
+36615,36616,36610,36619,36946,36927,36932,36937,36925,37136,37133,37135,37137,
+37142,37140,37131,37134,37230,37231,37448,37458,37424,37434,37478,37427,37477,
+37470,37507,37422,37450,37446,37485,37484,37455,37472,
+37479,37487,37430,37473,37488,37425,37460,37475,37456,37490,37454,37459,37452,
+37462,37426,38303,38300,38302,38299,38546,38547,38545,38551,38606,38650,38653,
+38648,38645,38771,38775,38776,38770,38927,38925,38926,39084,39158,39161,39343,
+39346,39344,39349,39597,39595,39771,40170,40173,40167,40576,40701,20710,20692,
+20695,20712,20723,20699,20714,20701,20708,20691,20716,20720,20719,20707,20704,
+20952,21120,21121,21225,21227,21296,21420,22055,22037,22028,22034,22012,22031,
+22044,22017,22035,22018,22010,22045,22020,22015,22009,22665,22652,22672,22680,
+22662,22657,22655,22644,22667,22650,22663,22673,22670,22646,22658,22664,22651,
+22676,22671,22782,22891,23260,23278,23269,23253,23274,23258,23277,23275,23283,
+23266,23264,23259,23276,23262,23261,23257,23272,23263,23415,23520,23523,23651,
+23938,23936,23933,23942,23930,23937,23927,23946,23945,23944,23934,23932,23949,
+23929,23935,24152,24153,24147,24280,24273,24279,24270,24284,24277,24281,24274,
+24276,24388,24387,24431,24502,24876,24872,24897,24926,24945,24947,24914,24915,
+24946,24940,24960,24948,24916,24954,24923,24933,24891,24938,24929,24918,25129,
+25127,25131,25643,25677,25691,25693,25716,25718,25714,25715,25725,25717,25702,
+25766,25678,25730,25694,25692,25675,25683,25696,25680,25727,25663,25708,25707,
+25689,25701,25719,25971,26016,26273,26272,26271,26373,26372,26402,27057,27062,
+27081,27040,27086,27030,27056,27052,27068,27025,27033,27022,27047,27021,27049,
+27070,27055,27071,27076,27069,27044,27092,27065,27082,27034,27087,27059,27027,
+27050,27041,27038,27097,27031,27024,27074,27061,27045,
+27078,27466,27469,27467,27550,27551,27552,27587,27588,27646,28366,28405,28401,
+28419,28453,28408,28471,28411,28462,28425,28494,28441,28442,28455,28440,28475,
+28434,28397,28426,28470,28531,28409,28398,28461,28480,28464,28476,28469,28395,
+28423,28430,28483,28421,28413,28406,28473,28444,28412,28474,28447,28429,28446,
+28424,28449,29063,29072,29065,29056,29061,29058,29071,29051,29062,29057,29079,
+29252,29267,29335,29333,29331,29507,29517,29521,29516,29794,29811,29809,29813,
+29810,29799,29806,29952,29954,29955,30077,30096,30230,30216,30220,30229,30225,
+30218,30228,30392,30593,30588,30597,30594,30574,30592,30575,30590,30595,30898,
+30890,30900,30893,30888,30846,30891,30878,30885,30880,30892,30882,30884,31128,
+31114,31115,31126,31125,31124,31123,31127,31112,31122,31120,31275,31306,31280,
+31279,31272,31270,31400,31403,31404,31470,31624,31644,31626,31633,31632,31638,
+31629,31628,31643,31630,31621,31640,21124,31641,31652,31618,31931,31935,31932,
+31930,32167,32183,32194,32163,32170,32193,32192,32197,32157,32206,32196,32198,
+32203,32204,32175,32185,32150,32188,32159,32166,32174,32169,32161,32201,32627,
+32738,32739,32741,32734,32804,32861,32860,33161,33158,33155,33159,33165,33164,
+33163,33301,33943,33956,33953,33951,33978,33998,33986,33964,33966,33963,33977,
+33972,33985,33997,33962,33946,33969,34000,33949,33959,33979,33954,33940,33991,
+33996,33947,33961,33967,33960,34006,33944,33974,33999,33952,34007,34004,34002,
+34011,33968,33937,34401,34611,34595,34600,34667,34624,34606,34590,34593,34585,
+34587,34627,34604,34625,34622,34630,34592,34610,34602,
+34605,34620,34578,34618,34609,34613,34626,34598,34599,34616,34596,34586,34608,
+34577,35063,35047,35057,35058,35066,35070,35054,35068,35062,35067,35056,35052,
+35051,35229,35233,35231,35230,35305,35307,35304,35499,35481,35467,35474,35471,
+35478,35901,35944,35945,36053,36047,36055,36246,36361,36354,36351,36365,36349,
+36362,36355,36359,36358,36357,36350,36352,36356,36624,36625,36622,36621,37155,
+37148,37152,37154,37151,37149,37146,37156,37153,37147,37242,37234,37241,37235,
+37541,37540,37494,37531,37498,37536,37524,37546,37517,37542,37530,37547,37497,
+37527,37503,37539,37614,37518,37506,37525,37538,37501,37512,37537,37514,37510,
+37516,37529,37543,37502,37511,37545,37533,37515,37421,38558,38561,38655,38744,
+38781,38778,38782,38787,38784,38786,38779,38788,38785,38783,38862,38861,38934,
+39085,39086,39170,39168,39175,39325,39324,39363,39353,39355,39354,39362,39357,
+39367,39601,39651,39655,39742,39743,39776,39777,39775,40177,40178,40181,40615,
+20735,20739,20784,20728,20742,20743,20726,20734,20747,20748,20733,20746,21131,
+21132,21233,21231,22088,22082,22092,22069,22081,22090,22089,22086,22104,22106,
+22080,22067,22077,22060,22078,22072,22058,22074,22298,22699,22685,22705,22688,
+22691,22703,22700,22693,22689,22783,23295,23284,23293,23287,23286,23299,23288,
+23298,23289,23297,23303,23301,23311,23655,23961,23959,23967,23954,23970,23955,
+23957,23968,23964,23969,23962,23966,24169,24157,24160,24156,32243,24283,24286,
+24289,24393,24498,24971,24963,24953,25009,25008,24994,24969,24987,24979,25007,
+25005,24991,24978,25002,24993,24973,24934,25011,25133,
+25710,25712,25750,25760,25733,25751,25756,25743,25739,25738,25740,25763,25759,
+25704,25777,25752,25974,25978,25977,25979,26034,26035,26293,26288,26281,26290,
+26295,26282,26287,27136,27142,27159,27109,27128,27157,27121,27108,27168,27135,
+27116,27106,27163,27165,27134,27175,27122,27118,27156,27127,27111,27200,27144,
+27110,27131,27149,27132,27115,27145,27140,27160,27173,27151,27126,27174,27143,
+27124,27158,27473,27557,27555,27554,27558,27649,27648,27647,27650,28481,28454,
+28542,28551,28614,28562,28557,28553,28556,28514,28495,28549,28506,28566,28534,
+28524,28546,28501,28530,28498,28496,28503,28564,28563,28509,28416,28513,28523,
+28541,28519,28560,28499,28555,28521,28543,28565,28515,28535,28522,28539,29106,
+29103,29083,29104,29088,29082,29097,29109,29085,29093,29086,29092,29089,29098,
+29084,29095,29107,29336,29338,29528,29522,29534,29535,29536,29533,29531,29537,
+29530,29529,29538,29831,29833,29834,29830,29825,29821,29829,29832,29820,29817,
+29960,29959,30078,30245,30238,30233,30237,30236,30243,30234,30248,30235,30364,
+30365,30366,30363,30605,30607,30601,30600,30925,30907,30927,30924,30929,30926,
+30932,30920,30915,30916,30921,31130,31137,31136,31132,31138,31131,27510,31289,
+31410,31412,31411,31671,31691,31678,31660,31694,31663,31673,31690,31669,31941,
+31944,31948,31947,32247,32219,32234,32231,32215,32225,32259,32250,32230,32246,
+32241,32240,32238,32223,32630,32684,32688,32685,32749,32747,32746,32748,32742,
+32744,32868,32871,33187,33183,33182,33173,33186,33177,33175,33302,33359,33363,
+33362,33360,33358,33361,34084,34107,34063,34048,34089,
+34062,34057,34061,34079,34058,34087,34076,34043,34091,34042,34056,34060,34036,
+34090,34034,34069,34039,34027,34035,34044,34066,34026,34025,34070,34046,34088,
+34077,34094,34050,34045,34078,34038,34097,34086,34023,34024,34032,34031,34041,
+34072,34080,34096,34059,34073,34095,34402,34646,34659,34660,34679,34785,34675,
+34648,34644,34651,34642,34657,34650,34641,34654,34669,34666,34640,34638,34655,
+34653,34671,34668,34682,34670,34652,34661,34639,34683,34677,34658,34663,34665,
+34906,35077,35084,35092,35083,35095,35096,35097,35078,35094,35089,35086,35081,
+35234,35236,35235,35309,35312,35308,35535,35526,35512,35539,35537,35540,35541,
+35515,35543,35518,35520,35525,35544,35523,35514,35517,35545,35902,35917,35983,
+36069,36063,36057,36072,36058,36061,36071,36256,36252,36257,36251,36384,36387,
+36389,36388,36398,36373,36379,36374,36369,36377,36390,36391,36372,36370,36376,
+36371,36380,36375,36378,36652,36644,36632,36634,36640,36643,36630,36631,36979,
+36976,36975,36967,36971,37167,37163,37161,37162,37170,37158,37166,37253,37254,
+37258,37249,37250,37252,37248,37584,37571,37572,37568,37593,37558,37583,37617,
+37599,37592,37609,37591,37597,37580,37615,37570,37608,37578,37576,37582,37606,
+37581,37589,37577,37600,37598,37607,37585,37587,37557,37601,37574,37556,38268,
+38316,38315,38318,38320,38564,38562,38611,38661,38664,38658,38746,38794,38798,
+38792,38864,38863,38942,38941,38950,38953,38952,38944,38939,38951,39090,39176,
+39162,39185,39188,39190,39191,39189,39388,39373,39375,39379,39380,39374,39369,
+39382,39384,39371,39383,39372,39603,39660,39659,39667,
+39666,39665,39750,39747,39783,39796,39793,39782,39798,39797,39792,39784,39780,
+39788,40188,40186,40189,40191,40183,40199,40192,40185,40187,40200,40197,40196,
+40579,40659,40719,40720,20764,20755,20759,20762,20753,20958,21300,21473,22128,
+22112,22126,22131,22118,22115,22125,22130,22110,22135,22300,22299,22728,22717,
+22729,22719,22714,22722,22716,22726,23319,23321,23323,23329,23316,23315,23312,
+23318,23336,23322,23328,23326,23535,23980,23985,23977,23975,23989,23984,23982,
+23978,23976,23986,23981,23983,23988,24167,24168,24166,24175,24297,24295,24294,
+24296,24293,24395,24508,24989,25000,24982,25029,25012,25030,25025,25036,25018,
+25023,25016,24972,25815,25814,25808,25807,25801,25789,25737,25795,25819,25843,
+25817,25907,25983,25980,26018,26312,26302,26304,26314,26315,26319,26301,26299,
+26298,26316,26403,27188,27238,27209,27239,27186,27240,27198,27229,27245,27254,
+27227,27217,27176,27226,27195,27199,27201,27242,27236,27216,27215,27220,27247,
+27241,27232,27196,27230,27222,27221,27213,27214,27206,27477,27476,27478,27559,
+27562,27563,27592,27591,27652,27651,27654,28589,28619,28579,28615,28604,28622,
+28616,28510,28612,28605,28574,28618,28584,28676,28581,28590,28602,28588,28586,
+28623,28607,28600,28578,28617,28587,28621,28591,28594,28592,29125,29122,29119,
+29112,29142,29120,29121,29131,29140,29130,29127,29135,29117,29144,29116,29126,
+29146,29147,29341,29342,29545,29542,29543,29548,29541,29547,29546,29823,29850,
+29856,29844,29842,29845,29857,29963,30080,30255,30253,30257,30269,30259,30268,
+30261,30258,30256,30395,30438,30618,30621,30625,30620,
+30619,30626,30627,30613,30617,30615,30941,30953,30949,30954,30942,30947,30939,
+30945,30946,30957,30943,30944,31140,31300,31304,31303,31414,31416,31413,31409,
+31415,31710,31715,31719,31709,31701,31717,31706,31720,31737,31700,31722,31714,
+31708,31723,31704,31711,31954,31956,31959,31952,31953,32274,32289,32279,32268,
+32287,32288,32275,32270,32284,32277,32282,32290,32267,32271,32278,32269,32276,
+32293,32292,32579,32635,32636,32634,32689,32751,32810,32809,32876,33201,33190,
+33198,33209,33205,33195,33200,33196,33204,33202,33207,33191,33266,33365,33366,
+33367,34134,34117,34155,34125,34131,34145,34136,34112,34118,34148,34113,34146,
+34116,34129,34119,34147,34110,34139,34161,34126,34158,34165,34133,34151,34144,
+34188,34150,34141,34132,34149,34156,34403,34405,34404,34715,34703,34711,34707,
+34706,34696,34689,34710,34712,34681,34695,34723,34693,34704,34705,34717,34692,
+34708,34716,34714,34697,35102,35110,35120,35117,35118,35111,35121,35106,35113,
+35107,35119,35116,35103,35313,35552,35554,35570,35572,35573,35549,35604,35556,
+35551,35568,35528,35550,35553,35560,35583,35567,35579,35985,35986,35984,36085,
+36078,36081,36080,36083,36204,36206,36261,36263,36403,36414,36408,36416,36421,
+36406,36412,36413,36417,36400,36415,36541,36662,36654,36661,36658,36665,36663,
+36660,36982,36985,36987,36998,37114,37171,37173,37174,37267,37264,37265,37261,
+37263,37671,37662,37640,37663,37638,37647,37754,37688,37692,37659,37667,37650,
+37633,37702,37677,37646,37645,37579,37661,37626,37669,37651,37625,37623,37684,
+37634,37668,37631,37673,37689,37685,37674,37652,37644,
+37643,37630,37641,37632,37627,37654,38332,38349,38334,38329,38330,38326,38335,
+38325,38333,38569,38612,38667,38674,38672,38809,38807,38804,38896,38904,38965,
+38959,38962,39204,39199,39207,39209,39326,39406,39404,39397,39396,39408,39395,
+39402,39401,39399,39609,39615,39604,39611,39670,39674,39673,39671,39731,39808,
+39813,39815,39804,39806,39803,39810,39827,39826,39824,39802,39829,39805,39816,
+40229,40215,40224,40222,40212,40233,40221,40216,40226,40208,40217,40223,40584,
+40582,40583,40622,40621,40661,40662,40698,40722,40765,20774,20773,20770,20772,
+20768,20777,21236,22163,22156,22157,22150,22148,22147,22142,22146,22143,22145,
+22742,22740,22735,22738,23341,23333,23346,23331,23340,23335,23334,23343,23342,
+23419,23537,23538,23991,24172,24170,24510,24507,25027,25013,25020,25063,25056,
+25061,25060,25064,25054,25839,25833,25827,25835,25828,25832,25985,25984,26038,
+26074,26322,27277,27286,27265,27301,27273,27295,27291,27297,27294,27271,27283,
+27278,27285,27267,27304,27300,27281,27263,27302,27290,27269,27276,27282,27483,
+27565,27657,28620,28585,28660,28628,28643,28636,28653,28647,28646,28638,28658,
+28637,28642,28648,29153,29169,29160,29170,29156,29168,29154,29555,29550,29551,
+29847,29874,29867,29840,29866,29869,29873,29861,29871,29968,29969,29970,29967,
+30084,30275,30280,30281,30279,30372,30441,30645,30635,30642,30647,30646,30644,
+30641,30632,30704,30963,30973,30978,30971,30972,30962,30981,30969,30974,30980,
+31147,31144,31324,31323,31318,31320,31316,31322,31422,31424,31425,31749,31759,
+31730,31744,31743,31739,31758,31732,31755,31731,31746,
+31753,31747,31745,31736,31741,31750,31728,31729,31760,31754,31976,32301,32316,
+32322,32307,38984,32312,32298,32329,32320,32327,32297,32332,32304,32315,32310,
+32324,32314,32581,32639,32638,32637,32756,32754,32812,33211,33220,33228,33226,
+33221,33223,33212,33257,33371,33370,33372,34179,34176,34191,34215,34197,34208,
+34187,34211,34171,34212,34202,34206,34167,34172,34185,34209,34170,34168,34135,
+34190,34198,34182,34189,34201,34205,34177,34210,34178,34184,34181,34169,34166,
+34200,34192,34207,34408,34750,34730,34733,34757,34736,34732,34745,34741,34748,
+34734,34761,34755,34754,34764,34743,34735,34756,34762,34740,34742,34751,34744,
+34749,34782,34738,35125,35123,35132,35134,35137,35154,35127,35138,35245,35247,
+35246,35314,35315,35614,35608,35606,35601,35589,35595,35618,35599,35602,35605,
+35591,35597,35592,35590,35612,35603,35610,35919,35952,35954,35953,35951,35989,
+35988,36089,36207,36430,36429,36435,36432,36428,36423,36675,36672,36997,36990,
+37176,37274,37282,37275,37273,37279,37281,37277,37280,37793,37763,37807,37732,
+37718,37703,37756,37720,37724,37750,37705,37712,37713,37728,37741,37775,37708,
+37738,37753,37719,37717,37714,37711,37745,37751,37755,37729,37726,37731,37735,
+37760,37710,37721,38343,38336,38345,38339,38341,38327,38574,38576,38572,38688,
+38687,38680,38685,38681,38810,38817,38812,38814,38813,38869,38868,38897,38977,
+38980,38986,38985,38981,38979,39205,39211,39212,39210,39219,39218,39215,39213,
+39217,39216,39320,39331,39329,39426,39418,39412,39415,39417,39416,39414,39419,
+39421,39422,39420,39427,39614,39678,39677,39681,39676,
+39752,39834,39848,39838,39835,39846,39841,39845,39844,39814,39842,39840,39855,
+40243,40257,40295,40246,40238,40239,40241,40248,40240,40261,40258,40259,40254,
+40247,40256,40253,32757,40237,40586,40585,40589,40624,40648,40666,40699,40703,
+40740,40739,40738,40788,40864,20785,20781,20782,22168,22172,22167,22170,22173,
+22169,22896,23356,23657,23658,24000,24173,24174,25048,25055,25069,25070,25073,
+25066,25072,25067,25046,25065,25855,25860,25853,25848,25857,25859,25852,26004,
+26075,26330,26331,26328,27333,27321,27325,27361,27334,27322,27318,27319,27335,
+27316,27309,27486,27593,27659,28679,28684,28685,28673,28677,28692,28686,28671,
+28672,28667,28710,28668,28663,28682,29185,29183,29177,29187,29181,29558,29880,
+29888,29877,29889,29886,29878,29883,29890,29972,29971,30300,30308,30297,30288,
+30291,30295,30298,30374,30397,30444,30658,30650,30975,30988,30995,30996,30985,
+30992,30994,30993,31149,31148,31327,31772,31785,31769,31776,31775,31789,31773,
+31782,31784,31778,31781,31792,32348,32336,32342,32355,32344,32354,32351,32337,
+32352,32343,32339,32693,32691,32759,32760,32885,33233,33234,33232,33375,33374,
+34228,34246,34240,34243,34242,34227,34229,34237,34247,34244,34239,34251,34254,
+34248,34245,34225,34230,34258,34340,34232,34231,34238,34409,34791,34790,34786,
+34779,34795,34794,34789,34783,34803,34788,34772,34780,34771,34797,34776,34787,
+34724,34775,34777,34817,34804,34792,34781,35155,35147,35151,35148,35142,35152,
+35153,35145,35626,35623,35619,35635,35632,35637,35655,35631,35644,35646,35633,
+35621,35639,35622,35638,35630,35620,35643,35645,35642,
+35906,35957,35993,35992,35991,36094,36100,36098,36096,36444,36450,36448,36439,
+36438,36446,36453,36455,36443,36442,36449,36445,36457,36436,36678,36679,36680,
+36683,37160,37178,37179,37182,37288,37285,37287,37295,37290,37813,37772,37778,
+37815,37787,37789,37769,37799,37774,37802,37790,37798,37781,37768,37785,37791,
+37773,37809,37777,37810,37796,37800,37812,37795,37797,38354,38355,38353,38579,
+38615,38618,24002,38623,38616,38621,38691,38690,38693,38828,38830,38824,38827,
+38820,38826,38818,38821,38871,38873,38870,38872,38906,38992,38993,38994,39096,
+39233,39228,39226,39439,39435,39433,39437,39428,39441,39434,39429,39431,39430,
+39616,39644,39688,39684,39685,39721,39733,39754,39756,39755,39879,39878,39875,
+39871,39873,39861,39864,39891,39862,39876,39865,39869,40284,40275,40271,40266,
+40283,40267,40281,40278,40268,40279,40274,40276,40287,40280,40282,40590,40588,
+40671,40705,40704,40726,40741,40747,40746,40745,40744,40780,40789,20788,20789,
+21142,21239,21428,22187,22189,22182,22183,22186,22188,22746,22749,22747,22802,
+23357,23358,23359,24003,24176,24511,25083,25863,25872,25869,25865,25868,25870,
+25988,26078,26077,26334,27367,27360,27340,27345,27353,27339,27359,27356,27344,
+27371,27343,27341,27358,27488,27568,27660,28697,28711,28704,28694,28715,28705,
+28706,28707,28713,28695,28708,28700,28714,29196,29194,29191,29186,29189,29349,
+29350,29348,29347,29345,29899,29893,29879,29891,29974,30304,30665,30666,30660,
+30705,31005,31003,31009,31004,30999,31006,31152,31335,31336,31795,31804,31801,
+31788,31803,31980,31978,32374,32373,32376,32368,32375,
+32367,32378,32370,32372,32360,32587,32586,32643,32646,32695,32765,32766,32888,
+33239,33237,33380,33377,33379,34283,34289,34285,34265,34273,34280,34266,34263,
+34284,34290,34296,34264,34271,34275,34268,34257,34288,34278,34287,34270,34274,
+34816,34810,34819,34806,34807,34825,34828,34827,34822,34812,34824,34815,34826,
+34818,35170,35162,35163,35159,35169,35164,35160,35165,35161,35208,35255,35254,
+35318,35664,35656,35658,35648,35667,35670,35668,35659,35669,35665,35650,35666,
+35671,35907,35959,35958,35994,36102,36103,36105,36268,36266,36269,36267,36461,
+36472,36467,36458,36463,36475,36546,36690,36689,36687,36688,36691,36788,37184,
+37183,37296,37293,37854,37831,37839,37826,37850,37840,37881,37868,37836,37849,
+37801,37862,37834,37844,37870,37859,37845,37828,37838,37824,37842,37863,38269,
+38362,38363,38625,38697,38699,38700,38696,38694,38835,38839,38838,38877,38878,
+38879,39004,39001,39005,38999,39103,39101,39099,39102,39240,39239,39235,39334,
+39335,39450,39445,39461,39453,39460,39451,39458,39456,39463,39459,39454,39452,
+39444,39618,39691,39690,39694,39692,39735,39914,39915,39904,39902,39908,39910,
+39906,39920,39892,39895,39916,39900,39897,39909,39893,39905,39898,40311,40321,
+40330,40324,40328,40305,40320,40312,40326,40331,40332,40317,40299,40308,40309,
+40304,40297,40325,40307,40315,40322,40303,40313,40319,40327,40296,40596,40593,
+40640,40700,40749,40768,40769,40781,40790,40791,40792,21303,22194,22197,22195,
+22755,23365,24006,24007,24302,24303,24512,24513,25081,25879,25878,25877,25875,
+26079,26344,26339,26340,27379,27376,27370,27368,27385,
+27377,27374,27375,28732,28725,28719,28727,28724,28721,28738,28728,28735,28730,
+28729,28736,28731,28723,28737,29203,29204,29352,29565,29564,29882,30379,30378,
+30398,30445,30668,30670,30671,30669,30706,31013,31011,31015,31016,31012,31017,
+31154,31342,31340,31341,31479,31817,31816,31818,31815,31813,31982,32379,32382,
+32385,32384,32698,32767,32889,33243,33241,33291,33384,33385,34338,34303,34305,
+34302,34331,34304,34294,34308,34313,34309,34316,34301,34841,34832,34833,34839,
+34835,34838,35171,35174,35257,35319,35680,35690,35677,35688,35683,35685,35687,
+35693,36270,36486,36488,36484,36697,36694,36695,36693,36696,36698,37005,37187,
+37185,37303,37301,37298,37299,37899,37907,37883,37920,37903,37908,37886,37909,
+37904,37928,37913,37901,37877,37888,37879,37895,37902,37910,37906,37882,37897,
+37880,37898,37887,37884,37900,37878,37905,37894,38366,38368,38367,38702,38703,
+38841,38843,38909,38910,39008,39010,39011,39007,39105,39106,39248,39246,39257,
+39244,39243,39251,39474,39476,39473,39468,39466,39478,39465,39470,39480,39469,
+39623,39626,39622,39696,39698,39697,39947,39944,39927,39941,39954,39928,40000,
+39943,39950,39942,39959,39956,39945,40351,40345,40356,40349,40338,40344,40336,
+40347,40352,40340,40348,40362,40343,40353,40346,40354,40360,40350,40355,40383,
+40361,40342,40358,40359,40601,40603,40602,40677,40676,40679,40678,40752,40750,
+40795,40800,40798,40797,40793,40849,20794,20793,21144,21143,22211,22205,22206,
+23368,23367,24011,24015,24305,25085,25883,27394,27388,27395,27384,27392,28739,
+28740,28746,28744,28745,28741,28742,29213,29210,29209,
+29566,29975,30314,30672,31021,31025,31023,31828,31827,31986,32394,32391,32392,
+32395,32390,32397,32589,32699,32816,33245,34328,34346,34342,34335,34339,34332,
+34329,34343,34350,34337,34336,34345,34334,34341,34857,34845,34843,34848,34852,
+34844,34859,34890,35181,35177,35182,35179,35322,35705,35704,35653,35706,35707,
+36112,36116,36271,36494,36492,36702,36699,36701,37190,37188,37189,37305,37951,
+37947,37942,37929,37949,37948,37936,37945,37930,37943,37932,37952,37937,38373,
+38372,38371,38709,38714,38847,38881,39012,39113,39110,39104,39256,39254,39481,
+39485,39494,39492,39490,39489,39482,39487,39629,39701,39703,39704,39702,39738,
+39762,39979,39965,39964,39980,39971,39976,39977,39972,39969,40375,40374,40380,
+40385,40391,40394,40399,40382,40389,40387,40379,40373,40398,40377,40378,40364,
+40392,40369,40365,40396,40371,40397,40370,40570,40604,40683,40686,40685,40731,
+40728,40730,40753,40782,40805,40804,40850,20153,22214,22213,22219,22897,23371,
+23372,24021,24017,24306,25889,25888,25894,25890,27403,27400,27401,27661,28757,
+28758,28759,28754,29214,29215,29353,29567,29912,29909,29913,29911,30317,30381,
+31029,31156,31344,31345,31831,31836,31833,31835,31834,31988,31985,32401,32591,
+32647,33246,33387,34356,34357,34355,34348,34354,34358,34860,34856,34854,34858,
+34853,35185,35263,35262,35323,35710,35716,35714,35718,35717,35711,36117,36501,
+36500,36506,36498,36496,36502,36503,36704,36706,37191,37964,37968,37962,37963,
+37967,37959,37957,37960,37961,37958,38719,38883,39018,39017,39115,39252,39259,
+39502,39507,39508,39500,39503,39496,39498,39497,39506,
+39504,39632,39705,39723,39739,39766,39765,40006,40008,39999,40004,39993,39987,
+40001,39996,39991,39988,39986,39997,39990,40411,40402,40414,40410,40395,40400,
+40412,40401,40415,40425,40409,40408,40406,40437,40405,40413,40630,40688,40757,
+40755,40754,40770,40811,40853,40866,20797,21145,22760,22759,22898,23373,24024,
+34863,24399,25089,25091,25092,25897,25893,26006,26347,27409,27410,27407,27594,
+28763,28762,29218,29570,29569,29571,30320,30676,31847,31846,32405,33388,34362,
+34368,34361,34364,34353,34363,34366,34864,34866,34862,34867,35190,35188,35187,
+35326,35724,35726,35723,35720,35909,36121,36504,36708,36707,37308,37986,37973,
+37981,37975,37982,38852,38853,38912,39510,39513,39710,39711,39712,40018,40024,
+40016,40010,40013,40011,40021,40025,40012,40014,40443,40439,40431,40419,40427,
+40440,40420,40438,40417,40430,40422,40434,40432,40418,40428,40436,40435,40424,
+40429,40642,40656,40690,40691,40710,40732,40760,40759,40758,40771,40783,40817,
+40816,40814,40815,22227,22221,23374,23661,25901,26349,26350,27411,28767,28769,
+28765,28768,29219,29915,29925,30677,31032,31159,31158,31850,32407,32649,33389,
+34371,34872,34871,34869,34891,35732,35733,36510,36511,36512,36509,37310,37309,
+37314,37995,37992,37993,38629,38726,38723,38727,38855,38885,39518,39637,39769,
+40035,40039,40038,40034,40030,40032,40450,40446,40455,40451,40454,40453,40448,
+40449,40457,40447,40445,40452,40608,40734,40774,40820,40821,40822,22228,25902,
+26040,27416,27417,27415,27418,28770,29222,29354,30680,30681,31033,31849,31851,
+31990,32410,32408,32411,32409,33248,33249,34374,34375,
+34376,35193,35194,35196,35195,35327,35736,35737,36517,36516,36515,37998,37997,
+37999,38001,38003,38729,39026,39263,40040,40046,40045,40459,40461,40464,40463,
+40466,40465,40609,40693,40713,40775,40824,40827,40826,40825,22302,28774,31855,
+34876,36274,36518,37315,38004,38008,38006,38005,39520,40052,40051,40049,40053,
+40468,40467,40694,40714,40868,28776,28773,31991,34410,34878,34877,34879,35742,
+35996,36521,36553,38731,39027,39028,39116,39265,39339,39524,39526,39527,39716,
+40469,40471,40776,25095,27422,29223,34380,36520,38018,38016,38017,39529,39528,
+39726,40473,29225,34379,35743,38019,40057,40631,30325,39531,40058,40477,28777,
+28778,40612,40830,40777,40856,30849,37561,35023,22715,24658,31911,23290,9556,
+9574,9559,9568,9580,9571,9562,9577,9565,9554,9572,9557,9566,9578,9569,9560,
+9575,9563,9555,9573,9558,9567,9579,9570,9561,9576,9564,9553,9552,9581,9582,
+9584,9583,9619,
libc/musl/src/locale/bind_textdomain_codeset.c
@@ -0,0 +1,11 @@
+#include <libintl.h>
+#include <string.h>
+#include <strings.h>
+#include <errno.h>
+
+char *bind_textdomain_codeset(const char *domainname, const char *codeset)
+{
+	if (codeset && strcasecmp(codeset, "UTF-8"))
+		errno = EINVAL;
+	return NULL;
+}
libc/musl/src/locale/c_locale.c
@@ -0,0 +1,15 @@
+#include "locale_impl.h"
+#include <stdint.h>
+
+static const uint32_t empty_mo[] = { 0x950412de, 0, -1, -1, -1 };
+
+const struct __locale_map __c_dot_utf8 = {
+	.map = empty_mo,
+	.map_size = sizeof empty_mo,
+	.name = "C.UTF-8"
+};
+
+const struct __locale_struct __c_locale = { 0 };
+const struct __locale_struct __c_dot_utf8_locale = {
+	.cat[LC_CTYPE] = &__c_dot_utf8
+};
libc/musl/src/locale/catclose.c
@@ -0,0 +1,6 @@
+#include <nl_types.h>
+
+int catclose (nl_catd catd)
+{
+	return 0;
+}
libc/musl/src/locale/catgets.c
@@ -0,0 +1,6 @@
+#include <nl_types.h>
+
+char *catgets (nl_catd catd, int set_id, int msg_id, const char *s)
+{
+	return (char *)s;
+}
libc/musl/src/locale/catopen.c
@@ -0,0 +1,8 @@
+#include <nl_types.h>
+#include <errno.h>
+
+nl_catd catopen (const char *name, int oflag)
+{
+	errno = EOPNOTSUPP;
+	return (nl_catd)-1;
+}
libc/musl/src/locale/codepages.h
@@ -0,0 +1,320 @@
+"iso88591\0"
+"latin1\0"
+"\0\100"
+
+"iso88592\0"
+"\0\50"
+"\240\20\364\127\116\244\334\364\324\51\250\124\65\125\126\156\265\42\27\134"
+"\260\24\24\230\116\264\340\4\225\137\270\130\105\225\126\157\15\66\127\134"
+"\111\5\43\214\100\304\314\144\320\61\14\45\143\321\62\30\65\343\214\103"
+"\20\355\364\323\64\324\24\145\315\65\115\215\245\115\131\334\164\163\325\67"
+"\112\205\43\316\100\344\320\164\320\71\15\245\163\321\72\31\265\343\316\103"
+"\21\361\4\324\74\364\30\145\317\75\116\221\245\217\131\374\364\203\25\140"
+
+"iso88593\0"
+"\0\50"
+"\240\220\364\327\50\244\0\40\322\51\250\260\64\25\107\56\265\2\0\134"
+"\260\224\44\313\54\264\324\62\322\55\270\264\104\125\107\57\365\2\100\134"
+"\300\4\43\14\0\304\50\204\320\61\310\44\243\314\62\314\64\343\314\63"
+"\0\104\43\315\64\324\170\144\315\65\32\145\243\315\66\334\204\25\325\67"
+"\340\204\43\16\0\344\54\224\320\71\350\244\243\316\72\354\264\343\316\73"
+"\0\304\43\317\74\364\174\144\317\75\33\345\243\317\76\374\210\45\25\140"
+
+"iso88594\0"
+"\0\50"
+"\240\20\44\323\122\244\230\124\323\51\250\124\45\21\110\133\265\42\327\53"
+"\260\24\24\30\123\264\234\144\223\137\270\130\65\121\110\134\5\65\227\120"
+"\0\5\43\314\60\304\24\143\214\112\14\45\143\321\62\24\65\343\14\112"
+"\20\365\64\24\114\324\124\143\315\65\330\234\245\315\66\334\164\365\325\67"
+"\1\205\43\316\70\344\224\143\316\112\15\245\163\321\72\25\265\343\116\112"
+"\21\371\104\124\114\364\324\143\317\75\370\240\245\317\76\374\170\5\26\140"
+
+"iso88595\0"
+"\0\50"
+"\240\104\47\335\164\324\125\147\335\165\330\145\247\335\166"
+"\334\265\322\235\167\337\201\27\236\170\343\221\127\236\171"
+"\347\241\227\236\172\353\261\327\236\173\357\301\27\237\174"
+"\363\321\127\237\175\367\341\227\237\176\373\361\327\237\177\377\1\30\240\200"
+"\3\22\130\240\201\7\42\230\240\202\13\62\330\240\203\17\102\30\241\204"
+"\23\122\130\241\205\27\142\230\241\206\33\162\330\241\207\46\177\10\142\210"
+"\42\216\110\142\211\46\236\210\142\212\52\236\262\42\213"
+
+"iso88596\0"
+"\0\50"
+"\240\0\0\0\0\244\0\0\0\0\0\0\0\0\0\142\266\2\0\0\0\0\0\0\0\0\0\0\0\0"
+"\0\0\0\300\230\0\0\0\0\231\0\224\151\346\231\150\246\251\346\232"
+"\154\266\351\346\233\160\306\51\347\234\164\326\151\347\235"
+"\170\346\251\347\236\174\366\351\47\0\0\0\0\0\0\177\2\32\250\240"
+"\203\22\132\250\241\207\42\232\250\242\213\62\332\250\243\217\102\32\51\0"
+"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+
+"iso88597\0"
+"\0\50"
+"\240\114\114\361\50\44\227\154\312\51\250\244\222\330\52\254\264\2\100\304"
+"\260\304\42\313\54\212\55\306\330\55\215\71\366\330\56\220\365\22\231\144"
+"\223\121\126\231\145\227\141\226\231\146\233\161\326\231\147"
+"\237\201\26\232\150\243\221\6\100\151\246\235\206\132\152\252\255\306\132\153"
+"\256\275\6\133\154\262\315\106\133\155\266\335\206\133\156\272\355\306\133\157"
+"\276\375\6\134\160\302\15\107\134\161\306\35\207\134\162\312\55\307\134\163"
+"\316\75\7\35\0"
+
+"iso88598\0"
+"\0\50"
+"\240\0\40\312\50\244\224\142\312\51\250\244\162\315\52\254\264\342\312\53"
+"\260\304\42\313\54\264\324\142\313\55\270\344\162\317\56\274\364\342\13\0"
+"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+"\0\0\0\200\304\102\16\111\144\221\106\36\211\144\222\112\56\311\144\223"
+"\116\76\11\145\224\122\116\111\145\225\126\136\211\145\226\132\156\311\45\0"
+"\0\64\354\60\0"
+
+"iso88599\0"
+"\0\64"
+"\34\105\43\315\64\324\124\143\315\65\330\144\243\315\66\334\260\64\325\67"
+"\340\204\43\316\70\344\224\143\316\71\350\244\243\316\72\354\264\343\316\73"
+"\35\305\43\317\74\364\324\143\317\75\370\344\243\317\76\374\264\104\325\77"
+
+"iso885910\0"
+"\0\50"
+"\240\20\44\21\110\50\231\4\323\51\65\101\124\325\126\162\265\362\125\120"
+"\260\24\64\121\110\51\235\24\323\55\66\105\144\25\127\163\105\14\226\120"
+"\0\5\43\314\60\304\24\143\214\112\14\45\143\321\62\24\65\343\314\63"
+"\320\364\64\324\64\324\124\143\115\127\330\234\245\315\66\334\164\343\315\67"
+"\1\205\43\316\70\344\224\143\316\112\15\245\163\321\72\25\265\343\316\73"
+"\360\370\104\324\74\364\324\143\217\127\370\240\245\317\76\374\364\343\217\114"
+
+"iso885911\0"
+"tis620\0"
+"\0\50"
+"\240\170\372\51\250\241\212\72\52\251\245\232\172\52\252\251\252\272\52\253"
+"\255\272\372\52\254\261\312\72\53\255\265\332\172\53\256\271\352\272\53\257"
+"\275\372\372\53\260\301\12\73\54\261\305\32\173\54\262\311\52\273\54\263"
+"\315\72\373\54\264\321\112\73\55\265\325\132\173\55\0\0\0\0\0\266"
+"\331\152\273\55\267\335\172\373\55\270\341\212\73\56\271\345\232\173\56\272"
+"\351\252\273\56\273\355\272\373\56\274\361\312\73\57\275\0\0\0\0\0"
+
+"iso885913\0"
+"\0\50"
+"\240\134\54\312\50\244\140\154\312\51\330\244\262\324\52\254\264\342\212\61"
+"\260\304\42\313\54\26\327\142\313\55\370\344\302\324\56\274\364\342\213\71"
+"\4\251\4\220\101\304\24\143\221\104\14\45\343\26\105\40\301\204\122\115"
+"\125\355\324\323\64\103\125\143\315\65\147\345\364\324\127\334\300\45\327\67"
+"\5\255\24\320\101\344\224\163\321\104\15\245\363\126\105\41\305\224\222\115"
+"\126\361\344\323\74\104\325\143\317\75\150\351\4\25\130\374\304\65\27\305"
+
+"iso885914\0"
+"\0\50"
+"\240\324\153\357\50\12\55\164\357\51\3\247\122\60\276\11\267\342\112\133"
+"\371\352\353\321\107\373\362\153\113\277\4\373\153\360\277\12\37\214\60\300"
+"\300\4\43\314\60\304\24\143\314\61\310\44\243\314\62\314\64\343\314\63"
+"\151\105\43\315\64\324\124\143\115\300\330\144\243\315\66\334\164\263\326\67"
+"\340\204\43\316\70\344\224\143\316\71\350\244\243\316\72\354\264\343\316\73"
+"\152\305\43\317\74\364\324\143\217\300\370\344\243\317\76\374\364\303\326\77"
+
+"iso885915\0"
+"latin9\0"
+"\0\51"
+"\44\227\122\325\51\126\245\242\312\52\254\264\342\312\53\260\304\42\313\54"
+"\162\325\142\313\55\163\345\242\313\56\107\41\325\326\57\300\4\43\314\60"
+"\304\24\143\314\61\310\44\243\314\62\314\64\343\314\63\320\104\43\315\64"
+"\324\124\143\315\65\330\144\243\315\66\334\164\343\315\67\340\204\43\316\70"
+"\344\224\143\316\71\350\244\243\316\72\354\264\343\316\73\360\304\43\317\74"
+"\364\324\143\317\75\370\344\243\317\76\374\364\343\317\77"
+
+"iso885916\0"
+"\0\50"
+"\240\20\124\120\116\44\143\134\325\51\126\245\222\327\52\156\265\362\26\134"
+"\260\304\302\220\116\162\135\154\313\55\163\65\244\327\56\107\41\325\126\134"
+"\300\4\43\214\100\304\30\144\314\61\310\44\243\314\62\314\64\343\314\63"
+"\20\355\44\315\64\324\24\145\315\123\145\145\243\315\66\334\130\264\327\67"
+"\340\204\43\316\100\344\34\144\316\71\350\244\243\316\72\354\264\343\316\73"
+"\21\361\44\317\74\364\30\145\17\124\146\345\243\317\76\374\134\304\327\77"
+
+"cp1250\0"
+"windows1250\0"
+"\0\40"
+"\44\3\120\61\0\30\163\234\261\306\0\164\134\225\307\117\145\45\227\133"
+"\0\114\114\261\305\27\157\374\60\304\0\234\154\325\307\120\151\65\327\133"
+"\240\370\365\127\116\244\20\144\312\51\250\244\62\325\52\254\264\342\12\134"
+"\260\304\22\230\116\264\324\142\313\55\270\24\104\325\56\67\15\206\123\134"
+"\111\5\43\214\100\304\314\144\320\61\14\45\143\321\62\30\65\343\214\103"
+"\20\355\364\323\64\324\24\145\315\65\115\215\245\115\131\334\164\163\325\67"
+"\112\205\43\316\100\344\320\164\320\71\15\245\163\321\72\31\265\343\316\103"
+"\21\361\4\324\74\364\30\145\317\75\116\221\245\217\131\374\364\203\25\140"
+
+"cp1251\0"
+"windows1251\0"
+"\0\40"
+"\322\115\127\161\210\30\163\234\261\306\44\167\234\235\307\332\161\267\235\167"
+"\40\116\114\261\305\27\157\374\60\304\0\234\174\342\307\50\252\230\42\213"
+"\240\164\267\42\166\244\264\150\312\51\321\245\102\335\52\254\264\342\312\165"
+"\260\304\142\35\211\56\326\142\313\55\37\232\54\342\56\46\126\67\142\211"
+"\337\201\27\236\170\343\221\127\236\171\347\241\227\236\172"
+"\353\261\327\236\173\357\301\27\237\174\363\321\127\237\175"
+"\367\341\227\237\176\373\361\327\237\177\377\1\30\240\200\3\22\130\240\201"
+"\7\42\230\240\202\13\62\330\240\203\17\102\30\241\204\23\122\130\241\205"
+"\27\142\230\241\206\33\162\330\241\207"
+
+"cp1252\0"
+"windows1252\0"
+"\0\40"
+"\44\3\120\61\135\30\163\234\261\306\175\165\134\225\307\107\1\40\27\0"
+"\0\114\114\261\305\27\157\374\60\304\202\235\154\325\307\110\1\60\127\133"
+"\240\204\42\312\50\244\224\142\312\51\250\244\242\312\52\254\264\342\312\53"
+"\260\304\42\313\54\264\324\142\313\55\270\344\242\313\56\274\364\342\313\57"
+"\300\4\43\314\60\304\24\143\314\61\310\44\243\314\62\314\64\343\314\63"
+"\320\104\43\315\64\324\124\143\315\65\330\144\243\315\66\334\164\343\315\67"
+"\340\204\43\316\70\344\224\143\316\71\350\244\243\316\72\354\264\343\316\73"
+"\360\304\43\317\74\364\324\143\317\75\370\344\243\317\76\374\364\343\317\77"
+
+"cp1253\0"
+"windows1253\0"
+"\0\40"
+"\44\3\120\61\135\30\163\234\261\306\0\164\14\200\307\0\0\0\0\0"
+"\0\114\114\261\305\27\157\374\60\304\0\234\14\300\307\0\0\0\0\0"
+"\240\54\306\330\50\244\224\142\312\51\250\244\2\300\52\254\264\342\112\304"
+"\260\304\42\313\54\212\325\142\313\55\215\71\366\330\56\220\365\22\231\144"
+"\223\121\126\231\145\227\141\226\231\146\233\161\326\231\147"
+"\237\201\26\232\150\243\221\6\100\151\246\235\206\132\152\252\255\306\132\153"
+"\256\275\6\133\154\262\315\106\133\155\266\335\206\133\156\272\355\306\133\157"
+"\276\375\6\134\160\302\15\107\134\161\306\35\207\134\162\312\55\307\134\163"
+"\316\75\7\35\0"
+
+"cp1254\0"
+"windows1254\0"
+"\0\40"
+"\44\3\120\61\135\30\163\234\261\306\175\165\134\225\307\107\1\0\0\0"
+"\0\114\114\261\305\27\157\374\60\304\202\235\154\325\307\110\1\0\100\133"
+"\240\204\42\312\50\244\224\142\312\51\250\244\242\312\52\254\264\342\312\53"
+"\260\304\42\313\54\264\324\142\313\55\270\344\242\313\56\274\364\342\313\57"
+"\300\4\43\314\60\304\24\143\314\61\310\44\243\314\62\314\64\343\314\63"
+"\34\105\43\315\64\324\124\143\315\65\330\144\243\315\66\334\260\64\325\67"
+"\340\204\43\316\70\344\224\143\316\71\350\244\243\316\72\354\264\343\316\73"
+"\35\305\43\317\74\364\324\143\317\75\370\344\243\317\76\374\264\104\325\77"
+
+"cp1255\0"
+"windows1255\0"
+"\0\40"
+"\44\3\120\61\135\30\163\234\261\306\175\165\14\200\307\0\0\0\0\0"
+"\0\114\114\261\305\27\157\374\60\304\202\235\14\300\307\0\0\0\0\0"
+"\240\204\42\312\50\42\227\142\312\51\250\244\162\315\52\254\264\342\312\53"
+"\260\304\42\313\54\264\324\142\313\55\270\344\162\317\56\274\364\342\313\57"
+"\57\302\30\243\214\63\322\130\243\215\67\342\10\100\216\72\356\310\143\217"
+"\76\376\10\144\220\135\172\371\45\230\141\2\0\0\0\0\0\0\0\0\102\16\111\144\221"
+"\106\36\211\144\222\112\56\311\144\223\116\76\11\145\224\122\116\111\145\225"
+"\126\136\211\145\226\132\156\311\45\0\0\64\354\60\0"
+
+"cp1256\0"
+"windows1256\0"
+"\0\40"
+"\44\117\132\61\135\30\163\234\261\306\175\165\54\251\307\107\121\172\151\245"
+"\231\116\114\261\305\27\157\374\60\304\230\236\154\351\307\110\55\314\260\246"
+"\240\210\51\312\50\244\224\142\312\51\250\244\262\351\52\254\264\342\312\53"
+"\260\304\42\313\54\264\324\142\313\55\270\344\62\346\56\274\364\342\13\231"
+"\234\226\151\346\231\150\246\251\346\232\154\266\351\346\233"
+"\160\306\51\347\234\164\326\151\347\235\170\346\251\347\65\173\362\331\247\237"
+"\177\2\32\250\240\340\14\52\16\241\205\32\172\350\71\350\244\243\316\72"
+"\210\46\352\316\73\212\56\312\150\243\364\70\372\350\75\220\346\23\351\76"
+"\374\64\354\160\247"
+
+"cp1257\0"
+"windows1257\0"
+"\0\40"
+"\44\3\120\61\0\30\163\234\261\306\0\164\14\200\307\0\240\342\27\56"
+"\0\114\114\261\305\27\157\374\60\304\0\234\14\300\307\0\274\22\30\0"
+"\240\0\40\312\50\244\0\140\312\51\330\244\262\324\52\254\264\342\212\61"
+"\260\304\42\313\54\264\324\142\313\55\370\344\302\324\56\274\364\342\213\71"
+"\4\251\4\220\101\304\24\143\221\104\14\45\343\26\105\40\301\204\122\115"
+"\125\355\324\323\64\103\125\143\315\65\147\345\364\324\127\334\300\45\327\67"
+"\5\255\24\320\101\344\224\163\321\104\15\245\363\126\105\41\305\224\222\115"
+"\126\361\344\323\74\104\325\143\317\75\150\351\4\25\130\374\304\65\27\140"
+
+"cp1258\0"
+"windows1258\0"
+"\0\40"
+"\44\3\120\61\135\30\163\234\261\306\175\165\14\200\307\107\1\0\0\0"
+"\0\114\114\261\305\27\157\374\60\304\202\235\14\300\307\110\1\0\100\133"
+"\240\204\42\312\50\244\224\142\312\51\250\244\242\312\52\254\264\342\312\53"
+"\260\304\42\313\54\264\324\142\313\55\270\344\242\313\56\274\364\342\313\57"
+"\300\4\43\214\100\304\24\143\314\61\310\44\243\314\62\204\65\343\314\63"
+"\20\105\163\330\64\324\324\145\315\65\330\144\243\315\66\334\334\145\330\67"
+"\340\204\43\316\100\344\224\143\316\71\350\244\243\316\72\205\265\343\316\73"
+"\21\305\203\330\74\364\330\145\317\75\370\344\243\317\76\374\340\65\362\77"
+
+"koi8r\0"
+"\0\40"
+"\63\323\134\263\315\67\343\234\263\316\73\363\334\363\326\134\167\355\365\327"
+"\140\207\55\166\314\143\243\234\62\313\56\277\14\212\314\260\310\162\313\75"
+"\76\377\14\364\207\101\13\75\64\321\105\33\175\64\322\111\53\275\64\323"
+"\115\73\375\164\164\120\107\55\365\324\124\127\155\365\325\130\147\255\165\52"
+"\35\376\7\140\205\3\22\70\241\200\24\36\210\140\202\12\56\310\140\203"
+"\16\172\370\40\204\21\112\130\140\200\33\152\150\340\205\34\142\150\141\206"
+"\375\175\7\136\175\343\221\67\237\170\364\235\207\136\172\352\255\307\136\173"
+"\356\371\367\36\174\361\311\127\136\170\373\351\147\336\175"
+"\374\341\147\137\176"
+
+"koi8u\0"
+"\0\40"
+"\63\323\134\263\315\67\343\234\263\316\73\363\334\363\326\134\167\355\365\327"
+"\140\207\55\166\314\143\243\234\62\313\56\277\14\212\314\260\310\162\313\75"
+"\76\377\14\364\207\42\12\115\142\211\105\33\175\64\322\111\273\270\64\323"
+"\115\73\375\164\164\324\105\155\335\165\124\127\155\365\325\130\267\250\165\52"
+"\35\376\7\140\205\3\22\70\241\200\24\36\210\140\202\12\56\310\140\203"
+"\16\172\370\40\204\21\112\130\140\200\33\152\150\340\205\34\142\150\141\206"
+"\375\175\7\136\175\343\221\67\237\170\364\235\207\136\172\352\255\307\136\173"
+"\356\371\367\36\174\361\311\127\136\170\373\351\147\336\175"
+"\374\341\147\137\176"
+
+"cp437\0"
+"\0\40"
+"\307\360\223\216\70\344\200\123\316\71\352\254\203\316\73\356\260\103\114\61"
+"\311\230\143\14\75\366\310\263\117\76\377\130\303\215\50\243\224\22\62\135"
+"\341\264\63\217\76\361\104\243\212\56\277\300\314\112\57\274\204\262\312\56"
+"\140\207\55\66\315\72\77\15\65\321\103\107\375\163\321\113\53\235\264\315"
+"\67\363\274\163\316\63\367\314\164\323\110\13\175\65\325\116\373\254\165\325"
+"\126\113\75\365\321\106\3\35\164\326\130\343\134\163\327\134\173\375\365\326"
+"\263\175\143\231\160\245\25\127\213\161\250\155\266\232\155\52\43\167\333\312"
+"\55\307\362\262\313\61\313\174\17\313\260\240\174\113\312\40\313\62\66\50"
+
+"cp850\0"
+"\0\40"
+"\307\360\223\216\70\344\200\123\316\71\352\254\203\316\73\356\260\103\114\61"
+"\311\230\143\14\75\366\310\263\117\76\377\130\303\15\76\243\140\163\15\135"
+"\341\264\63\217\76\361\104\243\212\56\277\270\302\112\57\274\204\262\312\56"
+"\140\207\55\66\315\72\7\43\14\60\251\104\375\163\321\113\213\122\212\315"
+"\67\363\274\163\316\63\367\74\316\60\110\13\175\65\325\116\373\254\65\51"
+"\360\100\243\314\62\310\264\324\214\63\317\340\134\163\327\134\233\302\314\326"
+"\323\174\103\215\64\365\124\123\213\77\336\150\263\115\66\375\164\363\12\55"
+"\255\304\42\261\57\266\234\162\17\56\260\240\162\113\56\263\310\62\66\50"
+
+"cp866\0"
+"\0\40"
+"\337\201\27\236\170\343\221\127\236\171\347\241\227\236\172"
+"\353\261\327\236\173\357\301\27\237\174\363\321\127\237\175"
+"\367\341\227\237\176\373\361\327\237\177\377\1\30\240\200\3\22\130\240\201"
+"\7\42\230\240\202\13\62\330\240\203\140\207\55\66\315\72\77\15\65\321"
+"\103\107\375\163\321\113\53\235\264\315\67\363\274\163\316\63\367\314\164\323"
+"\110\13\175\65\325\116\373\254\165\325\126\113\75\365\321\106\3\35\164\326"
+"\130\343\134\163\327\134\173\375\365\326\17\102\30\241\204\23\122\130\241\205"
+"\27\142\230\241\206\33\162\330\241\207\321\175\110\235\210\327\225\330\335\212"
+"\260\240\174\113\312\46\223\62\66\50"
+
+"ibm1047\0"
+"cp1047\0"
+"\0\1"
+"\234\44\140\310\37\227\64\342\310\2\14\64\340\300\3\20\104\40\301\4"
+"\235\24\202\300\41\30\144\40\311\43\34\164\340\301\7\200\4\42\310\40"
+"\204\50\160\301\6\210\44\242\310\42\214\24\140\300\1\220\104\142\301\44"
+"\224\124\142\11\1\230\144\242\311\46\24\124\340\211\6\40\200\42\16\71"
+"\340\204\63\116\71\347\304\43\212\13\74\240\260\2\37\46\244\243\316\72"
+"\350\264\343\316\73\354\174\23\2\11\52\244\260\203\27\55\274\40\14\61"
+"\300\4\63\114\61\307\104\143\12\13\45\174\341\303\17\370\44\243\314\62"
+"\310\64\343\314\63\314\200\241\303\10\100\234\320\203\10\330\204\41\306\30"
+"\144\224\141\306\31\150\244\261\312\56\360\364\343\117\54\260\250\261\6\33"
+"\155\270\361\6\34\161\310\241\212\56\346\340\142\14\51\265\370\61\7\35"
+"\165\330\161\7\36\171\350\21\312\57\320\154\341\215\53\254\214\122\312\55"
+"\251\234\142\13\57\275\370\322\15\52\257\164\101\313\65\173\4\41\304\20"
+"\104\24\141\304\21\110\44\321\12\75\366\310\63\117\75\175\50\261\4\23"
+"\115\70\361\4\24\121\110\221\313\76\374\344\243\317\77\134\334\63\5\25"
+"\125\130\161\5\26\131\150\41\13\65\326\110\63\115\65\60\304\40\303\14"
+"\64\324\140\303\15\70\344\60\313\66\334\144\243\315\47"
+
libc/musl/src/locale/dcngettext.c
@@ -0,0 +1,269 @@
+#include <libintl.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include <limits.h>
+#include <sys/stat.h>
+#include <sys/mman.h>
+#include <ctype.h>
+#include "locale_impl.h"
+#include "atomic.h"
+#include "pleval.h"
+#include "lock.h"
+
+struct binding {
+	struct binding *next;
+	int dirlen;
+	volatile int active;
+	char *domainname;
+	char *dirname;
+	char buf[];
+};
+
+static void *volatile bindings;
+
+static char *gettextdir(const char *domainname, size_t *dirlen)
+{
+	struct binding *p;
+	for (p=bindings; p; p=p->next) {
+		if (!strcmp(p->domainname, domainname) && p->active) {
+			*dirlen = p->dirlen;
+			return (char *)p->dirname;
+		}
+	}
+	return 0;
+}
+
+char *bindtextdomain(const char *domainname, const char *dirname)
+{
+	static volatile int lock[1];
+	struct binding *p, *q;
+
+	if (!domainname) return 0;
+	if (!dirname) return gettextdir(domainname, &(size_t){0});
+
+	size_t domlen = strnlen(domainname, NAME_MAX+1);
+	size_t dirlen = strnlen(dirname, PATH_MAX);
+	if (domlen > NAME_MAX || dirlen >= PATH_MAX) {
+		errno = EINVAL;
+		return 0;
+	}
+
+	LOCK(lock);
+
+	for (p=bindings; p; p=p->next) {
+		if (!strcmp(p->domainname, domainname) &&
+		    !strcmp(p->dirname, dirname)) {
+			break;
+		}
+	}
+
+	if (!p) {
+		p = calloc(sizeof *p + domlen + dirlen + 2, 1);
+		if (!p) {
+			UNLOCK(lock);
+			return 0;
+		}
+		p->next = bindings;
+		p->dirlen = dirlen;
+		p->domainname = p->buf;
+		p->dirname = p->buf + domlen + 1;
+		memcpy(p->domainname, domainname, domlen+1);
+		memcpy(p->dirname, dirname, dirlen+1);
+		a_cas_p(&bindings, bindings, p);
+	}
+
+	a_store(&p->active, 1);
+
+	for (q=bindings; q; q=q->next) {
+		if (!strcmp(q->domainname, domainname) && q != p)
+			a_store(&q->active, 0);
+	}
+
+	UNLOCK(lock);
+	
+	return (char *)p->dirname;
+}
+
+static const char catnames[][12] = {
+	"LC_CTYPE",
+	"LC_NUMERIC",
+	"LC_TIME",
+	"LC_COLLATE",
+	"LC_MONETARY",
+	"LC_MESSAGES",
+};
+
+static const char catlens[] = { 8, 10, 7, 10, 11, 11 };
+
+struct msgcat {
+	struct msgcat *next;
+	const void *map;
+	size_t map_size;
+	const char *plural_rule;
+	int nplurals;
+	struct binding *binding;
+	const struct __locale_map *lm;
+	int cat;
+};
+
+static char *dummy_gettextdomain()
+{
+	return "messages";
+}
+
+weak_alias(dummy_gettextdomain, __gettextdomain);
+
+char *dcngettext(const char *domainname, const char *msgid1, const char *msgid2, unsigned long int n, int category)
+{
+	static struct msgcat *volatile cats;
+	struct msgcat *p;
+	struct __locale_struct *loc = CURRENT_LOCALE;
+	const struct __locale_map *lm;
+	size_t domlen;
+	struct binding *q;
+
+	if ((unsigned)category >= LC_ALL) goto notrans;
+
+	if (!domainname) domainname = __gettextdomain();
+
+	domlen = strnlen(domainname, NAME_MAX+1);
+	if (domlen > NAME_MAX) goto notrans;
+
+	for (q=bindings; q; q=q->next)
+		if (!strcmp(q->domainname, domainname) && q->active)
+			break;
+	if (!q) goto notrans;
+
+	lm = loc->cat[category];
+	if (!lm) {
+notrans:
+		return (char *) ((n == 1) ? msgid1 : msgid2);
+	}
+
+	for (p=cats; p; p=p->next)
+		if (p->binding == q && p->lm == lm && p->cat == category)
+			break;
+
+	if (!p) {
+		const char *dirname, *locname, *catname, *modname, *locp;
+		size_t dirlen, loclen, catlen, modlen, alt_modlen;
+		void *old_cats;
+		size_t map_size;
+
+		dirname = q->dirname;
+		locname = lm->name;
+		catname = catnames[category];
+
+		dirlen = q->dirlen;
+		loclen = strlen(locname);
+		catlen = catlens[category];
+
+		/* Logically split @mod suffix from locale name. */
+		modname = memchr(locname, '@', loclen);
+		if (!modname) modname = locname + loclen;
+		alt_modlen = modlen = loclen - (modname-locname);
+		loclen = modname-locname;
+
+		/* Drop .charset identifier; it is not used. */
+		const char *csp = memchr(locname, '.', loclen);
+		if (csp) loclen = csp-locname;
+
+		char name[dirlen+1 + loclen+modlen+1 + catlen+1 + domlen+3 + 1];
+		const void *map;
+
+		for (;;) {
+			snprintf(name, sizeof name, "%s/%.*s%.*s/%s/%s.mo\0",
+				dirname, (int)loclen, locname,
+				(int)alt_modlen, modname, catname, domainname);
+			if (map = __map_file(name, &map_size)) break;
+
+			/* Try dropping @mod, _YY, then both. */
+			if (alt_modlen) {
+				alt_modlen = 0;
+			} else if ((locp = memchr(locname, '_', loclen))) {
+				loclen = locp-locname;
+				alt_modlen = modlen;
+			} else {
+				break;
+			}
+		}
+		if (!map) goto notrans;
+
+		p = calloc(sizeof *p, 1);
+		if (!p) {
+			__munmap((void *)map, map_size);
+			goto notrans;
+		}
+		p->cat = category;
+		p->binding = q;
+		p->lm = lm;
+		p->map = map;
+		p->map_size = map_size;
+
+		const char *rule = "n!=1;";
+		unsigned long np = 2;
+		const char *r = __mo_lookup(p->map, p->map_size, "");
+		char *z;
+		while (r && strncmp(r, "Plural-Forms:", 13)) {
+			z = strchr(r, '\n');
+			r = z ? z+1 : 0;
+		}
+		if (r) {
+			r += 13;
+			while (isspace(*r)) r++;
+			if (!strncmp(r, "nplurals=", 9)) {
+				np = strtoul(r+9, &z, 10);
+				r = z;
+			}
+			while (*r && *r != ';') r++;
+			if (*r) {
+				r++;
+				while (isspace(*r)) r++;
+				if (!strncmp(r, "plural=", 7))
+					rule = r+7;
+			}
+		}
+		p->nplurals = np;
+		p->plural_rule = rule;
+
+		do {
+			old_cats = cats;
+			p->next = old_cats;
+		} while (a_cas_p(&cats, old_cats, p) != old_cats);
+	}
+
+	const char *trans = __mo_lookup(p->map, p->map_size, msgid1);
+	if (!trans) goto notrans;
+
+	/* Non-plural-processing gettext forms pass a null pointer as
+	 * msgid2 to request that dcngettext suppress plural processing. */
+
+	if (msgid2 && p->nplurals) {
+		unsigned long plural = __pleval(p->plural_rule, n);
+		if (plural > p->nplurals) goto notrans;
+		while (plural--) {
+			size_t rem = p->map_size - (trans - (char *)p->map);
+			size_t l = strnlen(trans, rem);
+			if (l+1 >= rem)
+				goto notrans;
+			trans += l+1;
+		}
+	}
+	return (char *)trans;
+}
+
+char *dcgettext(const char *domainname, const char *msgid, int category)
+{
+	return dcngettext(domainname, msgid, 0, 1, category);
+}
+
+char *dngettext(const char *domainname, const char *msgid1, const char *msgid2, unsigned long int n)
+{
+	return dcngettext(domainname, msgid1, msgid2, n, LC_MESSAGES);
+}
+
+char *dgettext(const char *domainname, const char *msgid)
+{
+	return dcngettext(domainname, msgid, 0, 1, LC_MESSAGES);
+}
libc/musl/src/locale/duplocale.c
@@ -0,0 +1,15 @@
+#include <stdlib.h>
+#include <string.h>
+#include "locale_impl.h"
+#include "libc.h"
+
+locale_t __duplocale(locale_t old)
+{
+	locale_t new = malloc(sizeof *new);
+	if (!new) return 0;
+	if (old == LC_GLOBAL_LOCALE) old = &libc.global_locale;
+	*new = *old;
+	return new;
+}
+
+weak_alias(__duplocale, duplocale);
libc/musl/src/locale/freelocale.c
@@ -0,0 +1,9 @@
+#include <stdlib.h>
+#include "locale_impl.h"
+
+void freelocale(locale_t l)
+{
+	if (__loc_is_allocated(l)) free(l);
+}
+
+weak_alias(freelocale, __freelocale);
libc/musl/src/locale/gb18030.h
@@ -0,0 +1,1866 @@
+19970,19972,19973,19974,19983,19986,19991,19999,20000,20001,20003,20006,20009,
+20014,20015,20017,20019,20021,20023,20028,20032,20033,20034,20036,20038,20042,
+20049,20053,20055,20058,20059,20066,20067,20068,20069,20071,20072,20074,20075,
+20076,20077,20078,20079,20082,20084,20085,20086,20087,20088,20089,20090,20091,
+20092,20093,20095,20096,20097,20098,20099,20100,20101,20103,20106,20112,20118,
+20119,20121,20124,20125,20126,20131,20138,20143,20144,20145,20148,20150,20151,
+20152,20153,20156,20157,20158,20168,20172,20175,20176,20178,20186,20187,20188,
+20192,20194,20198,20199,20201,20205,20206,20207,20209,20212,20216,20217,20218,
+20220,20222,20224,20226,20227,20228,20229,20230,20231,20232,20235,20236,20242,
+20243,20244,20245,20246,20252,20253,20257,20259,20264,20265,20268,20269,20270,
+20273,20275,20277,20279,20281,20283,20286,20287,20288,20289,20290,20292,20293,
+20295,20296,20297,20298,20299,20300,20306,20308,20310,20321,20322,20326,20328,
+20330,20331,20333,20334,20337,20338,20341,20343,20344,20345,20346,20349,20352,
+20353,20354,20357,20358,20359,20362,20364,20366,20368,20370,20371,20373,20374,
+20376,20377,20378,20380,20382,20383,20385,20386,20388,20395,20397,20400,20401,
+20402,20403,20404,20406,20407,20408,20409,20410,20411,20412,20413,20414,20416,
+20417,20418,20422,20423,20424,20425,20427,20428,20429,20434,20435,20436,20437,
+20438,20441,20443,20448,20450,20452,20453,20455,20459,20460,20464,20466,20468,
+20469,20470,20471,20473,20475,20476,20477,20479,20480,20481,20482,20483,20484,
+20485,20486,20487,20488,20489,20490,20491,20494,
+20496,20497,20499,20501,20502,20503,20507,20509,20510,20512,20514,20515,20516,
+20519,20523,20527,20528,20529,20530,20531,20532,20533,20534,20535,20536,20537,
+20539,20541,20543,20544,20545,20546,20548,20549,20550,20553,20554,20555,20557,
+20560,20561,20562,20563,20564,20566,20567,20568,20569,20571,20573,20574,20575,
+20576,20577,20578,20579,20580,20582,20583,20584,20585,20586,20587,20589,20590,
+20591,20592,20593,20594,20595,20596,20597,20600,20601,20602,20604,20605,20609,
+20610,20611,20612,20614,20615,20617,20618,20619,20620,20622,20623,20624,20625,
+20626,20627,20628,20629,20630,20631,20632,20633,20634,20635,20636,20637,20638,
+20639,20640,20641,20642,20644,20646,20650,20651,20653,20654,20655,20656,20657,
+20659,20660,20661,20662,20663,20664,20665,20668,20669,20670,20671,20672,20673,
+20674,20675,20676,20677,20678,20679,20680,20681,20682,20683,20684,20685,20686,
+20688,20689,20690,20691,20692,20693,20695,20696,20697,20699,20700,20701,20702,
+20703,20704,20705,20706,20707,20708,20709,20712,20713,20714,20715,20719,20720,
+20721,20722,20724,20726,20727,20728,20729,20730,20732,20733,20734,20735,20736,
+20737,20738,20739,20740,20741,20744,20745,20746,20748,20749,20750,20751,20752,
+20753,20755,20756,20757,20758,20759,20760,20761,20762,20763,20764,20765,20766,
+20767,20768,20770,20771,20772,20773,20774,20775,20776,20777,20778,20779,20780,
+20781,20782,20783,20784,20785,20786,20787,20788,20789,20790,20791,20792,20793,
+20794,20795,20796,20797,20798,20802,20807,20810,20812,20814,20815,20816,20818,
+20819,20823,20824,20825,20827,20829,20830,20831,20832,
+20833,20835,20836,20838,20839,20841,20842,20847,20850,20858,20862,20863,20867,
+20868,20870,20871,20874,20875,20878,20879,20880,20881,20883,20884,20888,20890,
+20893,20894,20895,20897,20899,20902,20903,20904,20905,20906,20909,20910,20916,
+20920,20921,20922,20926,20927,20929,20930,20931,20933,20936,20938,20941,20942,
+20944,20946,20947,20948,20949,20950,20951,20952,20953,20954,20956,20958,20959,
+20962,20963,20965,20966,20967,20968,20969,20970,20972,20974,20977,20978,20980,
+20983,20990,20996,20997,21001,21003,21004,21007,21008,21011,21012,21013,21020,
+21022,21023,21025,21026,21027,21029,21030,21031,21034,21036,21039,21041,21042,
+21044,21045,21052,21054,21060,21061,21062,21063,21064,21065,21067,21070,21071,
+21074,21075,21077,21079,21080,21081,21082,21083,21085,21087,21088,21090,21091,
+21092,21094,21096,21099,21100,21101,21102,21104,21105,21107,21108,21109,21110,
+21111,21112,21113,21114,21115,21116,21118,21120,21123,21124,21125,21126,21127,
+21129,21130,21131,21132,21133,21134,21135,21137,21138,21140,21141,21142,21143,
+21144,21145,21146,21148,21156,21157,21158,21159,21166,21167,21168,21172,21173,
+21174,21175,21176,21177,21178,21179,21180,21181,21184,21185,21186,21188,21189,
+21190,21192,21194,21196,21197,21198,21199,21201,21203,21204,21205,21207,21209,
+21210,21211,21212,21213,21214,21216,21217,21218,21219,21221,21222,21223,21224,
+21225,21226,21227,21228,21229,21230,21231,21233,21234,21235,21236,21237,21238,
+21239,21240,21243,21244,21245,21249,21250,21251,21252,21255,21257,21258,21259,
+21260,21262,21265,21266,21267,21268,21272,21275,21276,
+21278,21279,21282,21284,21285,21287,21288,21289,21291,21292,21293,21295,21296,
+21297,21298,21299,21300,21301,21302,21303,21304,21308,21309,21312,21314,21316,
+21318,21323,21324,21325,21328,21332,21336,21337,21339,21341,21349,21352,21354,
+21356,21357,21362,21366,21369,21371,21372,21373,21374,21376,21377,21379,21383,
+21384,21386,21390,21391,21392,21393,21394,21395,21396,21398,21399,21401,21403,
+21404,21406,21408,21409,21412,21415,21418,21419,21420,21421,21423,21424,21425,
+21426,21427,21428,21429,21431,21432,21433,21434,21436,21437,21438,21440,21443,
+21444,21445,21446,21447,21454,21455,21456,21458,21459,21461,21466,21468,21469,
+21470,21473,21474,21479,21492,21498,21502,21503,21504,21506,21509,21511,21515,
+21524,21528,21529,21530,21532,21538,21540,21541,21546,21552,21555,21558,21559,
+21562,21565,21567,21569,21570,21572,21573,21575,21577,21580,21581,21582,21583,
+21585,21594,21597,21598,21599,21600,21601,21603,21605,21607,21609,21610,21611,
+21612,21613,21614,21615,21616,21620,21625,21626,21630,21631,21633,21635,21637,
+21639,21640,21641,21642,21645,21649,21651,21655,21656,21660,21662,21663,21664,
+21665,21666,21669,21678,21680,21682,21685,21686,21687,21689,21690,21692,21694,
+21699,21701,21706,21707,21718,21720,21723,21728,21729,21730,21731,21732,21739,
+21740,21743,21744,21745,21748,21749,21750,21751,21752,21753,21755,21758,21760,
+21762,21763,21764,21765,21768,21770,21771,21772,21773,21774,21778,21779,21781,
+21782,21783,21784,21785,21786,21788,21789,21790,21791,21793,21797,21798,21800,
+21801,21803,21805,21810,21812,21813,21814,21816,21817,
+21818,21819,21821,21824,21826,21829,21831,21832,21835,21836,21837,21838,21839,
+21841,21842,21843,21844,21847,21848,21849,21850,21851,21853,21854,21855,21856,
+21858,21859,21864,21865,21867,21871,21872,21873,21874,21875,21876,21881,21882,
+21885,21887,21893,21894,21900,21901,21902,21904,21906,21907,21909,21910,21911,
+21914,21915,21918,21920,21921,21922,21923,21924,21925,21926,21928,21929,21930,
+21931,21932,21933,21934,21935,21936,21938,21940,21942,21944,21946,21948,21951,
+21952,21953,21954,21955,21958,21959,21960,21962,21963,21966,21967,21968,21973,
+21975,21976,21977,21978,21979,21982,21984,21986,21991,21993,21997,21998,22000,
+22001,22004,22006,22008,22009,22010,22011,22012,22015,22018,22019,22020,22021,
+22022,22023,22026,22027,22029,22032,22033,22034,22035,22036,22037,22038,22039,
+22041,22042,22044,22045,22048,22049,22050,22053,22054,22056,22057,22058,22059,
+22062,22063,22064,22067,22069,22071,22072,22074,22076,22077,22078,22080,22081,
+22082,22083,22084,22085,22086,22087,22088,22089,22090,22091,22095,22096,22097,
+22098,22099,22101,22102,22106,22107,22109,22110,22111,22112,22113,22115,22117,
+22118,22119,22125,22126,22127,22128,22130,22131,22132,22133,22135,22136,22137,
+22138,22141,22142,22143,22144,22145,22146,22147,22148,22151,22152,22153,22154,
+22155,22156,22157,22160,22161,22162,22164,22165,22166,22167,22168,22169,22170,
+22171,22172,22173,22174,22175,22176,22177,22178,22180,22181,22182,22183,22184,
+22185,22186,22187,22188,22189,22190,22192,22193,22194,22195,22196,22197,22198,
+22200,22201,22202,22203,22205,22206,22207,22208,22209,
+22210,22211,22212,22213,22214,22215,22216,22217,22219,22220,22221,22222,22223,
+22224,22225,22226,22227,22229,22230,22232,22233,22236,22243,22245,22246,22247,
+22248,22249,22250,22252,22254,22255,22258,22259,22262,22263,22264,22267,22268,
+22272,22273,22274,22277,22279,22283,22284,22285,22286,22287,22288,22289,22290,
+22291,22292,22293,22294,22295,22296,22297,22298,22299,22301,22302,22304,22305,
+22306,22308,22309,22310,22311,22315,22321,22322,22324,22325,22326,22327,22328,
+22332,22333,22335,22337,22339,22340,22341,22342,22344,22345,22347,22354,22355,
+22356,22357,22358,22360,22361,22370,22371,22373,22375,22380,22382,22384,22385,
+22386,22388,22389,22392,22393,22394,22397,22398,22399,22400,22401,22407,22408,
+22409,22410,22413,22414,22415,22416,22417,22420,22421,22422,22423,22424,22425,
+22426,22428,22429,22430,22431,22437,22440,22442,22444,22447,22448,22449,22451,
+22453,22454,22455,22457,22458,22459,22460,22461,22462,22463,22464,22465,22468,
+22469,22470,22471,22472,22473,22474,22476,22477,22480,22481,22483,22486,22487,
+22491,22492,22494,22497,22498,22499,22501,22502,22503,22504,22505,22506,22507,
+22508,22510,22512,22513,22514,22515,22517,22518,22519,22523,22524,22526,22527,
+22529,22531,22532,22533,22536,22537,22538,22540,22542,22543,22544,22546,22547,
+22548,22550,22551,22552,22554,22555,22556,22557,22559,22562,22563,22565,22566,
+22567,22568,22569,22571,22572,22573,22574,22575,22577,22578,22579,22580,22582,
+22583,22584,22585,22586,22587,22588,22589,22590,22591,22592,22593,22594,22595,
+22597,22598,22599,22600,22601,22602,22603,22606,22607,
+22608,22610,22611,22613,22614,22615,22617,22618,22619,22620,22621,22623,22624,
+22625,22626,22627,22628,22630,22631,22632,22633,22634,22637,22638,22639,22640,
+22641,22642,22643,22644,22645,22646,22647,22648,22649,22650,22651,22652,22653,
+22655,22658,22660,22662,22663,22664,22666,22667,22668,22669,22670,22671,22672,
+22673,22676,22677,22678,22679,22680,22683,22684,22685,22688,22689,22690,22691,
+22692,22693,22694,22695,22698,22699,22700,22701,22702,22703,22704,22705,22706,
+22707,22708,22709,22710,22711,22712,22713,22714,22715,22717,22718,22719,22720,
+22722,22723,22724,22726,22727,22728,22729,22730,22731,22732,22733,22734,22735,
+22736,22738,22739,22740,22742,22743,22744,22745,22746,22747,22748,22749,22750,
+22751,22752,22753,22754,22755,22757,22758,22759,22760,22761,22762,22765,22767,
+22769,22770,22772,22773,22775,22776,22778,22779,22780,22781,22782,22783,22784,
+22785,22787,22789,22790,22792,22793,22794,22795,22796,22798,22800,22801,22802,
+22803,22807,22808,22811,22813,22814,22816,22817,22818,22819,22822,22824,22828,
+22832,22834,22835,22837,22838,22843,22845,22846,22847,22848,22851,22853,22854,
+22858,22860,22861,22864,22866,22867,22873,22875,22876,22877,22878,22879,22881,
+22883,22884,22886,22887,22888,22889,22890,22891,22892,22893,22894,22895,22896,
+22897,22898,22901,22903,22906,22907,22908,22910,22911,22912,22917,22921,22923,
+22924,22926,22927,22928,22929,22932,22933,22936,22938,22939,22940,22941,22943,
+22944,22945,22946,22950,22951,22956,22957,22960,22961,22963,22964,22965,22966,
+22967,22968,22970,22972,22973,22975,22976,22977,22978,
+22979,22980,22981,22983,22984,22985,22988,22989,22990,22991,22997,22998,23001,
+23003,23006,23007,23008,23009,23010,23012,23014,23015,23017,23018,23019,23021,
+23022,23023,23024,23025,23026,23027,23028,23029,23030,23031,23032,23034,23036,
+23037,23038,23040,23042,23050,23051,23053,23054,23055,23056,23058,23060,23061,
+23062,23063,23065,23066,23067,23069,23070,23073,23074,23076,23078,23079,23080,
+23082,23083,23084,23085,23086,23087,23088,23091,23093,23095,23096,23097,23098,
+23099,23101,23102,23103,23105,23106,23107,23108,23109,23111,23112,23115,23116,
+23117,23118,23119,23120,23121,23122,23123,23124,23126,23127,23128,23129,23131,
+23132,23133,23134,23135,23136,23137,23139,23140,23141,23142,23144,23145,23147,
+23148,23149,23150,23151,23152,23153,23154,23155,23160,23161,23163,23164,23165,
+23166,23168,23169,23170,23171,23172,23173,23174,23175,23176,23177,23178,23179,
+23180,23181,23182,23183,23184,23185,23187,23188,23189,23190,23191,23192,23193,
+23196,23197,23198,23199,23200,23201,23202,23203,23204,23205,23206,23207,23208,
+23209,23211,23212,23213,23214,23215,23216,23217,23220,23222,23223,23225,23226,
+23227,23228,23229,23231,23232,23235,23236,23237,23238,23239,23240,23242,23243,
+23245,23246,23247,23248,23249,23251,23253,23255,23257,23258,23259,23261,23262,
+23263,23266,23268,23269,23271,23272,23274,23276,23277,23278,23279,23280,23282,
+23283,23284,23285,23286,23287,23288,23289,23290,23291,23292,23293,23294,23295,
+23296,23297,23298,23299,23300,23301,23302,23303,23304,23306,23307,23308,23309,
+23310,23311,23312,23313,23314,23315,23316,23317,23320,
+23321,23322,23323,23324,23325,23326,23327,23328,23329,23330,23331,23332,23333,
+23334,23335,23336,23337,23338,23339,23340,23341,23342,23343,23344,23345,23347,
+23349,23350,23352,23353,23354,23355,23356,23357,23358,23359,23361,23362,23363,
+23364,23365,23366,23367,23368,23369,23370,23371,23372,23373,23374,23375,23378,
+23382,23390,23392,23393,23399,23400,23403,23405,23406,23407,23410,23412,23414,
+23415,23416,23417,23419,23420,23422,23423,23426,23430,23434,23437,23438,23440,
+23441,23442,23444,23446,23455,23463,23464,23465,23468,23469,23470,23471,23473,
+23474,23479,23482,23483,23484,23488,23489,23491,23496,23497,23498,23499,23501,
+23502,23503,23505,23508,23509,23510,23511,23512,23513,23514,23515,23516,23520,
+23522,23523,23526,23527,23529,23530,23531,23532,23533,23535,23537,23538,23539,
+23540,23541,23542,23543,23549,23550,23552,23554,23555,23557,23559,23560,23563,
+23564,23565,23566,23568,23570,23571,23575,23577,23579,23582,23583,23584,23585,
+23587,23590,23592,23593,23594,23595,23597,23598,23599,23600,23602,23603,23605,
+23606,23607,23619,23620,23622,23623,23628,23629,23634,23635,23636,23638,23639,
+23640,23642,23643,23644,23645,23647,23650,23652,23655,23656,23657,23658,23659,
+23660,23661,23664,23666,23667,23668,23669,23670,23671,23672,23675,23676,23677,
+23678,23680,23683,23684,23685,23686,23687,23689,23690,23691,23694,23695,23698,
+23699,23701,23709,23710,23711,23712,23713,23716,23717,23718,23719,23720,23722,
+23726,23727,23728,23730,23732,23734,23737,23738,23739,23740,23742,23744,23746,
+23747,23749,23750,23751,23752,23753,23754,23756,23757,
+23758,23759,23760,23761,23763,23764,23765,23766,23767,23768,23770,23771,23772,
+23773,23774,23775,23776,23778,23779,23783,23785,23787,23788,23790,23791,23793,
+23794,23795,23796,23797,23798,23799,23800,23801,23802,23804,23805,23806,23807,
+23808,23809,23812,23813,23816,23817,23818,23819,23820,23821,23823,23824,23825,
+23826,23827,23829,23831,23832,23833,23834,23836,23837,23839,23840,23841,23842,
+23843,23845,23848,23850,23851,23852,23855,23856,23857,23858,23859,23861,23862,
+23863,23864,23865,23866,23867,23868,23871,23872,23873,23874,23875,23876,23877,
+23878,23880,23881,23885,23886,23887,23888,23889,23890,23891,23892,23893,23894,
+23895,23897,23898,23900,23902,23903,23904,23905,23906,23907,23908,23909,23910,
+23911,23912,23914,23917,23918,23920,23921,23922,23923,23925,23926,23927,23928,
+23929,23930,23931,23932,23933,23934,23935,23936,23937,23939,23940,23941,23942,
+23943,23944,23945,23946,23947,23948,23949,23950,23951,23952,23953,23954,23955,
+23956,23957,23958,23959,23960,23962,23963,23964,23966,23967,23968,23969,23970,
+23971,23972,23973,23974,23975,23976,23977,23978,23979,23980,23981,23982,23983,
+23984,23985,23986,23987,23988,23989,23990,23992,23993,23994,23995,23996,23997,
+23998,23999,24000,24001,24002,24003,24004,24006,24007,24008,24009,24010,24011,
+24012,24014,24015,24016,24017,24018,24019,24020,24021,24022,24023,24024,24025,
+24026,24028,24031,24032,24035,24036,24042,24044,24045,24048,24053,24054,24056,
+24057,24058,24059,24060,24063,24064,24068,24071,24073,24074,24075,24077,24078,
+24082,24083,24087,24094,24095,24096,24097,24098,24099,
+24100,24101,24104,24105,24106,24107,24108,24111,24112,24114,24115,24116,24117,
+24118,24121,24122,24126,24127,24128,24129,24131,24134,24135,24136,24137,24138,
+24139,24141,24142,24143,24144,24145,24146,24147,24150,24151,24152,24153,24154,
+24156,24157,24159,24160,24163,24164,24165,24166,24167,24168,24169,24170,24171,
+24172,24173,24174,24175,24176,24177,24181,24183,24185,24190,24193,24194,24195,
+24197,24200,24201,24204,24205,24206,24210,24216,24219,24221,24225,24226,24227,
+24228,24232,24233,24234,24235,24236,24238,24239,24240,24241,24242,24244,24250,
+24251,24252,24253,24255,24256,24257,24258,24259,24260,24261,24262,24263,24264,
+24267,24268,24269,24270,24271,24272,24276,24277,24279,24280,24281,24282,24284,
+24285,24286,24287,24288,24289,24290,24291,24292,24293,24294,24295,24297,24299,
+24300,24301,24302,24303,24304,24305,24306,24307,24309,24312,24313,24315,24316,
+24317,24325,24326,24327,24329,24332,24333,24334,24336,24338,24340,24342,24345,
+24346,24348,24349,24350,24353,24354,24355,24356,24360,24363,24364,24366,24368,
+24370,24371,24372,24373,24374,24375,24376,24379,24381,24382,24383,24385,24386,
+24387,24388,24389,24390,24391,24392,24393,24394,24395,24396,24397,24398,24399,
+24401,24404,24409,24410,24411,24412,24414,24415,24416,24419,24421,24423,24424,
+24427,24430,24431,24434,24436,24437,24438,24440,24442,24445,24446,24447,24451,
+24454,24461,24462,24463,24465,24467,24468,24470,24474,24475,24477,24478,24479,
+24480,24482,24483,24484,24485,24486,24487,24489,24491,24492,24495,24496,24497,
+24498,24499,24500,24502,24504,24505,24506,24507,24510,
+24511,24512,24513,24514,24519,24520,24522,24523,24526,24531,24532,24533,24538,
+24539,24540,24542,24543,24546,24547,24549,24550,24552,24553,24556,24559,24560,
+24562,24563,24564,24566,24567,24569,24570,24572,24583,24584,24585,24587,24588,
+24592,24593,24595,24599,24600,24602,24606,24607,24610,24611,24612,24620,24621,
+24622,24624,24625,24626,24627,24628,24630,24631,24632,24633,24634,24637,24638,
+24640,24644,24645,24646,24647,24648,24649,24650,24652,24654,24655,24657,24659,
+24660,24662,24663,24664,24667,24668,24670,24671,24672,24673,24677,24678,24686,
+24689,24690,24692,24693,24695,24702,24704,24705,24706,24709,24710,24711,24712,
+24714,24715,24718,24719,24720,24721,24723,24725,24727,24728,24729,24732,24734,
+24737,24738,24740,24741,24743,24745,24746,24750,24752,24755,24757,24758,24759,
+24761,24762,24765,24766,24767,24768,24769,24770,24771,24772,24775,24776,24777,
+24780,24781,24782,24783,24784,24786,24787,24788,24790,24791,24793,24795,24798,
+24801,24802,24803,24804,24805,24810,24817,24818,24821,24823,24824,24827,24828,
+24829,24830,24831,24834,24835,24836,24837,24839,24842,24843,24844,24848,24849,
+24850,24851,24852,24854,24855,24856,24857,24859,24860,24861,24862,24865,24866,
+24869,24872,24873,24874,24876,24877,24878,24879,24880,24881,24882,24883,24884,
+24885,24886,24887,24888,24889,24890,24891,24892,24893,24894,24896,24897,24898,
+24899,24900,24901,24902,24903,24905,24907,24909,24911,24912,24914,24915,24916,
+24918,24919,24920,24921,24922,24923,24924,24926,24927,24928,24929,24931,24932,
+24933,24934,24937,24938,24939,24940,24941,24942,24943,
+24945,24946,24947,24948,24950,24952,24953,24954,24955,24956,24957,24958,24959,
+24960,24961,24962,24963,24964,24965,24966,24967,24968,24969,24970,24972,24973,
+24975,24976,24977,24978,24979,24981,24982,24983,24984,24985,24986,24987,24988,
+24990,24991,24992,24993,24994,24995,24996,24997,24998,25002,25003,25005,25006,
+25007,25008,25009,25010,25011,25012,25013,25014,25016,25017,25018,25019,25020,
+25021,25023,25024,25025,25027,25028,25029,25030,25031,25033,25036,25037,25038,
+25039,25040,25043,25045,25046,25047,25048,25049,25050,25051,25052,25053,25054,
+25055,25056,25057,25058,25059,25060,25061,25063,25064,25065,25066,25067,25068,
+25069,25070,25071,25072,25073,25074,25075,25076,25078,25079,25080,25081,25082,
+25083,25084,25085,25086,25088,25089,25090,25091,25092,25093,25095,25097,25107,
+25108,25113,25116,25117,25118,25120,25123,25126,25127,25128,25129,25131,25133,
+25135,25136,25137,25138,25141,25142,25144,25145,25146,25147,25148,25154,25156,
+25157,25158,25162,25167,25168,25173,25174,25175,25177,25178,25180,25181,25182,
+25183,25184,25185,25186,25188,25189,25192,25201,25202,25204,25205,25207,25208,
+25210,25211,25213,25217,25218,25219,25221,25222,25223,25224,25227,25228,25229,
+25230,25231,25232,25236,25241,25244,25245,25246,25251,25254,25255,25257,25258,
+25261,25262,25263,25264,25266,25267,25268,25270,25271,25272,25274,25278,25280,
+25281,25283,25291,25295,25297,25301,25309,25310,25312,25313,25316,25322,25323,
+25328,25330,25333,25336,25337,25338,25339,25344,25347,25348,25349,25350,25354,
+25355,25356,25357,25359,25360,25362,25363,25364,25365,
+25367,25368,25369,25372,25382,25383,25385,25388,25389,25390,25392,25393,25395,
+25396,25397,25398,25399,25400,25403,25404,25406,25407,25408,25409,25412,25415,
+25416,25418,25425,25426,25427,25428,25430,25431,25432,25433,25434,25435,25436,
+25437,25440,25444,25445,25446,25448,25450,25451,25452,25455,25456,25458,25459,
+25460,25461,25464,25465,25468,25469,25470,25471,25473,25475,25476,25477,25478,
+25483,25485,25489,25491,25492,25493,25495,25497,25498,25499,25500,25501,25502,
+25503,25505,25508,25510,25515,25519,25521,25522,25525,25526,25529,25531,25533,
+25535,25536,25537,25538,25539,25541,25543,25544,25546,25547,25548,25553,25555,
+25556,25557,25559,25560,25561,25562,25563,25564,25565,25567,25570,25572,25573,
+25574,25575,25576,25579,25580,25582,25583,25584,25585,25587,25589,25591,25593,
+25594,25595,25596,25598,25603,25604,25606,25607,25608,25609,25610,25613,25614,
+25617,25618,25621,25622,25623,25624,25625,25626,25629,25631,25634,25635,25636,
+25637,25639,25640,25641,25643,25646,25647,25648,25649,25650,25651,25653,25654,
+25655,25656,25657,25659,25660,25662,25664,25666,25667,25673,25675,25676,25677,
+25678,25679,25680,25681,25683,25685,25686,25687,25689,25690,25691,25692,25693,
+25695,25696,25697,25698,25699,25700,25701,25702,25704,25706,25707,25708,25710,
+25711,25712,25713,25714,25715,25716,25717,25718,25719,25723,25724,25725,25726,
+25727,25728,25729,25731,25734,25736,25737,25738,25739,25740,25741,25742,25743,
+25744,25747,25748,25751,25752,25754,25755,25756,25757,25759,25760,25761,25762,
+25763,25765,25766,25767,25768,25770,25771,25775,25777,
+25778,25779,25780,25782,25785,25787,25789,25790,25791,25793,25795,25796,25798,
+25799,25800,25801,25802,25803,25804,25807,25809,25811,25812,25813,25814,25817,
+25818,25819,25820,25821,25823,25824,25825,25827,25829,25831,25832,25833,25834,
+25835,25836,25837,25838,25839,25840,25841,25842,25843,25844,25845,25846,25847,
+25848,25849,25850,25851,25852,25853,25854,25855,25857,25858,25859,25860,25861,
+25862,25863,25864,25866,25867,25868,25869,25870,25871,25872,25873,25875,25876,
+25877,25878,25879,25881,25882,25883,25884,25885,25886,25887,25888,25889,25890,
+25891,25892,25894,25895,25896,25897,25898,25900,25901,25904,25905,25906,25907,
+25911,25914,25916,25917,25920,25921,25922,25923,25924,25926,25927,25930,25931,
+25933,25934,25936,25938,25939,25940,25943,25944,25946,25948,25951,25952,25953,
+25956,25957,25959,25960,25961,25962,25965,25966,25967,25969,25971,25973,25974,
+25976,25977,25978,25979,25980,25981,25982,25983,25984,25985,25986,25987,25988,
+25989,25990,25992,25993,25994,25997,25998,25999,26002,26004,26005,26006,26008,
+26010,26013,26014,26016,26018,26019,26022,26024,26026,26028,26030,26033,26034,
+26035,26036,26037,26038,26039,26040,26042,26043,26046,26047,26048,26050,26055,
+26056,26057,26058,26061,26064,26065,26067,26068,26069,26072,26073,26074,26075,
+26076,26077,26078,26079,26081,26083,26084,26090,26091,26098,26099,26100,26101,
+26104,26105,26107,26108,26109,26110,26111,26113,26116,26117,26119,26120,26121,
+26123,26125,26128,26129,26130,26134,26135,26136,26138,26139,26140,26142,26145,
+26146,26147,26148,26150,26153,26154,26155,26156,26158,
+26160,26162,26163,26167,26168,26169,26170,26171,26173,26175,26176,26178,26180,
+26181,26182,26183,26184,26185,26186,26189,26190,26192,26193,26200,26201,26203,
+26204,26205,26206,26208,26210,26211,26213,26215,26217,26218,26219,26220,26221,
+26225,26226,26227,26229,26232,26233,26235,26236,26237,26239,26240,26241,26243,
+26245,26246,26248,26249,26250,26251,26253,26254,26255,26256,26258,26259,26260,
+26261,26264,26265,26266,26267,26268,26270,26271,26272,26273,26274,26275,26276,
+26277,26278,26281,26282,26283,26284,26285,26287,26288,26289,26290,26291,26293,
+26294,26295,26296,26298,26299,26300,26301,26303,26304,26305,26306,26307,26308,
+26309,26310,26311,26312,26313,26314,26315,26316,26317,26318,26319,26320,26321,
+26322,26323,26324,26325,26326,26327,26328,26330,26334,26335,26336,26337,26338,
+26339,26340,26341,26343,26344,26346,26347,26348,26349,26350,26351,26353,26357,
+26358,26360,26362,26363,26365,26369,26370,26371,26372,26373,26374,26375,26380,
+26382,26383,26385,26386,26387,26390,26392,26393,26394,26396,26398,26400,26401,
+26402,26403,26404,26405,26407,26409,26414,26416,26418,26419,26422,26423,26424,
+26425,26427,26428,26430,26431,26433,26436,26437,26439,26442,26443,26445,26450,
+26452,26453,26455,26456,26457,26458,26459,26461,26466,26467,26468,26470,26471,
+26475,26476,26478,26481,26484,26486,26488,26489,26490,26491,26493,26496,26498,
+26499,26501,26502,26504,26506,26508,26509,26510,26511,26513,26514,26515,26516,
+26518,26521,26523,26527,26528,26529,26532,26534,26537,26540,26542,26545,26546,
+26548,26553,26554,26555,26556,26557,26558,26559,26560,
+26562,26565,26566,26567,26568,26569,26570,26571,26572,26573,26574,26581,26582,
+26583,26587,26591,26593,26595,26596,26598,26599,26600,26602,26603,26605,26606,
+26610,26613,26614,26615,26616,26617,26618,26619,26620,26622,26625,26626,26627,
+26628,26630,26637,26640,26642,26644,26645,26648,26649,26650,26651,26652,26654,
+26655,26656,26658,26659,26660,26661,26662,26663,26664,26667,26668,26669,26670,
+26671,26672,26673,26676,26677,26678,26682,26683,26687,26695,26699,26701,26703,
+26706,26710,26711,26712,26713,26714,26715,26716,26717,26718,26719,26730,26732,
+26733,26734,26735,26736,26737,26738,26739,26741,26744,26745,26746,26747,26748,
+26749,26750,26751,26752,26754,26756,26759,26760,26761,26762,26763,26764,26765,
+26766,26768,26769,26770,26772,26773,26774,26776,26777,26778,26779,26780,26781,
+26782,26783,26784,26785,26787,26788,26789,26793,26794,26795,26796,26798,26801,
+26802,26804,26806,26807,26808,26809,26810,26811,26812,26813,26814,26815,26817,
+26819,26820,26821,26822,26823,26824,26826,26828,26830,26831,26832,26833,26835,
+26836,26838,26839,26841,26843,26844,26845,26846,26847,26849,26850,26852,26853,
+26854,26855,26856,26857,26858,26859,26860,26861,26863,26866,26867,26868,26870,
+26871,26872,26875,26877,26878,26879,26880,26882,26883,26884,26886,26887,26888,
+26889,26890,26892,26895,26897,26899,26900,26901,26902,26903,26904,26905,26906,
+26907,26908,26909,26910,26913,26914,26915,26917,26918,26919,26920,26921,26922,
+26923,26924,26926,26927,26929,26930,26931,26933,26934,26935,26936,26938,26939,
+26940,26942,26944,26945,26947,26948,26949,26950,26951,
+26952,26953,26954,26955,26956,26957,26958,26959,26960,26961,26962,26963,26965,
+26966,26968,26969,26971,26972,26975,26977,26978,26980,26981,26983,26984,26985,
+26986,26988,26989,26991,26992,26994,26995,26996,26997,26998,27002,27003,27005,
+27006,27007,27009,27011,27013,27018,27019,27020,27022,27023,27024,27025,27026,
+27027,27030,27031,27033,27034,27037,27038,27039,27040,27041,27042,27043,27044,
+27045,27046,27049,27050,27052,27054,27055,27056,27058,27059,27061,27062,27064,
+27065,27066,27068,27069,27070,27071,27072,27074,27075,27076,27077,27078,27079,
+27080,27081,27083,27085,27087,27089,27090,27091,27093,27094,27095,27096,27097,
+27098,27100,27101,27102,27105,27106,27107,27108,27109,27110,27111,27112,27113,
+27114,27115,27116,27118,27119,27120,27121,27123,27124,27125,27126,27127,27128,
+27129,27130,27131,27132,27134,27136,27137,27138,27139,27140,27141,27142,27143,
+27144,27145,27147,27148,27149,27150,27151,27152,27153,27154,27155,27156,27157,
+27158,27161,27162,27163,27164,27165,27166,27168,27170,27171,27172,27173,27174,
+27175,27177,27179,27180,27181,27182,27184,27186,27187,27188,27190,27191,27192,
+27193,27194,27195,27196,27199,27200,27201,27202,27203,27205,27206,27208,27209,
+27210,27211,27212,27213,27214,27215,27217,27218,27219,27220,27221,27222,27223,
+27226,27228,27229,27230,27231,27232,27234,27235,27236,27238,27239,27240,27241,
+27242,27243,27244,27245,27246,27247,27248,27250,27251,27252,27253,27254,27255,
+27256,27258,27259,27261,27262,27263,27265,27266,27267,27269,27270,27271,27272,
+27273,27274,27275,27276,27277,27279,27282,27283,27284,
+27285,27286,27288,27289,27290,27291,27292,27293,27294,27295,27297,27298,27299,
+27300,27301,27302,27303,27304,27306,27309,27310,27311,27312,27313,27314,27315,
+27316,27317,27318,27319,27320,27321,27322,27323,27324,27325,27326,27327,27328,
+27329,27330,27331,27332,27333,27334,27335,27336,27337,27338,27339,27340,27341,
+27342,27343,27344,27345,27346,27347,27348,27349,27350,27351,27352,27353,27354,
+27355,27356,27357,27358,27359,27360,27361,27362,27363,27364,27365,27366,27367,
+27368,27369,27370,27371,27372,27373,27374,27375,27376,27377,27378,27379,27380,
+27381,27382,27383,27384,27385,27386,27387,27388,27389,27390,27391,27392,27393,
+27394,27395,27396,27397,27398,27399,27400,27401,27402,27403,27404,27405,27406,
+27407,27408,27409,27410,27411,27412,27413,27414,27415,27416,27417,27418,27419,
+27420,27421,27422,27423,27429,27430,27432,27433,27434,27435,27436,27437,27438,
+27439,27440,27441,27443,27444,27445,27446,27448,27451,27452,27453,27455,27456,
+27457,27458,27460,27461,27464,27466,27467,27469,27470,27471,27472,27473,27474,
+27475,27476,27477,27478,27479,27480,27482,27483,27484,27485,27486,27487,27488,
+27489,27496,27497,27499,27500,27501,27502,27503,27504,27505,27506,27507,27508,
+27509,27510,27511,27512,27514,27517,27518,27519,27520,27525,27528,27532,27534,
+27535,27536,27537,27540,27541,27543,27544,27545,27548,27549,27550,27551,27552,
+27554,27555,27556,27557,27558,27559,27560,27561,27563,27564,27565,27566,27567,
+27568,27569,27570,27574,27576,27577,27578,27579,27580,27581,27582,27584,27587,
+27588,27590,27591,27592,27593,27594,27596,27598,27600,
+27601,27608,27610,27612,27613,27614,27615,27616,27618,27619,27620,27621,27622,
+27623,27624,27625,27628,27629,27630,27632,27633,27634,27636,27638,27639,27640,
+27642,27643,27644,27646,27647,27648,27649,27650,27651,27652,27656,27657,27658,
+27659,27660,27662,27666,27671,27676,27677,27678,27680,27683,27685,27691,27692,
+27693,27697,27699,27702,27703,27705,27706,27707,27708,27710,27711,27715,27716,
+27717,27720,27723,27724,27725,27726,27727,27729,27730,27731,27734,27736,27737,
+27738,27746,27747,27749,27750,27751,27755,27756,27757,27758,27759,27761,27763,
+27765,27767,27768,27770,27771,27772,27775,27776,27780,27783,27786,27787,27789,
+27790,27793,27794,27797,27798,27799,27800,27802,27804,27805,27806,27808,27810,
+27816,27820,27823,27824,27828,27829,27830,27831,27834,27840,27841,27842,27843,
+27846,27847,27848,27851,27853,27854,27855,27857,27858,27864,27865,27866,27868,
+27869,27871,27876,27878,27879,27881,27884,27885,27890,27892,27897,27903,27904,
+27906,27907,27909,27910,27912,27913,27914,27917,27919,27920,27921,27923,27924,
+27925,27926,27928,27932,27933,27935,27936,27937,27938,27939,27940,27942,27944,
+27945,27948,27949,27951,27952,27956,27958,27959,27960,27962,27967,27968,27970,
+27972,27977,27980,27984,27989,27990,27991,27992,27995,27997,27999,28001,28002,
+28004,28005,28007,28008,28011,28012,28013,28016,28017,28018,28019,28021,28022,
+28025,28026,28027,28029,28030,28031,28032,28033,28035,28036,28038,28039,28042,
+28043,28045,28047,28048,28050,28054,28055,28056,28057,28058,28060,28066,28069,
+28076,28077,28080,28081,28083,28084,28086,28087,28089,
+28090,28091,28092,28093,28094,28097,28098,28099,28104,28105,28106,28109,28110,
+28111,28112,28114,28115,28116,28117,28119,28122,28123,28124,28127,28130,28131,
+28133,28135,28136,28137,28138,28141,28143,28144,28146,28148,28149,28150,28152,
+28154,28157,28158,28159,28160,28161,28162,28163,28164,28166,28167,28168,28169,
+28171,28175,28178,28179,28181,28184,28185,28187,28188,28190,28191,28194,28198,
+28199,28200,28202,28204,28206,28208,28209,28211,28213,28214,28215,28217,28219,
+28220,28221,28222,28223,28224,28225,28226,28229,28230,28231,28232,28233,28234,
+28235,28236,28239,28240,28241,28242,28245,28247,28249,28250,28252,28253,28254,
+28256,28257,28258,28259,28260,28261,28262,28263,28264,28265,28266,28268,28269,
+28271,28272,28273,28274,28275,28276,28277,28278,28279,28280,28281,28282,28283,
+28284,28285,28288,28289,28290,28292,28295,28296,28298,28299,28300,28301,28302,
+28305,28306,28307,28308,28309,28310,28311,28313,28314,28315,28317,28318,28320,
+28321,28323,28324,28326,28328,28329,28331,28332,28333,28334,28336,28339,28341,
+28344,28345,28348,28350,28351,28352,28355,28356,28357,28358,28360,28361,28362,
+28364,28365,28366,28368,28370,28374,28376,28377,28379,28380,28381,28387,28391,
+28394,28395,28396,28397,28398,28399,28400,28401,28402,28403,28405,28406,28407,
+28408,28410,28411,28412,28413,28414,28415,28416,28417,28419,28420,28421,28423,
+28424,28426,28427,28428,28429,28430,28432,28433,28434,28438,28439,28440,28441,
+28442,28443,28444,28445,28446,28447,28449,28450,28451,28453,28454,28455,28456,
+28460,28462,28464,28466,28468,28469,28471,28472,28473,
+28474,28475,28476,28477,28479,28480,28481,28482,28483,28484,28485,28488,28489,
+28490,28492,28494,28495,28496,28497,28498,28499,28500,28501,28502,28503,28505,
+28506,28507,28509,28511,28512,28513,28515,28516,28517,28519,28520,28521,28522,
+28523,28524,28527,28528,28529,28531,28533,28534,28535,28537,28539,28541,28542,
+28543,28544,28545,28546,28547,28549,28550,28551,28554,28555,28559,28560,28561,
+28562,28563,28564,28565,28566,28567,28568,28569,28570,28571,28573,28574,28575,
+28576,28578,28579,28580,28581,28582,28584,28585,28586,28587,28588,28589,28590,
+28591,28592,28593,28594,28596,28597,28599,28600,28602,28603,28604,28605,28606,
+28607,28609,28611,28612,28613,28614,28615,28616,28618,28619,28620,28621,28622,
+28623,28624,28627,28628,28629,28630,28631,28632,28633,28634,28635,28636,28637,
+28639,28642,28643,28644,28645,28646,28647,28648,28649,28650,28651,28652,28653,
+28656,28657,28658,28659,28660,28661,28662,28663,28664,28665,28666,28667,28668,
+28669,28670,28671,28672,28673,28674,28675,28676,28677,28678,28679,28680,28681,
+28682,28683,28684,28685,28686,28687,28688,28690,28691,28692,28693,28694,28695,
+28696,28697,28700,28701,28702,28703,28704,28705,28706,28708,28709,28710,28711,
+28712,28713,28714,28715,28716,28717,28718,28719,28720,28721,28722,28723,28724,
+28726,28727,28728,28730,28731,28732,28733,28734,28735,28736,28737,28738,28739,
+28740,28741,28742,28743,28744,28745,28746,28747,28749,28750,28752,28753,28754,
+28755,28756,28757,28758,28759,28760,28761,28762,28763,28764,28765,28767,28768,
+28769,28770,28771,28772,28773,28774,28775,28776,28777,
+28778,28782,28785,28786,28787,28788,28791,28793,28794,28795,28797,28801,28802,
+28803,28804,28806,28807,28808,28811,28812,28813,28815,28816,28817,28819,28823,
+28824,28826,28827,28830,28831,28832,28833,28834,28835,28836,28837,28838,28839,
+28840,28841,28842,28848,28850,28852,28853,28854,28858,28862,28863,28868,28869,
+28870,28871,28873,28875,28876,28877,28878,28879,28880,28881,28882,28883,28884,
+28885,28886,28887,28890,28892,28893,28894,28896,28897,28898,28899,28901,28906,
+28910,28912,28913,28914,28915,28916,28917,28918,28920,28922,28923,28924,28926,
+28927,28928,28929,28930,28931,28932,28933,28934,28935,28936,28939,28940,28941,
+28942,28943,28945,28946,28948,28951,28955,28956,28957,28958,28959,28960,28961,
+28962,28963,28964,28965,28967,28968,28969,28970,28971,28972,28973,28974,28978,
+28979,28980,28981,28983,28984,28985,28986,28987,28988,28989,28990,28991,28992,
+28993,28994,28995,28996,28998,28999,29000,29001,29003,29005,29007,29008,29009,
+29010,29011,29012,29013,29014,29015,29016,29017,29018,29019,29021,29023,29024,
+29025,29026,29027,29029,29033,29034,29035,29036,29037,29039,29040,29041,29044,
+29045,29046,29047,29049,29051,29052,29054,29055,29056,29057,29058,29059,29061,
+29062,29063,29064,29065,29067,29068,29069,29070,29072,29073,29074,29075,29077,
+29078,29079,29082,29083,29084,29085,29086,29089,29090,29091,29092,29093,29094,
+29095,29097,29098,29099,29101,29102,29103,29104,29105,29106,29108,29110,29111,
+29112,29114,29115,29116,29117,29118,29119,29120,29121,29122,29124,29125,29126,
+29127,29128,29129,29130,29131,29132,29133,29135,29136,
+29137,29138,29139,29142,29143,29144,29145,29146,29147,29148,29149,29150,29151,
+29153,29154,29155,29156,29158,29160,29161,29162,29163,29164,29165,29167,29168,
+29169,29170,29171,29172,29173,29174,29175,29176,29178,29179,29180,29181,29182,
+29183,29184,29185,29186,29187,29188,29189,29191,29192,29193,29194,29195,29196,
+29197,29198,29199,29200,29201,29202,29203,29204,29205,29206,29207,29208,29209,
+29210,29211,29212,29214,29215,29216,29217,29218,29219,29220,29221,29222,29223,
+29225,29227,29229,29230,29231,29234,29235,29236,29242,29244,29246,29248,29249,
+29250,29251,29252,29253,29254,29257,29258,29259,29262,29263,29264,29265,29267,
+29268,29269,29271,29272,29274,29276,29278,29280,29283,29284,29285,29288,29290,
+29291,29292,29293,29296,29297,29299,29300,29302,29303,29304,29307,29308,29309,
+29314,29315,29317,29318,29319,29320,29321,29324,29326,29328,29329,29331,29332,
+29333,29334,29335,29336,29337,29338,29339,29340,29341,29342,29344,29345,29346,
+29347,29348,29349,29350,29351,29352,29353,29354,29355,29358,29361,29362,29363,
+29365,29370,29371,29372,29373,29374,29375,29376,29381,29382,29383,29385,29386,
+29387,29388,29391,29393,29395,29396,29397,29398,29400,29402,29403,58566,58567,
+58568,58569,58570,58571,58572,58573,58574,58575,58576,58577,58578,58579,58580,
+58581,58582,58583,58584,58585,58586,58587,58588,58589,58590,58591,58592,58593,
+58594,58595,58596,58597,58598,58599,58600,58601,58602,58603,58604,58605,58606,
+58607,58608,58609,58610,58611,58612,58613,58614,58615,58616,58617,58618,58619,
+58620,58621,58622,58623,58624,58625,58626,58627,58628,
+58629,58630,58631,58632,58633,58634,58635,58636,58637,58638,58639,58640,58641,
+58642,58643,58644,58645,58646,58647,58648,58649,58650,58651,58652,58653,58654,
+58655,58656,58657,58658,58659,58660,58661,12288,12289,12290,183,713,711,168,
+12291,12293,8212,65374,8214,8230,8216,8217,8220,8221,12308,12309,12296,12297,
+12298,12299,12300,12301,12302,12303,12310,12311,12304,12305,177,215,247,8758,
+8743,8744,8721,8719,8746,8745,8712,8759,8730,8869,8741,8736,8978,8857,8747,
+8750,8801,8780,8776,8765,8733,8800,8814,8815,8804,8805,8734,8757,8756,9794,
+9792,176,8242,8243,8451,65284,164,65504,65505,8240,167,8470,9734,9733,9675,
+9679,9678,9671,9670,9633,9632,9651,9650,8251,8594,8592,8593,8595,12307,58662,
+58663,58664,58665,58666,58667,58668,58669,58670,58671,58672,58673,58674,58675,
+58676,58677,58678,58679,58680,58681,58682,58683,58684,58685,58686,58687,58688,
+58689,58690,58691,58692,58693,58694,58695,58696,58697,58698,58699,58700,58701,
+58702,58703,58704,58705,58706,58707,58708,58709,58710,58711,58712,58713,58714,
+58715,58716,58717,58718,58719,58720,58721,58722,58723,58724,58725,58726,58727,
+58728,58729,58730,58731,58732,58733,58734,58735,58736,58737,58738,58739,58740,
+58741,58742,58743,58744,58745,58746,58747,58748,58749,58750,58751,58752,58753,
+58754,58755,58756,58757,8560,8561,8562,8563,8564,8565,8566,8567,8568,8569,
+59238,59239,59240,59241,59242,59243,9352,9353,9354,9355,9356,9357,9358,9359,
+9360,9361,9362,9363,9364,9365,9366,9367,9368,
+9369,9370,9371,9332,9333,9334,9335,9336,9337,9338,9339,9340,9341,9342,9343,
+9344,9345,9346,9347,9348,9349,9350,9351,9312,9313,9314,9315,9316,9317,9318,
+9319,9320,9321,8364,59245,12832,12833,12834,12835,12836,12837,12838,12839,
+12840,12841,59246,59247,8544,8545,8546,8547,8548,8549,8550,8551,8552,8553,
+8554,8555,59248,59249,58758,58759,58760,58761,58762,58763,58764,58765,58766,
+58767,58768,58769,58770,58771,58772,58773,58774,58775,58776,58777,58778,58779,
+58780,58781,58782,58783,58784,58785,58786,58787,58788,58789,58790,58791,58792,
+58793,58794,58795,58796,58797,58798,58799,58800,58801,58802,58803,58804,58805,
+58806,58807,58808,58809,58810,58811,58812,58813,58814,58815,58816,58817,58818,
+58819,58820,58821,58822,58823,58824,58825,58826,58827,58828,58829,58830,58831,
+58832,58833,58834,58835,58836,58837,58838,58839,58840,58841,58842,58843,58844,
+58845,58846,58847,58848,58849,58850,58851,58852,58853,65281,65282,65283,65509,
+65285,65286,65287,65288,65289,65290,65291,65292,65293,65294,65295,65296,65297,
+65298,65299,65300,65301,65302,65303,65304,65305,65306,65307,65308,65309,65310,
+65311,65312,65313,65314,65315,65316,65317,65318,65319,65320,65321,65322,65323,
+65324,65325,65326,65327,65328,65329,65330,65331,65332,65333,65334,65335,65336,
+65337,65338,65339,65340,65341,65342,65343,65344,65345,65346,65347,65348,65349,
+65350,65351,65352,65353,65354,65355,65356,65357,65358,65359,65360,65361,65362,
+65363,65364,65365,65366,65367,65368,65369,65370,65371,65372,65373,65507,58854,
+58855,58856,58857,58858,
+58859,58860,58861,58862,58863,58864,58865,58866,58867,58868,58869,58870,58871,
+58872,58873,58874,58875,58876,58877,58878,58879,58880,58881,58882,58883,58884,
+58885,58886,58887,58888,58889,58890,58891,58892,58893,58894,58895,58896,58897,
+58898,58899,58900,58901,58902,58903,58904,58905,58906,58907,58908,58909,58910,
+58911,58912,58913,58914,58915,58916,58917,58918,58919,58920,58921,58922,58923,
+58924,58925,58926,58927,58928,58929,58930,58931,58932,58933,58934,58935,58936,
+58937,58938,58939,58940,58941,58942,58943,58944,58945,58946,58947,58948,58949,
+12353,12354,12355,12356,12357,12358,12359,12360,12361,12362,12363,12364,12365,
+12366,12367,12368,12369,12370,12371,12372,12373,12374,12375,12376,12377,12378,
+12379,12380,12381,12382,12383,12384,12385,12386,12387,12388,12389,12390,12391,
+12392,12393,12394,12395,12396,12397,12398,12399,12400,12401,12402,12403,12404,
+12405,12406,12407,12408,12409,12410,12411,12412,12413,12414,12415,12416,12417,
+12418,12419,12420,12421,12422,12423,12424,12425,12426,12427,12428,12429,12430,
+12431,12432,12433,12434,12435,59250,59251,59252,59253,59254,59255,59256,59257,
+59258,59259,59260,58950,58951,58952,58953,58954,58955,58956,58957,58958,58959,
+58960,58961,58962,58963,58964,58965,58966,58967,58968,58969,58970,58971,58972,
+58973,58974,58975,58976,58977,58978,58979,58980,58981,58982,58983,58984,58985,
+58986,58987,58988,58989,58990,58991,58992,58993,58994,58995,58996,58997,58998,
+58999,59000,59001,59002,59003,59004,59005,59006,59007,59008,59009,59010,59011,
+59012,59013,59014,59015,59016,59017,59018,59019,59020,
+59021,59022,59023,59024,59025,59026,59027,59028,59029,59030,59031,59032,59033,
+59034,59035,59036,59037,59038,59039,59040,59041,59042,59043,59044,59045,12449,
+12450,12451,12452,12453,12454,12455,12456,12457,12458,12459,12460,12461,12462,
+12463,12464,12465,12466,12467,12468,12469,12470,12471,12472,12473,12474,12475,
+12476,12477,12478,12479,12480,12481,12482,12483,12484,12485,12486,12487,12488,
+12489,12490,12491,12492,12493,12494,12495,12496,12497,12498,12499,12500,12501,
+12502,12503,12504,12505,12506,12507,12508,12509,12510,12511,12512,12513,12514,
+12515,12516,12517,12518,12519,12520,12521,12522,12523,12524,12525,12526,12527,
+12528,12529,12530,12531,12532,12533,12534,59261,59262,59263,59264,59265,59266,
+59267,59268,59046,59047,59048,59049,59050,59051,59052,59053,59054,59055,59056,
+59057,59058,59059,59060,59061,59062,59063,59064,59065,59066,59067,59068,59069,
+59070,59071,59072,59073,59074,59075,59076,59077,59078,59079,59080,59081,59082,
+59083,59084,59085,59086,59087,59088,59089,59090,59091,59092,59093,59094,59095,
+59096,59097,59098,59099,59100,59101,59102,59103,59104,59105,59106,59107,59108,
+59109,59110,59111,59112,59113,59114,59115,59116,59117,59118,59119,59120,59121,
+59122,59123,59124,59125,59126,59127,59128,59129,59130,59131,59132,59133,59134,
+59135,59136,59137,59138,59139,59140,59141,913,914,915,916,917,918,919,920,921,
+922,923,924,925,926,927,928,929,931,932,933,934,935,936,937,59269,59270,59271,
+59272,59273,59274,59275,59276,945,946,947,948,949,950,951,952,953,
+954,955,956,957,958,959,960,961,963,964,965,966,967,968,969,59277,59278,59279,
+59280,59281,59282,59283,65077,65078,65081,65082,65087,65088,65085,65086,65089,
+65090,65091,65092,59284,59285,65083,65084,65079,65080,65073,59286,65075,65076,
+59287,59288,59289,59290,59291,59292,59293,59294,59295,59142,59143,59144,59145,
+59146,59147,59148,59149,59150,59151,59152,59153,59154,59155,59156,59157,59158,
+59159,59160,59161,59162,59163,59164,59165,59166,59167,59168,59169,59170,59171,
+59172,59173,59174,59175,59176,59177,59178,59179,59180,59181,59182,59183,59184,
+59185,59186,59187,59188,59189,59190,59191,59192,59193,59194,59195,59196,59197,
+59198,59199,59200,59201,59202,59203,59204,59205,59206,59207,59208,59209,59210,
+59211,59212,59213,59214,59215,59216,59217,59218,59219,59220,59221,59222,59223,
+59224,59225,59226,59227,59228,59229,59230,59231,59232,59233,59234,59235,59236,
+59237,1040,1041,1042,1043,1044,1045,1025,1046,1047,1048,1049,1050,1051,1052,
+1053,1054,1055,1056,1057,1058,1059,1060,1061,1062,1063,1064,1065,1066,1067,
+1068,1069,1070,1071,59296,59297,59298,59299,59300,59301,59302,59303,59304,
+59305,59306,59307,59308,59309,59310,1072,1073,1074,1075,1076,1077,1105,1078,
+1079,1080,1081,1082,1083,1084,1085,1086,1087,1088,1089,1090,1091,1092,1093,
+1094,1095,1096,1097,1098,1099,1100,1101,1102,1103,59311,59312,59313,59314,
+59315,59316,59317,59318,59319,59320,59321,59322,59323,714,715,729,8211,8213,
+8229,8245,8453,8457,8598,8599,8600,8601,
+8725,8735,8739,8786,8806,8807,8895,9552,9553,9554,9555,9556,9557,9558,9559,
+9560,9561,9562,9563,9564,9565,9566,9567,9568,9569,9570,9571,9572,9573,9574,
+9575,9576,9577,9578,9579,9580,9581,9582,9583,9584,9585,9586,9587,9601,9602,
+9603,9604,9605,9606,9607,9608,9609,9610,9611,9612,9613,9614,9615,9619,9620,
+9621,9660,9661,9698,9699,9700,9701,9737,8853,12306,12317,12318,59324,59325,
+59326,59327,59328,59329,59330,59331,59332,59333,59334,257,225,462,224,275,233,
+283,232,299,237,464,236,333,243,466,242,363,250,468,249,470,472,474,476,252,
+234,593,59335,324,328,505,609,59337,59338,59339,59340,12549,12550,12551,12552,
+12553,12554,12555,12556,12557,12558,12559,12560,12561,12562,12563,12564,12565,
+12566,12567,12568,12569,12570,12571,12572,12573,12574,12575,12576,12577,12578,
+12579,12580,12581,12582,12583,12584,12585,59341,59342,59343,59344,59345,59346,
+59347,59348,59349,59350,59351,59352,59353,59354,59355,59356,59357,59358,59359,
+59360,59361,12321,12322,12323,12324,12325,12326,12327,12328,12329,12963,13198,
+13199,13212,13213,13214,13217,13252,13262,13265,13266,13269,65072,65506,65508,
+59362,8481,12849,59363,8208,59364,59365,59366,12540,12443,12444,12541,12542,
+12294,12445,12446,65097,65098,65099,65100,65101,65102,65103,65104,65105,65106,
+65108,65109,65110,65111,65113,65114,65115,65116,65117,65118,65119,65120,65121,
+65122,65123,65124,65125,65126,65128,65129,65130,65131,12350,12272,12273,12274,
+12275,12276,12277,
+12278,12279,12280,12281,12282,12283,12295,59380,59381,59382,59383,59384,59385,
+59386,59387,59388,59389,59390,59391,59392,9472,9473,9474,9475,9476,9477,9478,
+9479,9480,9481,9482,9483,9484,9485,9486,9487,9488,9489,9490,9491,9492,9493,
+9494,9495,9496,9497,9498,9499,9500,9501,9502,9503,9504,9505,9506,9507,9508,
+9509,9510,9511,9512,9513,9514,9515,9516,9517,9518,9519,9520,9521,9522,9523,
+9524,9525,9526,9527,9528,9529,9530,9531,9532,9533,9534,9535,9536,9537,9538,
+9539,9540,9541,9542,9543,9544,9545,9546,9547,59393,59394,59395,59396,59397,
+59398,59399,59400,59401,59402,59403,59404,59405,59406,59407,29404,29405,29407,
+29410,29411,29412,29413,29414,29415,29418,29419,29429,29430,29433,29437,29438,
+29439,29440,29442,29444,29445,29446,29447,29448,29449,29451,29452,29453,29455,
+29456,29457,29458,29460,29464,29465,29466,29471,29472,29475,29476,29478,29479,
+29480,29485,29487,29488,29490,29491,29493,29494,29498,29499,29500,29501,29504,
+29505,29506,29507,29508,29509,29510,29511,29512,29513,29514,29515,29516,29518,
+29519,29521,29523,29524,29525,29526,29528,29529,29530,29531,29532,29533,29534,
+29535,29537,29538,29539,29540,29541,29542,29543,29544,29545,29546,29547,29550,
+29552,29553,57344,57345,57346,57347,57348,57349,57350,57351,57352,57353,57354,
+57355,57356,57357,57358,57359,57360,57361,57362,57363,57364,57365,57366,57367,
+57368,57369,57370,57371,57372,57373,57374,57375,57376,57377,57378,57379,57380,
+57381,57382,57383,57384,57385,57386,57387,57388,57389,57390,57391,57392,
+57393,57394,57395,57396,57397,57398,57399,57400,57401,57402,57403,57404,57405,
+57406,57407,57408,57409,57410,57411,57412,57413,57414,57415,57416,57417,57418,
+57419,57420,57421,57422,57423,57424,57425,57426,57427,57428,57429,57430,57431,
+57432,57433,57434,57435,57436,57437,29554,29555,29556,29557,29558,29559,29560,
+29561,29562,29563,29564,29565,29567,29568,29569,29570,29571,29573,29574,29576,
+29578,29580,29581,29583,29584,29586,29587,29588,29589,29591,29592,29593,29594,
+29596,29597,29598,29600,29601,29603,29604,29605,29606,29607,29608,29610,29612,
+29613,29617,29620,29621,29622,29624,29625,29628,29629,29630,29631,29633,29635,
+29636,29637,29638,29639,29643,29644,29646,29650,29651,29652,29653,29654,29655,
+29656,29658,29659,29660,29661,29663,29665,29666,29667,29668,29670,29672,29674,
+29675,29676,29678,29679,29680,29681,29683,29684,29685,29686,29687,57438,57439,
+57440,57441,57442,57443,57444,57445,57446,57447,57448,57449,57450,57451,57452,
+57453,57454,57455,57456,57457,57458,57459,57460,57461,57462,57463,57464,57465,
+57466,57467,57468,57469,57470,57471,57472,57473,57474,57475,57476,57477,57478,
+57479,57480,57481,57482,57483,57484,57485,57486,57487,57488,57489,57490,57491,
+57492,57493,57494,57495,57496,57497,57498,57499,57500,57501,57502,57503,57504,
+57505,57506,57507,57508,57509,57510,57511,57512,57513,57514,57515,57516,57517,
+57518,57519,57520,57521,57522,57523,57524,57525,57526,57527,57528,57529,57530,
+57531,29688,29689,29690,29691,29692,29693,29694,29695,29696,29697,29698,29700,
+29703,29704,29707,29708,29709,29710,29713,29714,29715,
+29716,29717,29718,29719,29720,29721,29724,29725,29726,29727,29728,29729,29731,
+29732,29735,29737,29739,29741,29743,29745,29746,29751,29752,29753,29754,29755,
+29757,29758,29759,29760,29762,29763,29764,29765,29766,29767,29768,29769,29770,
+29771,29772,29773,29774,29775,29776,29777,29778,29779,29780,29782,29784,29789,
+29792,29793,29794,29795,29796,29797,29798,29799,29800,29801,29802,29803,29804,
+29806,29807,29809,29810,29811,29812,29813,29816,29817,29818,57532,57533,57534,
+57535,57536,57537,57538,57539,57540,57541,57542,57543,57544,57545,57546,57547,
+57548,57549,57550,57551,57552,57553,57554,57555,57556,57557,57558,57559,57560,
+57561,57562,57563,57564,57565,57566,57567,57568,57569,57570,57571,57572,57573,
+57574,57575,57576,57577,57578,57579,57580,57581,57582,57583,57584,57585,57586,
+57587,57588,57589,57590,57591,57592,57593,57594,57595,57596,57597,57598,57599,
+57600,57601,57602,57603,57604,57605,57606,57607,57608,57609,57610,57611,57612,
+57613,57614,57615,57616,57617,57618,57619,57620,57621,57622,57623,57624,57625,
+29819,29820,29821,29823,29826,29828,29829,29830,29832,29833,29834,29836,29837,
+29839,29841,29842,29843,29844,29845,29846,29847,29848,29849,29850,29851,29853,
+29855,29856,29857,29858,29859,29860,29861,29862,29866,29867,29868,29869,29870,
+29871,29872,29873,29874,29875,29876,29877,29878,29879,29880,29881,29883,29884,
+29885,29886,29887,29888,29889,29890,29891,29892,29893,29894,29895,29896,29897,
+29898,29899,29900,29901,29902,29903,29904,29905,29907,29908,29909,29910,29911,
+29912,29913,29914,29915,29917,29919,29921,29925,29927,
+29928,29929,29930,29931,29932,29933,29936,29937,29938,57626,57627,57628,57629,
+57630,57631,57632,57633,57634,57635,57636,57637,57638,57639,57640,57641,57642,
+57643,57644,57645,57646,57647,57648,57649,57650,57651,57652,57653,57654,57655,
+57656,57657,57658,57659,57660,57661,57662,57663,57664,57665,57666,57667,57668,
+57669,57670,57671,57672,57673,57674,57675,57676,57677,57678,57679,57680,57681,
+57682,57683,57684,57685,57686,57687,57688,57689,57690,57691,57692,57693,57694,
+57695,57696,57697,57698,57699,57700,57701,57702,57703,57704,57705,57706,57707,
+57708,57709,57710,57711,57712,57713,57714,57715,57716,57717,57718,57719,29939,
+29941,29944,29945,29946,29947,29948,29949,29950,29952,29953,29954,29955,29957,
+29958,29959,29960,29961,29962,29963,29964,29966,29968,29970,29972,29973,29974,
+29975,29979,29981,29982,29984,29985,29986,29987,29988,29990,29991,29994,29998,
+30004,30006,30009,30012,30013,30015,30017,30018,30019,30020,30022,30023,30025,
+30026,30029,30032,30033,30034,30035,30037,30038,30039,30040,30045,30046,30047,
+30048,30049,30050,30051,30052,30055,30056,30057,30059,30060,30061,30062,30063,
+30064,30065,30067,30069,30070,30071,30074,30075,30076,30077,30078,30080,30081,
+30082,30084,30085,30087,57720,57721,57722,57723,57724,57725,57726,57727,57728,
+57729,57730,57731,57732,57733,57734,57735,57736,57737,57738,57739,57740,57741,
+57742,57743,57744,57745,57746,57747,57748,57749,57750,57751,57752,57753,57754,
+57755,57756,57757,57758,57759,57760,57761,57762,57763,57764,57765,57766,57767,
+57768,57769,57770,57771,57772,57773,57774,57775,57776,
+57777,57778,57779,57780,57781,57782,57783,57784,57785,57786,57787,57788,57789,
+57790,57791,57792,57793,57794,57795,57796,57797,57798,57799,57800,57801,57802,
+57803,57804,57805,57806,57807,57808,57809,57810,57811,57812,57813,30088,30089,
+30090,30092,30093,30094,30096,30099,30101,30104,30107,30108,30110,30114,30118,
+30119,30120,30121,30122,30125,30134,30135,30138,30139,30143,30144,30145,30150,
+30155,30156,30158,30159,30160,30161,30163,30167,30169,30170,30172,30173,30175,
+30176,30177,30181,30185,30188,30189,30190,30191,30194,30195,30197,30198,30199,
+30200,30202,30203,30205,30206,30210,30212,30214,30215,30216,30217,30219,30221,
+30222,30223,30225,30226,30227,30228,30230,30234,30236,30237,30238,30241,30243,
+30247,30248,30252,30254,30255,30257,30258,30262,30263,30265,30266,30267,30269,
+30273,30274,30276,57814,57815,57816,57817,57818,57819,57820,57821,57822,57823,
+57824,57825,57826,57827,57828,57829,57830,57831,57832,57833,57834,57835,57836,
+57837,57838,57839,57840,57841,57842,57843,57844,57845,57846,57847,57848,57849,
+57850,57851,57852,57853,57854,57855,57856,57857,57858,57859,57860,57861,57862,
+57863,57864,57865,57866,57867,57868,57869,57870,57871,57872,57873,57874,57875,
+57876,57877,57878,57879,57880,57881,57882,57883,57884,57885,57886,57887,57888,
+57889,57890,57891,57892,57893,57894,57895,57896,57897,57898,57899,57900,57901,
+57902,57903,57904,57905,57906,57907,30277,30278,30279,30280,30281,30282,30283,
+30286,30287,30288,30289,30290,30291,30293,30295,30296,30297,30298,30299,30301,
+30303,30304,30305,30306,30308,30309,30310,30311,30312,
+30313,30314,30316,30317,30318,30320,30321,30322,30323,30324,30325,30326,30327,
+30329,30330,30332,30335,30336,30337,30339,30341,30345,30346,30348,30349,30351,
+30352,30354,30356,30357,30359,30360,30362,30363,30364,30365,30366,30367,30368,
+30369,30370,30371,30373,30374,30375,30376,30377,30378,30379,30380,30381,30383,
+30384,30387,30389,30390,30391,30392,30393,30394,30395,30396,30397,30398,30400,
+30401,30403,21834,38463,22467,25384,21710,21769,21696,30353,30284,34108,30702,
+33406,30861,29233,38552,38797,27688,23433,20474,25353,26263,23736,33018,26696,
+32942,26114,30414,20985,25942,29100,32753,34948,20658,22885,25034,28595,33453,
+25420,25170,21485,21543,31494,20843,30116,24052,25300,36299,38774,25226,32793,
+22365,38712,32610,29240,30333,26575,30334,25670,20336,36133,25308,31255,26001,
+29677,25644,25203,33324,39041,26495,29256,25198,25292,20276,29923,21322,21150,
+32458,37030,24110,26758,27036,33152,32465,26834,30917,34444,38225,20621,35876,
+33502,32990,21253,35090,21093,30404,30407,30409,30411,30412,30419,30421,30425,
+30426,30428,30429,30430,30432,30433,30434,30435,30436,30438,30439,30440,30441,
+30442,30443,30444,30445,30448,30451,30453,30454,30455,30458,30459,30461,30463,
+30464,30466,30467,30469,30470,30474,30476,30478,30479,30480,30481,30482,30483,
+30484,30485,30486,30487,30488,30491,30492,30493,30494,30497,30499,30500,30501,
+30503,30506,30507,30508,30510,30512,30513,30514,30515,30516,30521,30523,30525,
+30526,30527,30530,30532,30533,30534,30536,30537,30538,30539,30540,30541,30542,
+30543,30546,30547,30548,30549,30550,30551,30552,30553,
+30556,34180,38649,20445,22561,39281,23453,25265,25253,26292,35961,40077,29190,
+26479,30865,24754,21329,21271,36744,32972,36125,38049,20493,29384,22791,24811,
+28953,34987,22868,33519,26412,31528,23849,32503,29997,27893,36454,36856,36924,
+40763,27604,37145,31508,24444,30887,34006,34109,27605,27609,27606,24065,24199,
+30201,38381,25949,24330,24517,36767,22721,33218,36991,38491,38829,36793,32534,
+36140,25153,20415,21464,21342,36776,36777,36779,36941,26631,24426,33176,34920,
+40150,24971,21035,30250,24428,25996,28626,28392,23486,25672,20853,20912,26564,
+19993,31177,39292,28851,30557,30558,30559,30560,30564,30567,30569,30570,30573,
+30574,30575,30576,30577,30578,30579,30580,30581,30582,30583,30584,30586,30587,
+30588,30593,30594,30595,30598,30599,30600,30601,30602,30603,30607,30608,30611,
+30612,30613,30614,30615,30616,30617,30618,30619,30620,30621,30622,30625,30627,
+30628,30630,30632,30635,30637,30638,30639,30641,30642,30644,30646,30647,30648,
+30649,30650,30652,30654,30656,30657,30658,30659,30660,30661,30662,30663,30664,
+30665,30666,30667,30668,30670,30671,30672,30673,30674,30675,30676,30677,30678,
+30680,30681,30682,30685,30686,30687,30688,30689,30692,30149,24182,29627,33760,
+25773,25320,38069,27874,21338,21187,25615,38082,31636,20271,24091,33334,33046,
+33162,28196,27850,39539,25429,21340,21754,34917,22496,19981,24067,27493,31807,
+37096,24598,25830,29468,35009,26448,25165,36130,30572,36393,37319,24425,33756,
+34081,39184,21442,34453,27531,24813,24808,28799,33485,33329,20179,27815,34255,
+25805,31961,27133,26361,33609,21397,31574,20391,20876,
+27979,23618,36461,25554,21449,33580,33590,26597,30900,25661,23519,23700,24046,
+35815,25286,26612,35962,25600,25530,34633,39307,35863,32544,38130,20135,38416,
+39076,26124,29462,30694,30696,30698,30703,30704,30705,30706,30708,30709,30711,
+30713,30714,30715,30716,30723,30724,30725,30726,30727,30728,30730,30731,30734,
+30735,30736,30739,30741,30745,30747,30750,30752,30753,30754,30756,30760,30762,
+30763,30766,30767,30769,30770,30771,30773,30774,30781,30783,30785,30786,30787,
+30788,30790,30792,30793,30794,30795,30797,30799,30801,30803,30804,30808,30809,
+30810,30811,30812,30814,30815,30816,30817,30818,30819,30820,30821,30822,30823,
+30824,30825,30831,30832,30833,30834,30835,30836,30837,30838,30840,30841,30842,
+30843,30845,30846,30847,30848,30849,30850,30851,22330,23581,24120,38271,20607,
+32928,21378,25950,30021,21809,20513,36229,25220,38046,26397,22066,28526,24034,
+21557,28818,36710,25199,25764,25507,24443,28552,37108,33251,36784,23576,26216,
+24561,27785,38472,36225,34924,25745,31216,22478,27225,25104,21576,20056,31243,
+24809,28548,35802,25215,36894,39563,31204,21507,30196,25345,21273,27744,36831,
+24347,39536,32827,40831,20360,23610,36196,32709,26021,28861,20805,20914,34411,
+23815,23456,25277,37228,30068,36364,31264,24833,31609,20167,32504,30597,19985,
+33261,21021,20986,27249,21416,36487,38148,38607,28353,38500,26970,30852,30853,
+30854,30856,30858,30859,30863,30864,30866,30868,30869,30870,30873,30877,30878,
+30880,30882,30884,30886,30888,30889,30890,30891,30892,30893,30894,30895,30901,
+30902,30903,30904,30906,30907,30908,30909,30911,30912,
+30914,30915,30916,30918,30919,30920,30924,30925,30926,30927,30929,30930,30931,
+30934,30935,30936,30938,30939,30940,30941,30942,30943,30944,30945,30946,30947,
+30948,30949,30950,30951,30953,30954,30955,30957,30958,30959,30960,30961,30963,
+30965,30966,30968,30969,30971,30972,30973,30974,30975,30976,30978,30979,30980,
+30982,30983,30984,30985,30986,30987,30988,30784,20648,30679,25616,35302,22788,
+25571,24029,31359,26941,20256,33337,21912,20018,30126,31383,24162,24202,38383,
+21019,21561,28810,25462,38180,22402,26149,26943,37255,21767,28147,32431,34850,
+25139,32496,30133,33576,30913,38604,36766,24904,29943,35789,27492,21050,36176,
+27425,32874,33905,22257,21254,20174,19995,20945,31895,37259,31751,20419,36479,
+31713,31388,25703,23828,20652,33030,30209,31929,28140,32736,26449,23384,23544,
+30923,25774,25619,25514,25387,38169,25645,36798,31572,30249,25171,22823,21574,
+27513,20643,25140,24102,27526,20195,36151,34955,24453,36910,30989,30990,30991,
+30992,30993,30994,30996,30997,30998,30999,31000,31001,31002,31003,31004,31005,
+31007,31008,31009,31010,31011,31013,31014,31015,31016,31017,31018,31019,31020,
+31021,31022,31023,31024,31025,31026,31027,31029,31030,31031,31032,31033,31037,
+31039,31042,31043,31044,31045,31047,31050,31051,31052,31053,31054,31055,31056,
+31057,31058,31060,31061,31064,31065,31073,31075,31076,31078,31081,31082,31083,
+31084,31086,31088,31089,31090,31091,31092,31093,31094,31097,31099,31100,31101,
+31102,31103,31106,31107,31110,31111,31112,31113,31115,31116,31117,31118,31120,
+31121,31122,24608,32829,25285,20025,21333,37112,25528,
+32966,26086,27694,20294,24814,28129,35806,24377,34507,24403,25377,20826,33633,
+26723,20992,25443,36424,20498,23707,31095,23548,21040,31291,24764,36947,30423,
+24503,24471,30340,36460,28783,30331,31561,30634,20979,37011,22564,20302,28404,
+36842,25932,31515,29380,28068,32735,23265,25269,24213,22320,33922,31532,24093,
+24351,36882,32532,39072,25474,28359,30872,28857,20856,38747,22443,30005,20291,
+30008,24215,24806,22880,28096,27583,30857,21500,38613,20939,20993,25481,21514,
+38035,35843,36300,29241,30879,34678,36845,35853,21472,31123,31124,31125,31126,
+31127,31128,31129,31131,31132,31133,31134,31135,31136,31137,31138,31139,31140,
+31141,31142,31144,31145,31146,31147,31148,31149,31150,31151,31152,31153,31154,
+31156,31157,31158,31159,31160,31164,31167,31170,31172,31173,31175,31176,31178,
+31180,31182,31183,31184,31187,31188,31190,31191,31193,31194,31195,31196,31197,
+31198,31200,31201,31202,31205,31208,31210,31212,31214,31217,31218,31219,31220,
+31221,31222,31223,31225,31226,31228,31230,31231,31233,31236,31237,31239,31240,
+31241,31242,31244,31247,31248,31249,31250,31251,31253,31254,31256,31257,31259,
+31260,19969,30447,21486,38025,39030,40718,38189,23450,35746,20002,19996,20908,
+33891,25026,21160,26635,20375,24683,20923,27934,20828,25238,26007,38497,35910,
+36887,30168,37117,30563,27602,29322,29420,35835,22581,30585,36172,26460,38208,
+32922,24230,28193,22930,31471,30701,38203,27573,26029,32526,22534,20817,38431,
+23545,22697,21544,36466,25958,39039,22244,38045,30462,36929,25479,21702,22810,
+22842,22427,36530,26421,36346,33333,21057,24816,22549,
+34558,23784,40517,20420,39069,35769,23077,24694,21380,25212,36943,37122,39295,
+24681,32780,20799,32819,23572,39285,27953,20108,31261,31263,31265,31266,31268,
+31269,31270,31271,31272,31273,31274,31275,31276,31277,31278,31279,31280,31281,
+31282,31284,31285,31286,31288,31290,31294,31296,31297,31298,31299,31300,31301,
+31303,31304,31305,31306,31307,31308,31309,31310,31311,31312,31314,31315,31316,
+31317,31318,31320,31321,31322,31323,31324,31325,31326,31327,31328,31329,31330,
+31331,31332,31333,31334,31335,31336,31337,31338,31339,31340,31341,31342,31343,
+31345,31346,31347,31349,31355,31356,31357,31358,31362,31365,31367,31369,31370,
+31371,31372,31374,31375,31376,31379,31380,31385,31386,31387,31390,31393,31394,
+36144,21457,32602,31567,20240,20047,38400,27861,29648,34281,24070,30058,32763,
+27146,30718,38034,32321,20961,28902,21453,36820,33539,36137,29359,39277,27867,
+22346,33459,26041,32938,25151,38450,22952,20223,35775,32442,25918,33778,38750,
+21857,39134,32933,21290,35837,21536,32954,24223,27832,36153,33452,37210,21545,
+27675,20998,32439,22367,28954,27774,31881,22859,20221,24575,24868,31914,20016,
+23553,26539,34562,23792,38155,39118,30127,28925,36898,20911,32541,35773,22857,
+20964,20315,21542,22827,25975,32932,23413,25206,25282,36752,24133,27679,31526,
+20239,20440,26381,31395,31396,31399,31401,31402,31403,31406,31407,31408,31409,
+31410,31412,31413,31414,31415,31416,31417,31418,31419,31420,31421,31422,31424,
+31425,31426,31427,31428,31429,31430,31431,31432,31433,31434,31436,31437,31438,
+31439,31440,31441,31442,31443,31444,31445,31447,31448,
+31450,31451,31452,31453,31457,31458,31460,31463,31464,31465,31466,31467,31468,
+31470,31472,31473,31474,31475,31476,31477,31478,31479,31480,31483,31484,31486,
+31488,31489,31490,31493,31495,31497,31500,31501,31502,31504,31506,31507,31510,
+31511,31512,31514,31516,31517,31519,31521,31522,31523,31527,31529,31533,28014,
+28074,31119,34993,24343,29995,25242,36741,20463,37340,26023,33071,33105,24220,
+33104,36212,21103,35206,36171,22797,20613,20184,38428,29238,33145,36127,23500,
+35747,38468,22919,32538,21648,22134,22030,35813,25913,27010,38041,30422,28297,
+24178,29976,26438,26577,31487,32925,36214,24863,31174,25954,36195,20872,21018,
+38050,32568,32923,32434,23703,28207,26464,31705,30347,39640,33167,32660,31957,
+25630,38224,31295,21578,21733,27468,25601,25096,40509,33011,30105,21106,38761,
+33883,26684,34532,38401,38548,38124,20010,21508,32473,26681,36319,32789,26356,
+24218,32697,31535,31536,31538,31540,31541,31542,31543,31545,31547,31549,31551,
+31552,31553,31554,31555,31556,31558,31560,31562,31565,31566,31571,31573,31575,
+31577,31580,31582,31583,31585,31587,31588,31589,31590,31591,31592,31593,31594,
+31595,31596,31597,31599,31600,31603,31604,31606,31608,31610,31612,31613,31615,
+31617,31618,31619,31620,31622,31623,31624,31625,31626,31627,31628,31630,31631,
+31633,31634,31635,31638,31640,31641,31642,31643,31646,31647,31648,31651,31652,
+31653,31662,31663,31664,31666,31667,31669,31670,31671,31673,31674,31675,31676,
+31677,31678,31679,31680,31682,31683,31684,22466,32831,26775,24037,25915,21151,
+24685,40858,20379,36524,20844,23467,24339,24041,27742,
+25329,36129,20849,38057,21246,27807,33503,29399,22434,26500,36141,22815,36764,
+33735,21653,31629,20272,27837,23396,22993,40723,21476,34506,39592,35895,32929,
+25925,39038,22266,38599,21038,29916,21072,23521,25346,35074,20054,25296,24618,
+26874,20851,23448,20896,35266,31649,39302,32592,24815,28748,36143,20809,24191,
+36891,29808,35268,22317,30789,24402,40863,38394,36712,39740,35809,30328,26690,
+26588,36330,36149,21053,36746,28378,26829,38149,37101,22269,26524,35065,36807,
+21704,31685,31688,31689,31690,31691,31693,31694,31695,31696,31698,31700,31701,
+31702,31703,31704,31707,31708,31710,31711,31712,31714,31715,31716,31719,31720,
+31721,31723,31724,31725,31727,31728,31730,31731,31732,31733,31734,31736,31737,
+31738,31739,31741,31743,31744,31745,31746,31747,31748,31749,31750,31752,31753,
+31754,31757,31758,31760,31761,31762,31763,31764,31765,31767,31768,31769,31770,
+31771,31772,31773,31774,31776,31777,31778,31779,31780,31781,31784,31785,31787,
+31788,31789,31790,31791,31792,31793,31794,31795,31796,31797,31798,31799,31801,
+31802,31803,31804,31805,31806,31810,39608,23401,28023,27686,20133,23475,39559,
+37219,25000,37039,38889,21547,28085,23506,20989,21898,32597,32752,25788,25421,
+26097,25022,24717,28938,27735,27721,22831,26477,33322,22741,22158,35946,27627,
+37085,22909,32791,21495,28009,21621,21917,33655,33743,26680,31166,21644,20309,
+21512,30418,35977,38402,27827,28088,36203,35088,40548,36154,22079,40657,30165,
+24456,29408,24680,21756,20136,27178,34913,24658,36720,21700,28888,34425,40511,
+27946,23439,24344,32418,21897,20399,29492,21564,21402,
+20505,21518,21628,20046,24573,29786,22774,33899,32993,34676,29392,31946,28246,
+31811,31812,31813,31814,31815,31816,31817,31818,31819,31820,31822,31823,31824,
+31825,31826,31827,31828,31829,31830,31831,31832,31833,31834,31835,31836,31837,
+31838,31839,31840,31841,31842,31843,31844,31845,31846,31847,31848,31849,31850,
+31851,31852,31853,31854,31855,31856,31857,31858,31861,31862,31863,31864,31865,
+31866,31870,31871,31872,31873,31874,31875,31876,31877,31878,31879,31880,31882,
+31883,31884,31885,31886,31887,31888,31891,31892,31894,31897,31898,31899,31904,
+31905,31907,31910,31911,31912,31913,31915,31916,31917,31919,31920,31924,31925,
+31926,31927,31928,31930,31931,24359,34382,21804,25252,20114,27818,25143,33457,
+21719,21326,29502,28369,30011,21010,21270,35805,27088,24458,24576,28142,22351,
+27426,29615,26707,36824,32531,25442,24739,21796,30186,35938,28949,28067,23462,
+24187,33618,24908,40644,30970,34647,31783,30343,20976,24822,29004,26179,24140,
+24653,35854,28784,25381,36745,24509,24674,34516,22238,27585,24724,24935,21321,
+24800,26214,36159,31229,20250,28905,27719,35763,35826,32472,33636,26127,23130,
+39746,27985,28151,35905,27963,20249,28779,33719,25110,24785,38669,36135,31096,
+20987,22334,22522,26426,30072,31293,31215,31637,31935,31936,31938,31939,31940,
+31942,31945,31947,31950,31951,31952,31953,31954,31955,31956,31960,31962,31963,
+31965,31966,31969,31970,31971,31972,31973,31974,31975,31977,31978,31979,31980,
+31981,31982,31984,31985,31986,31987,31988,31989,31990,31991,31993,31994,31996,
+31997,31998,31999,32000,32001,32002,32003,32004,32005,
+32006,32007,32008,32009,32011,32012,32013,32014,32015,32016,32017,32018,32019,
+32020,32021,32022,32023,32024,32025,32026,32027,32028,32029,32030,32031,32033,
+32035,32036,32037,32038,32040,32041,32042,32044,32045,32046,32048,32049,32050,
+32051,32052,32053,32054,32908,39269,36857,28608,35749,40481,23020,32489,32521,
+21513,26497,26840,36753,31821,38598,21450,24613,30142,27762,21363,23241,32423,
+25380,20960,33034,24049,34015,25216,20864,23395,20238,31085,21058,24760,27982,
+23492,23490,35745,35760,26082,24524,38469,22931,32487,32426,22025,26551,22841,
+20339,23478,21152,33626,39050,36158,30002,38078,20551,31292,20215,26550,39550,
+23233,27516,30417,22362,23574,31546,38388,29006,20860,32937,33392,22904,32516,
+33575,26816,26604,30897,30839,25315,25441,31616,20461,21098,20943,33616,27099,
+37492,36341,36145,35265,38190,31661,20214,32055,32056,32057,32058,32059,32060,
+32061,32062,32063,32064,32065,32066,32067,32068,32069,32070,32071,32072,32073,
+32074,32075,32076,32077,32078,32079,32080,32081,32082,32083,32084,32085,32086,
+32087,32088,32089,32090,32091,32092,32093,32094,32095,32096,32097,32098,32099,
+32100,32101,32102,32103,32104,32105,32106,32107,32108,32109,32111,32112,32113,
+32114,32115,32116,32117,32118,32120,32121,32122,32123,32124,32125,32126,32127,
+32128,32129,32130,32131,32132,32133,32134,32135,32136,32137,32138,32139,32140,
+32141,32142,32143,32144,32145,32146,32147,32148,32149,32150,32151,32152,20581,
+33328,21073,39279,28176,28293,28071,24314,20725,23004,23558,27974,27743,30086,
+33931,26728,22870,35762,21280,37233,38477,34121,26898,
+30977,28966,33014,20132,37066,27975,39556,23047,22204,25605,38128,30699,20389,
+33050,29409,35282,39290,32564,32478,21119,25945,37237,36735,36739,21483,31382,
+25581,25509,30342,31224,34903,38454,25130,21163,33410,26708,26480,25463,30571,
+31469,27905,32467,35299,22992,25106,34249,33445,30028,20511,20171,30117,35819,
+23626,24062,31563,26020,37329,20170,27941,35167,32039,38182,20165,35880,36827,
+38771,26187,31105,36817,28908,28024,32153,32154,32155,32156,32157,32158,32159,
+32160,32161,32162,32163,32164,32165,32167,32168,32169,32170,32171,32172,32173,
+32175,32176,32177,32178,32179,32180,32181,32182,32183,32184,32185,32186,32187,
+32188,32189,32190,32191,32192,32193,32194,32195,32196,32197,32198,32199,32200,
+32201,32202,32203,32204,32205,32206,32207,32208,32209,32210,32211,32212,32213,
+32214,32215,32216,32217,32218,32219,32220,32221,32222,32223,32224,32225,32226,
+32227,32228,32229,32230,32231,32232,32233,32234,32235,32236,32237,32238,32239,
+32240,32241,32242,32243,32244,32245,32246,32247,32248,32249,32250,23613,21170,
+33606,20834,33550,30555,26230,40120,20140,24778,31934,31923,32463,20117,35686,
+26223,39048,38745,22659,25964,38236,24452,30153,38742,31455,31454,20928,28847,
+31384,25578,31350,32416,29590,38893,20037,28792,20061,37202,21417,25937,26087,
+33276,33285,21646,23601,30106,38816,25304,29401,30141,23621,39545,33738,23616,
+21632,30697,20030,27822,32858,25298,25454,24040,20855,36317,36382,38191,20465,
+21477,24807,28844,21095,25424,40515,23071,20518,30519,21367,32482,25733,25899,
+25225,25496,20500,29237,35273,20915,35776,32477,22343,
+33740,38055,20891,21531,23803,32251,32252,32253,32254,32255,32256,32257,32258,
+32259,32260,32261,32262,32263,32264,32265,32266,32267,32268,32269,32270,32271,
+32272,32273,32274,32275,32276,32277,32278,32279,32280,32281,32282,32283,32284,
+32285,32286,32287,32288,32289,32290,32291,32292,32293,32294,32295,32296,32297,
+32298,32299,32300,32301,32302,32303,32304,32305,32306,32307,32308,32309,32310,
+32311,32312,32313,32314,32316,32317,32318,32319,32320,32322,32323,32324,32325,
+32326,32328,32329,32330,32331,32332,32333,32334,32335,32336,32337,32338,32339,
+32340,32341,32342,32343,32344,32345,32346,32347,32348,32349,20426,31459,27994,
+37089,39567,21888,21654,21345,21679,24320,25577,26999,20975,24936,21002,22570,
+21208,22350,30733,30475,24247,24951,31968,25179,25239,20130,28821,32771,25335,
+28900,38752,22391,33499,26607,26869,30933,39063,31185,22771,21683,21487,28212,
+20811,21051,23458,35838,32943,21827,22438,24691,22353,21549,31354,24656,23380,
+25511,25248,21475,25187,23495,26543,21741,31391,33510,37239,24211,35044,22840,
+22446,25358,36328,33007,22359,31607,20393,24555,23485,27454,21281,31568,29378,
+26694,30719,30518,26103,20917,20111,30420,23743,31397,33909,22862,39745,20608,
+32350,32351,32352,32353,32354,32355,32356,32357,32358,32359,32360,32361,32362,
+32363,32364,32365,32366,32367,32368,32369,32370,32371,32372,32373,32374,32375,
+32376,32377,32378,32379,32380,32381,32382,32383,32384,32385,32387,32388,32389,
+32390,32391,32392,32393,32394,32395,32396,32397,32398,32399,32400,32401,32402,
+32403,32404,32405,32406,32407,32408,32409,32410,32412,
+32413,32414,32430,32436,32443,32444,32470,32484,32492,32505,32522,32528,32542,
+32567,32569,32571,32572,32573,32574,32575,32576,32577,32579,32582,32583,32584,
+32585,32586,32587,32588,32589,32590,32591,32594,32595,39304,24871,28291,22372,
+26118,25414,22256,25324,25193,24275,38420,22403,25289,21895,34593,33098,36771,
+21862,33713,26469,36182,34013,23146,26639,25318,31726,38417,20848,28572,35888,
+25597,35272,25042,32518,28866,28389,29701,27028,29436,24266,37070,26391,28010,
+25438,21171,29282,32769,20332,23013,37226,28889,28061,21202,20048,38647,38253,
+34174,30922,32047,20769,22418,25794,32907,31867,27882,26865,26974,20919,21400,
+26792,29313,40654,31729,29432,31163,28435,29702,26446,37324,40100,31036,33673,
+33620,21519,26647,20029,21385,21169,30782,21382,21033,20616,20363,20432,32598,
+32601,32603,32604,32605,32606,32608,32611,32612,32613,32614,32615,32619,32620,
+32621,32623,32624,32627,32629,32630,32631,32632,32634,32635,32636,32637,32639,
+32640,32642,32643,32644,32645,32646,32647,32648,32649,32651,32653,32655,32656,
+32657,32658,32659,32661,32662,32663,32664,32665,32667,32668,32672,32674,32675,
+32677,32678,32680,32681,32682,32683,32684,32685,32686,32689,32691,32692,32693,
+32694,32695,32698,32699,32702,32704,32706,32707,32708,32710,32711,32712,32713,
+32715,32717,32719,32720,32721,32722,32723,32726,32727,32729,32730,32731,32732,
+32733,32734,32738,32739,30178,31435,31890,27813,38582,21147,29827,21737,20457,
+32852,33714,36830,38256,24265,24604,28063,24088,25947,33080,38142,24651,28860,
+32451,31918,20937,26753,31921,33391,20004,36742,37327,
+26238,20142,35845,25769,32842,20698,30103,29134,23525,36797,28518,20102,25730,
+38243,24278,26009,21015,35010,28872,21155,29454,29747,26519,30967,38678,20020,
+37051,40158,28107,20955,36161,21533,25294,29618,33777,38646,40836,38083,20278,
+32666,20940,28789,38517,23725,39046,21478,20196,28316,29705,27060,30827,39311,
+30041,21016,30244,27969,26611,20845,40857,32843,21657,31548,31423,32740,32743,
+32744,32746,32747,32748,32749,32751,32754,32756,32757,32758,32759,32760,32761,
+32762,32765,32766,32767,32770,32775,32776,32777,32778,32782,32783,32785,32787,
+32794,32795,32797,32798,32799,32801,32803,32804,32811,32812,32813,32814,32815,
+32816,32818,32820,32825,32826,32828,32830,32832,32833,32836,32837,32839,32840,
+32841,32846,32847,32848,32849,32851,32853,32854,32855,32857,32859,32860,32861,
+32862,32863,32864,32865,32866,32867,32868,32869,32870,32871,32872,32875,32876,
+32877,32878,32879,32880,32882,32883,32884,32885,32886,32887,32888,32889,32890,
+32891,32892,32893,38534,22404,25314,38471,27004,23044,25602,31699,28431,38475,
+33446,21346,39045,24208,28809,25523,21348,34383,40065,40595,30860,38706,36335,
+36162,40575,28510,31108,24405,38470,25134,39540,21525,38109,20387,26053,23653,
+23649,32533,34385,27695,24459,29575,28388,32511,23782,25371,23402,28390,21365,
+20081,25504,30053,25249,36718,20262,20177,27814,32438,35770,33821,34746,32599,
+36923,38179,31657,39585,35064,33853,27931,39558,32476,22920,40635,29595,30721,
+34434,39532,39554,22043,21527,22475,20080,40614,21334,36808,33033,30610,39314,
+34542,28385,34067,26364,24930,28459,32894,32897,32898,
+32901,32904,32906,32909,32910,32911,32912,32913,32914,32916,32917,32919,32921,
+32926,32931,32934,32935,32936,32940,32944,32947,32949,32950,32952,32953,32955,
+32965,32967,32968,32969,32970,32971,32975,32976,32977,32978,32979,32980,32981,
+32984,32991,32992,32994,32995,32998,33006,33013,33015,33017,33019,33022,33023,
+33024,33025,33027,33028,33029,33031,33032,33035,33036,33045,33047,33049,33051,
+33052,33053,33055,33056,33057,33058,33059,33060,33061,33062,33063,33064,33065,
+33066,33067,33069,33070,33072,33075,33076,33077,33079,33081,33082,33083,33084,
+33085,33087,35881,33426,33579,30450,27667,24537,33725,29483,33541,38170,27611,
+30683,38086,21359,33538,20882,24125,35980,36152,20040,29611,26522,26757,37238,
+38665,29028,27809,30473,23186,38209,27599,32654,26151,23504,22969,23194,38376,
+38391,20204,33804,33945,27308,30431,38192,29467,26790,23391,30511,37274,38753,
+31964,36855,35868,24357,31859,31192,35269,27852,34588,23494,24130,26825,30496,
+32501,20885,20813,21193,23081,32517,38754,33495,25551,30596,34256,31186,28218,
+24217,22937,34065,28781,27665,25279,30399,25935,24751,38397,26126,34719,40483,
+38125,21517,21629,35884,25720,33088,33089,33090,33091,33092,33093,33095,33097,
+33101,33102,33103,33106,33110,33111,33112,33115,33116,33117,33118,33119,33121,
+33122,33123,33124,33126,33128,33130,33131,33132,33135,33138,33139,33141,33142,
+33143,33144,33153,33155,33156,33157,33158,33159,33161,33163,33164,33165,33166,
+33168,33170,33171,33172,33173,33174,33175,33177,33178,33182,33183,33184,33185,
+33186,33188,33189,33191,33193,33195,33196,33197,33198,
+33199,33200,33201,33202,33204,33205,33206,33207,33208,33209,33212,33213,33214,
+33215,33220,33221,33223,33224,33225,33227,33229,33230,33231,33232,33233,33234,
+33235,25721,34321,27169,33180,30952,25705,39764,25273,26411,33707,22696,40664,
+27819,28448,23518,38476,35851,29279,26576,25287,29281,20137,22982,27597,22675,
+26286,24149,21215,24917,26408,30446,30566,29287,31302,25343,21738,21584,38048,
+37027,23068,32435,27670,20035,22902,32784,22856,21335,30007,38590,22218,25376,
+33041,24700,38393,28118,21602,39297,20869,23273,33021,22958,38675,20522,27877,
+23612,25311,20320,21311,33147,36870,28346,34091,25288,24180,30910,25781,25467,
+24565,23064,37247,40479,23615,25423,32834,23421,21870,38218,38221,28037,24744,
+26592,29406,20957,23425,33236,33237,33238,33239,33240,33241,33242,33243,33244,
+33245,33246,33247,33248,33249,33250,33252,33253,33254,33256,33257,33259,33262,
+33263,33264,33265,33266,33269,33270,33271,33272,33273,33274,33277,33279,33283,
+33287,33288,33289,33290,33291,33294,33295,33297,33299,33301,33302,33303,33304,
+33305,33306,33309,33312,33316,33317,33318,33319,33321,33326,33330,33338,33340,
+33341,33343,33344,33345,33346,33347,33349,33350,33352,33354,33356,33357,33358,
+33360,33361,33362,33363,33364,33365,33366,33367,33369,33371,33372,33373,33374,
+33376,33377,33378,33379,33380,33381,33382,33383,33385,25319,27870,29275,25197,
+38062,32445,33043,27987,20892,24324,22900,21162,24594,22899,26262,34384,30111,
+25386,25062,31983,35834,21734,27431,40485,27572,34261,21589,20598,27812,21866,
+36276,29228,24085,24597,29750,25293,25490,29260,24472,
+28227,27966,25856,28504,30424,30928,30460,30036,21028,21467,20051,24222,26049,
+32810,32982,25243,21638,21032,28846,34957,36305,27873,21624,32986,22521,35060,
+36180,38506,37197,20329,27803,21943,30406,30768,25256,28921,28558,24429,34028,
+26842,30844,31735,33192,26379,40527,25447,30896,22383,30738,38713,25209,25259,
+21128,29749,27607,33386,33387,33388,33389,33393,33397,33398,33399,33400,33403,
+33404,33408,33409,33411,33413,33414,33415,33417,33420,33424,33427,33428,33429,
+33430,33434,33435,33438,33440,33442,33443,33447,33458,33461,33462,33466,33467,
+33468,33471,33472,33474,33475,33477,33478,33481,33488,33494,33497,33498,33501,
+33506,33511,33512,33513,33514,33516,33517,33518,33520,33522,33523,33525,33526,
+33528,33530,33532,33533,33534,33535,33536,33546,33547,33549,33552,33554,33555,
+33558,33560,33561,33565,33566,33567,33568,33569,33570,33571,33572,33573,33574,
+33577,33578,33582,33584,33586,33591,33595,33597,21860,33086,30130,30382,21305,
+30174,20731,23617,35692,31687,20559,29255,39575,39128,28418,29922,31080,25735,
+30629,25340,39057,36139,21697,32856,20050,22378,33529,33805,24179,20973,29942,
+35780,23631,22369,27900,39047,23110,30772,39748,36843,31893,21078,25169,38138,
+20166,33670,33889,33769,33970,22484,26420,22275,26222,28006,35889,26333,28689,
+26399,27450,26646,25114,22971,19971,20932,28422,26578,27791,20854,26827,22855,
+27495,30054,23822,33040,40784,26071,31048,31041,39569,36215,23682,20062,20225,
+21551,22865,30732,22120,27668,36804,24323,27773,27875,35755,25488,33598,33599,
+33601,33602,33604,33605,33608,33610,33611,33612,33613,
+33614,33619,33621,33622,33623,33624,33625,33629,33634,33648,33649,33650,33651,
+33652,33653,33654,33657,33658,33662,33663,33664,33665,33666,33667,33668,33671,
+33672,33674,33675,33676,33677,33679,33680,33681,33684,33685,33686,33687,33689,
+33690,33693,33695,33697,33698,33699,33700,33701,33702,33703,33708,33709,33710,
+33711,33717,33723,33726,33727,33730,33731,33732,33734,33736,33737,33739,33741,
+33742,33744,33745,33746,33747,33749,33751,33753,33754,33755,33758,33762,33763,
+33764,33766,33767,33768,33771,33772,33773,24688,27965,29301,25190,38030,38085,
+21315,36801,31614,20191,35878,20094,40660,38065,38067,21069,28508,36963,27973,
+35892,22545,23884,27424,27465,26538,21595,33108,32652,22681,34103,24378,25250,
+27207,38201,25970,24708,26725,30631,20052,20392,24039,38808,25772,32728,23789,
+20431,31373,20999,33540,19988,24623,31363,38054,20405,20146,31206,29748,21220,
+33465,25810,31165,23517,27777,38738,36731,27682,20542,21375,28165,25806,26228,
+27696,24773,39031,35831,24198,29756,31351,31179,19992,37041,29699,27714,22234,
+37195,27845,36235,21306,34502,26354,36527,23624,39537,28192,33774,33775,33779,
+33780,33781,33782,33783,33786,33787,33788,33790,33791,33792,33794,33797,33799,
+33800,33801,33802,33808,33810,33811,33812,33813,33814,33815,33817,33818,33819,
+33822,33823,33824,33825,33826,33827,33833,33834,33835,33836,33837,33838,33839,
+33840,33842,33843,33844,33845,33846,33847,33849,33850,33851,33854,33855,33856,
+33857,33858,33859,33860,33861,33863,33864,33865,33866,33867,33868,33869,33870,
+33871,33872,33874,33875,33876,33877,33878,33880,33885,
+33886,33887,33888,33890,33892,33893,33894,33895,33896,33898,33902,33903,33904,
+33906,33908,33911,33913,33915,33916,21462,23094,40843,36259,21435,22280,39079,
+26435,37275,27849,20840,30154,25331,29356,21048,21149,32570,28820,30264,21364,
+40522,27063,30830,38592,35033,32676,28982,29123,20873,26579,29924,22756,25880,
+22199,35753,39286,25200,32469,24825,28909,22764,20161,20154,24525,38887,20219,
+35748,20995,22922,32427,25172,20173,26085,25102,33592,33993,33635,34701,29076,
+28342,23481,32466,20887,25545,26580,32905,33593,34837,20754,23418,22914,36785,
+20083,27741,20837,35109,36719,38446,34122,29790,38160,38384,28070,33509,24369,
+25746,27922,33832,33134,40131,22622,36187,19977,21441,33917,33918,33919,33920,
+33921,33923,33924,33925,33926,33930,33933,33935,33936,33937,33938,33939,33940,
+33941,33942,33944,33946,33947,33949,33950,33951,33952,33954,33955,33956,33957,
+33958,33959,33960,33961,33962,33963,33964,33965,33966,33968,33969,33971,33973,
+33974,33975,33979,33980,33982,33984,33986,33987,33989,33990,33991,33992,33995,
+33996,33998,33999,34002,34004,34005,34007,34008,34009,34010,34011,34012,34014,
+34017,34018,34020,34023,34024,34025,34026,34027,34029,34030,34031,34033,34034,
+34035,34036,34037,34038,34039,34040,34041,34042,34043,34045,34046,34048,34049,
+34050,20254,25955,26705,21971,20007,25620,39578,25195,23234,29791,33394,28073,
+26862,20711,33678,30722,26432,21049,27801,32433,20667,21861,29022,31579,26194,
+29642,33515,26441,23665,21024,29053,34923,38378,38485,25797,36193,33203,21892,
+27733,25159,32558,22674,20260,21830,36175,26188,19978,
+23578,35059,26786,25422,31245,28903,33421,21242,38902,23569,21736,37045,32461,
+22882,36170,34503,33292,33293,36198,25668,23556,24913,28041,31038,35774,30775,
+30003,21627,20280,36523,28145,23072,32453,31070,27784,23457,23158,29978,32958,
+24910,28183,22768,29983,29989,29298,21319,32499,34051,34052,34053,34054,34055,
+34056,34057,34058,34059,34061,34062,34063,34064,34066,34068,34069,34070,34072,
+34073,34075,34076,34077,34078,34080,34082,34083,34084,34085,34086,34087,34088,
+34089,34090,34093,34094,34095,34096,34097,34098,34099,34100,34101,34102,34110,
+34111,34112,34113,34114,34116,34117,34118,34119,34123,34124,34125,34126,34127,
+34128,34129,34130,34131,34132,34133,34135,34136,34138,34139,34140,34141,34143,
+34144,34145,34146,34147,34149,34150,34151,34153,34154,34155,34156,34157,34158,
+34159,34160,34161,34163,34165,34166,34167,34168,34172,34173,34175,34176,34177,
+30465,30427,21097,32988,22307,24072,22833,29422,26045,28287,35799,23608,34417,
+21313,30707,25342,26102,20160,39135,34432,23454,35782,21490,30690,20351,23630,
+39542,22987,24335,31034,22763,19990,26623,20107,25325,35475,36893,21183,26159,
+21980,22124,36866,20181,20365,37322,39280,27663,24066,24643,23460,35270,35797,
+25910,25163,39318,23432,23551,25480,21806,21463,30246,20861,34092,26530,26803,
+27530,25234,36755,21460,33298,28113,30095,20070,36174,23408,29087,34223,26257,
+26329,32626,34560,40653,40736,23646,26415,36848,26641,26463,25101,31446,22661,
+24246,25968,28465,34178,34179,34182,34184,34185,34186,34187,34188,34189,34190,
+34192,34193,34194,34195,34196,34197,34198,34199,34200,
+34201,34202,34205,34206,34207,34208,34209,34210,34211,34213,34214,34215,34217,
+34219,34220,34221,34225,34226,34227,34228,34229,34230,34232,34234,34235,34236,
+34237,34238,34239,34240,34242,34243,34244,34245,34246,34247,34248,34250,34251,
+34252,34253,34254,34257,34258,34260,34262,34263,34264,34265,34266,34267,34269,
+34270,34271,34272,34273,34274,34275,34277,34278,34279,34280,34282,34283,34284,
+34285,34286,34287,34288,34289,34290,34291,34292,34293,34294,34295,34296,24661,
+21047,32781,25684,34928,29993,24069,26643,25332,38684,21452,29245,35841,27700,
+30561,31246,21550,30636,39034,33308,35828,30805,26388,28865,26031,25749,22070,
+24605,31169,21496,19997,27515,32902,23546,21987,22235,20282,20284,39282,24051,
+26494,32824,24578,39042,36865,23435,35772,35829,25628,33368,25822,22013,33487,
+37221,20439,32032,36895,31903,20723,22609,28335,23487,35785,32899,37240,33948,
+31639,34429,38539,38543,32485,39635,30862,23681,31319,36930,38567,31071,23385,
+25439,31499,34001,26797,21766,32553,29712,32034,38145,25152,22604,20182,23427,
+22905,22612,34297,34298,34300,34301,34302,34304,34305,34306,34307,34308,34310,
+34311,34312,34313,34314,34315,34316,34317,34318,34319,34320,34322,34323,34324,
+34325,34327,34328,34329,34330,34331,34332,34333,34334,34335,34336,34337,34338,
+34339,34340,34341,34342,34344,34346,34347,34348,34349,34350,34351,34352,34353,
+34354,34355,34356,34357,34358,34359,34361,34362,34363,34365,34366,34367,34368,
+34369,34370,34371,34372,34373,34374,34375,34376,34377,34378,34379,34380,34386,
+34387,34389,34390,34391,34392,34393,34395,34396,34397,
+34399,34400,34401,34403,34404,34405,34406,34407,34408,34409,34410,29549,25374,
+36427,36367,32974,33492,25260,21488,27888,37214,22826,24577,27760,22349,25674,
+36138,30251,28393,22363,27264,30192,28525,35885,35848,22374,27631,34962,30899,
+25506,21497,28845,27748,22616,25642,22530,26848,33179,21776,31958,20504,36538,
+28108,36255,28907,25487,28059,28372,32486,33796,26691,36867,28120,38518,35752,
+22871,29305,34276,33150,30140,35466,26799,21076,36386,38161,25552,39064,36420,
+21884,20307,26367,22159,24789,28053,21059,23625,22825,28155,22635,30000,29980,
+24684,33300,33094,25361,26465,36834,30522,36339,36148,38081,24086,21381,21548,
+28867,34413,34415,34416,34418,34419,34420,34421,34422,34423,34424,34435,34436,
+34437,34438,34439,34440,34441,34446,34447,34448,34449,34450,34452,34454,34455,
+34456,34457,34458,34459,34462,34463,34464,34465,34466,34469,34470,34475,34477,
+34478,34482,34483,34487,34488,34489,34491,34492,34493,34494,34495,34497,34498,
+34499,34501,34504,34508,34509,34514,34515,34517,34518,34519,34522,34524,34525,
+34528,34529,34530,34531,34533,34534,34535,34536,34538,34539,34540,34543,34549,
+34550,34551,34554,34555,34556,34557,34559,34561,34564,34565,34566,34571,34572,
+34574,34575,34576,34577,34580,34582,27712,24311,20572,20141,24237,25402,33351,
+36890,26704,37230,30643,21516,38108,24420,31461,26742,25413,31570,32479,30171,
+20599,25237,22836,36879,20984,31171,31361,22270,24466,36884,28034,23648,22303,
+21520,20820,28237,22242,25512,39059,33151,34581,35114,36864,21534,23663,33216,
+25302,25176,33073,40501,38464,39534,39548,26925,22949,
+25299,21822,25366,21703,34521,27964,23043,29926,34972,27498,22806,35916,24367,
+28286,29609,39037,20024,28919,23436,30871,25405,26202,30358,24779,23451,23113,
+19975,33109,27754,29579,20129,26505,32593,24448,26106,26395,24536,22916,23041,
+34585,34587,34589,34591,34592,34596,34598,34599,34600,34602,34603,34604,34605,
+34607,34608,34610,34611,34613,34614,34616,34617,34618,34620,34621,34624,34625,
+34626,34627,34628,34629,34630,34634,34635,34637,34639,34640,34641,34642,34644,
+34645,34646,34648,34650,34651,34652,34653,34654,34655,34657,34658,34662,34663,
+34664,34665,34666,34667,34668,34669,34671,34673,34674,34675,34677,34679,34680,
+34681,34682,34687,34688,34689,34692,34694,34695,34697,34698,34700,34702,34703,
+34704,34705,34706,34708,34709,34710,34712,34713,34714,34715,34716,34717,34718,
+34720,34721,34722,34723,34724,24013,24494,21361,38886,36829,26693,22260,21807,
+24799,20026,28493,32500,33479,33806,22996,20255,20266,23614,32428,26410,34074,
+21619,30031,32963,21890,39759,20301,28205,35859,23561,24944,21355,30239,28201,
+34442,25991,38395,32441,21563,31283,32010,38382,21985,32705,29934,25373,34583,
+28065,31389,25105,26017,21351,25569,27779,24043,21596,38056,20044,27745,35820,
+23627,26080,33436,26791,21566,21556,27595,27494,20116,25410,21320,33310,20237,
+20398,22366,25098,38654,26212,29289,21247,21153,24735,35823,26132,29081,26512,
+35199,30802,30717,26224,22075,21560,38177,29306,34725,34726,34727,34729,34730,
+34734,34736,34737,34738,34740,34742,34743,34744,34745,34747,34748,34750,34751,
+34753,34754,34755,34756,34757,34759,34760,34761,34764,
+34765,34766,34767,34768,34772,34773,34774,34775,34776,34777,34778,34780,34781,
+34782,34783,34785,34786,34787,34788,34790,34791,34792,34793,34795,34796,34797,
+34799,34800,34801,34802,34803,34804,34805,34806,34807,34808,34810,34811,34812,
+34813,34815,34816,34817,34818,34820,34821,34822,34823,34824,34825,34827,34828,
+34829,34830,34831,34832,34833,34834,34836,34839,34840,34841,34842,34844,34845,
+34846,34847,34848,34851,31232,24687,24076,24713,33181,22805,24796,29060,28911,
+28330,27728,29312,27268,34989,24109,20064,23219,21916,38115,27927,31995,38553,
+25103,32454,30606,34430,21283,38686,36758,26247,23777,20384,29421,19979,21414,
+22799,21523,25472,38184,20808,20185,40092,32420,21688,36132,34900,33335,38386,
+28046,24358,23244,26174,38505,29616,29486,21439,33146,39301,32673,23466,38519,
+38480,32447,30456,21410,38262,39321,31665,35140,28248,20065,32724,31077,35814,
+24819,21709,20139,39033,24055,27233,20687,21521,35937,33831,30813,38660,21066,
+21742,22179,38144,28040,23477,28102,26195,34852,34853,34854,34855,34856,34857,
+34858,34859,34860,34861,34862,34863,34864,34865,34867,34868,34869,34870,34871,
+34872,34874,34875,34877,34878,34879,34881,34882,34883,34886,34887,34888,34889,
+34890,34891,34894,34895,34896,34897,34898,34899,34901,34902,34904,34906,34907,
+34908,34909,34910,34911,34912,34918,34919,34922,34925,34927,34929,34931,34932,
+34933,34934,34936,34937,34938,34939,34940,34944,34947,34950,34951,34953,34954,
+34956,34958,34959,34960,34961,34963,34964,34965,34967,34968,34969,34970,34971,
+34973,34974,34975,34976,34977,34979,34981,34982,34983,
+34984,34985,34986,23567,23389,26657,32918,21880,31505,25928,26964,20123,27463,
+34638,38795,21327,25375,25658,37034,26012,32961,35856,20889,26800,21368,34809,
+25032,27844,27899,35874,23633,34218,33455,38156,27427,36763,26032,24571,24515,
+20449,34885,26143,33125,29481,24826,20852,21009,22411,24418,37026,34892,37266,
+24184,26447,24615,22995,20804,20982,33016,21256,27769,38596,29066,20241,20462,
+32670,26429,21957,38152,31168,34966,32483,22687,25100,38656,34394,22040,39035,
+24464,35768,33988,37207,21465,26093,24207,30044,24676,32110,23167,32490,32493,
+36713,21927,23459,24748,26059,29572,34988,34990,34991,34992,34994,34995,34996,
+34997,34998,35000,35001,35002,35003,35005,35006,35007,35008,35011,35012,35015,
+35016,35018,35019,35020,35021,35023,35024,35025,35027,35030,35031,35034,35035,
+35036,35037,35038,35040,35041,35046,35047,35049,35050,35051,35052,35053,35054,
+35055,35058,35061,35062,35063,35066,35067,35069,35071,35072,35073,35075,35076,
+35077,35078,35079,35080,35081,35083,35084,35085,35086,35087,35089,35092,35093,
+35094,35095,35096,35100,35101,35102,35103,35104,35106,35107,35108,35110,35111,
+35112,35113,35116,35117,35118,35119,35121,35122,35123,35125,35127,36873,30307,
+30505,32474,38772,34203,23398,31348,38634,34880,21195,29071,24490,26092,35810,
+23547,39535,24033,27529,27739,35757,35759,36874,36805,21387,25276,40486,40493,
+21568,20011,33469,29273,34460,23830,34905,28079,38597,21713,20122,35766,28937,
+21693,38409,28895,28153,30416,20005,30740,34578,23721,24310,35328,39068,38414,
+28814,27839,22852,25513,30524,34893,28436,33395,22576,
+29141,21388,30746,38593,21761,24422,28976,23476,35866,39564,27523,22830,40495,
+31207,26472,25196,20335,30113,32650,27915,38451,27687,20208,30162,20859,26679,
+28478,36992,33136,22934,29814,35128,35129,35130,35131,35132,35133,35134,35135,
+35136,35138,35139,35141,35142,35143,35144,35145,35146,35147,35148,35149,35150,
+35151,35152,35153,35154,35155,35156,35157,35158,35159,35160,35161,35162,35163,
+35164,35165,35168,35169,35170,35171,35172,35173,35175,35176,35177,35178,35179,
+35180,35181,35182,35183,35184,35185,35186,35187,35188,35189,35190,35191,35192,
+35193,35194,35196,35197,35198,35200,35202,35204,35205,35207,35208,35209,35210,
+35211,35212,35213,35214,35215,35216,35217,35218,35219,35220,35221,35222,35223,
+35224,35225,35226,35227,35228,35229,35230,35231,35232,35233,25671,23591,36965,
+31377,35875,23002,21676,33280,33647,35201,32768,26928,22094,32822,29239,37326,
+20918,20063,39029,25494,19994,21494,26355,33099,22812,28082,19968,22777,21307,
+25558,38129,20381,20234,34915,39056,22839,36951,31227,20202,33008,30097,27778,
+23452,23016,24413,26885,34433,20506,24050,20057,30691,20197,33402,25233,26131,
+37009,23673,20159,24441,33222,36920,32900,30123,20134,35028,24847,27589,24518,
+20041,30410,28322,35811,35758,35850,35793,24322,32764,32716,32462,33589,33643,
+22240,27575,38899,38452,23035,21535,38134,28139,23493,39278,23609,24341,38544,
+35234,35235,35236,35237,35238,35239,35240,35241,35242,35243,35244,35245,35246,
+35247,35248,35249,35250,35251,35252,35253,35254,35255,35256,35257,35258,35259,
+35260,35261,35262,35263,35264,35267,35277,35283,35284,
+35285,35287,35288,35289,35291,35293,35295,35296,35297,35298,35300,35303,35304,
+35305,35306,35308,35309,35310,35312,35313,35314,35316,35317,35318,35319,35320,
+35321,35322,35323,35324,35325,35326,35327,35329,35330,35331,35332,35333,35334,
+35336,35337,35338,35339,35340,35341,35342,35343,35344,35345,35346,35347,35348,
+35349,35350,35351,35352,35353,35354,35355,35356,35357,21360,33521,27185,23156,
+40560,24212,32552,33721,33828,33829,33639,34631,36814,36194,30408,24433,39062,
+30828,26144,21727,25317,20323,33219,30152,24248,38605,36362,34553,21647,27891,
+28044,27704,24703,21191,29992,24189,20248,24736,24551,23588,30001,37038,38080,
+29369,27833,28216,37193,26377,21451,21491,20305,37321,35825,21448,24188,36802,
+28132,20110,30402,27014,34398,24858,33286,20313,20446,36926,40060,24841,28189,
+28180,38533,20104,23089,38632,19982,23679,31161,23431,35821,32701,29577,22495,
+33419,37057,21505,36935,21947,23786,24481,24840,27442,29425,32946,35465,35358,
+35359,35360,35361,35362,35363,35364,35365,35366,35367,35368,35369,35370,35371,
+35372,35373,35374,35375,35376,35377,35378,35379,35380,35381,35382,35383,35384,
+35385,35386,35387,35388,35389,35391,35392,35393,35394,35395,35396,35397,35398,
+35399,35401,35402,35403,35404,35405,35406,35407,35408,35409,35410,35411,35412,
+35413,35414,35415,35416,35417,35418,35419,35420,35421,35422,35423,35424,35425,
+35426,35427,35428,35429,35430,35431,35432,35433,35434,35435,35436,35437,35438,
+35439,35440,35441,35442,35443,35444,35445,35446,35447,35448,35450,35451,35452,
+35453,35454,35455,35456,28020,23507,35029,39044,35947,
+39533,40499,28170,20900,20803,22435,34945,21407,25588,36757,22253,21592,22278,
+29503,28304,32536,36828,33489,24895,24616,38498,26352,32422,36234,36291,38053,
+23731,31908,26376,24742,38405,32792,20113,37095,21248,38504,20801,36816,34164,
+37213,26197,38901,23381,21277,30776,26434,26685,21705,28798,23472,36733,20877,
+22312,21681,25874,26242,36190,36163,33039,33900,36973,31967,20991,34299,26531,
+26089,28577,34468,36481,22122,36896,30338,28790,29157,36131,25321,21017,27901,
+36156,24590,22686,24974,26366,36192,25166,21939,28195,26413,36711,35457,35458,
+35459,35460,35461,35462,35463,35464,35467,35468,35469,35470,35471,35472,35473,
+35474,35476,35477,35478,35479,35480,35481,35482,35483,35484,35485,35486,35487,
+35488,35489,35490,35491,35492,35493,35494,35495,35496,35497,35498,35499,35500,
+35501,35502,35503,35504,35505,35506,35507,35508,35509,35510,35511,35512,35513,
+35514,35515,35516,35517,35518,35519,35520,35521,35522,35523,35524,35525,35526,
+35527,35528,35529,35530,35531,35532,35533,35534,35535,35536,35537,35538,35539,
+35540,35541,35542,35543,35544,35545,35546,35547,35548,35549,35550,35551,35552,
+35553,35554,35555,38113,38392,30504,26629,27048,21643,20045,28856,35784,25688,
+25995,23429,31364,20538,23528,30651,27617,35449,31896,27838,30415,26025,36759,
+23853,23637,34360,26632,21344,25112,31449,28251,32509,27167,31456,24432,28467,
+24352,25484,28072,26454,19976,24080,36134,20183,32960,30260,38556,25307,26157,
+25214,27836,36213,29031,32617,20806,32903,21484,36974,25240,21746,34544,36761,
+32773,38167,34071,36825,27993,29645,26015,30495,29956,
+30759,33275,36126,38024,20390,26517,30137,35786,38663,25391,38215,38453,33976,
+25379,30529,24449,29424,20105,24596,25972,25327,27491,25919,35556,35557,35558,
+35559,35560,35561,35562,35563,35564,35565,35566,35567,35568,35569,35570,35571,
+35572,35573,35574,35575,35576,35577,35578,35579,35580,35581,35582,35583,35584,
+35585,35586,35587,35588,35589,35590,35592,35593,35594,35595,35596,35597,35598,
+35599,35600,35601,35602,35603,35604,35605,35606,35607,35608,35609,35610,35611,
+35612,35613,35614,35615,35616,35617,35618,35619,35620,35621,35623,35624,35625,
+35626,35627,35628,35629,35630,35631,35632,35633,35634,35635,35636,35637,35638,
+35639,35640,35641,35642,35643,35644,35645,35646,35647,35648,35649,35650,35651,
+35652,35653,24103,30151,37073,35777,33437,26525,25903,21553,34584,30693,32930,
+33026,27713,20043,32455,32844,30452,26893,27542,25191,20540,20356,22336,25351,
+27490,36286,21482,26088,32440,24535,25370,25527,33267,33268,32622,24092,23769,
+21046,26234,31209,31258,36136,28825,30164,28382,27835,31378,20013,30405,24544,
+38047,34935,32456,31181,32959,37325,20210,20247,33311,21608,24030,27954,35788,
+31909,36724,32920,24090,21650,30385,23449,26172,39588,29664,26666,34523,26417,
+29482,35832,35803,36880,31481,28891,29038,25284,30633,22065,20027,33879,26609,
+21161,34496,36142,38136,31569,35654,35655,35656,35657,35658,35659,35660,35661,
+35662,35663,35664,35665,35666,35667,35668,35669,35670,35671,35672,35673,35674,
+35675,35676,35677,35678,35679,35680,35681,35682,35683,35684,35685,35687,35688,
+35689,35690,35691,35693,35694,35695,35696,35697,35698,
+35699,35700,35701,35702,35703,35704,35705,35706,35707,35708,35709,35710,35711,
+35712,35713,35714,35715,35716,35717,35718,35719,35720,35721,35722,35723,35724,
+35725,35726,35727,35728,35729,35730,35731,35732,35733,35734,35735,35736,35737,
+35738,35739,35740,35741,35742,35743,35756,35761,35771,35783,35792,35818,35849,
+35870,20303,27880,31069,39547,25235,29226,25341,19987,30742,36716,25776,36186,
+31686,26729,24196,35013,22918,25758,22766,29366,26894,38181,36861,36184,22368,
+32512,35846,20934,25417,25305,21331,26700,29730,33537,37196,21828,30528,28796,
+27978,20857,21672,36164,23039,28363,28100,23388,32043,20180,31869,28371,23376,
+33258,28173,23383,39683,26837,36394,23447,32508,24635,32437,37049,36208,22863,
+25549,31199,36275,21330,26063,31062,35781,38459,32452,38075,32386,22068,37257,
+26368,32618,23562,36981,26152,24038,20304,26590,20570,20316,22352,24231,59408,
+59409,59410,59411,59412,35896,35897,35898,35899,35900,35901,35902,35903,35904,
+35906,35907,35908,35909,35912,35914,35915,35917,35918,35919,35920,35921,35922,
+35923,35924,35926,35927,35928,35929,35931,35932,35933,35934,35935,35936,35939,
+35940,35941,35942,35943,35944,35945,35948,35949,35950,35951,35952,35953,35954,
+35956,35957,35958,35959,35963,35964,35965,35966,35967,35968,35969,35971,35972,
+35974,35975,35976,35979,35981,35982,35983,35984,35985,35986,35987,35989,35990,
+35991,35993,35994,35995,35996,35997,35998,35999,36000,36001,36002,36003,36004,
+36005,36006,36007,36008,36009,36010,36011,36012,36013,20109,19980,20800,19984,
+24319,21317,19989,20120,19998,39730,23404,22121,20008,
+31162,20031,21269,20039,22829,29243,21358,27664,22239,32996,39319,27603,30590,
+40727,20022,20127,40720,20060,20073,20115,33416,23387,21868,22031,20164,21389,
+21405,21411,21413,21422,38757,36189,21274,21493,21286,21294,21310,36188,21350,
+21347,20994,21000,21006,21037,21043,21055,21056,21068,21086,21089,21084,33967,
+21117,21122,21121,21136,21139,20866,32596,20155,20163,20169,20162,20200,20193,
+20203,20190,20251,20211,20258,20324,20213,20261,20263,20233,20267,20318,20327,
+25912,20314,20317,36014,36015,36016,36017,36018,36019,36020,36021,36022,36023,
+36024,36025,36026,36027,36028,36029,36030,36031,36032,36033,36034,36035,36036,
+36037,36038,36039,36040,36041,36042,36043,36044,36045,36046,36047,36048,36049,
+36050,36051,36052,36053,36054,36055,36056,36057,36058,36059,36060,36061,36062,
+36063,36064,36065,36066,36067,36068,36069,36070,36071,36072,36073,36074,36075,
+36076,36077,36078,36079,36080,36081,36082,36083,36084,36085,36086,36087,36088,
+36089,36090,36091,36092,36093,36094,36095,36096,36097,36098,36099,36100,36101,
+36102,36103,36104,36105,36106,36107,36108,36109,20319,20311,20274,20285,20342,
+20340,20369,20361,20355,20367,20350,20347,20394,20348,20396,20372,20454,20456,
+20458,20421,20442,20451,20444,20433,20447,20472,20521,20556,20467,20524,20495,
+20526,20525,20478,20508,20492,20517,20520,20606,20547,20565,20552,20558,20588,
+20603,20645,20647,20649,20666,20694,20742,20717,20716,20710,20718,20743,20747,
+20189,27709,20312,20325,20430,40864,27718,31860,20846,24061,40649,39320,20865,
+22804,21241,21261,35335,21264,20971,22809,20821,20128,
+20822,20147,34926,34980,20149,33044,35026,31104,23348,34819,32696,20907,20913,
+20925,20924,36110,36111,36112,36113,36114,36115,36116,36117,36118,36119,36120,
+36121,36122,36123,36124,36128,36177,36178,36183,36191,36197,36200,36201,36202,
+36204,36206,36207,36209,36210,36216,36217,36218,36219,36220,36221,36222,36223,
+36224,36226,36227,36230,36231,36232,36233,36236,36237,36238,36239,36240,36242,
+36243,36245,36246,36247,36248,36249,36250,36251,36252,36253,36254,36256,36257,
+36258,36260,36261,36262,36263,36264,36265,36266,36267,36268,36269,36270,36271,
+36272,36274,36278,36279,36281,36283,36285,36288,36289,36290,36293,36295,36296,
+36297,36298,36301,36304,36306,36307,36308,20935,20886,20898,20901,35744,35750,
+35751,35754,35764,35765,35767,35778,35779,35787,35791,35790,35794,35795,35796,
+35798,35800,35801,35804,35807,35808,35812,35816,35817,35822,35824,35827,35830,
+35833,35836,35839,35840,35842,35844,35847,35852,35855,35857,35858,35860,35861,
+35862,35865,35867,35864,35869,35871,35872,35873,35877,35879,35882,35883,35886,
+35887,35890,35891,35893,35894,21353,21370,38429,38434,38433,38449,38442,38461,
+38460,38466,38473,38484,38495,38503,38508,38514,38516,38536,38541,38551,38576,
+37015,37019,37021,37017,37036,37025,37044,37043,37046,37050,36309,36312,36313,
+36316,36320,36321,36322,36325,36326,36327,36329,36333,36334,36336,36337,36338,
+36340,36342,36348,36350,36351,36352,36353,36354,36355,36356,36358,36359,36360,
+36363,36365,36366,36368,36369,36370,36371,36373,36374,36375,36376,36377,36378,
+36379,36380,36384,36385,36388,36389,36390,36391,36392,
+36395,36397,36400,36402,36403,36404,36406,36407,36408,36411,36412,36414,36415,
+36419,36421,36422,36428,36429,36430,36431,36432,36435,36436,36437,36438,36439,
+36440,36442,36443,36444,36445,36446,36447,36448,36449,36450,36451,36452,36453,
+36455,36456,36458,36459,36462,36465,37048,37040,37071,37061,37054,37072,37060,
+37063,37075,37094,37090,37084,37079,37083,37099,37103,37118,37124,37154,37150,
+37155,37169,37167,37177,37187,37190,21005,22850,21154,21164,21165,21182,21759,
+21200,21206,21232,21471,29166,30669,24308,20981,20988,39727,21430,24321,30042,
+24047,22348,22441,22433,22654,22716,22725,22737,22313,22316,22314,22323,22329,
+22318,22319,22364,22331,22338,22377,22405,22379,22406,22396,22395,22376,22381,
+22390,22387,22445,22436,22412,22450,22479,22439,22452,22419,22432,22485,22488,
+22490,22489,22482,22456,22516,22511,22520,22500,22493,36467,36469,36471,36472,
+36473,36474,36475,36477,36478,36480,36482,36483,36484,36486,36488,36489,36490,
+36491,36492,36493,36494,36497,36498,36499,36501,36502,36503,36504,36505,36506,
+36507,36509,36511,36512,36513,36514,36515,36516,36517,36518,36519,36520,36521,
+36522,36525,36526,36528,36529,36531,36532,36533,36534,36535,36536,36537,36539,
+36540,36541,36542,36543,36544,36545,36546,36547,36548,36549,36550,36551,36552,
+36553,36554,36555,36556,36557,36559,36560,36561,36562,36563,36564,36565,36566,
+36567,36568,36569,36570,36571,36572,36573,36574,36575,36576,36577,36578,36579,
+36580,22539,22541,22525,22509,22528,22558,22553,22596,22560,22629,22636,22657,
+22665,22682,22656,39336,40729,25087,33401,33405,33407,
+33423,33418,33448,33412,33422,33425,33431,33433,33451,33464,33470,33456,33480,
+33482,33507,33432,33463,33454,33483,33484,33473,33449,33460,33441,33450,33439,
+33476,33486,33444,33505,33545,33527,33508,33551,33543,33500,33524,33490,33496,
+33548,33531,33491,33553,33562,33542,33556,33557,33504,33493,33564,33617,33627,
+33628,33544,33682,33596,33588,33585,33691,33630,33583,33615,33607,33603,33631,
+33600,33559,33632,33581,33594,33587,33638,33637,36581,36582,36583,36584,36585,
+36586,36587,36588,36589,36590,36591,36592,36593,36594,36595,36596,36597,36598,
+36599,36600,36601,36602,36603,36604,36605,36606,36607,36608,36609,36610,36611,
+36612,36613,36614,36615,36616,36617,36618,36619,36620,36621,36622,36623,36624,
+36625,36626,36627,36628,36629,36630,36631,36632,36633,36634,36635,36636,36637,
+36638,36639,36640,36641,36642,36643,36644,36645,36646,36647,36648,36649,36650,
+36651,36652,36653,36654,36655,36656,36657,36658,36659,36660,36661,36662,36663,
+36664,36665,36666,36667,36668,36669,36670,36671,36672,36673,36674,36675,36676,
+33640,33563,33641,33644,33642,33645,33646,33712,33656,33715,33716,33696,33706,
+33683,33692,33669,33660,33718,33705,33661,33720,33659,33688,33694,33704,33722,
+33724,33729,33793,33765,33752,22535,33816,33803,33757,33789,33750,33820,33848,
+33809,33798,33748,33759,33807,33795,33784,33785,33770,33733,33728,33830,33776,
+33761,33884,33873,33882,33881,33907,33927,33928,33914,33929,33912,33852,33862,
+33897,33910,33932,33934,33841,33901,33985,33997,34000,34022,33981,34003,33994,
+33983,33978,34016,33953,33977,33972,33943,34021,34019,
+34060,29965,34104,34032,34105,34079,34106,36677,36678,36679,36680,36681,36682,
+36683,36684,36685,36686,36687,36688,36689,36690,36691,36692,36693,36694,36695,
+36696,36697,36698,36699,36700,36701,36702,36703,36704,36705,36706,36707,36708,
+36709,36714,36736,36748,36754,36765,36768,36769,36770,36772,36773,36774,36775,
+36778,36780,36781,36782,36783,36786,36787,36788,36789,36791,36792,36794,36795,
+36796,36799,36800,36803,36806,36809,36810,36811,36812,36813,36815,36818,36822,
+36823,36826,36832,36833,36835,36839,36844,36847,36849,36850,36852,36853,36854,
+36858,36859,36860,36862,36863,36871,36872,36876,36878,36883,36885,36888,34134,
+34107,34047,34044,34137,34120,34152,34148,34142,34170,30626,34115,34162,34171,
+34212,34216,34183,34191,34169,34222,34204,34181,34233,34231,34224,34259,34241,
+34268,34303,34343,34309,34345,34326,34364,24318,24328,22844,22849,32823,22869,
+22874,22872,21263,23586,23589,23596,23604,25164,25194,25247,25275,25290,25306,
+25303,25326,25378,25334,25401,25419,25411,25517,25590,25457,25466,25486,25524,
+25453,25516,25482,25449,25518,25532,25586,25592,25568,25599,25540,25566,25550,
+25682,25542,25534,25669,25665,25611,25627,25632,25612,25638,25633,25694,25732,
+25709,25750,36889,36892,36899,36900,36901,36903,36904,36905,36906,36907,36908,
+36912,36913,36914,36915,36916,36919,36921,36922,36925,36927,36928,36931,36933,
+36934,36936,36937,36938,36939,36940,36942,36948,36949,36950,36953,36954,36956,
+36957,36958,36959,36960,36961,36964,36966,36967,36969,36970,36971,36972,36975,
+36976,36977,36978,36979,36982,36983,36984,36985,36986,
+36987,36988,36990,36993,36996,36997,36998,36999,37001,37002,37004,37005,37006,
+37007,37008,37010,37012,37014,37016,37018,37020,37022,37023,37024,37028,37029,
+37031,37032,37033,37035,37037,37042,37047,37052,37053,37055,37056,25722,25783,
+25784,25753,25786,25792,25808,25815,25828,25826,25865,25893,25902,24331,24530,
+29977,24337,21343,21489,21501,21481,21480,21499,21522,21526,21510,21579,21586,
+21587,21588,21590,21571,21537,21591,21593,21539,21554,21634,21652,21623,21617,
+21604,21658,21659,21636,21622,21606,21661,21712,21677,21698,21684,21714,21671,
+21670,21715,21716,21618,21667,21717,21691,21695,21708,21721,21722,21724,21673,
+21674,21668,21725,21711,21726,21787,21735,21792,21757,21780,21747,21794,21795,
+21775,21777,21799,21802,21863,21903,21941,21833,21869,21825,21845,21823,21840,
+21820,37058,37059,37062,37064,37065,37067,37068,37069,37074,37076,37077,37078,
+37080,37081,37082,37086,37087,37088,37091,37092,37093,37097,37098,37100,37102,
+37104,37105,37106,37107,37109,37110,37111,37113,37114,37115,37116,37119,37120,
+37121,37123,37125,37126,37127,37128,37129,37130,37131,37132,37133,37134,37135,
+37136,37137,37138,37139,37140,37141,37142,37143,37144,37146,37147,37148,37149,
+37151,37152,37153,37156,37157,37158,37159,37160,37161,37162,37163,37164,37165,
+37166,37168,37170,37171,37172,37173,37174,37175,37176,37178,37179,37180,37181,
+37182,37183,37184,37185,37186,37188,21815,21846,21877,21878,21879,21811,21808,
+21852,21899,21970,21891,21937,21945,21896,21889,21919,21886,21974,21905,21883,
+21983,21949,21950,21908,21913,21994,22007,21961,22047,
+21969,21995,21996,21972,21990,21981,21956,21999,21989,22002,22003,21964,21965,
+21992,22005,21988,36756,22046,22024,22028,22017,22052,22051,22014,22016,22055,
+22061,22104,22073,22103,22060,22093,22114,22105,22108,22092,22100,22150,22116,
+22129,22123,22139,22140,22149,22163,22191,22228,22231,22237,22241,22261,22251,
+22265,22271,22276,22282,22281,22300,24079,24089,24084,24081,24113,24123,24124,
+37189,37191,37192,37201,37203,37204,37205,37206,37208,37209,37211,37212,37215,
+37216,37222,37223,37224,37227,37229,37235,37242,37243,37244,37248,37249,37250,
+37251,37252,37254,37256,37258,37262,37263,37267,37268,37269,37270,37271,37272,
+37273,37276,37277,37278,37279,37280,37281,37284,37285,37286,37287,37288,37289,
+37291,37292,37296,37297,37298,37299,37302,37303,37304,37305,37307,37308,37309,
+37310,37311,37312,37313,37314,37315,37316,37317,37318,37320,37323,37328,37330,
+37331,37332,37333,37334,37335,37336,37337,37338,37339,37341,37342,37343,37344,
+37345,37346,37347,37348,37349,24119,24132,24148,24155,24158,24161,23692,23674,
+23693,23696,23702,23688,23704,23705,23697,23706,23708,23733,23714,23741,23724,
+23723,23729,23715,23745,23735,23748,23762,23780,23755,23781,23810,23811,23847,
+23846,23854,23844,23838,23814,23835,23896,23870,23860,23869,23916,23899,23919,
+23901,23915,23883,23882,23913,23924,23938,23961,23965,35955,23991,24005,24435,
+24439,24450,24455,24457,24460,24469,24473,24476,24488,24493,24501,24508,34914,
+24417,29357,29360,29364,29367,29368,29379,29377,29390,29389,29394,29416,29423,
+29417,29426,29428,29431,29441,29427,29443,29434,37350,
+37351,37352,37353,37354,37355,37356,37357,37358,37359,37360,37361,37362,37363,
+37364,37365,37366,37367,37368,37369,37370,37371,37372,37373,37374,37375,37376,
+37377,37378,37379,37380,37381,37382,37383,37384,37385,37386,37387,37388,37389,
+37390,37391,37392,37393,37394,37395,37396,37397,37398,37399,37400,37401,37402,
+37403,37404,37405,37406,37407,37408,37409,37410,37411,37412,37413,37414,37415,
+37416,37417,37418,37419,37420,37421,37422,37423,37424,37425,37426,37427,37428,
+37429,37430,37431,37432,37433,37434,37435,37436,37437,37438,37439,37440,37441,
+37442,37443,37444,37445,29435,29463,29459,29473,29450,29470,29469,29461,29474,
+29497,29477,29484,29496,29489,29520,29517,29527,29536,29548,29551,29566,33307,
+22821,39143,22820,22786,39267,39271,39272,39273,39274,39275,39276,39284,39287,
+39293,39296,39300,39303,39306,39309,39312,39313,39315,39316,39317,24192,24209,
+24203,24214,24229,24224,24249,24245,24254,24243,36179,24274,24273,24283,24296,
+24298,33210,24516,24521,24534,24527,24579,24558,24580,24545,24548,24574,24581,
+24582,24554,24557,24568,24601,24629,24614,24603,24591,24589,24617,24619,24586,
+24639,24609,24696,24697,24699,24698,24642,37446,37447,37448,37449,37450,37451,
+37452,37453,37454,37455,37456,37457,37458,37459,37460,37461,37462,37463,37464,
+37465,37466,37467,37468,37469,37470,37471,37472,37473,37474,37475,37476,37477,
+37478,37479,37480,37481,37482,37483,37484,37485,37486,37487,37488,37489,37490,
+37491,37493,37494,37495,37496,37497,37498,37499,37500,37501,37502,37503,37504,
+37505,37506,37507,37508,37509,37510,37511,37512,37513,
+37514,37515,37516,37517,37519,37520,37521,37522,37523,37524,37525,37526,37527,
+37528,37529,37530,37531,37532,37533,37534,37535,37536,37537,37538,37539,37540,
+37541,37542,37543,24682,24701,24726,24730,24749,24733,24707,24722,24716,24731,
+24812,24763,24753,24797,24792,24774,24794,24756,24864,24870,24853,24867,24820,
+24832,24846,24875,24906,24949,25004,24980,24999,25015,25044,25077,24541,38579,
+38377,38379,38385,38387,38389,38390,38396,38398,38403,38404,38406,38408,38410,
+38411,38412,38413,38415,38418,38421,38422,38423,38425,38426,20012,29247,25109,
+27701,27732,27740,27722,27811,27781,27792,27796,27788,27752,27753,27764,27766,
+27782,27817,27856,27860,27821,27895,27896,27889,27863,27826,27872,27862,27898,
+27883,27886,27825,27859,27887,27902,37544,37545,37546,37547,37548,37549,37551,
+37552,37553,37554,37555,37556,37557,37558,37559,37560,37561,37562,37563,37564,
+37565,37566,37567,37568,37569,37570,37571,37572,37573,37574,37575,37577,37578,
+37579,37580,37581,37582,37583,37584,37585,37586,37587,37588,37589,37590,37591,
+37592,37593,37594,37595,37596,37597,37598,37599,37600,37601,37602,37603,37604,
+37605,37606,37607,37608,37609,37610,37611,37612,37613,37614,37615,37616,37617,
+37618,37619,37620,37621,37622,37623,37624,37625,37626,37627,37628,37629,37630,
+37631,37632,37633,37634,37635,37636,37637,37638,37639,37640,37641,27961,27943,
+27916,27971,27976,27911,27908,27929,27918,27947,27981,27950,27957,27930,27983,
+27986,27988,27955,28049,28015,28062,28064,27998,28051,28052,27996,28000,28028,
+28003,28186,28103,28101,28126,28174,28095,28128,28177,
+28134,28125,28121,28182,28075,28172,28078,28203,28270,28238,28267,28338,28255,
+28294,28243,28244,28210,28197,28228,28383,28337,28312,28384,28461,28386,28325,
+28327,28349,28347,28343,28375,28340,28367,28303,28354,28319,28514,28486,28487,
+28452,28437,28409,28463,28470,28491,28532,28458,28425,28457,28553,28557,28556,
+28536,28530,28540,28538,28625,37642,37643,37644,37645,37646,37647,37648,37649,
+37650,37651,37652,37653,37654,37655,37656,37657,37658,37659,37660,37661,37662,
+37663,37664,37665,37666,37667,37668,37669,37670,37671,37672,37673,37674,37675,
+37676,37677,37678,37679,37680,37681,37682,37683,37684,37685,37686,37687,37688,
+37689,37690,37691,37692,37693,37695,37696,37697,37698,37699,37700,37701,37702,
+37703,37704,37705,37706,37707,37708,37709,37710,37711,37712,37713,37714,37715,
+37716,37717,37718,37719,37720,37721,37722,37723,37724,37725,37726,37727,37728,
+37729,37730,37731,37732,37733,37734,37735,37736,37737,37739,28617,28583,28601,
+28598,28610,28641,28654,28638,28640,28655,28698,28707,28699,28729,28725,28751,
+28766,23424,23428,23445,23443,23461,23480,29999,39582,25652,23524,23534,35120,
+23536,36423,35591,36790,36819,36821,36837,36846,36836,36841,36838,36851,36840,
+36869,36868,36875,36902,36881,36877,36886,36897,36917,36918,36909,36911,36932,
+36945,36946,36944,36968,36952,36962,36955,26297,36980,36989,36994,37000,36995,
+37003,24400,24407,24406,24408,23611,21675,23632,23641,23409,23651,23654,32700,
+24362,24361,24365,33396,24380,39739,23662,22913,22915,22925,22953,22954,22947,
+37740,37741,37742,37743,37744,37745,37746,37747,37748,
+37749,37750,37751,37752,37753,37754,37755,37756,37757,37758,37759,37760,37761,
+37762,37763,37764,37765,37766,37767,37768,37769,37770,37771,37772,37773,37774,
+37776,37777,37778,37779,37780,37781,37782,37783,37784,37785,37786,37787,37788,
+37789,37790,37791,37792,37793,37794,37795,37796,37797,37798,37799,37800,37801,
+37802,37803,37804,37805,37806,37807,37808,37809,37810,37811,37812,37813,37814,
+37815,37816,37817,37818,37819,37820,37821,37822,37823,37824,37825,37826,37827,
+37828,37829,37830,37831,37832,37833,37835,37836,37837,22935,22986,22955,22942,
+22948,22994,22962,22959,22999,22974,23045,23046,23005,23048,23011,23000,23033,
+23052,23049,23090,23092,23057,23075,23059,23104,23143,23114,23125,23100,23138,
+23157,33004,23210,23195,23159,23162,23230,23275,23218,23250,23252,23224,23264,
+23267,23281,23254,23270,23256,23260,23305,23319,23318,23346,23351,23360,23573,
+23580,23386,23397,23411,23377,23379,23394,39541,39543,39544,39546,39551,39549,
+39552,39553,39557,39560,39562,39568,39570,39571,39574,39576,39579,39580,39581,
+39583,39584,39586,39587,39589,39591,32415,32417,32419,32421,32424,32425,37838,
+37839,37840,37841,37842,37843,37844,37845,37847,37848,37849,37850,37851,37852,
+37853,37854,37855,37856,37857,37858,37859,37860,37861,37862,37863,37864,37865,
+37866,37867,37868,37869,37870,37871,37872,37873,37874,37875,37876,37877,37878,
+37879,37880,37881,37882,37883,37884,37885,37886,37887,37888,37889,37890,37891,
+37892,37893,37894,37895,37896,37897,37898,37899,37900,37901,37902,37903,37904,
+37905,37906,37907,37908,37909,37910,37911,37912,37913,
+37914,37915,37916,37917,37918,37919,37920,37921,37922,37923,37924,37925,37926,
+37927,37928,37929,37930,37931,37932,37933,37934,32429,32432,32446,32448,32449,
+32450,32457,32459,32460,32464,32468,32471,32475,32480,32481,32488,32491,32494,
+32495,32497,32498,32525,32502,32506,32507,32510,32513,32514,32515,32519,32520,
+32523,32524,32527,32529,32530,32535,32537,32540,32539,32543,32545,32546,32547,
+32548,32549,32550,32551,32554,32555,32556,32557,32559,32560,32561,32562,32563,
+32565,24186,30079,24027,30014,37013,29582,29585,29614,29602,29599,29647,29634,
+29649,29623,29619,29632,29641,29640,29669,29657,39036,29706,29673,29671,29662,
+29626,29682,29711,29738,29787,29734,29733,29736,29744,29742,29740,37935,37936,
+37937,37938,37939,37940,37941,37942,37943,37944,37945,37946,37947,37948,37949,
+37951,37952,37953,37954,37955,37956,37957,37958,37959,37960,37961,37962,37963,
+37964,37965,37966,37967,37968,37969,37970,37971,37972,37973,37974,37975,37976,
+37977,37978,37979,37980,37981,37982,37983,37984,37985,37986,37987,37988,37989,
+37990,37991,37992,37993,37994,37996,37997,37998,37999,38000,38001,38002,38003,
+38004,38005,38006,38007,38008,38009,38010,38011,38012,38013,38014,38015,38016,
+38017,38018,38019,38020,38033,38038,38040,38087,38095,38099,38100,38106,38118,
+38139,38172,38176,29723,29722,29761,29788,29783,29781,29785,29815,29805,29822,
+29852,29838,29824,29825,29831,29835,29854,29864,29865,29840,29863,29906,29882,
+38890,38891,38892,26444,26451,26462,26440,26473,26533,26503,26474,26483,26520,
+26535,26485,26536,26526,26541,26507,26487,26492,26608,
+26633,26584,26634,26601,26544,26636,26585,26549,26586,26547,26589,26624,26563,
+26552,26594,26638,26561,26621,26674,26675,26720,26721,26702,26722,26692,26724,
+26755,26653,26709,26726,26689,26727,26688,26686,26698,26697,26665,26805,26767,
+26740,26743,26771,26731,26818,26990,26876,26911,26912,26873,38183,38195,38205,
+38211,38216,38219,38229,38234,38240,38254,38260,38261,38263,38264,38265,38266,
+38267,38268,38269,38270,38272,38273,38274,38275,38276,38277,38278,38279,38280,
+38281,38282,38283,38284,38285,38286,38287,38288,38289,38290,38291,38292,38293,
+38294,38295,38296,38297,38298,38299,38300,38301,38302,38303,38304,38305,38306,
+38307,38308,38309,38310,38311,38312,38313,38314,38315,38316,38317,38318,38319,
+38320,38321,38322,38323,38324,38325,38326,38327,38328,38329,38330,38331,38332,
+38333,38334,38335,38336,38337,38338,38339,38340,38341,38342,38343,38344,38345,
+38346,38347,26916,26864,26891,26881,26967,26851,26896,26993,26937,26976,26946,
+26973,27012,26987,27008,27032,27000,26932,27084,27015,27016,27086,27017,26982,
+26979,27001,27035,27047,27067,27051,27053,27092,27057,27073,27082,27103,27029,
+27104,27021,27135,27183,27117,27159,27160,27237,27122,27204,27198,27296,27216,
+27227,27189,27278,27257,27197,27176,27224,27260,27281,27280,27305,27287,27307,
+29495,29522,27521,27522,27527,27524,27538,27539,27533,27546,27547,27553,27562,
+36715,36717,36721,36722,36723,36725,36726,36728,36727,36729,36730,36732,36734,
+36737,36738,36740,36743,36747,38348,38349,38350,38351,38352,38353,38354,38355,
+38356,38357,38358,38359,38360,38361,38362,38363,38364,
+38365,38366,38367,38368,38369,38370,38371,38372,38373,38374,38375,38380,38399,
+38407,38419,38424,38427,38430,38432,38435,38436,38437,38438,38439,38440,38441,
+38443,38444,38445,38447,38448,38455,38456,38457,38458,38462,38465,38467,38474,
+38478,38479,38481,38482,38483,38486,38487,38488,38489,38490,38492,38493,38494,
+38496,38499,38501,38502,38507,38509,38510,38511,38512,38513,38515,38520,38521,
+38522,38523,38524,38525,38526,38527,38528,38529,38530,38531,38532,38535,38537,
+38538,36749,36750,36751,36760,36762,36558,25099,25111,25115,25119,25122,25121,
+25125,25124,25132,33255,29935,29940,29951,29967,29969,29971,25908,26094,26095,
+26096,26122,26137,26482,26115,26133,26112,28805,26359,26141,26164,26161,26166,
+26165,32774,26207,26196,26177,26191,26198,26209,26199,26231,26244,26252,26279,
+26269,26302,26331,26332,26342,26345,36146,36147,36150,36155,36157,36160,36165,
+36166,36168,36169,36167,36173,36181,36185,35271,35274,35275,35276,35278,35279,
+35280,35281,29294,29343,29277,29286,29295,29310,29311,29316,29323,29325,29327,
+29330,25352,25394,25520,38540,38542,38545,38546,38547,38549,38550,38554,38555,
+38557,38558,38559,38560,38561,38562,38563,38564,38565,38566,38568,38569,38570,
+38571,38572,38573,38574,38575,38577,38578,38580,38581,38583,38584,38586,38587,
+38591,38594,38595,38600,38602,38603,38608,38609,38611,38612,38614,38615,38616,
+38617,38618,38619,38620,38621,38622,38623,38625,38626,38627,38628,38629,38630,
+38631,38635,38636,38637,38638,38640,38641,38642,38644,38645,38648,38650,38651,
+38652,38653,38655,38658,38659,38661,38666,38667,38668,
+38672,38673,38674,38676,38677,38679,38680,38681,38682,38683,38685,38687,38688,
+25663,25816,32772,27626,27635,27645,27637,27641,27653,27655,27654,27661,27669,
+27672,27673,27674,27681,27689,27684,27690,27698,25909,25941,25963,29261,29266,
+29270,29232,34402,21014,32927,32924,32915,32956,26378,32957,32945,32939,32941,
+32948,32951,32999,33000,33001,33002,32987,32962,32964,32985,32973,32983,26384,
+32989,33003,33009,33012,33005,33037,33038,33010,33020,26389,33042,35930,33078,
+33054,33068,33048,33074,33096,33100,33107,33140,33113,33114,33137,33120,33129,
+33148,33149,33133,33127,22605,23221,33160,33154,33169,28373,33187,33194,33228,
+26406,33226,33211,38689,38690,38691,38692,38693,38694,38695,38696,38697,38699,
+38700,38702,38703,38705,38707,38708,38709,38710,38711,38714,38715,38716,38717,
+38719,38720,38721,38722,38723,38724,38725,38726,38727,38728,38729,38730,38731,
+38732,38733,38734,38735,38736,38737,38740,38741,38743,38744,38746,38748,38749,
+38751,38755,38756,38758,38759,38760,38762,38763,38764,38765,38766,38767,38768,
+38769,38770,38773,38775,38776,38777,38778,38779,38781,38782,38783,38784,38785,
+38786,38787,38788,38790,38791,38792,38793,38794,38796,38798,38799,38800,38803,
+38805,38806,38807,38809,38810,38811,38812,38813,33217,33190,27428,27447,27449,
+27459,27462,27481,39121,39122,39123,39125,39129,39130,27571,24384,27586,35315,
+26000,40785,26003,26044,26054,26052,26051,26060,26062,26066,26070,28800,28828,
+28822,28829,28859,28864,28855,28843,28849,28904,28874,28944,28947,28950,28975,
+28977,29043,29020,29032,28997,29042,29002,29048,29050,
+29080,29107,29109,29096,29088,29152,29140,29159,29177,29213,29224,28780,28952,
+29030,29113,25150,25149,25155,25160,25161,31035,31040,31046,31049,31067,31068,
+31059,31066,31074,31063,31072,31087,31079,31098,31109,31114,31130,31143,31155,
+24529,24528,38814,38815,38817,38818,38820,38821,38822,38823,38824,38825,38826,
+38828,38830,38832,38833,38835,38837,38838,38839,38840,38841,38842,38843,38844,
+38845,38846,38847,38848,38849,38850,38851,38852,38853,38854,38855,38856,38857,
+38858,38859,38860,38861,38862,38863,38864,38865,38866,38867,38868,38869,38870,
+38871,38872,38873,38874,38875,38876,38877,38878,38879,38880,38881,38882,38883,
+38884,38885,38888,38894,38895,38896,38897,38898,38900,38903,38904,38905,38906,
+38907,38908,38909,38910,38911,38912,38913,38914,38915,38916,38917,38918,38919,
+38920,38921,38922,38923,38924,38925,38926,24636,24669,24666,24679,24641,24665,
+24675,24747,24838,24845,24925,25001,24989,25035,25041,25094,32896,32895,27795,
+27894,28156,30710,30712,30720,30729,30743,30744,30737,26027,30765,30748,30749,
+30777,30778,30779,30751,30780,30757,30764,30755,30761,30798,30829,30806,30807,
+30758,30800,30791,30796,30826,30875,30867,30874,30855,30876,30881,30883,30898,
+30905,30885,30932,30937,30921,30956,30962,30981,30964,30995,31012,31006,31028,
+40859,40697,40699,40700,30449,30468,30477,30457,30471,30472,30490,30498,30489,
+30509,30502,30517,30520,30544,30545,30535,30531,30554,30568,38927,38928,38929,
+38930,38931,38932,38933,38934,38935,38936,38937,38938,38939,38940,38941,38942,
+38943,38944,38945,38946,38947,38948,38949,38950,38951,
+38952,38953,38954,38955,38956,38957,38958,38959,38960,38961,38962,38963,38964,
+38965,38966,38967,38968,38969,38970,38971,38972,38973,38974,38975,38976,38977,
+38978,38979,38980,38981,38982,38983,38984,38985,38986,38987,38988,38989,38990,
+38991,38992,38993,38994,38995,38996,38997,38998,38999,39000,39001,39002,39003,
+39004,39005,39006,39007,39008,39009,39010,39011,39012,39013,39014,39015,39016,
+39017,39018,39019,39020,39021,39022,30562,30565,30591,30605,30589,30592,30604,
+30609,30623,30624,30640,30645,30653,30010,30016,30030,30027,30024,30043,30066,
+30073,30083,32600,32609,32607,35400,32616,32628,32625,32633,32641,32638,30413,
+30437,34866,38021,38022,38023,38027,38026,38028,38029,38031,38032,38036,38039,
+38037,38042,38043,38044,38051,38052,38059,38058,38061,38060,38063,38064,38066,
+38068,38070,38071,38072,38073,38074,38076,38077,38079,38084,38088,38089,38090,
+38091,38092,38093,38094,38096,38097,38098,38101,38102,38103,38105,38104,38107,
+38110,38111,38112,38114,38116,38117,38119,38120,38122,39023,39024,39025,39026,
+39027,39028,39051,39054,39058,39061,39065,39075,39080,39081,39082,39083,39084,
+39085,39086,39087,39088,39089,39090,39091,39092,39093,39094,39095,39096,39097,
+39098,39099,39100,39101,39102,39103,39104,39105,39106,39107,39108,39109,39110,
+39111,39112,39113,39114,39115,39116,39117,39119,39120,39124,39126,39127,39131,
+39132,39133,39136,39137,39138,39139,39140,39141,39142,39145,39146,39147,39148,
+39149,39150,39151,39152,39153,39154,39155,39156,39157,39158,39159,39160,39161,
+39162,39163,39164,39165,39166,39167,39168,39169,39170,
+39171,39172,39173,39174,39175,38121,38123,38126,38127,38131,38132,38133,38135,
+38137,38140,38141,38143,38147,38146,38150,38151,38153,38154,38157,38158,38159,
+38162,38163,38164,38165,38166,38168,38171,38173,38174,38175,38178,38186,38187,
+38185,38188,38193,38194,38196,38198,38199,38200,38204,38206,38207,38210,38197,
+38212,38213,38214,38217,38220,38222,38223,38226,38227,38228,38230,38231,38232,
+38233,38235,38238,38239,38237,38241,38242,38244,38245,38246,38247,38248,38249,
+38250,38251,38252,38255,38257,38258,38259,38202,30695,30700,38601,31189,31213,
+31203,31211,31238,23879,31235,31234,31262,31252,39176,39177,39178,39179,39180,
+39182,39183,39185,39186,39187,39188,39189,39190,39191,39192,39193,39194,39195,
+39196,39197,39198,39199,39200,39201,39202,39203,39204,39205,39206,39207,39208,
+39209,39210,39211,39212,39213,39215,39216,39217,39218,39219,39220,39221,39222,
+39223,39224,39225,39226,39227,39228,39229,39230,39231,39232,39233,39234,39235,
+39236,39237,39238,39239,39240,39241,39242,39243,39244,39245,39246,39247,39248,
+39249,39250,39251,39254,39255,39256,39257,39258,39259,39260,39261,39262,39263,
+39264,39265,39266,39268,39270,39283,39288,39289,39291,39294,39298,39299,39305,
+31289,31287,31313,40655,39333,31344,30344,30350,30355,30361,30372,29918,29920,
+29996,40480,40482,40488,40489,40490,40491,40492,40498,40497,40502,40504,40503,
+40505,40506,40510,40513,40514,40516,40518,40519,40520,40521,40523,40524,40526,
+40529,40533,40535,40538,40539,40540,40542,40547,40550,40551,40552,40553,40554,
+40555,40556,40561,40557,40563,30098,30100,30102,30112,
+30109,30124,30115,30131,30132,30136,30148,30129,30128,30147,30146,30166,30157,
+30179,30184,30182,30180,30187,30183,30211,30193,30204,30207,30224,30208,30213,
+30220,30231,30218,30245,30232,30229,30233,39308,39310,39322,39323,39324,39325,
+39326,39327,39328,39329,39330,39331,39332,39334,39335,39337,39338,39339,39340,
+39341,39342,39343,39344,39345,39346,39347,39348,39349,39350,39351,39352,39353,
+39354,39355,39356,39357,39358,39359,39360,39361,39362,39363,39364,39365,39366,
+39367,39368,39369,39370,39371,39372,39373,39374,39375,39376,39377,39378,39379,
+39380,39381,39382,39383,39384,39385,39386,39387,39388,39389,39390,39391,39392,
+39393,39394,39395,39396,39397,39398,39399,39400,39401,39402,39403,39404,39405,
+39406,39407,39408,39409,39410,39411,39412,39413,39414,39415,39416,39417,30235,
+30268,30242,30240,30272,30253,30256,30271,30261,30275,30270,30259,30285,30302,
+30292,30300,30294,30315,30319,32714,31462,31352,31353,31360,31366,31368,31381,
+31398,31392,31404,31400,31405,31411,34916,34921,34930,34941,34943,34946,34978,
+35014,34999,35004,35017,35042,35022,35043,35045,35057,35098,35068,35048,35070,
+35056,35105,35097,35091,35099,35082,35124,35115,35126,35137,35174,35195,30091,
+32997,30386,30388,30684,32786,32788,32790,32796,32800,32802,32805,32806,32807,
+32809,32808,32817,32779,32821,32835,32838,32845,32850,32873,32881,35203,39032,
+39040,39043,39418,39419,39420,39421,39422,39423,39424,39425,39426,39427,39428,
+39429,39430,39431,39432,39433,39434,39435,39436,39437,39438,39439,39440,39441,
+39442,39443,39444,39445,39446,39447,39448,39449,39450,
+39451,39452,39453,39454,39455,39456,39457,39458,39459,39460,39461,39462,39463,
+39464,39465,39466,39467,39468,39469,39470,39471,39472,39473,39474,39475,39476,
+39477,39478,39479,39480,39481,39482,39483,39484,39485,39486,39487,39488,39489,
+39490,39491,39492,39493,39494,39495,39496,39497,39498,39499,39500,39501,39502,
+39503,39504,39505,39506,39507,39508,39509,39510,39511,39512,39513,39049,39052,
+39053,39055,39060,39066,39067,39070,39071,39073,39074,39077,39078,34381,34388,
+34412,34414,34431,34426,34428,34427,34472,34445,34443,34476,34461,34471,34467,
+34474,34451,34473,34486,34500,34485,34510,34480,34490,34481,34479,34505,34511,
+34484,34537,34545,34546,34541,34547,34512,34579,34526,34548,34527,34520,34513,
+34563,34567,34552,34568,34570,34573,34569,34595,34619,34590,34597,34606,34586,
+34622,34632,34612,34609,34601,34615,34623,34690,34594,34685,34686,34683,34656,
+34672,34636,34670,34699,34643,34659,34684,34660,34649,34661,34707,34735,34728,
+34770,39514,39515,39516,39517,39518,39519,39520,39521,39522,39523,39524,39525,
+39526,39527,39528,39529,39530,39531,39538,39555,39561,39565,39566,39572,39573,
+39577,39590,39593,39594,39595,39596,39597,39598,39599,39602,39603,39604,39605,
+39609,39611,39613,39614,39615,39619,39620,39622,39623,39624,39625,39626,39629,
+39630,39631,39632,39634,39636,39637,39638,39639,39641,39642,39643,39644,39645,
+39646,39648,39650,39651,39652,39653,39655,39656,39657,39658,39660,39662,39664,
+39665,39666,39667,39668,39669,39670,39671,39672,39674,39676,39677,39678,39679,
+39680,39681,39682,39684,39685,39686,34758,34696,34693,
+34733,34711,34691,34731,34789,34732,34741,34739,34763,34771,34749,34769,34752,
+34762,34779,34794,34784,34798,34838,34835,34814,34826,34843,34849,34873,34876,
+32566,32578,32580,32581,33296,31482,31485,31496,31491,31492,31509,31498,31531,
+31503,31559,31544,31530,31513,31534,31537,31520,31525,31524,31539,31550,31518,
+31576,31578,31557,31605,31564,31581,31584,31598,31611,31586,31602,31601,31632,
+31654,31655,31672,31660,31645,31656,31621,31658,31644,31650,31659,31668,31697,
+31681,31692,31709,31706,31717,31718,31722,31756,31742,31740,31759,31766,31755,
+39687,39689,39690,39691,39692,39693,39694,39696,39697,39698,39700,39701,39702,
+39703,39704,39705,39706,39707,39708,39709,39710,39712,39713,39714,39716,39717,
+39718,39719,39720,39721,39722,39723,39724,39725,39726,39728,39729,39731,39732,
+39733,39734,39735,39736,39737,39738,39741,39742,39743,39744,39750,39754,39755,
+39756,39758,39760,39762,39763,39765,39766,39767,39768,39769,39770,39771,39772,
+39773,39774,39775,39776,39777,39778,39779,39780,39781,39782,39783,39784,39785,
+39786,39787,39788,39789,39790,39791,39792,39793,39794,39795,39796,39797,39798,
+39799,39800,39801,39802,39803,31775,31786,31782,31800,31809,31808,33278,33281,
+33282,33284,33260,34884,33313,33314,33315,33325,33327,33320,33323,33336,33339,
+33331,33332,33342,33348,33353,33355,33359,33370,33375,33384,34942,34949,34952,
+35032,35039,35166,32669,32671,32679,32687,32688,32690,31868,25929,31889,31901,
+31900,31902,31906,31922,31932,31933,31937,31943,31948,31949,31944,31941,31959,
+31976,33390,26280,32703,32718,32725,32741,32737,32742,
+32745,32750,32755,31992,32119,32166,32174,32327,32411,40632,40628,36211,36228,
+36244,36241,36273,36199,36205,35911,35913,37194,37200,37198,37199,37220,39804,
+39805,39806,39807,39808,39809,39810,39811,39812,39813,39814,39815,39816,39817,
+39818,39819,39820,39821,39822,39823,39824,39825,39826,39827,39828,39829,39830,
+39831,39832,39833,39834,39835,39836,39837,39838,39839,39840,39841,39842,39843,
+39844,39845,39846,39847,39848,39849,39850,39851,39852,39853,39854,39855,39856,
+39857,39858,39859,39860,39861,39862,39863,39864,39865,39866,39867,39868,39869,
+39870,39871,39872,39873,39874,39875,39876,39877,39878,39879,39880,39881,39882,
+39883,39884,39885,39886,39887,39888,39889,39890,39891,39892,39893,39894,39895,
+39896,39897,39898,39899,37218,37217,37232,37225,37231,37245,37246,37234,37236,
+37241,37260,37253,37264,37261,37265,37282,37283,37290,37293,37294,37295,37301,
+37300,37306,35925,40574,36280,36331,36357,36441,36457,36277,36287,36284,36282,
+36292,36310,36311,36314,36318,36302,36303,36315,36294,36332,36343,36344,36323,
+36345,36347,36324,36361,36349,36372,36381,36383,36396,36398,36387,36399,36410,
+36416,36409,36405,36413,36401,36425,36417,36418,36433,36434,36426,36464,36470,
+36476,36463,36468,36485,36495,36500,36496,36508,36510,35960,35970,35978,35973,
+35992,35988,26011,35286,35294,35290,35292,39900,39901,39902,39903,39904,39905,
+39906,39907,39908,39909,39910,39911,39912,39913,39914,39915,39916,39917,39918,
+39919,39920,39921,39922,39923,39924,39925,39926,39927,39928,39929,39930,39931,
+39932,39933,39934,39935,39936,39937,39938,39939,39940,
+39941,39942,39943,39944,39945,39946,39947,39948,39949,39950,39951,39952,39953,
+39954,39955,39956,39957,39958,39959,39960,39961,39962,39963,39964,39965,39966,
+39967,39968,39969,39970,39971,39972,39973,39974,39975,39976,39977,39978,39979,
+39980,39981,39982,39983,39984,39985,39986,39987,39988,39989,39990,39991,39992,
+39993,39994,39995,35301,35307,35311,35390,35622,38739,38633,38643,38639,38662,
+38657,38664,38671,38670,38698,38701,38704,38718,40832,40835,40837,40838,40839,
+40840,40841,40842,40844,40702,40715,40717,38585,38588,38589,38606,38610,30655,
+38624,37518,37550,37576,37694,37738,37834,37775,37950,37995,40063,40066,40069,
+40070,40071,40072,31267,40075,40078,40080,40081,40082,40084,40085,40090,40091,
+40094,40095,40096,40097,40098,40099,40101,40102,40103,40104,40105,40107,40109,
+40110,40112,40113,40114,40115,40116,40117,40118,40119,40122,40123,40124,40125,
+40132,40133,40134,40135,40138,40139,39996,39997,39998,39999,40000,40001,40002,
+40003,40004,40005,40006,40007,40008,40009,40010,40011,40012,40013,40014,40015,
+40016,40017,40018,40019,40020,40021,40022,40023,40024,40025,40026,40027,40028,
+40029,40030,40031,40032,40033,40034,40035,40036,40037,40038,40039,40040,40041,
+40042,40043,40044,40045,40046,40047,40048,40049,40050,40051,40052,40053,40054,
+40055,40056,40057,40058,40059,40061,40062,40064,40067,40068,40073,40074,40076,
+40079,40083,40086,40087,40088,40089,40093,40106,40108,40111,40121,40126,40127,
+40128,40129,40130,40136,40137,40145,40146,40154,40155,40160,40161,40140,40141,
+40142,40143,40144,40147,40148,40149,40151,40152,40153,
+40156,40157,40159,40162,38780,38789,38801,38802,38804,38831,38827,38819,38834,
+38836,39601,39600,39607,40536,39606,39610,39612,39617,39616,39621,39618,39627,
+39628,39633,39749,39747,39751,39753,39752,39757,39761,39144,39181,39214,39253,
+39252,39647,39649,39654,39663,39659,39675,39661,39673,39688,39695,39699,39711,
+39715,40637,40638,32315,40578,40583,40584,40587,40594,37846,40605,40607,40667,
+40668,40669,40672,40671,40674,40681,40679,40677,40682,40687,40738,40748,40751,
+40761,40759,40765,40766,40772,40163,40164,40165,40166,40167,40168,40169,40170,
+40171,40172,40173,40174,40175,40176,40177,40178,40179,40180,40181,40182,40183,
+40184,40185,40186,40187,40188,40189,40190,40191,40192,40193,40194,40195,40196,
+40197,40198,40199,40200,40201,40202,40203,40204,40205,40206,40207,40208,40209,
+40210,40211,40212,40213,40214,40215,40216,40217,40218,40219,40220,40221,40222,
+40223,40224,40225,40226,40227,40228,40229,40230,40231,40232,40233,40234,40235,
+40236,40237,40238,40239,40240,40241,40242,40243,40244,40245,40246,40247,40248,
+40249,40250,40251,40252,40253,40254,40255,40256,40257,40258,57908,57909,57910,
+57911,57912,57913,57914,57915,57916,57917,57918,57919,57920,57921,57922,57923,
+57924,57925,57926,57927,57928,57929,57930,57931,57932,57933,57934,57935,57936,
+57937,57938,57939,57940,57941,57942,57943,57944,57945,57946,57947,57948,57949,
+57950,57951,57952,57953,57954,57955,57956,57957,57958,57959,57960,57961,57962,
+57963,57964,57965,57966,57967,57968,57969,57970,57971,57972,57973,57974,57975,
+57976,57977,57978,57979,57980,57981,57982,57983,57984,
+57985,57986,57987,57988,57989,57990,57991,57992,57993,57994,57995,57996,57997,
+57998,57999,58000,58001,40259,40260,40261,40262,40263,40264,40265,40266,40267,
+40268,40269,40270,40271,40272,40273,40274,40275,40276,40277,40278,40279,40280,
+40281,40282,40283,40284,40285,40286,40287,40288,40289,40290,40291,40292,40293,
+40294,40295,40296,40297,40298,40299,40300,40301,40302,40303,40304,40305,40306,
+40307,40308,40309,40310,40311,40312,40313,40314,40315,40316,40317,40318,40319,
+40320,40321,40322,40323,40324,40325,40326,40327,40328,40329,40330,40331,40332,
+40333,40334,40335,40336,40337,40338,40339,40340,40341,40342,40343,40344,40345,
+40346,40347,40348,40349,40350,40351,40352,40353,40354,58002,58003,58004,58005,
+58006,58007,58008,58009,58010,58011,58012,58013,58014,58015,58016,58017,58018,
+58019,58020,58021,58022,58023,58024,58025,58026,58027,58028,58029,58030,58031,
+58032,58033,58034,58035,58036,58037,58038,58039,58040,58041,58042,58043,58044,
+58045,58046,58047,58048,58049,58050,58051,58052,58053,58054,58055,58056,58057,
+58058,58059,58060,58061,58062,58063,58064,58065,58066,58067,58068,58069,58070,
+58071,58072,58073,58074,58075,58076,58077,58078,58079,58080,58081,58082,58083,
+58084,58085,58086,58087,58088,58089,58090,58091,58092,58093,58094,58095,40355,
+40356,40357,40358,40359,40360,40361,40362,40363,40364,40365,40366,40367,40368,
+40369,40370,40371,40372,40373,40374,40375,40376,40377,40378,40379,40380,40381,
+40382,40383,40384,40385,40386,40387,40388,40389,40390,40391,40392,40393,40394,
+40395,40396,40397,40398,40399,40400,40401,40402,40403,
+40404,40405,40406,40407,40408,40409,40410,40411,40412,40413,40414,40415,40416,
+40417,40418,40419,40420,40421,40422,40423,40424,40425,40426,40427,40428,40429,
+40430,40431,40432,40433,40434,40435,40436,40437,40438,40439,40440,40441,40442,
+40443,40444,40445,40446,40447,40448,40449,40450,58096,58097,58098,58099,58100,
+58101,58102,58103,58104,58105,58106,58107,58108,58109,58110,58111,58112,58113,
+58114,58115,58116,58117,58118,58119,58120,58121,58122,58123,58124,58125,58126,
+58127,58128,58129,58130,58131,58132,58133,58134,58135,58136,58137,58138,58139,
+58140,58141,58142,58143,58144,58145,58146,58147,58148,58149,58150,58151,58152,
+58153,58154,58155,58156,58157,58158,58159,58160,58161,58162,58163,58164,58165,
+58166,58167,58168,58169,58170,58171,58172,58173,58174,58175,58176,58177,58178,
+58179,58180,58181,58182,58183,58184,58185,58186,58187,58188,58189,40451,40452,
+40453,40454,40455,40456,40457,40458,40459,40460,40461,40462,40463,40464,40465,
+40466,40467,40468,40469,40470,40471,40472,40473,40474,40475,40476,40477,40478,
+40484,40487,40494,40496,40500,40507,40508,40512,40525,40528,40530,40531,40532,
+40534,40537,40541,40543,40544,40545,40546,40549,40558,40559,40562,40564,40565,
+40566,40567,40568,40569,40570,40571,40572,40573,40576,40577,40579,40580,40581,
+40582,40585,40586,40588,40589,40590,40591,40592,40593,40596,40597,40598,40599,
+40600,40601,40602,40603,40604,40606,40608,40609,40610,40611,40612,40613,40615,
+40616,40617,40618,58190,58191,58192,58193,58194,58195,58196,58197,58198,58199,
+58200,58201,58202,58203,58204,58205,58206,58207,58208,
+58209,58210,58211,58212,58213,58214,58215,58216,58217,58218,58219,58220,58221,
+58222,58223,58224,58225,58226,58227,58228,58229,58230,58231,58232,58233,58234,
+58235,58236,58237,58238,58239,58240,58241,58242,58243,58244,58245,58246,58247,
+58248,58249,58250,58251,58252,58253,58254,58255,58256,58257,58258,58259,58260,
+58261,58262,58263,58264,58265,58266,58267,58268,58269,58270,58271,58272,58273,
+58274,58275,58276,58277,58278,58279,58280,58281,58282,58283,40619,40620,40621,
+40622,40623,40624,40625,40626,40627,40629,40630,40631,40633,40634,40636,40639,
+40640,40641,40642,40643,40645,40646,40647,40648,40650,40651,40652,40656,40658,
+40659,40661,40662,40663,40665,40666,40670,40673,40675,40676,40678,40680,40683,
+40684,40685,40686,40688,40689,40690,40691,40692,40693,40694,40695,40696,40698,
+40701,40703,40704,40705,40706,40707,40708,40709,40710,40711,40712,40713,40714,
+40716,40719,40721,40722,40724,40725,40726,40728,40730,40731,40732,40733,40734,
+40735,40737,40739,40740,40741,40742,40743,40744,40745,40746,40747,40749,40750,
+40752,40753,58284,58285,58286,58287,58288,58289,58290,58291,58292,58293,58294,
+58295,58296,58297,58298,58299,58300,58301,58302,58303,58304,58305,58306,58307,
+58308,58309,58310,58311,58312,58313,58314,58315,58316,58317,58318,58319,58320,
+58321,58322,58323,58324,58325,58326,58327,58328,58329,58330,58331,58332,58333,
+58334,58335,58336,58337,58338,58339,58340,58341,58342,58343,58344,58345,58346,
+58347,58348,58349,58350,58351,58352,58353,58354,58355,58356,58357,58358,58359,
+58360,58361,58362,58363,58364,58365,58366,58367,58368,
+58369,58370,58371,58372,58373,58374,58375,58376,58377,40754,40755,40756,40757,
+40758,40760,40762,40764,40767,40768,40769,40770,40771,40773,40774,40775,40776,
+40777,40778,40779,40780,40781,40782,40783,40786,40787,40788,40789,40790,40791,
+40792,40793,40794,40795,40796,40797,40798,40799,40800,40801,40802,40803,40804,
+40805,40806,40807,40808,40809,40810,40811,40812,40813,40814,40815,40816,40817,
+40818,40819,40820,40821,40822,40823,40824,40825,40826,40827,40828,40829,40830,
+40833,40834,40845,40846,40847,40848,40849,40850,40851,40852,40853,40854,40855,
+40856,40860,40861,40862,40865,40866,40867,40868,40869,63788,63865,63893,63975,
+63985,58378,58379,58380,58381,58382,58383,58384,58385,58386,58387,58388,58389,
+58390,58391,58392,58393,58394,58395,58396,58397,58398,58399,58400,58401,58402,
+58403,58404,58405,58406,58407,58408,58409,58410,58411,58412,58413,58414,58415,
+58416,58417,58418,58419,58420,58421,58422,58423,58424,58425,58426,58427,58428,
+58429,58430,58431,58432,58433,58434,58435,58436,58437,58438,58439,58440,58441,
+58442,58443,58444,58445,58446,58447,58448,58449,58450,58451,58452,58453,58454,
+58455,58456,58457,58458,58459,58460,58461,58462,58463,58464,58465,58466,58467,
+58468,58469,58470,58471,64012,64013,64014,64015,64017,64019,64020,64024,64031,
+64032,64033,64035,64036,64039,64040,64041,11905,59414,59415,59416,11908,13427,
+13383,11912,11915,59422,13726,13850,13838,11916,11927,14702,14616,59430,14799,
+14815,14963,14800,59435,59436,15182,15470,15584,11943,59441,59442,11946,16470,
+16735,11950,17207,11955,11958,11959,59451,17329,17324,
+11963,17373,17622,18017,17996,59459,18211,18217,18300,18317,11978,18759,18810,
+18813,18818,18819,18821,18822,18847,18843,18871,18870,59476,59477,19619,19615,
+19616,19617,19575,19618,19731,19732,19733,19734,19735,19736,19737,19886,59492,
+58472,58473,58474,58475,58476,58477,58478,58479,58480,58481,58482,58483,58484,
+58485,58486,58487,58488,58489,58490,58491,58492,58493,58494,58495,58496,58497,
+58498,58499,58500,58501,58502,58503,58504,58505,58506,58507,58508,58509,58510,
+58511,58512,58513,58514,58515,58516,58517,58518,58519,58520,58521,58522,58523,
+58524,58525,58526,58527,58528,58529,58530,58531,58532,58533,58534,58535,58536,
+58537,58538,58539,58540,58541,58542,58543,58544,58545,58546,58547,58548,58549,
+58550,58551,58552,58553,58554,58555,58556,58557,58558,58559,58560,58561,58562,
+58563,58564,58565,
libc/musl/src/locale/hkscs.h
@@ -0,0 +1,390 @@
+17392,19506,17923,17830,17784,29287,19831,17843,31921,19682,31941,15253,18230,
+18244,19527,19520,17087,13847,29522,28299,28882,19543,41809,18255,17882,19589,
+31852,19719,19108,18081,27427,29221,23124,6755,15878,16225,26189,22267,0,
+32149,22813,35769,15860,38708,31727,23515,7518,23204,13861,40624,23249,23479,
+23804,26478,34195,39237,29793,29853,14453,7507,13982,24609,16108,22750,15093,
+31484,40855,16737,35085,12778,2698,12894,17162,33924,40854,37935,18736,34323,
+22678,38730,37400,31184,31282,26208,27177,34973,29772,31685,26498,31276,21071,
+36934,13542,29636,23993,29894,40903,22451,18735,21580,16689,13966,22552,31346,
+31589,35727,18094,28296,16769,23961,31662,9404,40904,9409,9417,9420,40905,
+34052,13755,16564,40906,17633,44543,25281,28782,40907,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,12736,12737,12738,12739,12740,268,12741,
+209,205,12742,12743,203,8168,12744,202,12745,12746,12747,12748,270,12749,
+12750,256,193,461,192,274,201,282,200,332,211,465,210,56320,7870,56324,7872,
+202,257,225,462,224,593,275,233,283,232,299,237,464,236,333,243,466,242,363,
+250,468,249,470,472,474,476,252,56328,7871,56332,7873,234,609,9178,9179,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,41897,4421,0,25866,0,0,20029,28381,
+40270,37343,0,0,30517,25745,20250,20264,20392,20822,20852,20892,20964,21153,
+21160,21307,21326,21457,21464,22242,22768,22788,22791,22834,22836,23398,23454,
+23455,23706,24198,24635,25993,26622,26628,26725,27982,28860,30005,32420,32428,
+32442,32455,32463,32479,32518,32567,33402,33487,33647,35270,35774,35810,36710,
+36711,36718,29713,31996,32205,26950,31433,21031,0,0,0,0,37260,30904,37214,
+32956,0,36107,33014,2535,0,0,32927,40647,19661,40393,40460,19518,40438,28686,
+40458,41267,13761,0,28314,33342,29977,0,18705,39532,39567,40857,31111,33900,
+7626,1488,10982,20004,20097,20096,20103,20159,20203,20279,13388,20413,15944,
+20483,20616,13437,13459,13477,20870,22789,20955,20988,20997,20105,21113,21136,
+21287,13767,21417,13649,21424,13651,21442,21539,13677,13682,13953,21651,21667,
+21684,21689,21712,21743,21784,21795,21800,13720,21823,13733,13759,21975,13765,
+32132,21797,0,3138,3349,20779,21904,11462,14828,833,36422,19896,38117,16467,
+32958,30586,11320,14900,18389,33117,27122,19946,25821,3452,4020,3285,4340,
+25741,36478,3734,3083,3940,11433,33366,17619,0,3398,39501,33001,18420,
+20135,11458,39602,14951,38388,16365,13574,21191,38868,30920,11588,40302,38933,
+0,17369,24741,25780,21731,11596,11210,4215,14843,4207,26330,26390,31136,25834,
+20562,3139,36456,8609,35660,1841,0,18443,425,16378,22643,11661,0,17864,1276,
+24727,3916,3478,21881,16571,17338,0,19124,10854,4253,33194,39157,3484,25465,
+14846,10101,36288,22177,25724,15939,0,42497,3593,10959,11465,0,4296,14786,
+14738,14854,33435,13688,24137,8391,22098,3889,11442,38688,13500,27709,20027,0,
+0,30068,11915,8712,42587,36045,3706,3124,26652,32659,4303,10243,10553,13819,
+20963,3724,3981,3754,16275,3888,3399,4431,3660,0,3755,2985,3400,4288,4413,
+16377,9878,25650,4013,13300,30265,11214,3454,3455,11345,11349,14872,3736,4295,
+3886,42546,27472,36050,36249,36042,38314,21708,33476,21945,0,40643,39974,
+39606,30558,11758,28992,33133,33004,23580,25970,33076,14231,21343,32957,37302,
+3834,3599,3703,3835,13789,19947,13833,3286,22191,10165,4297,3600,3704,4216,
+4424,33287,5205,3705,20048,11684,23124,4125,4126,4341,4342,22428,3601,30356,
+33485,4021,3707,20862,14083,4022,4480,21208,41661,18906,6202,16759,33404,
+22681,21096,13850,22333,31666,23400,18432,19244,40743,18919,39967,39821,23412,
+12605,22011,13810,22153,20008,22786,7105,63608,38737,134,20059,20155,13630,
+23587,24401,24516,14586,25164,25909,27514,27701,27706,28780,29227,20012,29357,
+18665,32594,31035,31993,32595,25194,13505,0,25419,32770,32896,26130,26961,
+21341,34916,35265,30898,35744,36125,38021,38264,38271,38376,
+36367,38886,39029,39118,39134,39267,38928,40060,40479,40644,27503,63751,20023,
+135,38429,25143,38050,0,20539,28158,40051,40870,15817,34959,16718,28791,23797,
+19232,20941,13657,23856,24866,35378,36775,37366,29073,26393,29626,12929,41223,
+15499,6528,19216,30948,29698,20910,34575,16393,27235,41658,16931,34319,2671,
+31274,39239,35562,38741,28749,21284,8318,37876,30425,35299,40871,30685,20131,
+20464,20668,20015,20247,40872,21556,32139,22674,22736,7606,24210,24217,24514,
+10002,25995,13305,26905,27203,15459,27903,0,29184,17669,29580,16091,18963,
+23317,29881,35715,23716,22165,31379,31724,31939,32364,33528,34199,40873,34960,
+40874,36537,40875,36815,34143,39392,37409,40876,36281,5183,16497,17058,23066,
+0,0,0,39016,26475,17014,22333,0,34262,18811,33471,28941,19585,28020,23931,
+27413,28606,40877,40878,23446,40879,26343,32347,28247,31178,15752,17603,12886,
+10134,17306,17718,0,23765,15130,35577,23672,15634,13649,23928,40882,29015,
+17752,16620,7715,19575,14712,13386,420,27713,35532,20404,569,22975,33132,
+38998,39162,24379,2975,0,8641,35181,16642,18107,36985,16135,40883,41397,16632,
+14294,18167,27718,16764,34482,29695,17773,14548,21658,17761,17691,19849,19579,
+19830,17898,16328,19215,13921,17630,17597,16877,23870,23880,23894,15868,14351,
+23972,23993,14368,14392,24130,24253,24357,24451,14600,14612,14655,14669,24791,
+24893,23781,14729,25015,25017,25039,14776,25132,25232,25317,25368,14840,22193,
+14851,25570,25595,25607,25690,14923,25792,23829,22049,40863,14999,25990,15037,
+26111,26195,15090,26258,15138,
+26390,15170,26532,26624,15192,26698,26756,15218,15217,15227,26889,26947,29276,
+26980,27039,27013,15292,27094,15325,27237,27252,27249,27266,15340,27289,15346,
+27307,27317,27348,27382,27521,27585,27626,27765,27818,15563,27906,27910,27942,
+28033,15599,28068,28081,28181,28184,28201,28294,35264,28347,28386,28378,40831,
+28392,28393,28452,28468,15686,16193,28545,28606,15722,15733,29111,23705,15754,
+28716,15761,28752,28756,28783,28799,28809,805,17345,13809,3800,16087,22462,
+28371,28990,22496,13902,27042,35817,23412,31305,22753,38105,31333,31357,22956,
+31419,31408,31426,31427,29137,25741,16842,31450,31453,31466,16879,21682,23553,
+31499,31573,31529,21262,23806,31650,31599,33692,23476,27775,31696,33825,31634,
+0,23840,15789,23653,33938,31738,0,31797,23745,31812,31875,18562,31910,26237,
+17784,31945,31943,31974,31860,31987,31989,0,32359,17693,28228,32093,28374,
+29837,32137,32171,28981,32179,0,16471,24617,32228,15635,32245,6137,32229,
+33645,0,24865,24922,32366,32402,17195,37996,32295,32576,32577,32583,31030,
+25296,39393,32663,25425,32675,5729,104,17756,14182,17667,33594,32762,25737,0,
+32776,32797,0,32815,41095,27843,32827,32828,32865,10004,18825,26150,15843,
+26344,26405,32935,35400,33031,33050,22704,9974,27775,25752,20408,25831,5258,
+33304,6238,27219,19045,19093,17530,33321,2829,27218,15742,20473,5373,34018,
+33634,27402,18855,13616,6003,15864,33450,26907,63892,16859,34123,33488,33562,
+3606,6068,14017,12669,13658,33403,33506,33560,16011,28067,27397,27543,13774,
+15807,33565,21996,33669,17675,28069,33708,
+0,33747,13438,28372,27223,34138,13462,28226,12015,33880,23524,33905,15827,
+17636,27303,33866,15541,31064,0,27542,28279,28227,34014,0,33681,17568,33939,
+34020,23697,16960,23744,17731,34100,23282,28313,17703,34163,17686,26559,34326,
+34341,34363,34241,28808,34306,5506,28877,63922,17770,34344,13896,6306,21495,
+29594,34430,34673,41208,34798,11303,34737,34778,34831,22113,34412,26710,17935,
+34885,34886,30176,15801,30180,34910,34972,18011,34996,34997,25537,35013,30583,
+30479,35207,35210,0,0,35239,35260,35365,35303,31012,31421,35484,30611,37374,
+35472,31321,31465,31546,16271,18195,31544,29052,35596,35615,21552,21861,35647,
+35660,35661,35497,19066,35728,35739,35503,5855,17941,34895,35995,32084,32143,
+63956,14117,32083,36054,32152,32189,36114,36099,6416,36059,28764,36113,19657,
+16080,0,36265,32770,4116,18826,15228,33212,28940,31463,36525,36534,36547,
+37588,36633,36653,33637,33810,36773,37635,41631,2640,36787,18730,35294,34109,
+15803,24312,12898,36857,40980,34492,34049,8997,14720,28375,36919,34108,31422,
+36961,34156,34315,37032,34579,37060,34534,37038,0,37223,15088,37289,37316,
+31916,35123,7817,37390,27807,37441,37474,21945,0,35526,15515,35596,21979,3377,
+37676,37739,35553,35819,28815,23235,35554,35557,18789,37444,35820,35897,35839,
+37747,37979,36540,38277,38310,37926,38304,28662,17081,9850,34520,4732,15918,
+18911,27676,38523,38550,16748,38563,28373,25050,38582,30965,35552,38589,21452,
+18849,27832,628,25616,37039,37093,19153,6421,13066,38705,34370,38710,18959,
+17725,17797,19177,28789,23361,38683,
+0,37333,38743,23370,37355,38751,37925,20688,12471,12476,38793,38815,38833,
+38846,38848,38866,38880,21612,38894,29724,37939,0,38901,37917,31098,19153,
+38964,38963,38987,39014,15118,29045,15697,1584,16732,22278,39114,39095,39112,
+39111,19199,27943,5843,21936,39137,39142,39148,37752,39225,18985,19314,38999,
+39173,39413,39436,39483,39440,39512,22309,14020,37041,39893,39648,39650,39685,
+39668,19470,39700,39725,34304,20532,39732,27048,14531,12413,39760,39744,40254,
+23109,6243,39822,16971,39938,39935,39948,40552,40404,40887,41362,41387,41185,
+41251,41439,40318,40323,41268,40462,26760,40388,8539,41363,41504,6459,41523,
+40249,41145,41652,40592,40597,40606,40610,19764,40618,40623,17252,40641,15200,
+14821,15645,20274,14270,35883,40706,40712,19350,37924,28066,40727,0,40761,
+22175,22154,40773,39352,37003,38898,33919,40802,40809,31452,40846,29206,19390,
+18805,18875,29047,18936,17224,19025,29598,35802,6394,31135,35198,36406,37737,
+37875,35396,37612,37761,37835,35180,17593,29207,16107,30578,31299,28880,17523,
+17400,29054,6127,28835,6334,13721,16071,6277,21551,6136,14114,5883,6201,14049,
+6004,6353,24395,14115,5824,22363,18981,5118,4776,5062,5302,34051,13990,0,
+33877,18836,29029,15921,21852,16123,28754,17652,14062,39325,28454,26617,14131,
+15381,15847,22636,6434,26640,16471,14143,16609,16523,16655,27681,21707,22174,
+26289,22162,4063,2984,3597,37830,35603,37788,20216,20779,14361,17462,20156,
+1125,895,20299,20362,22097,23144,427,971,14745,778,1044,13365,20265,704,36531,
+629,35546,524,20120,20685,
+20749,20386,20227,18958,16010,20290,20526,20588,20609,20428,20453,20568,20732,
+0,0,0,0,28278,13717,15929,16063,28018,6276,16009,20904,20931,1504,17629,1187,
+1170,1169,36218,35484,1806,21081,21156,2163,21217,0,18042,29068,17292,3104,
+18860,4324,27089,3613,0,16094,29849,29716,29782,29592,19342,19132,16525,21456,
+13700,29199,16585,21940,837,21709,3014,22301,37469,38644,37734,22493,22413,
+22399,13886,22731,23193,35398,5882,5999,5904,23084,22968,37519,23166,23247,
+23058,22854,6643,6241,17045,14069,27909,29763,23073,24195,23169,35799,1043,
+37856,29836,4867,28933,18802,37896,35323,37821,14240,23582,23710,24158,24136,
+6550,6524,15086,24269,23375,6403,6404,14081,6304,14045,5886,14035,33066,35399,
+7610,13426,35240,24332,24334,6439,6059,23147,5947,23364,34324,30205,34912,
+24702,10336,9771,24539,16056,9647,9662,37000,28531,25024,62,70,9755,24985,
+24984,24693,11419,11527,18132,37197,25713,18021,11114,14889,11042,13392,39146,
+11896,25399,42075,25782,25393,25553,18915,11623,25252,11425,25659,25963,26994,
+15348,12430,12973,18825,12971,21773,13024,6361,37951,26318,12937,12723,15072,
+16784,21892,35618,21903,5884,21851,21541,30958,12547,6186,12852,13412,12815,
+12674,17097,26254,27940,26219,19347,26160,30832,7659,26211,13010,13025,26142,
+22642,14545,14394,14268,15257,14242,13310,29904,15254,26511,17962,26806,26654,
+15300,27326,14435,14293,17543,27187,27218,27337,27397,6418,25873,26776,27212,
+15319,27258,27479,16320,15514,37792,37618,35818,35531,37513,32798,35292,37991,
+28069,28427,
+18924,0,16255,15759,28164,16444,23101,28170,22599,27940,30786,28987,17178,
+17014,28913,29264,29319,29332,18319,18213,20857,19108,1515,29818,16120,13919,
+19018,18711,24545,16134,16049,19167,35875,16181,24743,16115,29900,29756,37767,
+29751,17567,28138,17745,30083,16227,19673,19718,16216,30037,30323,42438,15129,
+29800,35532,18859,18830,15099,15821,19022,16127,18885,18675,37370,22322,37698,
+35555,6244,20703,21025,20967,30584,12850,30478,30479,30587,18071,14209,14942,
+18672,29752,29851,16063,19130,19143,16584,19094,25006,37639,21889,30750,30861,
+30856,30930,29648,31065,30529,22243,16654,0,33942,31141,27181,16122,31290,
+31220,16750,5862,16690,37429,31217,3404,18828,665,15802,5998,13719,21867,
+13680,13994,468,3085,31458,23129,9973,23215,23196,23053,603,30960,23082,23494,
+31486,16889,31837,31853,16913,23475,24252,24230,31949,18937,6064,31886,31868,
+31918,27314,32220,32263,32211,32590,25185,24924,31560,32151,24194,17002,27509,
+2326,26582,78,13775,22468,25618,25592,18786,32733,31527,2092,23273,23875,
+31500,24078,39398,34373,39523,27164,13375,14818,18935,26029,39455,26016,33920,
+28967,27857,17642,33079,17410,32966,33033,33090,26548,39107,27202,33378,33381,
+27217,33875,28071,34320,29211,23174,16767,6208,23339,6305,23268,6360,34464,
+63932,15759,34861,29730,23042,34926,20293,34951,35007,35046,35173,35149,22147,
+35156,30597,30596,35829,35801,35740,35321,16045,33955,18165,18127,14322,35389,
+35356,37960,24397,37419,17028,26068,28969,28868,6213,40301,35999,36073,32220,
+22938,30659,23024,17262,14036,36394,36519,19465,
+36656,36682,17140,27736,28603,8993,18587,28537,28299,6106,39913,14005,18735,
+37051,0,21873,18694,37307,37892,35403,16482,35580,37927,35869,35899,34021,
+35371,38297,38311,38295,38294,36148,29765,16066,18687,19010,17386,16103,12837,
+38543,36583,36454,36453,16076,18925,19064,16366,29714,29803,16124,38721,37040,
+26695,18973,37011,22495,0,37736,35209,35878,35631,25534,37562,23313,35689,
+18748,29689,16923,38811,38769,39224,3878,24001,35781,19122,38943,38106,37622,
+38359,37349,17600,35664,19047,35684,39132,35397,16128,37418,18725,33812,39227,
+39245,31494,15869,39323,19311,39338,39516,35685,22728,27279,39457,23294,39471,
+39153,19344,39240,39356,19389,19351,37757,22642,4866,22562,18872,5352,30788,
+10015,15800,26821,15741,37976,14631,24912,10113,10603,24839,40015,40019,40059,
+39989,39952,39807,39887,40493,39839,41461,41214,40225,19630,16644,40472,19632,
+40204,41396,41197,41203,39215,40357,33981,28178,28639,27522,34300,17715,28068,
+28292,28144,33824,34286,28160,14295,24676,31202,13724,13888,18733,18910,15714,
+37851,37566,37704,703,30905,37495,37965,20452,13376,36964,21853,30781,30804,
+30902,30795,5975,12745,18753,13978,20338,28634,28633,0,28702,21524,16821,
+22459,22771,22410,40214,22487,28980,13487,16812,29163,27712,20375,0,6069,
+35401,24844,23246,23051,17084,17544,14124,19323,35324,37819,37816,6358,3869,
+33906,27840,5139,17146,11302,17345,22932,15799,26433,32168,24923,24740,18873,
+18827,35322,37605,29666,16105,29876,35683,6303,16097,19123,27352,29683,29691,
+16086,19006,19092,6105,19046,935,5156,18917,29768,
+18710,28837,18806,37508,29670,37727,1278,37681,35534,35350,37766,35815,21973,
+18741,35458,29035,18755,3327,22180,1562,3051,3256,21762,31172,6138,32254,5826,
+19024,6226,17710,37889,14090,35520,18861,22960,6335,6275,29828,23201,14050,
+15707,14000,37471,23161,35457,6242,37748,15565,2740,19094,14730,20724,15721,
+15692,5020,29045,17147,33304,28175,37092,17643,27991,32335,28775,27823,15574,
+16365,15917,28162,28428,15727,1013,30033,14012,13512,18048,16090,18545,22980,
+37486,18750,36673,35868,27584,22546,22472,14038,5202,28926,17250,19057,12259,
+4784,9149,26809,26983,5016,13541,31732,14047,35459,14294,13306,19615,27162,
+13997,27831,33854,17631,17614,27942,27985,27778,28638,28439,28937,33597,5946,
+33773,27776,28755,6107,22921,23170,6067,23137,23153,6405,16892,14125,23023,
+5948,14023,29070,37776,26266,17061,23150,23083,17043,27179,16121,30518,17499,
+17098,28957,16985,35297,20400,27944,23746,17614,32333,17341,27148,16982,4868,
+28838,28979,17385,15781,27871,63525,19023,32357,23019,23855,15859,24412,19037,
+6111,32164,33830,21637,15098,13056,532,22398,2261,1561,16357,8094,41654,28675,
+37211,23920,29583,31955,35417,37920,20424,32743,29389,29456,31476,29496,29497,
+22262,29505,29512,16041,31512,36972,29173,18674,29665,33270,16074,30476,16081,
+27810,22269,29721,29726,29727,16098,16112,16116,16122,29907,16142,16211,30018,
+30061,30066,30093,16252,30152,30172,16320,30285,16343,30324,16348,30330,20316,
+29064,22051,35200,22633,16413,30531,16441,26465,16453,13787,30616,16490,16495,
+23646,30654,30667,22770,30744,28857,30748,
+16552,30777,30791,30801,30822,33864,21813,31027,26627,31026,16643,16649,31121,
+31129,36795,31238,36796,16743,31377,16818,31420,33401,16836,31439,31451,16847,
+20001,31586,31596,31611,31762,31771,16992,17018,31867,31900,17036,31928,17044,
+31981,36755,28864,3279,32207,32212,32208,32253,32686,32692,29343,17303,32800,
+32805,31545,32814,32817,32852,15820,22452,28832,32951,33001,17389,33036,29482,
+33038,33042,30048,33044,17409,15161,33110,33113,33114,17427,22586,33148,33156,
+17445,33171,17453,33189,22511,33217,33252,33364,17551,33446,33398,33482,33496,
+33535,17584,33623,38505,27018,33797,28917,33892,24803,33928,17668,33982,34017,
+34040,34064,34104,34130,17723,34159,34160,34272,17783,34418,34450,34482,34543,
+38469,34699,17926,17943,34990,35071,35108,35143,35217,31079,35369,35384,35476,
+35508,35921,36052,36082,36124,18328,22623,36291,18413,20206,36410,21976,22356,
+36465,22005,36528,18487,36558,36578,36580,36589,36594,36791,36801,36810,36812,
+36915,39364,18605,39136,37395,18718,37416,37464,37483,37553,37550,37567,37603,
+37611,37619,37620,37629,37699,37764,37805,18757,18769,40639,37911,21249,37917,
+37933,37950,18794,37972,38009,38189,38306,18855,38388,38451,18917,26528,18980,
+38720,18997,38834,38850,22100,19172,24808,39097,19225,39153,22596,39182,39193,
+20916,39196,39223,39234,39261,39266,19312,39365,19357,39484,39695,31363,39785,
+39809,39901,39921,39924,19565,39968,14191,7106,40265,39994,40702,22096,40339,
+40381,40384,40444,38134,36790,40571,40620,40625,40637,40646,38108,40674,40689,
+40696,31432,40772,148,695,928,26906,38083,22956,
+1239,22592,38081,14265,1493,1557,1654,5818,22359,29043,2754,2765,3007,21610,
+63547,3019,21662,3067,3131,3155,3173,3196,24807,3213,22138,3253,3293,3309,
+3439,3506,3528,26965,39983,34725,3588,3598,3799,3984,3885,3699,23584,4028,
+24075,4188,4175,4214,26398,4219,4232,4246,13895,4287,4307,4399,4411,21348,
+33965,4835,4981,4918,35713,5495,5657,6083,6087,20088,28859,6189,6506,6701,
+6725,7210,7280,7340,7880,25283,7893,7957,29080,26709,8261,27113,14024,8828,
+9175,9210,10026,10353,10575,33533,10599,10643,10965,35237,10984,36768,11022,
+38840,11071,38983,39613,11340,0,11400,11447,23528,11528,11538,11703,11669,
+11842,12148,12236,12339,12390,13087,13278,24497,26184,26303,31353,13671,13811,
+0,18874,0,13850,14102,0,838,22709,26382,26904,15015,30295,24546,15889,16057,
+30206,8346,18640,19128,16665,35482,17134,17165,16443,17204,17302,19013,1482,
+20946,1553,22943,7848,15294,15615,17412,17622,22408,18036,14747,18223,34280,
+39369,14178,8643,35678,35662,0,18450,18683,18965,29193,19136,3192,22885,20133,
+20358,1913,36570,20524,21135,22335,29041,21145,21529,16202,19111,21948,21574,
+21614,27474,0,13427,21823,30258,21854,18200,21858,21862,22471,18751,22621,
+20582,13563,13260,0,22787,18300,35144,23214,23433,23558,7568,22433,29009,0,
+24834,31762,36950,25010,20378,35682,25602,25674,23899,27639,0,25732,6428,
+35562,18934,25736,16367,25874,19392,26047,26293,10011,37989,22497,24981,23079,
+63693,0,22201,17697,26364,20074,18740,38486,28047,27837,13848,35191,
+26521,26734,25617,26718,0,26823,31554,37056,2577,26918,0,26937,31301,0,27130,
+39462,27181,13919,25705,33,31107,27188,27483,23852,13593,0,27549,18128,27812,
+30011,34917,28078,22710,14108,9613,28747,29133,15444,29312,29317,37505,8570,
+29323,37680,29414,18896,27705,38047,29776,3832,34855,35061,10534,33907,6065,
+28344,18986,6176,14756,14009,0,0,17727,26294,40109,39076,35139,30668,30808,
+22230,16607,5642,14753,14127,33000,5061,29101,33638,31197,37288,0,19639,28847,
+35243,31229,31242,31499,32102,16762,31555,31102,32777,28597,41695,27139,33560,
+21410,28167,37823,26678,38749,33135,32803,27061,5101,12847,32840,23941,35888,
+32899,22293,38947,35145,23979,18824,26046,27093,21458,19109,16257,15377,26422,
+32912,33012,33070,8097,33103,33161,33199,33306,33542,33583,33674,13770,33896,
+34474,18682,25574,35158,30728,37461,35256,17394,35303,17375,35304,35654,35796,
+23032,35849,0,36805,37100,0,37136,37180,15863,37214,19146,36816,29327,22155,
+38119,38377,38320,38328,38706,39121,39241,39274,39363,39464,39694,40282,40347,
+32415,40696,40739,19620,38215,41619,29090,41727,19857,36882,42443,19868,3228,
+36798,21953,36794,9392,36793,19091,17673,32383,28502,27313,20202,13540,35628,
+30877,14138,36480,6133,32804,35692,35737,31294,26287,15851,30293,15543,22069,
+22870,20122,24193,25176,22207,3693,36366,23405,16008,19614,25566,0,6134,6267,
+25904,22061,23626,21530,21265,15814,40344,19581,22050,22046,32585,24280,22901,
+15680,34672,19996,4074,3401,14010,33047,40286,36120,30267,40005,30286,30649,
+37701,21554,
+33096,33527,22053,33074,33816,32957,21994,31074,22083,21526,3741,13774,22021,
+22001,26353,33506,13869,30004,22000,21946,21655,21874,3137,3222,24272,20808,
+3702,11362,3746,40619,32090,21982,4213,25245,38765,21652,36045,29174,37238,
+25596,25529,25598,21865,11075,40050,11955,20890,13535,3495,20903,21581,21790,
+21779,30310,36397,26762,30129,32950,34820,34694,35015,33206,33820,4289,17644,
+29444,18182,23440,33547,26771,22139,9972,32047,16803,32115,28368,29366,37232,
+4569,37384,15612,42665,3756,3833,29286,7330,18254,20418,32761,4075,16634,
+40029,25887,11680,18675,18400,40316,4076,3594,0,30115,4077,0,24648,4487,29091,
+32398,40272,19994,19972,13687,23309,27826,21351,13996,14812,21373,13989,17944,
+22682,19310,33325,21579,22442,23189,2425,0,14930,9317,29556,40620,19721,39917,
+15614,40752,19547,20393,38302,40926,33884,15798,29362,26547,14112,25390,32037,
+16119,15916,14890,36872,21196,15988,13946,17897,1166,30272,23280,3766,30842,
+32558,22695,16575,22140,39819,23924,30292,42036,40581,19681,0,14331,24857,
+12506,17394,0,22109,4777,22439,18787,40454,21044,28846,13741,0,40316,31830,
+39737,22494,5996,23635,25811,38096,25397,29028,34477,3368,27938,19170,3441,0,
+20990,7951,23950,38659,7633,40577,36940,31519,39682,23761,31651,25192,25397,
+39679,31695,39722,31870,0,31810,31878,39957,31740,39689,0,39963,18750,40794,
+21875,23491,20477,40600,20466,21088,15878,21201,22375,20566,22967,24082,38856,
+40363,36700,21609,38836,39232,38842,21292,24880,26924,21466,39946,40194,19515,
+38465,27008,20646,
+30022,5997,39386,21107,0,37209,38529,37212,0,37201,36503,25471,27939,27338,
+22033,37262,30074,25221,1020,29519,31856,23585,15613,0,18713,30422,39837,
+20010,3284,33726,34882,0,23626,27072,0,22394,21023,24053,20174,27697,498,
+20281,21660,21722,21146,36226,13822,0,13811,0,27474,37244,40869,39831,38958,
+39092,39610,40616,40580,29050,31508,0,27642,34840,32632,0,22048,42570,36471,
+40787,0,36308,36431,40476,36353,25218,33661,36392,36469,31443,19063,31294,
+30936,27882,35431,30215,35418,40742,27854,34774,30147,41650,30803,63552,36108,
+29410,29553,35629,29442,29937,36075,19131,34351,24506,34976,17591,0,6203,
+28165,0,35454,9499,0,24829,30311,39639,40260,37742,39823,34805,0,0,36087,
+29484,38689,39856,13782,29362,19463,31825,39242,24921,24921,19460,40598,24957,
+0,22367,24943,25254,25145,0,14940,25058,21418,13301,25444,26626,13778,23895,
+35778,36826,36409,0,20697,7494,30982,21298,38456,3899,16485,0,30718,0,31938,
+24346,31962,31277,32870,32867,32077,29957,29938,35220,33306,26380,32866,29830,
+32859,29936,33027,30500,35209,26572,30035,28369,34729,34766,33224,34700,35401,
+36013,35651,30507,29944,34010,13877,27058,36262,0,35241,0,28089,34753,16401,
+29927,15835,29046,24740,24988,15569,0,24695,0,32625,35629,0,24809,19326,21024,
+15384,15559,24279,30294,21809,6468,4862,39171,28124,28845,23745,25005,35343,
+13943,238,26694,20238,17762,23327,25420,40784,40614,25195,1351,37595,1503,
+16325,34124,17077,29679,20917,13897,18754,35300,37700,6619,
+33518,15560,30780,26436,25311,18739,35242,672,27571,4869,20395,9453,20488,
+27945,31364,13824,19121,9491,0,894,24484,896,839,28379,1055,0,20737,13434,
+20750,39020,14147,33814,18852,1159,20832,13236,20842,3071,8444,741,9520,1422,
+12851,6531,23426,34685,1459,15513,20914,20920,40244,20937,20943,20945,15580,
+20947,19110,20915,20962,21314,20973,33741,26942,14125,24443,21003,21030,21052,
+21173,21079,21140,21177,21189,31765,34114,21216,34317,27411,0,35550,21833,
+28377,16256,2388,16364,21299,0,3042,27851,5926,26651,29653,24650,16042,14540,
+5864,29149,17570,21357,21364,34475,21374,0,5526,5651,30694,21395,35483,21408,
+21419,21422,29607,22386,16217,29596,21441,21445,27721,20041,22526,21465,15019,
+2959,21472,16363,11683,21494,3191,21523,28793,21803,26199,27995,21613,27475,
+3444,21853,21647,21668,18342,5901,3805,15796,3405,35260,9880,21831,19693,
+21551,29719,21894,21929,0,6359,16442,17746,17461,26291,4276,22071,26317,12938,
+26276,26285,22093,22095,30961,22257,38791,21502,22272,22255,22253,35686,13859,
+4687,22342,16805,27758,28811,22338,14001,27774,22502,5142,22531,5204,17251,
+22566,19445,22620,22698,13665,22752,22748,4668,22779,23551,22339,41296,17016,
+37843,13729,22815,26790,14019,28249,5694,23076,21843,5778,34053,22985,3406,
+27777,27946,6108,23001,6139,6066,28070,28017,6184,5845,23033,28229,23211,
+23139,14054,18857,0,14088,23190,29797,23251,28577,9556,15749,6417,14130,5816,
+24195,21200,23414,25992,23420,31246,16388,18525,516,23509,24928,6708,22988,
+1445,23539,
+23453,19728,23557,6980,23571,29646,23572,7333,27432,23625,18653,23685,23785,
+23791,23947,7673,7735,23824,23832,23878,7844,23738,24023,33532,14381,18689,
+8265,8563,33415,14390,15298,24110,27274,0,24186,17596,3283,21414,20151,0,
+21416,6001,24073,24308,33922,24313,24315,14496,24316,26686,37915,24333,449,
+63636,15070,18606,4922,24378,26760,9168,0,9329,24419,38845,28270,24434,37696,
+35382,24487,23990,15711,21072,8042,28920,9832,37334,670,35369,24625,26245,
+6263,14691,15815,13881,22416,10164,31089,15936,24734,0,24755,18818,18831,
+31315,29860,20705,23200,24932,33828,24898,63654,28370,24961,20980,1622,24967,
+23466,16311,10335,25043,35741,39261,25040,14642,10624,10433,24611,24924,25886,
+25483,280,25285,6000,25301,11789,25452,18911,14871,25656,25592,5006,6140,0,
+28554,11830,38932,16524,22301,25825,25829,38011,14950,25658,14935,25933,28438,
+18984,18979,25989,25965,25951,12414,26037,18752,19255,26065,16600,6185,26080,
+26083,24543,13312,26136,12791,12792,26180,12708,12709,26187,3701,26215,20966,
+26227,0,7741,12849,34292,12744,21267,30661,10487,39332,26370,17308,18977,
+15147,27130,14274,0,26471,26466,16845,37101,26583,17641,26658,28240,37436,
+26625,13286,28064,26717,13423,27105,27147,35551,26995,26819,13773,26881,26880,
+15666,14849,13884,15232,26540,26977,35402,17148,26934,27032,15265,969,33635,
+20624,27129,13913,8490,27205,14083,27293,15347,26545,27336,37276,15373,27421,
+2339,24798,27445,27508,10189,28341,15067,949,6488,14144,21537,15194,27617,
+16124,27612,27703,9355,18673,27473,
+27738,33318,27769,15804,17605,15805,16804,18700,18688,15561,14053,15595,3378,
+39811,12793,9361,32655,26679,27941,28065,28139,28054,27996,28284,28420,18815,
+16517,28274,34099,28532,20935,0,0,33838,35617,0,15919,29779,16258,31180,28239,
+23185,12363,28664,14093,28573,15920,28410,5271,16445,17749,37872,28484,28508,
+15694,28532,37232,15675,28575,16708,28627,16529,16725,16441,16368,16308,16703,
+20959,16726,16727,16704,25053,28747,28798,28839,28801,28876,28885,28886,28895,
+16644,15848,29108,29078,17015,28971,28997,23176,29002,0,23708,17253,29007,
+37730,17089,28972,17498,18983,18978,29114,35816,28861,29198,37954,29205,22801,
+37955,29220,37697,22021,29230,29248,18804,26813,29269,29271,15957,12356,26637,
+28477,29314,0,29483,18467,34859,18669,34820,29480,29486,29647,29610,3130,
+27182,29641,29769,16866,5863,18980,26147,14021,18871,18829,18939,29687,29717,
+26883,18982,29753,1475,16087,0,10413,29792,36530,29767,29668,29814,33721,
+29804,14128,29812,37873,27180,29826,18771,19084,16735,19065,35727,23366,35843,
+6302,29896,6536,29966,0,29982,36569,6731,23511,36524,37765,30029,30026,30055,
+30062,20354,16132,19731,30094,29789,30110,30132,30210,30252,30289,30287,30319,
+30326,25589,30352,33263,14328,26897,26894,30369,30373,30391,30412,28575,33890,
+20637,20861,7708,30494,30502,30528,25775,21024,30552,12972,30639,35172,35176,
+5825,30708,0,4982,18962,26826,30895,30919,30931,38565,31022,21984,30935,31028,
+30897,30220,36792,34948,35627,24707,9756,31110,35072,26882,31104,22615,31133,
+31545,31036,31145,28202,28966,
+16040,31174,37133,31188,1312,17503,21007,47234,248,16384,43296,1102,0,0,2868,
+1,0,0,0,0,0,0,0,3072,64,0,0,0,1024,88,60,0,0,23680,56493,48115,17353,60910,
+4004,49446,30363,61426,64478,63482,12815,44868,61438,65277,24593,176,8448,
+33049,4128,43144,8544,9321,17408,50313,0,16387,53,33859,20785,26771,514,0,0,0,
+0,0,16384,256,44160,33380,35904,37025,20484,54368,53760,6186,26781,38709,
+55375,8440,33476,10268,30082,660,16440,41376,4293,19825,3524,47512,23390,
+17153,39327,30723,57888,2079,393,16585,775,39437,21136,20433,892,8450,49184,
+4974,46467,62939,30693,20368,39447,5942,12,47726,12041,21600,7680,26744,28706,
+40534,62245,46990,2839,59119,6007,7003,4289,36248,6162,53174,12545,6770,11355,
+49334,57888,23747,7042,56032,34254,16598,21673,53259,18447,16452,2320,16596,
+15278,7780,11076,2071,33414,6198,35232,40167,2139,900,55810,60560,34779,49029,
+44450,36509,39069,9504,70,40774,58239,51669,62596,19926,58118,6326,2322,0,
+1024,0,32,0,512,0,0,0,0,8192,0,0,0,0,0,0,8,36352,28280,16223,56702,63293,
+39932,44796,65490,27535,59377,47807,28334,61207,42972,46654,30645,37577,42455,
+19126,39790,33209,26445,21758,39921,65122,21103,14039,49150,17705,63873,26045,
+17062,57,16896,36704,37888,16448,45010,53719,219,39072,31666,20998,38944,
+51222,2365,0,1,0,2561,2226,128,0,34820,5152,19472,0,4,17569,16,321,
+2048,61504,20447,22582,62961,32949,26613,16512,20480,16718,33992,23040,55392,
+11009,20481,5793,16580,28402,44049,14624,49348,1800,2316,38552,39876,7184,
+27800,10886,422,4422,58733,50379,37568,8464,4630,29341,27124,5902,41514,62593,
+123,41992,36875,11280,14796,330,5872,2571,3136,59933,17420,17678,2,
libc/musl/src/locale/iconv.c
@@ -0,0 +1,685 @@
+#include <iconv.h>
+#include <errno.h>
+#include <wchar.h>
+#include <string.h>
+#include <stdlib.h>
+#include <limits.h>
+#include <stdint.h>
+#include "locale_impl.h"
+
+#define UTF_32BE    0300
+#define UTF_16LE    0301
+#define UTF_16BE    0302
+#define UTF_32LE    0303
+#define UCS2BE      0304
+#define UCS2LE      0305
+#define WCHAR_T     0306
+#define US_ASCII    0307
+#define UTF_8       0310
+#define UTF_16      0312
+#define UTF_32      0313
+#define UCS2        0314
+#define EUC_JP      0320
+#define SHIFT_JIS   0321
+#define ISO2022_JP  0322
+#define GB18030     0330
+#define GBK         0331
+#define GB2312      0332
+#define BIG5        0340
+#define EUC_KR      0350
+
+/* Definitions of charmaps. Each charmap consists of:
+ * 1. Empty-string-terminated list of null-terminated aliases.
+ * 2. Special type code or number of elided quads of entries.
+ * 3. Character table (size determined by field 2), consisting
+ *    of 5 bytes for every 4 characters, interpreted as 10-bit
+ *    indices into the legacy_chars table. */
+
+static const unsigned char charmaps[] =
+"utf8\0char\0\0\310"
+"wchart\0\0\306"
+"ucs2be\0\0\304"
+"ucs2le\0\0\305"
+"utf16be\0\0\302"
+"utf16le\0\0\301"
+"ucs4be\0utf32be\0\0\300"
+"ucs4le\0utf32le\0\0\303"
+"ascii\0usascii\0iso646\0iso646us\0\0\307"
+"utf16\0\0\312"
+"ucs4\0utf32\0\0\313"
+"ucs2\0\0\314"
+"eucjp\0\0\320"
+"shiftjis\0sjis\0\0\321"
+"iso2022jp\0\0\322"
+"gb18030\0\0\330"
+"gbk\0\0\331"
+"gb2312\0\0\332"
+"big5\0bigfive\0cp950\0big5hkscs\0\0\340"
+"euckr\0ksc5601\0ksx1001\0cp949\0\0\350"
+#include "codepages.h"
+;
+
+/* Table of characters that appear in legacy 8-bit codepages,
+ * limited to 1024 slots (10 bit indices). The first 256 entries
+ * are elided since those characters are obviously all included. */
+static const unsigned short legacy_chars[] = {
+#include "legacychars.h"
+};
+
+static const unsigned short jis0208[84][94] = {
+#include "jis0208.h"
+};
+
+static const unsigned short gb18030[126][190] = {
+#include "gb18030.h"
+};
+
+static const unsigned short big5[89][157] = {
+#include "big5.h"
+};
+
+static const unsigned short hkscs[] = {
+#include "hkscs.h"
+};
+
+static const unsigned short ksc[93][94] = {
+#include "ksc.h"
+};
+
+static const unsigned short rev_jis[] = {
+#include "revjis.h"
+};
+
+static int fuzzycmp(const unsigned char *a, const unsigned char *b)
+{
+	for (; *a && *b; a++, b++) {
+		while (*a && (*a|32U)-'a'>26 && *a-'0'>10U) a++;
+		if ((*a|32U) != *b) return 1;
+	}
+	return *a != *b;
+}
+
+static size_t find_charmap(const void *name)
+{
+	const unsigned char *s;
+	if (!*(char *)name) name=charmaps; /* "utf8" */
+	for (s=charmaps; *s; ) {
+		if (!fuzzycmp(name, s)) {
+			for (; *s; s+=strlen((void *)s)+1);
+			return s+1-charmaps;
+		}
+		s += strlen((void *)s)+1;
+		if (!*s) {
+			if (s[1] > 0200) s+=2;
+			else s+=2+(64U-s[1])*5;
+		}
+	}
+	return -1;
+}
+
+struct stateful_cd {
+	iconv_t base_cd;
+	unsigned state;
+};
+
+static iconv_t combine_to_from(size_t t, size_t f)
+{
+	return (void *)(f<<16 | t<<1 | 1);
+}
+
+static size_t extract_from(iconv_t cd)
+{
+	return (size_t)cd >> 16;
+}
+
+static size_t extract_to(iconv_t cd)
+{
+	return (size_t)cd >> 1 & 0x7fff;
+}
+
+iconv_t iconv_open(const char *to, const char *from)
+{
+	size_t f, t;
+	struct stateful_cd *scd;
+
+	if ((t = find_charmap(to))==-1
+	 || (f = find_charmap(from))==-1
+	 || (charmaps[t] >= 0330)) {
+		errno = EINVAL;
+		return (iconv_t)-1;
+	}
+	iconv_t cd = combine_to_from(t, f);
+
+	switch (charmaps[f]) {
+	case UTF_16:
+	case UTF_32:
+	case UCS2:
+	case ISO2022_JP:
+		scd = malloc(sizeof *scd);
+		if (!scd) return (iconv_t)-1;
+		scd->base_cd = cd;
+		scd->state = 0;
+		cd = (iconv_t)scd;
+	}
+
+	return cd;
+}
+
+static unsigned get_16(const unsigned char *s, int e)
+{
+	e &= 1;
+	return s[e]<<8 | s[1-e];
+}
+
+static void put_16(unsigned char *s, unsigned c, int e)
+{
+	e &= 1;
+	s[e] = c>>8;
+	s[1-e] = c;
+}
+
+static unsigned get_32(const unsigned char *s, int e)
+{
+	e &= 3;
+	return s[e]+0U<<24 | s[e^1]<<16 | s[e^2]<<8 | s[e^3];
+}
+
+static void put_32(unsigned char *s, unsigned c, int e)
+{
+	e &= 3;
+	s[e^0] = c>>24;
+	s[e^1] = c>>16;
+	s[e^2] = c>>8;
+	s[e^3] = c;
+}
+
+/* Adapt as needed */
+#define mbrtowc_utf8 mbrtowc
+#define wctomb_utf8 wctomb
+
+static unsigned legacy_map(const unsigned char *map, unsigned c)
+{
+	if (c < 4*map[-1]) return c;
+	unsigned x = c - 4*map[-1];
+	x = map[x*5/4]>>2*x%8 | map[x*5/4+1]<<8-2*x%8 & 1023;
+	return x < 256 ? x : legacy_chars[x-256];
+}
+
+static unsigned uni_to_jis(unsigned c)
+{
+	unsigned nel = sizeof rev_jis / sizeof *rev_jis;
+	unsigned d, j, i, b = 0;
+	for (;;) {
+		i = nel/2;
+		j = rev_jis[b+i];
+		d = jis0208[j/256][j%256];
+		if (d==c) return j + 0x2121;
+		else if (nel == 1) return 0;
+		else if (c < d)
+			nel /= 2;
+		else {
+			b += i;
+			nel -= nel/2;
+		}
+	}
+}
+
+size_t iconv(iconv_t cd, char **restrict in, size_t *restrict inb, char **restrict out, size_t *restrict outb)
+{
+	size_t x=0;
+	struct stateful_cd *scd=0;
+	if (!((size_t)cd & 1)) {
+		scd = (void *)cd;
+		cd = scd->base_cd;
+	}
+	unsigned to = extract_to(cd);
+	unsigned from = extract_from(cd);
+	const unsigned char *map = charmaps+from+1;
+	const unsigned char *tomap = charmaps+to+1;
+	mbstate_t st = {0};
+	wchar_t wc;
+	unsigned c, d;
+	size_t k, l;
+	int err;
+	unsigned char type = map[-1];
+	unsigned char totype = tomap[-1];
+	locale_t *ploc = &CURRENT_LOCALE, loc = *ploc;
+
+	if (!in || !*in || !*inb) return 0;
+
+	*ploc = UTF8_LOCALE;
+
+	for (; *inb; *in+=l, *inb-=l) {
+		c = *(unsigned char *)*in;
+		l = 1;
+
+		switch (type) {
+		case UTF_8:
+			if (c < 128) break;
+			l = mbrtowc_utf8(&wc, *in, *inb, &st);
+			if (l == (size_t)-1) goto ilseq;
+			if (l == (size_t)-2) goto starved;
+			c = wc;
+			break;
+		case US_ASCII:
+			if (c >= 128) goto ilseq;
+			break;
+		case WCHAR_T:
+			l = sizeof(wchar_t);
+			if (*inb < l) goto starved;
+			c = *(wchar_t *)*in;
+			if (0) {
+		case UTF_32BE:
+		case UTF_32LE:
+			l = 4;
+			if (*inb < 4) goto starved;
+			c = get_32((void *)*in, type);
+			}
+			if (c-0xd800u < 0x800u || c >= 0x110000u) goto ilseq;
+			break;
+		case UCS2BE:
+		case UCS2LE:
+		case UTF_16BE:
+		case UTF_16LE:
+			l = 2;
+			if (*inb < 2) goto starved;
+			c = get_16((void *)*in, type);
+			if ((unsigned)(c-0xdc00) < 0x400) goto ilseq;
+			if ((unsigned)(c-0xd800) < 0x400) {
+				if (type-UCS2BE < 2U) goto ilseq;
+				l = 4;
+				if (*inb < 4) goto starved;
+				d = get_16((void *)(*in + 2), type);
+				if ((unsigned)(d-0xdc00) >= 0x400) goto ilseq;
+				c = ((c-0xd7c0)<<10) + (d-0xdc00);
+			}
+			break;
+		case UCS2:
+		case UTF_16:
+			l = 0;
+			if (!scd->state) {
+				if (*inb < 2) goto starved;
+				c = get_16((void *)*in, 0);
+				scd->state = type==UCS2
+					? c==0xfffe ? UCS2LE : UCS2BE
+					: c==0xfffe ? UTF_16LE : UTF_16BE;
+				if (c == 0xfffe || c == 0xfeff)
+					l = 2;
+			}
+			type = scd->state;
+			continue;
+		case UTF_32:
+			l = 0;
+			if (!scd->state) {
+				if (*inb < 4) goto starved;
+				c = get_32((void *)*in, 0);
+				scd->state = c==0xfffe0000 ? UTF_32LE : UTF_32BE;
+				if (c == 0xfffe0000 || c == 0xfeff)
+					l = 4;
+			}
+			type = scd->state;
+			continue;
+		case SHIFT_JIS:
+			if (c < 128) break;
+			if (c-0xa1 <= 0xdf-0xa1) {
+				c += 0xff61-0xa1;
+				break;
+			}
+			l = 2;
+			if (*inb < 2) goto starved;
+			d = *((unsigned char *)*in + 1);
+			if (c-129 <= 159-129) c -= 129;
+			else if (c-224 <= 239-224) c -= 193;
+			else goto ilseq;
+			c *= 2;
+			if (d-64 <= 158-64) {
+				if (d==127) goto ilseq;
+				if (d>127) d--;
+				d -= 64;
+			} else if (d-159 <= 252-159) {
+				c++;
+				d -= 159;
+			}
+			c = jis0208[c][d];
+			if (!c) goto ilseq;
+			break;
+		case EUC_JP:
+			if (c < 128) break;
+			l = 2;
+			if (*inb < 2) goto starved;
+			d = *((unsigned char *)*in + 1);
+			if (c==0x8e) {
+				c = d;
+				if (c-0xa1 > 0xdf-0xa1) goto ilseq;
+				c += 0xff61 - 0xa1;
+				break;
+			}
+			c -= 0xa1;
+			d -= 0xa1;
+			if (c >= 84 || d >= 94) goto ilseq;
+			c = jis0208[c][d];
+			if (!c) goto ilseq;
+			break;
+		case ISO2022_JP:
+			if (c >= 128) goto ilseq;
+			if (c == '\033') {
+				l = 3;
+				if (*inb < 3) goto starved;
+				c = *((unsigned char *)*in + 1);
+				d = *((unsigned char *)*in + 2);
+				if (c != '(' && c != '$') goto ilseq;
+				switch (128*(c=='$') + d) {
+				case 'B': scd->state=0; continue;
+				case 'J': scd->state=1; continue;
+				case 'I': scd->state=4; continue;
+				case 128+'@': scd->state=2; continue;
+				case 128+'B': scd->state=3; continue;
+				}
+				goto ilseq;
+			}
+			switch (scd->state) {
+			case 1:
+				if (c=='\\') c = 0xa5;
+				if (c=='~') c = 0x203e;
+				break;
+			case 2:
+			case 3:
+				l = 2;
+				if (*inb < 2) goto starved;
+				d = *((unsigned char *)*in + 1);
+				c -= 0x21;
+				d -= 0x21;
+				if (c >= 84 || d >= 94) goto ilseq;
+				c = jis0208[c][d];
+				if (!c) goto ilseq;
+				break;
+			case 4:
+				if (c-0x60 < 0x1f) goto ilseq;
+				if (c-0x21 < 0x5e) c += 0xff61-0x21;
+				break;
+			}
+			break;
+		case GB2312:
+			if (c < 128) break;
+			if (c < 0xa1) goto ilseq;
+		case GBK:
+		case GB18030:
+			if (c < 128) break;
+			c -= 0x81;
+			if (c >= 126) goto ilseq;
+			l = 2;
+			if (*inb < 2) goto starved;
+			d = *((unsigned char *)*in + 1);
+			if (d < 0xa1 && type == GB2312) goto ilseq;
+			if (d-0x40>=191 || d==127) {
+				if (d-'0'>9 || type != GB18030)
+					goto ilseq;
+				l = 4;
+				if (*inb < 4) goto starved;
+				c = (10*c + d-'0') * 1260;
+				d = *((unsigned char *)*in + 2);
+				if (d-0x81>126) goto ilseq;
+				c += 10*(d-0x81);
+				d = *((unsigned char *)*in + 3);
+				if (d-'0'>9) goto ilseq;
+				c += d-'0';
+				c += 128;
+				for (d=0; d<=c; ) {
+					k = 0;
+					for (int i=0; i<126; i++)
+						for (int j=0; j<190; j++)
+							if (gb18030[i][j]-d <= c-d)
+								k++;
+					d = c+1;
+					c += k;
+				}
+				break;
+			}
+			d -= 0x40;
+			if (d>63) d--;
+			c = gb18030[c][d];
+			break;
+		case BIG5:
+			if (c < 128) break;
+			l = 2;
+			if (*inb < 2) goto starved;
+			d = *((unsigned char *)*in + 1);
+			if (d-0x40>=0xff-0x40 || d-0x7f<0xa1-0x7f) goto ilseq;
+			d -= 0x40;
+			if (d > 0x3e) d -= 0x22;
+			if (c-0xa1>=0xfa-0xa1) {
+				if (c-0x87>=0xff-0x87) goto ilseq;
+				if (c < 0xa1) c -= 0x87;
+				else c -= 0x87 + (0xfa-0xa1);
+				c = (hkscs[4867+(c*157+d)/16]>>(c*157+d)%16)%2<<17
+					| hkscs[c*157+d];
+				/* A few HKSCS characters map to pairs of UCS
+				 * characters. These are mapped to surrogate
+				 * range in the hkscs table then hard-coded
+				 * here. Ugly, yes. */
+				if (c/256 == 0xdc) {
+					union {
+						char c[8];
+						wchar_t wc[2];
+					} tmp;
+					char *ptmp = tmp.c;
+					size_t tmpx = iconv(combine_to_from(to, find_charmap("utf8")),
+						&(char *){"\303\212\314\204"
+						"\303\212\314\214"
+						"\303\252\314\204"
+						"\303\252\314\214"
+						+c%256}, &(size_t){4},
+						&ptmp, &(size_t){sizeof tmp});
+					size_t tmplen = ptmp - tmp.c;
+					if (tmplen > *outb) goto toobig;
+					if (tmpx) x++;
+					memcpy(*out, &tmp, tmplen);
+					*out += tmplen;
+					*outb -= tmplen;
+					continue;
+				}
+				if (!c) goto ilseq;
+				break;
+			}
+			c -= 0xa1;
+			c = big5[c][d]|(c==0x27&&(d==0x3a||d==0x3c||d==0x42))<<17;
+			if (!c) goto ilseq;
+			break;
+		case EUC_KR:
+			if (c < 128) break;
+			l = 2;
+			if (*inb < 2) goto starved;
+			d = *((unsigned char *)*in + 1);
+			c -= 0xa1;
+			d -= 0xa1;
+			if (c >= 93 || d >= 94) {
+				c += (0xa1-0x81);
+				d += 0xa1;
+				if (c >= 93 || c>=0xc6-0x81 && d>0x52)
+					goto ilseq;
+				if (d-'A'<26) d = d-'A';
+				else if (d-'a'<26) d = d-'a'+26;
+				else if (d-0x81<0xff-0x81) d = d-0x81+52;
+				else goto ilseq;
+				if (c < 0x20) c = 178*c + d;
+				else c = 178*0x20 + 84*(c-0x20) + d;
+				c += 0xac00;
+				for (d=0xac00; d<=c; ) {
+					k = 0;
+					for (int i=0; i<93; i++)
+						for (int j=0; j<94; j++)
+							if (ksc[i][j]-d <= c-d)
+								k++;
+					d = c+1;
+					c += k;
+				}
+				break;
+			}
+			c = ksc[c][d];
+			if (!c) goto ilseq;
+			break;
+		default:
+			if (!c) break;
+			c = legacy_map(map, c);
+			if (!c) goto ilseq;
+		}
+
+		switch (totype) {
+		case WCHAR_T:
+			if (*outb < sizeof(wchar_t)) goto toobig;
+			*(wchar_t *)*out = c;
+			*out += sizeof(wchar_t);
+			*outb -= sizeof(wchar_t);
+			break;
+		case UTF_8:
+			if (*outb < 4) {
+				char tmp[4];
+				k = wctomb_utf8(tmp, c);
+				if (*outb < k) goto toobig;
+				memcpy(*out, tmp, k);
+			} else k = wctomb_utf8(*out, c);
+			*out += k;
+			*outb -= k;
+			break;
+		case US_ASCII:
+			if (c > 0x7f) subst: x++, c='*';
+		default:
+			if (*outb < 1) goto toobig;
+			if (c<256 && c==legacy_map(tomap, c)) {
+			revout:
+				if (*outb < 1) goto toobig;
+				*(*out)++ = c;
+				*outb -= 1;
+				break;
+			}
+			d = c;
+			for (c=4*totype; c<256; c++) {
+				if (d == legacy_map(tomap, c)) {
+					goto revout;
+				}
+			}
+			goto subst;
+		case SHIFT_JIS:
+			if (c < 128) goto revout;
+			if (c == 0xa5) {
+				x++;
+				c = '\\';
+				goto revout;
+			}
+			if (c == 0x203e) {
+				x++;
+				c = '~';
+				goto revout;
+			}
+			if (c-0xff61 <= 0xdf-0xa1) {
+				c += 0xa1 - 0xff61;
+				goto revout;
+			}
+			c = uni_to_jis(c);
+			if (!c) goto subst;
+			if (*outb < 2) goto toobig;
+			d = c%256;
+			c = c/256;
+			*(*out)++ = (c+1)/2 + (c<95 ? 112 : 176);
+			*(*out)++ = c%2 ? d + 31 + d/96 : d + 126;
+			*outb -= 2;
+			break;
+		case EUC_JP:
+			if (c < 128) goto revout;
+			if (c-0xff61 <= 0xdf-0xa1) {
+				c += 0x0e00 + 0x21 - 0xff61;
+			} else {
+				c = uni_to_jis(c);
+			}
+			if (!c) goto subst;
+			if (*outb < 2) goto toobig;
+			*(*out)++ = c/256 + 0x80;
+			*(*out)++ = c%256 + 0x80;
+			*outb -= 2;
+			break;
+		case ISO2022_JP:
+			if (c < 128) goto revout;
+			if (c-0xff61 <= 0xdf-0xa1 || c==0xa5 || c==0x203e) {
+				if (*outb < 7) goto toobig;
+				*(*out)++ = '\033';
+				*(*out)++ = '(';
+				if (c==0xa5) {
+					*(*out)++ = 'J';
+					*(*out)++ = '\\';
+				} else if (c==0x203e) {
+					*(*out)++ = 'J';
+					*(*out)++ = '~';
+				} else {
+					*(*out)++ = 'I';
+					*(*out)++ = c-0xff61+0x21;
+				}
+				*(*out)++ = '\033';
+				*(*out)++ = '(';
+				*(*out)++ = 'B';
+				*outb -= 7;
+				break;
+			}
+			c = uni_to_jis(c);
+			if (!c) goto subst;
+			if (*outb < 8) goto toobig;
+			*(*out)++ = '\033';
+			*(*out)++ = '$';
+			*(*out)++ = 'B';
+			*(*out)++ = c/256;
+			*(*out)++ = c%256;
+			*(*out)++ = '\033';
+			*(*out)++ = '(';
+			*(*out)++ = 'B';
+			*outb -= 8;
+			break;
+		case UCS2:
+			totype = UCS2BE;
+		case UCS2BE:
+		case UCS2LE:
+		case UTF_16:
+		case UTF_16BE:
+		case UTF_16LE:
+			if (c < 0x10000 || totype-UCS2BE < 2U) {
+				if (c >= 0x10000) c = 0xFFFD;
+				if (*outb < 2) goto toobig;
+				put_16((void *)*out, c, totype);
+				*out += 2;
+				*outb -= 2;
+				break;
+			}
+			if (*outb < 4) goto toobig;
+			c -= 0x10000;
+			put_16((void *)*out, (c>>10)|0xd800, totype);
+			put_16((void *)(*out + 2), (c&0x3ff)|0xdc00, totype);
+			*out += 4;
+			*outb -= 4;
+			break;
+		case UTF_32:
+			totype = UTF_32BE;
+		case UTF_32BE:
+		case UTF_32LE:
+			if (*outb < 4) goto toobig;
+			put_32((void *)*out, c, totype);
+			*out += 4;
+			*outb -= 4;
+			break;
+		}
+	}
+	*ploc = loc;
+	return x;
+ilseq:
+	err = EILSEQ;
+	x = -1;
+	goto end;
+toobig:
+	err = E2BIG;
+	x = -1;
+	goto end;
+starved:
+	err = EINVAL;
+	x = -1;
+end:
+	errno = err;
+	*ploc = loc;
+	return x;
+}
libc/musl/src/locale/iconv_close.c
@@ -0,0 +1,8 @@
+#include <iconv.h>
+#include <stdlib.h>
+
+int iconv_close(iconv_t cd)
+{
+	if (!((size_t)cd & 1)) free((void *)cd);
+	return 0;
+}
libc/musl/src/locale/jis0208.h
@@ -0,0 +1,563 @@
+12288,12289,12290,65292,65294,12539,65306,65307,65311,65281,12443,12444,180,
+65344,168,65342,65507,65343,12541,12542,12445,12446,12291,20189,12293,12294,
+12295,12540,8213,8208,65295,92,12316,8214,65372,8230,8229,8216,8217,8220,8221,
+65288,65289,12308,12309,65339,65341,65371,65373,12296,12297,12298,12299,12300,
+12301,12302,12303,12304,12305,65291,8722,177,215,247,65309,8800,65308,65310,
+8806,8807,8734,8756,9794,9792,176,8242,8243,8451,65509,65284,162,163,65285,
+65283,65286,65290,65312,167,9734,9733,9675,9679,9678,9671,9670,9633,9632,9651,
+9650,9661,9660,8251,12306,8594,8592,8593,8595,12307,0,0,0,0,0,0,0,0,0,0,0,
+8712,8715,8838,8839,8834,8835,8746,8745,0,0,0,0,0,0,0,0,8743,8744,172,8658,
+8660,8704,8707,0,0,0,0,0,0,0,0,0,0,0,8736,8869,8978,8706,8711,8801,8786,8810,
+8811,8730,8765,8733,8757,8747,8748,0,0,0,0,0,0,0,8491,8240,9839,9837,9834,
+8224,8225,182,0,0,0,0,9711,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,65296,65297,65298,
+65299,65300,65301,65302,65303,65304,65305,0,0,0,0,0,0,0,65313,65314,65315,
+65316,65317,65318,65319,65320,65321,65322,65323,65324,65325,65326,65327,65328,
+65329,65330,65331,65332,65333,65334,65335,65336,65337,65338,0,0,0,0,0,0,65345,
+65346,65347,
+65348,65349,65350,65351,65352,65353,65354,65355,65356,65357,65358,65359,65360,
+65361,65362,65363,65364,65365,65366,65367,65368,65369,65370,0,0,0,0,12353,
+12354,12355,12356,12357,12358,12359,12360,12361,12362,12363,12364,12365,12366,
+12367,12368,12369,12370,12371,12372,12373,12374,12375,12376,12377,12378,12379,
+12380,12381,12382,12383,12384,12385,12386,12387,12388,12389,12390,12391,12392,
+12393,12394,12395,12396,12397,12398,12399,12400,12401,12402,12403,12404,12405,
+12406,12407,12408,12409,12410,12411,12412,12413,12414,12415,12416,12417,12418,
+12419,12420,12421,12422,12423,12424,12425,12426,12427,12428,12429,12430,12431,
+12432,12433,12434,12435,0,0,0,0,0,0,0,0,0,0,0,12449,12450,12451,12452,12453,
+12454,12455,12456,12457,12458,12459,12460,12461,12462,12463,12464,12465,12466,
+12467,12468,12469,12470,12471,12472,12473,12474,12475,12476,12477,12478,12479,
+12480,12481,12482,12483,12484,12485,12486,12487,12488,12489,12490,12491,12492,
+12493,12494,12495,12496,12497,12498,12499,12500,12501,12502,12503,12504,12505,
+12506,12507,12508,12509,12510,12511,12512,12513,12514,12515,12516,12517,12518,
+12519,12520,12521,12522,12523,12524,12525,12526,12527,12528,12529,12530,12531,
+12532,12533,12534,0,0,0,0,0,0,0,0,913,914,915,916,917,918,919,920,921,922,923,
+924,925,926,927,928,929,931,932,933,934,935,936,937,0,0,0,0,0,0,0,0,945,946,
+947,948,949,950,951,952,953,
+954,955,956,957,958,959,960,961,963,964,965,966,967,968,969,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1040,1041,1042,1043,
+1044,1045,1025,1046,1047,1048,1049,1050,1051,1052,1053,1054,1055,1056,1057,
+1058,1059,1060,1061,1062,1063,1064,1065,1066,1067,1068,1069,1070,1071,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,1072,1073,1074,1075,1076,1077,1105,1078,1079,1080,1081,
+1082,1083,1084,1085,1086,1087,1088,1089,1090,1091,1092,1093,1094,1095,1096,
+1097,1098,1099,1100,1101,1102,1103,0,0,0,0,0,0,0,0,0,0,0,0,0,9472,9474,9484,
+9488,9496,9492,9500,9516,9508,9524,9532,9473,9475,9487,9491,9499,9495,9507,
+9523,9515,9531,9547,9504,9519,9512,9527,9535,9501,9520,9509,9528,9538,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,20124,21782,23043,38463,21696,24859,25384,23030,
+36898,33909,33564,31312,24746,25569,28197,26093,33894,33446,39925,26771,22311,
+26017,25201,23451,22992,34427,39156,32098,32190,39822,25110,31903,34999,23433,
+24245,25353,26263,26696,38343,38797,26447,20197,20234,20301,20381,20553,22258,
+22839,22996,23041,23561,24799,24847,24944,26131,26885,28858,30031,30064,31227,
+32173,32239,32963,33806,34915,35586,36949,36986,21307,20117,20133,22495,32946,
+37057,30959,19968,22769,28322,36920,31282,33576,33419,39983,20801,21360,21693,
+21729,22240,23035,24341,39154,28139,32996,34093,38498,38512,38560,38907,21515,
+21491,23431,28879,32701,36802,38632,21359,40284,31418,19985,30867,33276,28198,
+22040,21764,27421,34074,39995,23013,21417,28006,29916,38287,22082,20113,36939,
+38642,33615,39180,21473,21942,23344,24433,26144,26355,26628,27704,27891,27945,
+29787,30408,31310,38964,33521,34907,35424,37613,28082,30123,30410,39365,24742,
+35585,36234,38322,27022,21421,20870,22290,22576,22852,23476,24310,24616,25513,
+25588,27839,28436,28814,28948,29017,29141,29503,32257,33398,33489,34199,36960,
+37467,40219,22633,26044,27738,29989,20985,22830,22885,24448,24540,25276,26106,
+27178,27431,27572,29579,32705,35158,40236,40206,40644,23713,27798,33659,20740,
+23627,25014,33222,26742,29281,20057,20474,21368,24681,28201,31311,38899,19979,
+21270,20206,20309,20285,20385,20339,21152,21487,22025,22799,23233,23478,23521,
+31185,26247,26524,26550,27468,27827,28779,29634,31117,31166,31292,31623,33457,
+33499,33540,33655,33775,33747,34662,35506,22057,36008,36838,36942,38686,34442,
+20420,23784,25105,29273,30011,33253,33469,34558,36032,38597,39187,39381,20171,
+20250,35299,22238,22602,22730,24315,24555,24618,24724,24674,25040,25106,25296,
+25913,39745,26214,26800,28023,28784,30028,30342,32117,33445,34809,38283,38542,
+35997,20977,21182,22806,21683,23475,23830,24936,27010,28079,30861,33995,34903,
+35442,37799,39608,28012,39336,34521,22435,26623,34510,37390,21123,22151,21508,
+24275,25313,25785,26684,26680,27579,29554,30906,31339,35226,35282,36203,36611,
+37101,38307,38548,38761,23398,23731,27005,38989,38990,25499,31520,27179,27263,
+26806,39949,28511,21106,21917,24688,25324,27963,28167,28369,33883,35088,36676,
+19988,39993,21494,26907,27194,38788,26666,20828,31427,33970,37340,37772,22107,
+40232,26658,33541,33841,31909,21000,33477,29926,20094,
+20355,20896,23506,21002,21208,21223,24059,21914,22570,23014,23436,23448,23515,
+24178,24185,24739,24863,24931,25022,25563,25954,26577,26707,26874,27454,27475,
+27735,28450,28567,28485,29872,29976,30435,30475,31487,31649,31777,32233,32566,
+32752,32925,33382,33694,35251,35532,36011,36996,37969,38291,38289,38306,38501,
+38867,39208,33304,20024,21547,23736,24012,29609,30284,30524,23721,32747,36107,
+38593,38929,38996,39000,20225,20238,21361,21916,22120,22522,22855,23305,23492,
+23696,24076,24190,24524,25582,26426,26071,26082,26399,26827,26820,27231,24112,
+27589,27671,27773,30079,31048,23395,31232,32000,24509,35215,35352,36020,36215,
+36556,36637,39138,39438,39740,20096,20605,20736,22931,23452,25135,25216,25836,
+27450,29344,30097,31047,32681,34811,35516,35696,25516,33738,38816,21513,21507,
+21931,26708,27224,35440,30759,26485,40653,21364,23458,33050,34384,36870,19992,
+20037,20167,20241,21450,21560,23470,24339,24613,25937,26429,27714,27762,27875,
+28792,29699,31350,31406,31496,32026,31998,32102,26087,29275,21435,23621,24040,
+25298,25312,25369,28192,34394,35377,36317,37624,28417,31142,39770,20136,20139,
+20140,20379,20384,20689,20807,31478,20849,20982,21332,21281,21375,21483,21932,
+22659,23777,24375,24394,24623,24656,24685,25375,25945,27211,27841,29378,29421,
+30703,33016,33029,33288,34126,37111,37857,38911,39255,39514,20208,20957,23597,
+26241,26989,23616,26354,26997,29577,26704,31873,20677,21220,22343,24062,37670,
+26020,27427,27453,29748,31105,31165,31563,32202,33465,33740,34943,35167,35641,
+36817,37329,21535,37504,20061,20534,21477,21306,29399,
+29590,30697,33510,36527,39366,39368,39378,20855,24858,34398,21936,31354,20598,
+23507,36935,38533,20018,27355,37351,23633,23624,25496,31391,27795,38772,36705,
+31402,29066,38536,31874,26647,32368,26705,37740,21234,21531,34219,35347,32676,
+36557,37089,21350,34952,31041,20418,20670,21009,20804,21843,22317,29674,22411,
+22865,24418,24452,24693,24950,24935,25001,25522,25658,25964,26223,26690,28179,
+30054,31293,31995,32076,32153,32331,32619,33550,33610,34509,35336,35427,35686,
+36605,38938,40335,33464,36814,39912,21127,25119,25731,28608,38553,26689,20625,
+27424,27770,28500,31348,32080,34880,35363,26376,20214,20537,20518,20581,20860,
+21048,21091,21927,22287,22533,23244,24314,25010,25080,25331,25458,26908,27177,
+29309,29356,29486,30740,30831,32121,30476,32937,35211,35609,36066,36562,36963,
+37749,38522,38997,39443,40568,20803,21407,21427,24187,24358,28187,28304,29572,
+29694,32067,33335,35328,35578,38480,20046,20491,21476,21628,22266,22993,23396,
+24049,24235,24359,25144,25925,26543,28246,29392,31946,34996,32929,32993,33776,
+34382,35463,36328,37431,38599,39015,40723,20116,20114,20237,21320,21577,21566,
+23087,24460,24481,24735,26791,27278,29786,30849,35486,35492,35703,37264,20062,
+39881,20132,20348,20399,20505,20502,20809,20844,21151,21177,21246,21402,21475,
+21521,21518,21897,22353,22434,22909,23380,23389,23439,24037,24039,24055,24184,
+24195,24218,24247,24344,24658,24908,25239,25304,25511,25915,26114,26179,26356,
+26477,26657,26775,27083,27743,27946,28009,28207,28317,30002,30343,30828,31295,
+31968,32005,32024,32094,32177,32789,32771,32943,32945,
+33108,33167,33322,33618,34892,34913,35611,36002,36092,37066,37237,37489,30783,
+37628,38308,38477,38917,39321,39640,40251,21083,21163,21495,21512,22741,25335,
+28640,35946,36703,40633,20811,21051,21578,22269,31296,37239,40288,40658,29508,
+28425,33136,29969,24573,24794,39592,29403,36796,27492,38915,20170,22256,22372,
+22718,23130,24680,25031,26127,26118,26681,26801,28151,30165,32058,33390,39746,
+20123,20304,21449,21766,23919,24038,24046,26619,27801,29811,30722,35408,37782,
+35039,22352,24231,25387,20661,20652,20877,26368,21705,22622,22971,23472,24425,
+25165,25505,26685,27507,28168,28797,37319,29312,30741,30758,31085,25998,32048,
+33756,35009,36617,38555,21092,22312,26448,32618,36001,20916,22338,38442,22586,
+27018,32948,21682,23822,22524,30869,40442,20316,21066,21643,25662,26152,26388,
+26613,31364,31574,32034,37679,26716,39853,31545,21273,20874,21047,23519,25334,
+25774,25830,26413,27578,34217,38609,30352,39894,25420,37638,39851,30399,26194,
+19977,20632,21442,23665,24808,25746,25955,26719,29158,29642,29987,31639,32386,
+34453,35715,36059,37240,39184,26028,26283,27531,20181,20180,20282,20351,21050,
+21496,21490,21987,22235,22763,22987,22985,23039,23376,23629,24066,24107,24535,
+24605,25351,25903,23388,26031,26045,26088,26525,27490,27515,27663,29509,31049,
+31169,31992,32025,32043,32930,33026,33267,35222,35422,35433,35430,35468,35566,
+36039,36060,38604,39164,27503,20107,20284,20365,20816,23383,23546,24904,25345,
+26178,27425,28363,27835,29246,29885,30164,30913,31034,32780,32819,33258,33940,
+36766,27728,40575,24335,35672,40235,31482,36600,23437,
+38635,19971,21489,22519,22833,23241,23460,24713,28287,28422,30142,36074,23455,
+34048,31712,20594,26612,33437,23649,34122,32286,33294,20889,23556,25448,36198,
+26012,29038,31038,32023,32773,35613,36554,36974,34503,37034,20511,21242,23610,
+26451,28796,29237,37196,37320,37675,33509,23490,24369,24825,20027,21462,23432,
+25163,26417,27530,29417,29664,31278,33131,36259,37202,39318,20754,21463,21610,
+23551,25480,27193,32172,38656,22234,21454,21608,23447,23601,24030,20462,24833,
+25342,27954,31168,31179,32066,32333,32722,33261,33311,33936,34886,35186,35728,
+36468,36655,36913,37195,37228,38598,37276,20160,20303,20805,21313,24467,25102,
+26580,27713,28171,29539,32294,37325,37507,21460,22809,23487,28113,31069,32302,
+31899,22654,29087,20986,34899,36848,20426,23803,26149,30636,31459,33308,39423,
+20934,24490,26092,26991,27529,28147,28310,28516,30462,32020,24033,36981,37255,
+38918,20966,21021,25152,26257,26329,28186,24246,32210,32626,26360,34223,34295,
+35576,21161,21465,22899,24207,24464,24661,37604,38500,20663,20767,21213,21280,
+21319,21484,21736,21830,21809,22039,22888,22974,23100,23477,23558,23567,23569,
+23578,24196,24202,24288,24432,25215,25220,25307,25484,25463,26119,26124,26157,
+26230,26494,26786,27167,27189,27836,28040,28169,28248,28988,28966,29031,30151,
+30465,30813,30977,31077,31216,31456,31505,31911,32057,32918,33750,33931,34121,
+34909,35059,35359,35388,35412,35443,35937,36062,37284,37478,37758,37912,38556,
+38808,19978,19976,19998,20055,20887,21104,22478,22580,22732,23330,24120,24773,
+25854,26465,26454,27972,29366,30067,31331,33976,35698,
+37304,37664,22065,22516,39166,25325,26893,27542,29165,32340,32887,33394,35302,
+39135,34645,36785,23611,20280,20449,20405,21767,23072,23517,23529,24515,24910,
+25391,26032,26187,26862,27035,28024,28145,30003,30137,30495,31070,31206,32051,
+33251,33455,34218,35242,35386,36523,36763,36914,37341,38663,20154,20161,20995,
+22645,22764,23563,29978,23613,33102,35338,36805,38499,38765,31525,35535,38920,
+37218,22259,21416,36887,21561,22402,24101,25512,27700,28810,30561,31883,32736,
+34928,36930,37204,37648,37656,38543,29790,39620,23815,23913,25968,26530,36264,
+38619,25454,26441,26905,33733,38935,38592,35070,28548,25722,23544,19990,28716,
+30045,26159,20932,21046,21218,22995,24449,24615,25104,25919,25972,26143,26228,
+26866,26646,27491,28165,29298,29983,30427,31934,32854,22768,35069,35199,35488,
+35475,35531,36893,37266,38738,38745,25993,31246,33030,38587,24109,24796,25114,
+26021,26132,26512,30707,31309,31821,32318,33034,36012,36196,36321,36447,30889,
+20999,25305,25509,25666,25240,35373,31363,31680,35500,38634,32118,33292,34633,
+20185,20808,21315,21344,23459,23554,23574,24029,25126,25159,25776,26643,26676,
+27849,27973,27927,26579,28508,29006,29053,26059,31359,31661,32218,32330,32680,
+33146,33307,33337,34214,35438,36046,36341,36984,36983,37549,37521,38275,39854,
+21069,21892,28472,28982,20840,31109,32341,33203,31950,22092,22609,23720,25514,
+26366,26365,26970,29401,30095,30094,30990,31062,31199,31895,32032,32068,34311,
+35380,38459,36961,40736,20711,21109,21452,21474,20489,21930,22766,22863,29245,
+23435,23652,21277,24803,24819,25436,25475,25407,25531,
+25805,26089,26361,24035,27085,27133,28437,29157,20105,30185,30456,31379,31967,
+32207,32156,32865,33609,33624,33900,33980,34299,35013,36208,36865,36973,37783,
+38684,39442,20687,22679,24974,33235,34101,36104,36896,20419,20596,21063,21363,
+24687,25417,26463,28204,36275,36895,20439,23646,36042,26063,32154,21330,34966,
+20854,25539,23384,23403,23562,25613,26449,36956,20182,22810,22826,27760,35409,
+21822,22549,22949,24816,25171,26561,33333,26965,38464,39364,39464,20307,22534,
+23550,32784,23729,24111,24453,24608,24907,25140,26367,27888,28382,32974,33151,
+33492,34955,36024,36864,36910,38538,40667,39899,20195,21488,22823,31532,37261,
+38988,40441,28381,28711,21331,21828,23429,25176,25246,25299,27810,28655,29730,
+35351,37944,28609,35582,33592,20967,34552,21482,21481,20294,36948,36784,22890,
+33073,24061,31466,36799,26842,35895,29432,40008,27197,35504,20025,21336,22022,
+22374,25285,25506,26086,27470,28129,28251,28845,30701,31471,31658,32187,32829,
+32966,34507,35477,37723,22243,22727,24382,26029,26262,27264,27573,30007,35527,
+20516,30693,22320,24347,24677,26234,27744,30196,31258,32622,33268,34584,36933,
+39347,31689,30044,31481,31569,33988,36880,31209,31378,33590,23265,30528,20013,
+20210,23449,24544,25277,26172,26609,27880,34411,34935,35387,37198,37619,39376,
+27159,28710,29482,33511,33879,36015,19969,20806,20939,21899,23541,24086,24115,
+24193,24340,24373,24427,24500,25074,25361,26274,26397,28526,29266,30010,30522,
+32884,33081,33144,34678,35519,35548,36229,36339,37530,38263,38914,40165,21189,
+25431,30452,26389,27784,29645,36035,37806,38515,27941,
+22684,26894,27084,36861,37786,30171,36890,22618,26626,25524,27131,20291,28460,
+26584,36795,34086,32180,37716,26943,28528,22378,22775,23340,32044,29226,21514,
+37347,40372,20141,20302,20572,20597,21059,35998,21576,22564,23450,24093,24213,
+24237,24311,24351,24716,25269,25402,25552,26799,27712,30855,31118,31243,32224,
+33351,35330,35558,36420,36883,37048,37165,37336,40718,27877,25688,25826,25973,
+28404,30340,31515,36969,37841,28346,21746,24505,25764,36685,36845,37444,20856,
+22635,22825,23637,24215,28155,32399,29980,36028,36578,39003,28857,20253,27583,
+28593,30000,38651,20814,21520,22581,22615,22956,23648,24466,26007,26460,28193,
+30331,33759,36077,36884,37117,37709,30757,30778,21162,24230,22303,22900,24594,
+20498,20826,20908,20941,20992,21776,22612,22616,22871,23445,23798,23947,24764,
+25237,25645,26481,26691,26812,26847,30423,28120,28271,28059,28783,29128,24403,
+30168,31095,31561,31572,31570,31958,32113,21040,33891,34153,34276,35342,35588,
+35910,36367,36867,36879,37913,38518,38957,39472,38360,20685,21205,21516,22530,
+23566,24999,25758,27934,30643,31461,33012,33796,36947,37509,23776,40199,21311,
+24471,24499,28060,29305,30563,31167,31716,27602,29420,35501,26627,27233,20984,
+31361,26932,23626,40182,33515,23493,37193,28702,22136,23663,24775,25958,27788,
+35930,36929,38931,21585,26311,37389,22856,37027,20869,20045,20970,34201,35598,
+28760,25466,37707,26978,39348,32260,30071,21335,26976,36575,38627,27741,20108,
+23612,24336,36841,21250,36049,32905,34425,24319,26085,20083,20837,22914,23615,
+38894,20219,22922,24525,35469,28641,31152,31074,23527,
+33905,29483,29105,24180,24565,25467,25754,29123,31896,20035,24316,20043,22492,
+22178,24745,28611,32013,33021,33075,33215,36786,35223,34468,24052,25226,25773,
+35207,26487,27874,27966,29750,30772,23110,32629,33453,39340,20467,24259,25309,
+25490,25943,26479,30403,29260,32972,32954,36649,37197,20493,22521,23186,26757,
+26995,29028,29437,36023,22770,36064,38506,36889,34687,31204,30695,33833,20271,
+21093,21338,25293,26575,27850,30333,31636,31893,33334,34180,36843,26333,28448,
+29190,32283,33707,39361,40614,20989,31665,30834,31672,32903,31560,27368,24161,
+32908,30033,30048,20843,37474,28300,30330,37271,39658,20240,32624,25244,31567,
+38309,40169,22138,22617,34532,38588,20276,21028,21322,21453,21467,24070,25644,
+26001,26495,27710,27726,29256,29359,29677,30036,32321,33324,34281,36009,31684,
+37318,29033,38930,39151,25405,26217,30058,30436,30928,34115,34542,21290,21329,
+21542,22915,24199,24444,24754,25161,25209,25259,26000,27604,27852,30130,30382,
+30865,31192,32203,32631,32933,34987,35513,36027,36991,38750,39131,27147,31800,
+20633,23614,24494,26503,27608,29749,30473,32654,40763,26570,31255,21305,30091,
+39661,24422,33181,33777,32920,24380,24517,30050,31558,36924,26727,23019,23195,
+32016,30334,35628,20469,24426,27161,27703,28418,29922,31080,34920,35413,35961,
+24287,25551,30149,31186,33495,37672,37618,33948,34541,39981,21697,24428,25996,
+27996,28693,36007,36051,38971,25935,29942,19981,20184,22496,22827,23142,23500,
+20904,24067,24220,24598,25206,25975,26023,26222,28014,29238,31526,33104,33178,
+33433,35676,36000,36070,36212,38428,38468,20398,25771,
+27494,33310,33889,34154,37096,23553,26963,39080,33914,34135,20239,21103,24489,
+24133,26381,31119,33145,35079,35206,28149,24343,25173,27832,20175,29289,39826,
+20998,21563,22132,22707,24996,25198,28954,22894,31881,31966,32027,38640,25991,
+32862,19993,20341,20853,22592,24163,24179,24330,26564,20006,34109,38281,38491,
+31859,38913,20731,22721,30294,30887,21029,30629,34065,31622,20559,22793,29255,
+31687,32232,36794,36820,36941,20415,21193,23081,24321,38829,20445,33303,37610,
+22275,25429,27497,29995,35036,36628,31298,21215,22675,24917,25098,26286,27597,
+31807,33769,20515,20472,21253,21574,22577,22857,23453,23792,23791,23849,24214,
+25265,25447,25918,26041,26379,27861,27873,28921,30770,32299,32990,33459,33804,
+34028,34562,35090,35370,35914,37030,37586,39165,40179,40300,20047,20129,20621,
+21078,22346,22952,24125,24536,24537,25151,26292,26395,26576,26834,20882,32033,
+32938,33192,35584,35980,36031,37502,38450,21536,38956,21271,20693,21340,22696,
+25778,26420,29287,30566,31302,37350,21187,27809,27526,22528,24140,22868,26412,
+32763,20961,30406,25705,30952,39764,40635,22475,22969,26151,26522,27598,21737,
+27097,24149,33180,26517,39850,26622,40018,26717,20134,20451,21448,25273,26411,
+27819,36804,20397,32365,40639,19975,24930,28288,28459,34067,21619,26410,39749,
+24051,31637,23724,23494,34588,28234,34001,31252,33032,22937,31885,27665,30496,
+21209,22818,28961,29279,30683,38695,40289,26891,23167,23064,20901,21517,21629,
+26126,30431,36855,37528,40180,23018,29277,28357,20813,26825,32191,32236,38754,
+40634,25720,27169,33538,22916,23391,27611,29467,30450,
+32178,32791,33945,20786,26408,40665,30446,26466,21247,39173,23588,25147,31870,
+36016,21839,24758,32011,38272,21249,20063,20918,22812,29242,32822,37326,24357,
+30690,21380,24441,32004,34220,35379,36493,38742,26611,34222,37971,24841,24840,
+27833,30290,35565,36664,21807,20305,20778,21191,21451,23461,24189,24736,24962,
+25558,26377,26586,28263,28044,29494,29495,30001,31056,35029,35480,36938,37009,
+37109,38596,34701,22805,20104,20313,19982,35465,36671,38928,20653,24188,22934,
+23481,24248,25562,25594,25793,26332,26954,27096,27915,28342,29076,29992,31407,
+32650,32768,33865,33993,35201,35617,36362,36965,38525,39178,24958,25233,27442,
+27779,28020,32716,32764,28096,32645,34746,35064,26469,33713,38972,38647,27931,
+32097,33853,37226,20081,21365,23888,27396,28651,34253,34349,35239,21033,21519,
+23653,26446,26792,29702,29827,30178,35023,35041,37324,38626,38520,24459,29575,
+31435,33870,25504,30053,21129,27969,28316,29705,30041,30827,31890,38534,31452,
+40845,20406,24942,26053,34396,20102,20142,20698,20001,20940,23534,26009,26753,
+28092,29471,30274,30637,31260,31975,33391,35538,36988,37327,38517,38936,21147,
+32209,20523,21400,26519,28107,29136,29747,33256,36650,38563,40023,40607,29792,
+22593,28057,32047,39006,20196,20278,20363,20919,21169,23994,24604,29618,31036,
+33491,37428,38583,38646,38666,40599,40802,26278,27508,21015,21155,28872,35010,
+24265,24651,24976,28451,29001,31806,32244,32879,34030,36899,37676,21570,39791,
+27347,28809,36034,36335,38706,21172,23105,24266,24324,26391,27004,27028,28010,
+28431,29282,29436,31725,32769,32894,34635,37070,20845,
+40595,31108,32907,37682,35542,20525,21644,35441,27498,36036,33031,24785,26528,
+40434,20121,20120,39952,35435,34241,34152,26880,28286,30871,33109,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+24332,19984,19989,20010,20017,20022,20028,20031,20034,20054,20056,20098,20101,
+35947,20106,33298,24333,20110,20126,20127,20128,20130,20144,20147,20150,20174,
+20173,20164,20166,20162,20183,20190,20205,20191,20215,20233,20314,20272,20315,
+20317,20311,20295,20342,20360,20367,20376,20347,20329,20336,20369,20335,20358,
+20374,20760,20436,20447,20430,20440,20443,20433,20442,20432,20452,20453,20506,
+20520,20500,20522,20517,20485,20252,20470,20513,20521,20524,20478,20463,20497,
+20486,20547,20551,26371,20565,20560,20552,20570,20566,20588,20600,20608,20634,
+20613,20660,20658,20681,20682,20659,20674,20694,20702,20709,20717,20707,20718,
+20729,20725,20745,20737,20738,20758,20757,20756,20762,20769,20794,20791,20796,
+20795,20799,20800,20818,20812,20820,20834,31480,20841,20842,20846,20864,20866,
+22232,20876,20873,20879,20881,20883,20885,20886,20900,20902,20898,20905,20906,
+20907,20915,20913,20914,20912,20917,20925,20933,20937,20955,20960,34389,20969,
+20973,20976,20981,20990,20996,21003,21012,21006,21031,21034,21038,21043,21049,
+21071,21060,21067,21068,21086,21076,21098,21108,21097,21107,21119,21117,21133,
+21140,21138,21105,21128,21137,36776,36775,
+21164,21165,21180,21173,21185,21197,21207,21214,21219,21222,39149,21216,21235,
+21237,21240,21241,21254,21256,30008,21261,21264,21263,21269,21274,21283,21295,
+21297,21299,21304,21312,21318,21317,19991,21321,21325,20950,21342,21353,21358,
+22808,21371,21367,21378,21398,21408,21414,21413,21422,21424,21430,21443,31762,
+38617,21471,26364,29166,21486,21480,21485,21498,21505,21565,21568,21548,21549,
+21564,21550,21558,21545,21533,21582,21647,21621,21646,21599,21617,21623,21616,
+21650,21627,21632,21622,21636,21648,21638,21703,21666,21688,21669,21676,21700,
+21704,21672,21675,21698,21668,21694,21692,21720,21733,21734,21775,21780,21757,
+21742,21741,21754,21730,21817,21824,21859,21836,21806,21852,21829,21846,21847,
+21816,21811,21853,21913,21888,21679,21898,21919,21883,21886,21912,21918,21934,
+21884,21891,21929,21895,21928,21978,21957,21983,21956,21980,21988,21972,22036,
+22007,22038,22014,22013,22043,22009,22094,22096,29151,22068,22070,22066,22072,
+22123,22116,22063,22124,22122,22150,22144,22154,22176,22164,22159,22181,22190,
+22198,22196,22210,22204,22209,22211,22208,22216,22222,22225,22227,22231,22254,
+22265,22272,22271,22276,22281,22280,22283,22285,22291,22296,22294,21959,22300,
+22310,22327,22328,22350,22331,22336,22351,22377,22464,22408,22369,22399,22409,
+22419,22432,22451,22436,22442,22448,22467,22470,22484,22482,22483,22538,22486,
+22499,22539,22553,22557,22642,22561,22626,22603,22640,27584,22610,22589,22649,
+22661,22713,22687,22699,22714,22750,22715,22712,22702,22725,22739,22737,22743,
+22745,22744,22757,22748,22756,22751,22767,22778,22777,
+22779,22780,22781,22786,22794,22800,22811,26790,22821,22828,22829,22834,22840,
+22846,31442,22869,22864,22862,22874,22872,22882,22880,22887,22892,22889,22904,
+22913,22941,20318,20395,22947,22962,22982,23016,23004,22925,23001,23002,23077,
+23071,23057,23068,23049,23066,23104,23148,23113,23093,23094,23138,23146,23194,
+23228,23230,23243,23234,23229,23267,23255,23270,23273,23254,23290,23291,23308,
+23307,23318,23346,23248,23338,23350,23358,23363,23365,23360,23377,23381,23386,
+23387,23397,23401,23408,23411,23413,23416,25992,23418,23424,23427,23462,23480,
+23491,23495,23497,23508,23504,23524,23526,23522,23518,23525,23531,23536,23542,
+23539,23557,23559,23560,23565,23571,23584,23586,23592,23608,23609,23617,23622,
+23630,23635,23632,23631,23409,23660,23662,20066,23670,23673,23692,23697,23700,
+22939,23723,23739,23734,23740,23735,23749,23742,23751,23769,23785,23805,23802,
+23789,23948,23786,23819,23829,23831,23900,23839,23835,23825,23828,23842,23834,
+23833,23832,23884,23890,23886,23883,23916,23923,23926,23943,23940,23938,23970,
+23965,23980,23982,23997,23952,23991,23996,24009,24013,24019,24018,24022,24027,
+24043,24050,24053,24075,24090,24089,24081,24091,24118,24119,24132,24131,24128,
+24142,24151,24148,24159,24162,24164,24135,24181,24182,24186,40636,24191,24224,
+24257,24258,24264,24272,24271,24278,24291,24285,24282,24283,24290,24289,24296,
+24297,24300,24305,24307,24304,24308,24312,24318,24323,24329,24413,24412,24331,
+24337,24342,24361,24365,24376,24385,24392,24396,24398,24367,24401,24406,24407,
+24409,24417,24429,24435,24439,24451,24450,24447,24458,
+24456,24465,24455,24478,24473,24472,24480,24488,24493,24508,24534,24571,24548,
+24568,24561,24541,24755,24575,24609,24672,24601,24592,24617,24590,24625,24603,
+24597,24619,24614,24591,24634,24666,24641,24682,24695,24671,24650,24646,24653,
+24675,24643,24676,24642,24684,24683,24665,24705,24717,24807,24707,24730,24708,
+24731,24726,24727,24722,24743,24715,24801,24760,24800,24787,24756,24560,24765,
+24774,24757,24792,24909,24853,24838,24822,24823,24832,24820,24826,24835,24865,
+24827,24817,24845,24846,24903,24894,24872,24871,24906,24895,24892,24876,24884,
+24893,24898,24900,24947,24951,24920,24921,24922,24939,24948,24943,24933,24945,
+24927,24925,24915,24949,24985,24982,24967,25004,24980,24986,24970,24977,25003,
+25006,25036,25034,25033,25079,25032,25027,25030,25018,25035,32633,25037,25062,
+25059,25078,25082,25076,25087,25085,25084,25086,25088,25096,25097,25101,25100,
+25108,25115,25118,25121,25130,25134,25136,25138,25139,25153,25166,25182,25187,
+25179,25184,25192,25212,25218,25225,25214,25234,25235,25238,25300,25219,25236,
+25303,25297,25275,25295,25343,25286,25812,25288,25308,25292,25290,25282,25287,
+25243,25289,25356,25326,25329,25383,25346,25352,25327,25333,25424,25406,25421,
+25628,25423,25494,25486,25472,25515,25462,25507,25487,25481,25503,25525,25451,
+25449,25534,25577,25536,25542,25571,25545,25554,25590,25540,25622,25652,25606,
+25619,25638,25654,25885,25623,25640,25615,25703,25711,25718,25678,25898,25749,
+25747,25765,25769,25736,25788,25818,25810,25797,25799,25787,25816,25794,25841,
+25831,33289,25824,25825,25260,25827,25839,25900,25846,
+25844,25842,25850,25856,25853,25880,25884,25861,25892,25891,25899,25908,25909,
+25911,25910,25912,30027,25928,25942,25941,25933,25944,25950,25949,25970,25976,
+25986,25987,35722,26011,26015,26027,26039,26051,26054,26049,26052,26060,26066,
+26075,26073,26080,26081,26097,26482,26122,26115,26107,26483,26165,26166,26164,
+26140,26191,26180,26185,26177,26206,26205,26212,26215,26216,26207,26210,26224,
+26243,26248,26254,26249,26244,26264,26269,26305,26297,26313,26302,26300,26308,
+26296,26326,26330,26336,26175,26342,26345,26352,26357,26359,26383,26390,26398,
+26406,26407,38712,26414,26431,26422,26433,26424,26423,26438,26462,26464,26457,
+26467,26468,26505,26480,26537,26492,26474,26508,26507,26534,26529,26501,26551,
+26607,26548,26604,26547,26601,26552,26596,26590,26589,26594,26606,26553,26574,
+26566,26599,27292,26654,26694,26665,26688,26701,26674,26702,26803,26667,26713,
+26723,26743,26751,26783,26767,26797,26772,26781,26779,26755,27310,26809,26740,
+26805,26784,26810,26895,26765,26750,26881,26826,26888,26840,26914,26918,26849,
+26892,26829,26836,26855,26837,26934,26898,26884,26839,26851,26917,26873,26848,
+26863,26920,26922,26906,26915,26913,26822,27001,26999,26972,27000,26987,26964,
+27006,26990,26937,26996,26941,26969,26928,26977,26974,26973,27009,26986,27058,
+27054,27088,27071,27073,27091,27070,27086,23528,27082,27101,27067,27075,27047,
+27182,27025,27040,27036,27029,27060,27102,27112,27138,27163,27135,27402,27129,
+27122,27111,27141,27057,27166,27117,27156,27115,27146,27154,27329,27171,27155,
+27204,27148,27250,27190,27256,27207,27234,27225,27238,
+27208,27192,27170,27280,27277,27296,27268,27298,27299,27287,34327,27323,27331,
+27330,27320,27315,27308,27358,27345,27359,27306,27354,27370,27387,27397,34326,
+27386,27410,27414,39729,27423,27448,27447,30428,27449,39150,27463,27459,27465,
+27472,27481,27476,27483,27487,27489,27512,27513,27519,27520,27524,27523,27533,
+27544,27541,27550,27556,27562,27563,27567,27570,27569,27571,27575,27580,27590,
+27595,27603,27615,27628,27627,27635,27631,40638,27656,27667,27668,27675,27684,
+27683,27742,27733,27746,27754,27778,27789,27802,27777,27803,27774,27752,27763,
+27794,27792,27844,27889,27859,27837,27863,27845,27869,27822,27825,27838,27834,
+27867,27887,27865,27882,27935,34893,27958,27947,27965,27960,27929,27957,27955,
+27922,27916,28003,28051,28004,27994,28025,27993,28046,28053,28644,28037,28153,
+28181,28170,28085,28103,28134,28088,28102,28140,28126,28108,28136,28114,28101,
+28154,28121,28132,28117,28138,28142,28205,28270,28206,28185,28274,28255,28222,
+28195,28267,28203,28278,28237,28191,28227,28218,28238,28196,28415,28189,28216,
+28290,28330,28312,28361,28343,28371,28349,28335,28356,28338,28372,28373,28303,
+28325,28354,28319,28481,28433,28748,28396,28408,28414,28479,28402,28465,28399,
+28466,28364,28478,28435,28407,28550,28538,28536,28545,28544,28527,28507,28659,
+28525,28546,28540,28504,28558,28561,28610,28518,28595,28579,28577,28580,28601,
+28614,28586,28639,28629,28652,28628,28632,28657,28654,28635,28681,28683,28666,
+28689,28673,28687,28670,28699,28698,28532,28701,28696,28703,28720,28734,28722,
+28753,28771,28825,28818,28847,28913,28844,28856,28851,
+28846,28895,28875,28893,28889,28937,28925,28956,28953,29029,29013,29064,29030,
+29026,29004,29014,29036,29071,29179,29060,29077,29096,29100,29143,29113,29118,
+29138,29129,29140,29134,29152,29164,29159,29173,29180,29177,29183,29197,29200,
+29211,29224,29229,29228,29232,29234,29243,29244,29247,29248,29254,29259,29272,
+29300,29310,29314,29313,29319,29330,29334,29346,29351,29369,29362,29379,29382,
+29380,29390,29394,29410,29408,29409,29433,29431,20495,29463,29450,29468,29462,
+29469,29492,29487,29481,29477,29502,29518,29519,40664,29527,29546,29544,29552,
+29560,29557,29563,29562,29640,29619,29646,29627,29632,29669,29678,29662,29858,
+29701,29807,29733,29688,29746,29754,29781,29759,29791,29785,29761,29788,29801,
+29808,29795,29802,29814,29822,29835,29854,29863,29898,29903,29908,29681,29920,
+29923,29927,29929,29934,29938,29936,29937,29944,29943,29956,29955,29957,29964,
+29966,29965,29973,29971,29982,29990,29996,30012,30020,30029,30026,30025,30043,
+30022,30042,30057,30052,30055,30059,30061,30072,30070,30086,30087,30068,30090,
+30089,30082,30100,30106,30109,30117,30115,30146,30131,30147,30133,30141,30136,
+30140,30129,30157,30154,30162,30169,30179,30174,30206,30207,30204,30209,30192,
+30202,30194,30195,30219,30221,30217,30239,30247,30240,30241,30242,30244,30260,
+30256,30267,30279,30280,30278,30300,30296,30305,30306,30312,30313,30314,30311,
+30316,30320,30322,30326,30328,30332,30336,30339,30344,30347,30350,30358,30355,
+30361,30362,30384,30388,30392,30393,30394,30402,30413,30422,30418,30430,30433,
+30437,30439,30442,34351,30459,30472,30471,30468,30505,
+30500,30494,30501,30502,30491,30519,30520,30535,30554,30568,30571,30555,30565,
+30591,30590,30585,30606,30603,30609,30624,30622,30640,30646,30649,30655,30652,
+30653,30651,30663,30669,30679,30682,30684,30691,30702,30716,30732,30738,31014,
+30752,31018,30789,30862,30836,30854,30844,30874,30860,30883,30901,30890,30895,
+30929,30918,30923,30932,30910,30908,30917,30922,30956,30951,30938,30973,30964,
+30983,30994,30993,31001,31020,31019,31040,31072,31063,31071,31066,31061,31059,
+31098,31103,31114,31133,31143,40779,31146,31150,31155,31161,31162,31177,31189,
+31207,31212,31201,31203,31240,31245,31256,31257,31264,31263,31104,31281,31291,
+31294,31287,31299,31319,31305,31329,31330,31337,40861,31344,31353,31357,31368,
+31383,31381,31384,31382,31401,31432,31408,31414,31429,31428,31423,36995,31431,
+31434,31437,31439,31445,31443,31449,31450,31453,31457,31458,31462,31469,31472,
+31490,31503,31498,31494,31539,31512,31513,31518,31541,31528,31542,31568,31610,
+31492,31565,31499,31564,31557,31605,31589,31604,31591,31600,31601,31596,31598,
+31645,31640,31647,31629,31644,31642,31627,31634,31631,31581,31641,31691,31681,
+31692,31695,31668,31686,31709,31721,31761,31764,31718,31717,31840,31744,31751,
+31763,31731,31735,31767,31757,31734,31779,31783,31786,31775,31799,31787,31805,
+31820,31811,31828,31823,31808,31824,31832,31839,31844,31830,31845,31852,31861,
+31875,31888,31908,31917,31906,31915,31905,31912,31923,31922,31921,31918,31929,
+31933,31936,31941,31938,31960,31954,31964,31970,39739,31983,31986,31988,31990,
+31994,32006,32002,32028,32021,32010,32069,32075,32046,
+32050,32063,32053,32070,32115,32086,32078,32114,32104,32110,32079,32099,32147,
+32137,32091,32143,32125,32155,32186,32174,32163,32181,32199,32189,32171,32317,
+32162,32175,32220,32184,32159,32176,32216,32221,32228,32222,32251,32242,32225,
+32261,32266,32291,32289,32274,32305,32287,32265,32267,32290,32326,32358,32315,
+32309,32313,32323,32311,32306,32314,32359,32349,32342,32350,32345,32346,32377,
+32362,32361,32380,32379,32387,32213,32381,36782,32383,32392,32393,32396,32402,
+32400,32403,32404,32406,32398,32411,32412,32568,32570,32581,32588,32589,32590,
+32592,32593,32597,32596,32600,32607,32608,32616,32617,32615,32632,32642,32646,
+32643,32648,32647,32652,32660,32670,32669,32666,32675,32687,32690,32697,32686,
+32694,32696,35697,32709,32710,32714,32725,32724,32737,32742,32745,32755,32761,
+39132,32774,32772,32779,32786,32792,32793,32796,32801,32808,32831,32827,32842,
+32838,32850,32856,32858,32863,32866,32872,32883,32882,32880,32886,32889,32893,
+32895,32900,32902,32901,32923,32915,32922,32941,20880,32940,32987,32997,32985,
+32989,32964,32986,32982,33033,33007,33009,33051,33065,33059,33071,33099,38539,
+33094,33086,33107,33105,33020,33137,33134,33125,33126,33140,33155,33160,33162,
+33152,33154,33184,33173,33188,33187,33119,33171,33193,33200,33205,33214,33208,
+33213,33216,33218,33210,33225,33229,33233,33241,33240,33224,33242,33247,33248,
+33255,33274,33275,33278,33281,33282,33285,33287,33290,33293,33296,33302,33321,
+33323,33336,33331,33344,33369,33368,33373,33370,33375,33380,33378,33384,33386,
+33387,33326,33393,33399,33400,33406,33421,33426,33451,
+33439,33467,33452,33505,33507,33503,33490,33524,33523,33530,33683,33539,33531,
+33529,33502,33542,33500,33545,33497,33589,33588,33558,33586,33585,33600,33593,
+33616,33605,33583,33579,33559,33560,33669,33690,33706,33695,33698,33686,33571,
+33678,33671,33674,33660,33717,33651,33653,33696,33673,33704,33780,33811,33771,
+33742,33789,33795,33752,33803,33729,33783,33799,33760,33778,33805,33826,33824,
+33725,33848,34054,33787,33901,33834,33852,34138,33924,33911,33899,33965,33902,
+33922,33897,33862,33836,33903,33913,33845,33994,33890,33977,33983,33951,34009,
+33997,33979,34010,34000,33985,33990,34006,33953,34081,34047,34036,34071,34072,
+34092,34079,34069,34068,34044,34112,34147,34136,34120,34113,34306,34123,34133,
+34176,34212,34184,34193,34186,34216,34157,34196,34203,34282,34183,34204,34167,
+34174,34192,34249,34234,34255,34233,34256,34261,34269,34277,34268,34297,34314,
+34323,34315,34302,34298,34310,34338,34330,34352,34367,34381,20053,34388,34399,
+34407,34417,34451,34467,34473,34474,34443,34444,34486,34479,34500,34502,34480,
+34505,34851,34475,34516,34526,34537,34540,34527,34523,34543,34578,34566,34568,
+34560,34563,34555,34577,34569,34573,34553,34570,34612,34623,34615,34619,34597,
+34601,34586,34656,34655,34680,34636,34638,34676,34647,34664,34670,34649,34643,
+34659,34666,34821,34722,34719,34690,34735,34763,34749,34752,34768,38614,34731,
+34756,34739,34759,34758,34747,34799,34802,34784,34831,34829,34814,34806,34807,
+34830,34770,34833,34838,34837,34850,34849,34865,34870,34873,34855,34875,34884,
+34882,34898,34905,34910,34914,34923,34945,34942,34974,
+34933,34941,34997,34930,34946,34967,34962,34990,34969,34978,34957,34980,34992,
+35007,34993,35011,35012,35028,35032,35033,35037,35065,35074,35068,35060,35048,
+35058,35076,35084,35082,35091,35139,35102,35109,35114,35115,35137,35140,35131,
+35126,35128,35148,35101,35168,35166,35174,35172,35181,35178,35183,35188,35191,
+35198,35203,35208,35210,35219,35224,35233,35241,35238,35244,35247,35250,35258,
+35261,35263,35264,35290,35292,35293,35303,35316,35320,35331,35350,35344,35340,
+35355,35357,35365,35382,35393,35419,35410,35398,35400,35452,35437,35436,35426,
+35461,35458,35460,35496,35489,35473,35493,35494,35482,35491,35524,35533,35522,
+35546,35563,35571,35559,35556,35569,35604,35552,35554,35575,35550,35547,35596,
+35591,35610,35553,35606,35600,35607,35616,35635,38827,35622,35627,35646,35624,
+35649,35660,35663,35662,35657,35670,35675,35674,35691,35679,35692,35695,35700,
+35709,35712,35724,35726,35730,35731,35734,35737,35738,35898,35905,35903,35912,
+35916,35918,35920,35925,35938,35948,35960,35962,35970,35977,35973,35978,35981,
+35982,35988,35964,35992,25117,36013,36010,36029,36018,36019,36014,36022,36040,
+36033,36068,36067,36058,36093,36090,36091,36100,36101,36106,36103,36111,36109,
+36112,40782,36115,36045,36116,36118,36199,36205,36209,36211,36225,36249,36290,
+36286,36282,36303,36314,36310,36300,36315,36299,36330,36331,36319,36323,36348,
+36360,36361,36351,36381,36382,36368,36383,36418,36405,36400,36404,36426,36423,
+36425,36428,36432,36424,36441,36452,36448,36394,36451,36437,36470,36466,36476,
+36481,36487,36485,36484,36491,36490,36499,36497,36500,
+36505,36522,36513,36524,36528,36550,36529,36542,36549,36552,36555,36571,36579,
+36604,36603,36587,36606,36618,36613,36629,36626,36633,36627,36636,36639,36635,
+36620,36646,36659,36667,36665,36677,36674,36670,36684,36681,36678,36686,36695,
+36700,36706,36707,36708,36764,36767,36771,36781,36783,36791,36826,36837,36834,
+36842,36847,36999,36852,36869,36857,36858,36881,36885,36897,36877,36894,36886,
+36875,36903,36918,36917,36921,36856,36943,36944,36945,36946,36878,36937,36926,
+36950,36952,36958,36968,36975,36982,38568,36978,36994,36989,36993,36992,37002,
+37001,37007,37032,37039,37041,37045,37090,37092,25160,37083,37122,37138,37145,
+37170,37168,37194,37206,37208,37219,37221,37225,37235,37234,37259,37257,37250,
+37282,37291,37295,37290,37301,37300,37306,37312,37313,37321,37323,37328,37334,
+37343,37345,37339,37372,37365,37366,37406,37375,37396,37420,37397,37393,37470,
+37463,37445,37449,37476,37448,37525,37439,37451,37456,37532,37526,37523,37531,
+37466,37583,37561,37559,37609,37647,37626,37700,37678,37657,37666,37658,37667,
+37690,37685,37691,37724,37728,37756,37742,37718,37808,37804,37805,37780,37817,
+37846,37847,37864,37861,37848,37827,37853,37840,37832,37860,37914,37908,37907,
+37891,37895,37904,37942,37931,37941,37921,37946,37953,37970,37956,37979,37984,
+37986,37982,37994,37417,38000,38005,38007,38013,37978,38012,38014,38017,38015,
+38274,38279,38282,38292,38294,38296,38297,38304,38312,38311,38317,38332,38331,
+38329,38334,38346,28662,38339,38349,38348,38357,38356,38358,38364,38369,38373,
+38370,38433,38440,38446,38447,38466,38476,38479,38475,
+38519,38492,38494,38493,38495,38502,38514,38508,38541,38552,38549,38551,38570,
+38567,38577,38578,38576,38580,38582,38584,38585,38606,38603,38601,38605,35149,
+38620,38669,38613,38649,38660,38662,38664,38675,38670,38673,38671,38678,38681,
+38692,38698,38704,38713,38717,38718,38724,38726,38728,38722,38729,38748,38752,
+38756,38758,38760,21202,38763,38769,38777,38789,38780,38785,38778,38790,38795,
+38799,38800,38812,38824,38822,38819,38835,38836,38851,38854,38856,38859,38876,
+38893,40783,38898,31455,38902,38901,38927,38924,38968,38948,38945,38967,38973,
+38982,38991,38987,39019,39023,39024,39025,39028,39027,39082,39087,39089,39094,
+39108,39107,39110,39145,39147,39171,39177,39186,39188,39192,39201,39197,39198,
+39204,39200,39212,39214,39229,39230,39234,39241,39237,39248,39243,39249,39250,
+39244,39253,39319,39320,39333,39341,39342,39356,39391,39387,39389,39384,39377,
+39405,39406,39409,39410,39419,39416,39425,39439,39429,39394,39449,39467,39479,
+39493,39490,39488,39491,39486,39509,39501,39515,39511,39519,39522,39525,39524,
+39529,39531,39530,39597,39600,39612,39616,39631,39633,39635,39636,39646,39647,
+39650,39651,39654,39663,39659,39662,39668,39665,39671,39675,39686,39704,39706,
+39711,39714,39715,39717,39719,39720,39721,39722,39726,39727,39730,39748,39747,
+39759,39757,39758,39761,39768,39796,39827,39811,39825,39830,39831,39839,39840,
+39848,39860,39872,39882,39865,39878,39887,39889,39890,39907,39906,39908,39892,
+39905,39994,39922,39921,39920,39957,39956,39945,39955,39948,39942,39944,39954,
+39946,39940,39982,39963,39973,39972,39969,39984,40007,
+39986,40006,39998,40026,40032,40039,40054,40056,40167,40172,40176,40201,40200,
+40171,40195,40198,40234,40230,40367,40227,40223,40260,40213,40210,40257,40255,
+40254,40262,40264,40285,40286,40292,40273,40272,40281,40306,40329,40327,40363,
+40303,40314,40346,40356,40361,40370,40388,40385,40379,40376,40378,40390,40399,
+40386,40409,40403,40440,40422,40429,40431,40445,40474,40475,40478,40565,40569,
+40573,40577,40584,40587,40588,40594,40597,40593,40605,40613,40617,40632,40618,
+40621,38753,40652,40654,40655,40656,40660,40668,40670,40669,40672,40677,40680,
+40687,40692,40694,40695,40697,40699,40700,40701,40711,40712,30391,40725,40737,
+40748,40766,40778,40786,40788,40803,40799,40800,40801,40806,40807,40812,40810,
+40823,40818,40822,40853,40860,40864,22575,27079,36953,29796,20956,29081,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,
libc/musl/src/locale/ksc.h
@@ -0,0 +1,650 @@
+12288,12289,12290,183,8229,8230,168,12291,173,8213,8741,65340,8764,8216,8217,
+8220,8221,12308,12309,12296,12297,12298,12299,12300,12301,12302,12303,12304,
+12305,177,215,247,8800,8804,8805,8734,8756,176,8242,8243,8451,8491,65504,
+65505,65509,9794,9792,8736,8869,8978,8706,8711,8801,8786,167,8251,9734,9733,
+9675,9679,9678,9671,9670,9633,9632,9651,9650,9661,9660,8594,8592,8593,8595,
+8596,12307,8810,8811,8730,8765,8733,8757,8747,8748,8712,8715,8838,8839,8834,
+8835,8746,8745,8743,8744,65506,8658,8660,8704,8707,180,65374,711,728,733,730,
+729,184,731,161,191,720,8750,8721,8719,164,8457,8240,9665,9664,9655,9654,9828,
+9824,9825,9829,9831,9827,8857,9672,9635,9680,9681,9618,9636,9637,9640,9639,
+9638,9641,9832,9743,9742,9756,9758,182,8224,8225,8597,8599,8601,8598,8600,
+9837,9833,9834,9836,12927,12828,8470,13255,8482,13250,13272,8481,8364,174,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,65281,65282,65283,65284,65285,65286,
+65287,65288,65289,65290,65291,65292,65293,65294,65295,65296,65297,65298,65299,
+65300,65301,65302,65303,65304,65305,65306,65307,65308,65309,65310,65311,65312,
+65313,65314,65315,65316,65317,65318,65319,65320,65321,65322,65323,65324,65325,
+65326,65327,65328,65329,65330,65331,65332,65333,65334,65335,65336,65337,65338,
+65339,65510,65341,65342,65343,65344,65345,65346,65347,
+65348,65349,65350,65351,65352,65353,65354,65355,65356,65357,65358,65359,65360,
+65361,65362,65363,65364,65365,65366,65367,65368,65369,65370,65371,65372,65373,
+65507,12593,12594,12595,12596,12597,12598,12599,12600,12601,12602,12603,12604,
+12605,12606,12607,12608,12609,12610,12611,12612,12613,12614,12615,12616,12617,
+12618,12619,12620,12621,12622,12623,12624,12625,12626,12627,12628,12629,12630,
+12631,12632,12633,12634,12635,12636,12637,12638,12639,12640,12641,12642,12643,
+12644,12645,12646,12647,12648,12649,12650,12651,12652,12653,12654,12655,12656,
+12657,12658,12659,12660,12661,12662,12663,12664,12665,12666,12667,12668,12669,
+12670,12671,12672,12673,12674,12675,12676,12677,12678,12679,12680,12681,12682,
+12683,12684,12685,12686,8560,8561,8562,8563,8564,8565,8566,8567,8568,8569,0,0,
+0,0,0,8544,8545,8546,8547,8548,8549,8550,8551,8552,8553,0,0,0,0,0,0,0,913,914,
+915,916,917,918,919,920,921,922,923,924,925,926,927,928,929,931,932,933,934,
+935,936,937,0,0,0,0,0,0,0,0,945,946,947,948,949,950,951,952,953,954,955,956,
+957,958,959,960,961,963,964,965,966,967,968,969,0,0,0,0,0,0,9472,9474,9484,
+9488,9496,9492,9500,9516,9508,9524,9532,9473,9475,9487,9491,9499,9495,9507,
+9523,9515,9531,9547,9504,9519,9512,9527,9535,9501,9520,9509,9528,9538,9490,
+9489,9498,9497,9494,9493,9486,9485,9502,
+9503,9505,9506,9510,9511,9513,9514,9517,9518,9521,9522,9525,9526,9529,9530,
+9533,9534,9536,9537,9539,9540,9541,9542,9543,9544,9545,9546,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,13205,13206,13207,8467,13208,13252,13219,
+13220,13221,13222,13209,13210,13211,13212,13213,13214,13215,13216,13217,13218,
+13258,13197,13198,13199,13263,13192,13193,13256,13223,13224,13232,13233,13234,
+13235,13236,13237,13238,13239,13240,13241,13184,13185,13186,13187,13188,13242,
+13243,13244,13245,13246,13247,13200,13201,13202,13203,13204,8486,13248,13249,
+13194,13195,13196,13270,13253,13229,13230,13231,13275,13225,13226,13227,13228,
+13277,13264,13267,13251,13257,13276,13254,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,198,
+208,170,294,0,306,0,319,321,216,338,186,222,358,330,0,12896,12897,12898,12899,
+12900,12901,12902,12903,12904,12905,12906,12907,12908,12909,12910,12911,12912,
+12913,12914,12915,12916,12917,12918,12919,12920,12921,12922,12923,9424,9425,
+9426,9427,9428,9429,9430,9431,9432,9433,9434,9435,9436,9437,9438,9439,9440,
+9441,9442,9443,9444,9445,9446,9447,9448,9449,9312,9313,9314,9315,9316,9317,
+9318,9319,9320,9321,9322,9323,9324,9325,9326,189,8531,8532,188,190,8539,8540,
+8541,8542,230,273,240,295,305,307,312,320,322,248,339,223,254,359,331,
+329,12800,12801,12802,12803,12804,12805,12806,12807,12808,12809,12810,12811,
+12812,12813,12814,12815,12816,12817,12818,12819,12820,12821,12822,12823,12824,
+12825,12826,12827,9372,9373,9374,9375,9376,9377,9378,9379,9380,9381,9382,9383,
+9384,9385,9386,9387,9388,9389,9390,9391,9392,9393,9394,9395,9396,9397,9332,
+9333,9334,9335,9336,9337,9338,9339,9340,9341,9342,9343,9344,9345,9346,185,178,
+179,8308,8319,8321,8322,8323,8324,12353,12354,12355,12356,12357,12358,12359,
+12360,12361,12362,12363,12364,12365,12366,12367,12368,12369,12370,12371,12372,
+12373,12374,12375,12376,12377,12378,12379,12380,12381,12382,12383,12384,12385,
+12386,12387,12388,12389,12390,12391,12392,12393,12394,12395,12396,12397,12398,
+12399,12400,12401,12402,12403,12404,12405,12406,12407,12408,12409,12410,12411,
+12412,12413,12414,12415,12416,12417,12418,12419,12420,12421,12422,12423,12424,
+12425,12426,12427,12428,12429,12430,12431,12432,12433,12434,12435,0,0,0,0,0,0,
+0,0,0,0,0,12449,12450,12451,12452,12453,12454,12455,12456,12457,12458,12459,
+12460,12461,12462,12463,12464,12465,12466,12467,12468,12469,12470,12471,12472,
+12473,12474,12475,12476,12477,12478,12479,12480,12481,12482,12483,12484,12485,
+12486,12487,12488,12489,12490,12491,12492,12493,12494,12495,12496,12497,12498,
+12499,12500,12501,12502,12503,12504,12505,12506,12507,12508,12509,12510,12511,
+12512,12513,12514,12515,12516,12517,12518,12519,12520,12521,12522,12523,12524,
+12525,12526,12527,12528,12529,12530,12531,
+12532,12533,12534,0,0,0,0,0,0,0,0,1040,1041,1042,1043,1044,1045,1025,1046,
+1047,1048,1049,1050,1051,1052,1053,1054,1055,1056,1057,1058,1059,1060,1061,
+1062,1063,1064,1065,1066,1067,1068,1069,1070,1071,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,1072,1073,1074,1075,1076,1077,1105,1078,1079,1080,1081,1082,1083,1084,1085,
+1086,1087,1088,1089,1090,1091,1092,1093,1094,1095,1096,1097,1098,1099,1100,
+1101,1102,1103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,44032,44033,44036,44039,44040,44041,44042,44048,
+44049,44050,44051,44052,44053,44054,44055,44057,44058,44059,44060,44061,44064,
+44068,44076,44077,44079,44080,44081,44088,44089,44092,44096,44107,44109,44116,
+44120,44124,44144,44145,44148,44151,44152,44154,44160,44161,44163,44164,44165,
+44166,44169,44170,44171,44172,44176,44180,44188,44189,44191,44192,44193,44200,
+44201,44202,44204,44207,44208,44216,44217,44219,44220,44221,44225,44228,44232,
+44236,44245,44247,44256,44257,44260,44263,44264,44266,44268,44271,44272,44273,
+44275,44277,44278,44284,44285,44288,44292,44294,44300,44301,44303,44305,44312,
+44316,44320,44329,44332,44333,44340,44341,44344,44348,44356,44357,44359,44361,
+44368,44372,44376,44385,44387,44396,44397,44400,44403,44404,44405,44406,44411,
+44412,44413,44415,44417,44418,44424,44425,44428,44432,44444,44445,44452,44471,
+44480,44481,44484,44488,44496,44497,44499,44508,44512,44516,44536,44537,44540,
+44543,44544,44545,44552,44553,44555,44557,44564,44592,44593,44596,44599,44600,
+44602,44608,44609,44611,44613,44614,44618,44620,44621,44622,44624,44628,44630,
+44636,44637,44639,44640,44641,44645,44648,44649,44652,44656,44664,44665,44667,
+44668,44669,44676,44677,44684,44732,44733,44734,44736,44740,44748,44749,44751,
+44752,44753,44760,44761,44764,44776,44779,44781,44788,44792,44796,44807,44808,
+44813,44816,44844,44845,44848,44850,44852,44860,44861,44863,44865,44866,44867,
+44872,44873,44880,44892,44893,44900,44901,44921,44928,44932,44936,44944,44945,
+44949,44956,44984,44985,44988,44992,44999,45000,45001,45003,45005,45006,45012,
+45020,45032,45033,45040,45041,45044,45048,45056,45057,45060,45068,45072,45076,
+45084,45085,45096,45124,45125,45128,45130,45132,45134,45139,45140,45141,45143,
+45145,45149,45180,45181,45184,45188,45196,45197,45199,45201,45208,45209,45210,
+45212,45215,45216,45217,45218,45224,45225,45227,45228,45229,45230,45231,45233,
+45235,45236,45237,45240,45244,45252,45253,45255,45256,45257,45264,45265,45268,
+45272,45280,45285,45320,45321,45323,45324,45328,45330,45331,45336,45337,45339,
+45340,45341,45347,45348,45349,45352,45356,45364,45365,45367,45368,45369,45376,
+45377,45380,45384,45392,45393,45396,45397,45400,45404,45408,45432,45433,45436,
+45440,45442,45448,45449,45451,45453,45458,45459,45460,45464,45468,45480,45516,
+45520,45524,45532,45533,45535,45544,45545,45548,45552,
+45561,45563,45565,45572,45573,45576,45579,45580,45588,45589,45591,45593,45600,
+45620,45628,45656,45660,45664,45672,45673,45684,45685,45692,45700,45701,45705,
+45712,45713,45716,45720,45721,45722,45728,45729,45731,45733,45734,45738,45740,
+45744,45748,45768,45769,45772,45776,45778,45784,45785,45787,45789,45794,45796,
+45797,45798,45800,45803,45804,45805,45806,45807,45811,45812,45813,45815,45816,
+45817,45818,45819,45823,45824,45825,45828,45832,45840,45841,45843,45844,45845,
+45852,45908,45909,45910,45912,45915,45916,45918,45919,45924,45925,45927,45929,
+45931,45934,45936,45937,45940,45944,45952,45953,45955,45956,45957,45964,45968,
+45972,45984,45985,45992,45996,46020,46021,46024,46027,46028,46030,46032,46036,
+46037,46039,46041,46043,46045,46048,46052,46056,46076,46096,46104,46108,46112,
+46120,46121,46123,46132,46160,46161,46164,46168,46176,46177,46179,46181,46188,
+46208,46216,46237,46244,46248,46252,46261,46263,46265,46272,46276,46280,46288,
+46293,46300,46301,46304,46307,46308,46310,46316,46317,46319,46321,46328,46356,
+46357,46360,46363,46364,46372,46373,46375,46376,46377,46378,46384,46385,46388,
+46392,46400,46401,46403,46404,46405,46411,46412,46413,46416,46420,46428,46429,
+46431,46432,46433,46496,46497,46500,46504,46506,46507,46512,46513,46515,46516,
+46517,46523,46524,46525,46528,46532,46540,46541,46543,46544,46545,46552,46572,
+46608,46609,46612,46616,46629,46636,46644,46664,46692,46696,46748,46749,46752,
+46756,46763,46764,46769,46804,46832,46836,46840,46848,46849,46853,46888,46889,
+46892,46895,46896,46904,46905,46907,46916,46920,46924,
+46932,46933,46944,46948,46952,46960,46961,46963,46965,46972,46973,46976,46980,
+46988,46989,46991,46992,46993,46994,46998,46999,47000,47001,47004,47008,47016,
+47017,47019,47020,47021,47028,47029,47032,47047,47049,47084,47085,47088,47092,
+47100,47101,47103,47104,47105,47111,47112,47113,47116,47120,47128,47129,47131,
+47133,47140,47141,47144,47148,47156,47157,47159,47160,47161,47168,47172,47185,
+47187,47196,47197,47200,47204,47212,47213,47215,47217,47224,47228,47245,47272,
+47280,47284,47288,47296,47297,47299,47301,47308,47312,47316,47325,47327,47329,
+47336,47337,47340,47344,47352,47353,47355,47357,47364,47384,47392,47420,47421,
+47424,47428,47436,47439,47441,47448,47449,47452,47456,47464,47465,47467,47469,
+47476,47477,47480,47484,47492,47493,47495,47497,47498,47501,47502,47532,47533,
+47536,47540,47548,47549,47551,47553,47560,47561,47564,47566,47567,47568,47569,
+47570,47576,47577,47579,47581,47582,47585,47587,47588,47589,47592,47596,47604,
+47605,47607,47608,47609,47610,47616,47617,47624,47637,47672,47673,47676,47680,
+47682,47688,47689,47691,47693,47694,47699,47700,47701,47704,47708,47716,47717,
+47719,47720,47721,47728,47729,47732,47736,47747,47748,47749,47751,47756,47784,
+47785,47787,47788,47792,47794,47800,47801,47803,47805,47812,47816,47832,47833,
+47868,47872,47876,47885,47887,47889,47896,47900,47904,47913,47915,47924,47925,
+47926,47928,47931,47932,47933,47934,47940,47941,47943,47945,47949,47951,47952,
+47956,47960,47969,47971,47980,48008,48012,48016,48036,48040,48044,48052,48055,
+48064,48068,48072,48080,48083,48120,48121,48124,48127,
+48128,48130,48136,48137,48139,48140,48141,48143,48145,48148,48149,48150,48151,
+48152,48155,48156,48157,48158,48159,48164,48165,48167,48169,48173,48176,48177,
+48180,48184,48192,48193,48195,48196,48197,48201,48204,48205,48208,48221,48260,
+48261,48264,48267,48268,48270,48276,48277,48279,48281,48282,48288,48289,48292,
+48295,48296,48304,48305,48307,48308,48309,48316,48317,48320,48324,48333,48335,
+48336,48337,48341,48344,48348,48372,48373,48374,48376,48380,48388,48389,48391,
+48393,48400,48404,48420,48428,48448,48456,48457,48460,48464,48472,48473,48484,
+48488,48512,48513,48516,48519,48520,48521,48522,48528,48529,48531,48533,48537,
+48538,48540,48548,48560,48568,48596,48597,48600,48604,48617,48624,48628,48632,
+48640,48643,48645,48652,48653,48656,48660,48668,48669,48671,48708,48709,48712,
+48716,48718,48724,48725,48727,48729,48730,48731,48736,48737,48740,48744,48746,
+48752,48753,48755,48756,48757,48763,48764,48765,48768,48772,48780,48781,48783,
+48784,48785,48792,48793,48808,48848,48849,48852,48855,48856,48864,48867,48868,
+48869,48876,48897,48904,48905,48920,48921,48923,48924,48925,48960,48961,48964,
+48968,48976,48977,48981,49044,49072,49093,49100,49101,49104,49108,49116,49119,
+49121,49212,49233,49240,49244,49248,49256,49257,49296,49297,49300,49304,49312,
+49313,49315,49317,49324,49325,49327,49328,49331,49332,49333,49334,49340,49341,
+49343,49344,49345,49349,49352,49353,49356,49360,49368,49369,49371,49372,49373,
+49380,49381,49384,49388,49396,49397,49399,49401,49408,49412,49416,49424,49429,
+49436,49437,49438,49439,49440,49443,49444,49446,49447,
+49452,49453,49455,49456,49457,49462,49464,49465,49468,49472,49480,49481,49483,
+49484,49485,49492,49493,49496,49500,49508,49509,49511,49512,49513,49520,49524,
+49528,49541,49548,49549,49550,49552,49556,49558,49564,49565,49567,49569,49573,
+49576,49577,49580,49584,49597,49604,49608,49612,49620,49623,49624,49632,49636,
+49640,49648,49649,49651,49660,49661,49664,49668,49676,49677,49679,49681,49688,
+49689,49692,49695,49696,49704,49705,49707,49709,49711,49713,49714,49716,49736,
+49744,49745,49748,49752,49760,49765,49772,49773,49776,49780,49788,49789,49791,
+49793,49800,49801,49808,49816,49819,49821,49828,49829,49832,49836,49837,49844,
+49845,49847,49849,49884,49885,49888,49891,49892,49899,49900,49901,49903,49905,
+49910,49912,49913,49915,49916,49920,49928,49929,49932,49933,49939,49940,49941,
+49944,49948,49956,49957,49960,49961,49989,50024,50025,50028,50032,50034,50040,
+50041,50044,50045,50052,50056,50060,50112,50136,50137,50140,50143,50144,50146,
+50152,50153,50157,50164,50165,50168,50184,50192,50212,50220,50224,50228,50236,
+50237,50248,50276,50277,50280,50284,50292,50293,50297,50304,50324,50332,50360,
+50364,50409,50416,50417,50420,50424,50426,50431,50432,50433,50444,50448,50452,
+50460,50472,50473,50476,50480,50488,50489,50491,50493,50500,50501,50504,50505,
+50506,50508,50509,50510,50515,50516,50517,50519,50520,50521,50525,50526,50528,
+50529,50532,50536,50544,50545,50547,50548,50549,50556,50557,50560,50564,50567,
+50572,50573,50575,50577,50581,50583,50584,50588,50592,50601,50612,50613,50616,
+50617,50619,50620,50621,50622,50628,50629,50630,50631,
+50632,50633,50634,50636,50638,50640,50641,50644,50648,50656,50657,50659,50661,
+50668,50669,50670,50672,50676,50678,50679,50684,50685,50686,50687,50688,50689,
+50693,50694,50695,50696,50700,50704,50712,50713,50715,50716,50724,50725,50728,
+50732,50733,50734,50736,50739,50740,50741,50743,50745,50747,50752,50753,50756,
+50760,50768,50769,50771,50772,50773,50780,50781,50784,50796,50799,50801,50808,
+50809,50812,50816,50824,50825,50827,50829,50836,50837,50840,50844,50852,50853,
+50855,50857,50864,50865,50868,50872,50873,50874,50880,50881,50883,50885,50892,
+50893,50896,50900,50908,50909,50912,50913,50920,50921,50924,50928,50936,50937,
+50941,50948,50949,50952,50956,50964,50965,50967,50969,50976,50977,50980,50984,
+50992,50993,50995,50997,50999,51004,51005,51008,51012,51018,51020,51021,51023,
+51025,51026,51027,51028,51029,51030,51031,51032,51036,51040,51048,51051,51060,
+51061,51064,51068,51069,51070,51075,51076,51077,51079,51080,51081,51082,51086,
+51088,51089,51092,51094,51095,51096,51098,51104,51105,51107,51108,51109,51110,
+51116,51117,51120,51124,51132,51133,51135,51136,51137,51144,51145,51148,51150,
+51152,51160,51165,51172,51176,51180,51200,51201,51204,51208,51210,51216,51217,
+51219,51221,51222,51228,51229,51232,51236,51244,51245,51247,51249,51256,51260,
+51264,51272,51273,51276,51277,51284,51312,51313,51316,51320,51322,51328,51329,
+51331,51333,51334,51335,51339,51340,51341,51348,51357,51359,51361,51368,51388,
+51389,51396,51400,51404,51412,51413,51415,51417,51424,51425,51428,51445,51452,
+51453,51456,51460,51461,51462,51468,51469,51471,51473,
+51480,51500,51508,51536,51537,51540,51544,51552,51553,51555,51564,51568,51572,
+51580,51592,51593,51596,51600,51608,51609,51611,51613,51648,51649,51652,51655,
+51656,51658,51664,51665,51667,51669,51670,51673,51674,51676,51677,51680,51682,
+51684,51687,51692,51693,51695,51696,51697,51704,51705,51708,51712,51720,51721,
+51723,51724,51725,51732,51736,51753,51788,51789,51792,51796,51804,51805,51807,
+51808,51809,51816,51837,51844,51864,51900,51901,51904,51908,51916,51917,51919,
+51921,51923,51928,51929,51936,51948,51956,51976,51984,51988,51992,52000,52001,
+52033,52040,52041,52044,52048,52056,52057,52061,52068,52088,52089,52124,52152,
+52180,52196,52199,52201,52236,52237,52240,52244,52252,52253,52257,52258,52263,
+52264,52265,52268,52270,52272,52280,52281,52283,52284,52285,52286,52292,52293,
+52296,52300,52308,52309,52311,52312,52313,52320,52324,52326,52328,52336,52341,
+52376,52377,52380,52384,52392,52393,52395,52396,52397,52404,52405,52408,52412,
+52420,52421,52423,52425,52432,52436,52452,52460,52464,52481,52488,52489,52492,
+52496,52504,52505,52507,52509,52516,52520,52524,52537,52572,52576,52580,52588,
+52589,52591,52593,52600,52616,52628,52629,52632,52636,52644,52645,52647,52649,
+52656,52676,52684,52688,52712,52716,52720,52728,52729,52731,52733,52740,52744,
+52748,52756,52761,52768,52769,52772,52776,52784,52785,52787,52789,52824,52825,
+52828,52831,52832,52833,52840,52841,52843,52845,52852,52853,52856,52860,52868,
+52869,52871,52873,52880,52881,52884,52888,52896,52897,52899,52900,52901,52908,
+52909,52929,52964,52965,52968,52971,52972,52980,52981,
+52983,52984,52985,52992,52993,52996,53000,53008,53009,53011,53013,53020,53024,
+53028,53036,53037,53039,53040,53041,53048,53076,53077,53080,53084,53092,53093,
+53095,53097,53104,53105,53108,53112,53120,53125,53132,53153,53160,53168,53188,
+53216,53217,53220,53224,53232,53233,53235,53237,53244,53248,53252,53265,53272,
+53293,53300,53301,53304,53308,53316,53317,53319,53321,53328,53332,53336,53344,
+53356,53357,53360,53364,53372,53373,53377,53412,53413,53416,53420,53428,53429,
+53431,53433,53440,53441,53444,53448,53449,53456,53457,53459,53460,53461,53468,
+53469,53472,53476,53484,53485,53487,53488,53489,53496,53517,53552,53553,53556,
+53560,53562,53568,53569,53571,53572,53573,53580,53581,53584,53588,53596,53597,
+53599,53601,53608,53612,53628,53636,53640,53664,53665,53668,53672,53680,53681,
+53683,53685,53690,53692,53696,53720,53748,53752,53767,53769,53776,53804,53805,
+53808,53812,53820,53821,53823,53825,53832,53852,53860,53888,53889,53892,53896,
+53904,53905,53909,53916,53920,53924,53932,53937,53944,53945,53948,53951,53952,
+53954,53960,53961,53963,53972,53976,53980,53988,53989,54000,54001,54004,54008,
+54016,54017,54019,54021,54028,54029,54030,54032,54036,54038,54044,54045,54047,
+54048,54049,54053,54056,54057,54060,54064,54072,54073,54075,54076,54077,54084,
+54085,54140,54141,54144,54148,54156,54157,54159,54160,54161,54168,54169,54172,
+54176,54184,54185,54187,54189,54196,54200,54204,54212,54213,54216,54217,54224,
+54232,54241,54243,54252,54253,54256,54260,54268,54269,54271,54273,54280,54301,
+54336,54340,54364,54368,54372,54381,54383,54392,54393,
+54396,54399,54400,54402,54408,54409,54411,54413,54420,54441,54476,54480,54484,
+54492,54495,54504,54508,54512,54520,54523,54525,54532,54536,54540,54548,54549,
+54551,54588,54589,54592,54596,54604,54605,54607,54609,54616,54617,54620,54624,
+54629,54632,54633,54635,54637,54644,54645,54648,54652,54660,54661,54663,54664,
+54665,54672,54693,54728,54729,54732,54736,54738,54744,54745,54747,54749,54756,
+54757,54760,54764,54772,54773,54775,54777,54784,54785,54788,54792,54800,54801,
+54803,54804,54805,54812,54816,54820,54829,54840,54841,54844,54848,54853,54856,
+54857,54859,54861,54865,54868,54869,54872,54876,54887,54889,54896,54897,54900,
+54915,54917,54924,54925,54928,54932,54941,54943,54945,54952,54956,54960,54969,
+54971,54980,54981,54984,54988,54993,54996,54999,55001,55008,55012,55016,55024,
+55029,55036,55037,55040,55044,55057,55064,55065,55068,55072,55080,55081,55083,
+55085,55092,55093,55096,55100,55108,55111,55113,55120,55121,55124,55126,55127,
+55128,55129,55136,55137,55139,55141,55145,55148,55152,55156,55164,55165,55169,
+55176,55177,55180,55184,55192,55193,55195,55197,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,20285,20339,20551,20729,21152,21487,21621,21733,
+22025,23233,23478,26247,26550,26551,26607,27468,29634,30146,31292,33499,33540,
+34903,34952,35382,36040,36303,36603,36838,39381,21051,21364,21508,24682,24932,
+27580,29647,33050,35258,35282,38307,20355,21002,22718,22904,23014,24178,24185,
+25031,25536,26438,26604,26751,28567,30286,30475,30965,31240,31487,31777,32925,
+33390,33393,35563,38291,20075,21917,26359,28212,30883,31469,33883,35088,34638,
+38824,21208,22350,22570,23884,24863,25022,25121,25954,26577,27204,28187,29976,
+30131,30435,30640,32058,37039,37969,37970,40853,21283,23724,30002,32987,37440,
+38296,21083,22536,23004,23713,23831,24247,24378,24394,24951,27743,30074,30086,
+31968,32115,32177,32652,33108,33313,34193,35137,35611,37628,38477,40007,20171,
+20215,20491,20977,22607,24887,24894,24936,25913,27114,28433,30117,30342,30422,
+31623,33445,33995,63744,37799,38283,21888,23458,22353,63745,31923,32697,37301,
+20520,21435,23621,24040,25298,25454,25818,25831,28192,28844,31067,36317,36382,
+63746,36989,37445,37624,20094,20214,20581,24062,24314,24838,26967,33137,34388,
+36423,37749,39467,20062,20625,26480,26688,20745,21133,21138,27298,30652,37392,
+40660,21163,24623,36850,20552,25001,25581,25802,26684,27268,28608,33160,35233,
+38548,22533,29309,29356,29956,32121,32365,32937,35211,35700,36963,40273,25225,
+27770,28500,32080,32570,35363,20860,24906,31645,35609,37463,37772,20140,20435,
+20510,20670,20742,21185,21197,21375,22384,22659,24218,24465,24950,25004,
+25806,25964,26223,26299,26356,26775,28039,28805,28913,29855,29861,29898,30169,
+30828,30956,31455,31478,32069,32147,32789,32831,33051,33686,35686,36629,36885,
+37857,38915,38968,39514,39912,20418,21843,22586,22865,23395,23622,24760,25106,
+26690,26800,26856,28330,30028,30328,30926,31293,31995,32363,32380,35336,35489,
+35903,38542,40388,21476,21481,21578,21617,22266,22993,23396,23611,24235,25335,
+25911,25925,25970,26272,26543,27073,27837,30204,30352,30590,31295,32660,32771,
+32929,33167,33510,33533,33776,34241,34865,34996,35493,63747,36764,37678,38599,
+39015,39640,40723,21741,26011,26354,26767,31296,35895,40288,22256,22372,23825,
+26118,26801,26829,28414,29736,34974,39908,27752,63748,39592,20379,20844,20849,
+21151,23380,24037,24656,24685,25329,25511,25915,29657,31354,34467,36002,38799,
+20018,23521,25096,26524,29916,31185,33747,35463,35506,36328,36942,37707,38982,
+24275,27112,34303,37101,63749,20896,23448,23532,24931,26874,27454,28748,29743,
+29912,31649,32592,33733,35264,36011,38364,39208,21038,24669,25324,36866,20362,
+20809,21281,22745,24291,26336,27960,28826,29378,29654,31568,33009,37979,21350,
+25499,32619,20054,20608,22602,22750,24618,24871,25296,27088,39745,23439,32024,
+32945,36703,20132,20689,21676,21932,23308,23968,24039,25898,25934,26657,27211,
+29409,30350,30703,32094,32761,33184,34126,34527,36611,36686,37066,39171,39509,
+39851,19992,20037,20061,20167,20465,20855,21246,21312,21475,21477,21646,22036,
+22389,22434,23495,23943,24272,25084,25304,25937,26552,26601,27083,27472,27590,
+27628,27714,28317,28792,29399,29590,29699,30655,30697,
+31350,32127,32777,33276,33285,33290,33503,34914,35635,36092,36544,36881,37041,
+37476,37558,39378,39493,40169,40407,40860,22283,23616,33738,38816,38827,40628,
+21531,31384,32676,35033,36557,37089,22528,23624,25496,31391,23470,24339,31353,
+31406,33422,36524,20518,21048,21240,21367,22280,25331,25458,27402,28099,30519,
+21413,29527,34152,36470,38357,26426,27331,28528,35437,36556,39243,63750,26231,
+27512,36020,39740,63751,21483,22317,22862,25542,27131,29674,30789,31418,31429,
+31998,33909,35215,36211,36917,38312,21243,22343,30023,31584,33740,37406,63752,
+27224,20811,21067,21127,25119,26840,26997,38553,20677,21156,21220,25027,26020,
+26681,27135,29822,31563,33465,33771,35250,35641,36817,39241,63753,20170,22935,
+25810,26129,27278,29748,31105,31165,33449,34942,34943,35167,63754,37670,20235,
+21450,24613,25201,27762,32026,32102,20120,20834,30684,32943,20225,20238,20854,
+20864,21980,22120,22331,22522,22524,22804,22855,22931,23492,23696,23822,24049,
+24190,24524,25216,26071,26083,26398,26399,26462,26827,26820,27231,27450,27683,
+27773,27778,28103,29592,29734,29738,29826,29859,30072,30079,30849,30959,31041,
+31047,31048,31098,31637,32000,32186,32648,32774,32813,32908,35352,35663,35912,
+36215,37665,37668,39138,39249,39438,39439,39525,40594,32202,20342,21513,25326,
+26708,37329,21931,20794,63755,63756,23068,25062,63757,25295,25343,63758,63759,
+63760,63761,63762,63763,37027,63764,63765,63766,63767,63768,35582,63769,63770,
+63771,63772,26262,63773,29014,63774,63775,38627,63776,25423,25466,21335,63777,
+26511,26976,28275,63778,30007,63779,63780,63781,32013,
+63782,63783,34930,22218,23064,63784,63785,63786,63787,63788,20035,63789,20839,
+22856,26608,32784,63790,22899,24180,25754,31178,24565,24684,25288,25467,23527,
+23511,21162,63791,22900,24361,24594,63792,63793,63794,29785,63795,63796,63797,
+63798,63799,63800,39377,63801,63802,63803,63804,63805,63806,63807,63808,63809,
+63810,63811,28611,63812,63813,33215,36786,24817,63814,63815,33126,63816,63817,
+23615,63818,63819,63820,63821,63822,63823,63824,63825,23273,35365,26491,32016,
+63826,63827,63828,63829,63830,63831,33021,63832,63833,23612,27877,21311,28346,
+22810,33590,20025,20150,20294,21934,22296,22727,24406,26039,26086,27264,27573,
+28237,30701,31471,31774,32222,34507,34962,37170,37723,25787,28606,29562,30136,
+36948,21846,22349,25018,25812,26311,28129,28251,28525,28601,30192,32835,33213,
+34113,35203,35527,35674,37663,27795,30035,31572,36367,36957,21776,22530,22616,
+24162,25095,25758,26848,30070,31958,34739,40680,20195,22408,22382,22823,23565,
+23729,24118,24453,25140,25825,29619,33274,34955,36024,38538,40667,23429,24503,
+24755,20498,20992,21040,22294,22581,22615,23566,23648,23798,23947,24230,24466,
+24764,25361,25481,25623,26691,26873,27330,28120,28193,28372,28644,29182,30428,
+30585,31153,31291,33796,35241,36077,36339,36424,36867,36884,36947,37117,37709,
+38518,38876,27602,28678,29272,29346,29544,30563,31167,31716,32411,35712,22697,
+24775,25958,26109,26302,27788,28958,29129,35930,38931,20077,31361,20189,20908,
+20941,21205,21516,24999,26481,26704,26847,27934,28540,30140,30643,31461,33012,
+33891,37509,20828,26007,26460,26515,30168,31431,33651,
+63834,35910,36887,38957,23663,33216,33434,36929,36975,37389,24471,23965,27225,
+29128,30331,31561,34276,35588,37159,39472,21895,25078,63835,30313,32645,34367,
+34746,35064,37007,63836,27931,28889,29662,32097,33853,63837,37226,39409,63838,
+20098,21365,27396,27410,28734,29211,34349,40478,21068,36771,23888,25829,25900,
+27414,28651,31811,32412,34253,35172,35261,25289,33240,34847,24266,26391,28010,
+29436,29701,29807,34690,37086,20358,23821,24480,33802,20919,25504,30053,20142,
+20486,20841,20937,26753,27153,31918,31921,31975,33391,35538,36635,37327,20406,
+20791,21237,21570,24300,24942,25150,26053,27354,28670,31018,34268,34851,38317,
+39522,39530,40599,40654,21147,26310,27511,28701,31019,36706,38722,24976,25088,
+25891,28451,29001,29833,32244,32879,34030,36646,36899,37706,20925,21015,21155,
+27916,28872,35010,24265,25986,27566,28610,31806,29557,20196,20278,22265,63839,
+23738,23994,24604,29618,31533,32666,32718,32838,36894,37428,38646,38728,38936,
+40801,20363,28583,31150,37300,38583,21214,63840,25736,25796,27347,28510,28696,
+29200,30439,32769,34310,34396,36335,36613,38706,39791,40442,40565,30860,31103,
+32160,33737,37636,40575,40595,35542,22751,24324,26407,28711,29903,31840,32894,
+20769,28712,29282,30922,36034,36058,36084,38647,20102,20698,23534,24278,26009,
+29134,30274,30637,32842,34044,36988,39719,40845,22744,23105,23650,27155,28122,
+28431,30267,32047,32311,34078,35128,37860,38475,21129,26066,26611,27060,27969,
+28316,28687,29705,29792,30041,30244,30827,35628,39006,20845,25134,38520,20374,
+20523,23833,28138,32184,36650,24459,24900,26647,63841,
+38534,21202,32907,20956,20940,26974,31260,32190,33777,38517,20442,21033,21400,
+21519,21774,23653,24743,26446,26792,28012,29313,29432,29702,29827,63842,30178,
+31852,32633,32696,33673,35023,35041,37324,37328,38626,39881,21533,28542,29136,
+29848,34298,36522,38563,40023,40607,26519,28107,29747,33256,38678,30764,31435,
+31520,31890,25705,29802,30194,30908,30952,39340,39764,40635,23518,24149,28448,
+33180,33707,37000,19975,21325,23081,24018,24398,24930,25405,26217,26364,28415,
+28459,28771,30622,33836,34067,34875,36627,39237,39995,21788,25273,26411,27819,
+33545,35178,38778,20129,22916,24536,24537,26395,32178,32596,33426,33579,33725,
+36638,37017,22475,22969,23186,23504,26151,26522,26757,27599,29028,32629,36023,
+36067,36993,39749,33032,35978,38476,39488,40613,23391,27667,29467,30450,30431,
+33804,20906,35219,20813,20885,21193,26825,27796,30468,30496,32191,32236,38754,
+40629,28357,34065,20901,21517,21629,26126,26269,26919,28319,30399,30609,33559,
+33986,34719,37225,37528,40180,34946,20398,20882,21215,22982,24125,24917,25720,
+25721,26286,26576,27169,27597,27611,29279,29281,29761,30520,30683,32791,33468,
+33541,35584,35624,35980,26408,27792,29287,30446,30566,31302,40361,27519,27794,
+22818,26406,33945,21359,22675,22937,24287,25551,26164,26483,28218,29483,31447,
+33495,37672,21209,24043,25006,25035,25098,25287,25771,26080,26969,27494,27595,
+28961,29687,30045,32326,33310,33538,34154,35491,36031,38695,40289,22696,40664,
+20497,21006,21563,21839,25991,27766,32010,32011,32862,34442,38272,38639,21247,
+27797,29289,21619,23194,23614,23883,24396,24494,26410,
+26806,26979,28220,28228,30473,31859,32654,34183,35598,36855,38753,40692,23735,
+24758,24845,25003,25935,26107,26108,27665,27887,29599,29641,32225,38292,23494,
+34588,35600,21085,21338,25293,25615,25778,26420,27192,27850,29632,29854,31636,
+31893,32283,33162,33334,34180,36843,38649,39361,20276,21322,21453,21467,25292,
+25644,25856,26001,27075,27886,28504,29677,30036,30242,30436,30460,30928,30971,
+31020,32070,33324,34784,36820,38930,39151,21187,25300,25765,28196,28497,30332,
+36299,37297,37474,39662,39747,20515,20621,22346,22952,23592,24135,24439,25151,
+25918,26041,26049,26121,26507,27036,28354,30917,32033,32938,33152,33323,33459,
+33953,34444,35370,35607,37030,38450,40848,20493,20467,63843,22521,24472,25308,
+25490,26479,28227,28953,30403,32972,32986,35060,35061,35097,36064,36649,37197,
+38506,20271,20336,24091,26575,26658,30333,30334,39748,24161,27146,29033,29140,
+30058,63844,32321,34115,34281,39132,20240,31567,32624,38309,20961,24070,26805,
+27710,27726,27867,29359,31684,33539,27861,29754,20731,21128,22721,25816,27287,
+29863,30294,30887,34327,38370,38713,63845,21342,24321,35722,36776,36783,37002,
+21029,30629,40009,40712,19993,20482,20853,23643,24183,26142,26170,26564,26821,
+28851,29953,30149,31177,31453,36647,39200,39432,20445,22561,22577,23542,26222,
+27493,27921,28282,28541,29668,29995,33769,35036,35091,35676,36628,20239,20693,
+21264,21340,23443,24489,26381,31119,33145,33583,34068,35079,35206,36665,36667,
+39333,39954,26412,20086,20472,22857,23553,23791,23792,25447,26834,28925,29090,
+29739,32299,34028,34562,36898,37586,40179,19981,20184,
+20463,20613,21078,21103,21542,21648,22496,22827,23142,23386,23413,23500,24220,
+63846,25206,25975,26023,28014,28325,29238,31526,31807,32566,33104,33105,33178,
+33344,33433,33705,35331,36000,36070,36091,36212,36282,37096,37340,38428,38468,
+39385,40167,21271,20998,21545,22132,22707,22868,22894,24575,24996,25198,26128,
+27774,28954,30406,31881,31966,32027,33452,36033,38640,63847,20315,24343,24447,
+25282,23849,26379,26842,30844,32323,40300,19989,20633,21269,21290,21329,22915,
+23138,24199,24754,24970,25161,25209,26000,26503,27047,27604,27606,27607,27608,
+27832,63848,29749,30202,30738,30865,31189,31192,31875,32203,32737,32933,33086,
+33218,33778,34586,35048,35513,35692,36027,37145,38750,39131,40763,22188,23338,
+24428,25996,27315,27567,27996,28657,28693,29277,29613,36007,36051,38971,24977,
+27703,32856,39425,20045,20107,20123,20181,20282,20284,20351,20447,20735,21490,
+21496,21766,21987,22235,22763,22882,23057,23531,23546,23556,24051,24107,24473,
+24605,25448,26012,26031,26614,26619,26797,27515,27801,27863,28195,28681,29509,
+30722,31038,31040,31072,31169,31721,32023,32114,32902,33293,33678,34001,34503,
+35039,35408,35422,35613,36060,36198,36781,37034,39164,39391,40605,21066,63849,
+26388,63850,20632,21034,23665,25955,27733,29642,29987,30109,31639,33948,37240,
+38704,20087,25746,27578,29022,34217,19977,63851,26441,26862,28183,33439,34072,
+34923,25591,28545,37394,39087,19978,20663,20687,20767,21830,21930,22039,23360,
+23577,23776,24120,24202,24224,24258,24819,26705,27233,28248,29245,29248,29376,
+30456,31077,31665,32724,35059,35316,35443,35937,36062,
+38684,22622,29885,36093,21959,63852,31329,32034,33394,29298,29983,29989,63853,
+31513,22661,22779,23996,24207,24246,24464,24661,25234,25471,25933,26257,26329,
+26360,26646,26866,29312,29790,31598,32110,32214,32626,32997,33298,34223,35199,
+35475,36893,37604,40653,40736,22805,22893,24109,24796,26132,26227,26512,27728,
+28101,28511,30707,30889,33990,37323,37675,20185,20682,20808,21892,23307,23459,
+25159,25982,26059,28210,29053,29697,29764,29831,29887,30316,31146,32218,32341,
+32680,33146,33203,33337,34330,34796,35445,36323,36984,37521,37925,39245,39854,
+21352,23633,26964,27844,27945,28203,33292,34203,35131,35373,35498,38634,40807,
+21089,26297,27570,32406,34814,36109,38275,38493,25885,28041,29166,63854,22478,
+22995,23468,24615,24826,25104,26143,26207,29481,29689,30427,30465,31596,32854,
+32882,33125,35488,37266,19990,21218,27506,27927,31237,31545,32048,63855,36016,
+21484,22063,22609,23477,23567,23569,24034,25152,25475,25620,26157,26803,27836,
+28040,28335,28703,28836,29138,29990,30095,30094,30233,31505,31712,31787,32032,
+32057,34092,34157,34311,35380,36877,36961,37045,37559,38902,39479,20439,23660,
+26463,28049,31903,32396,35606,36118,36895,23403,24061,25613,33984,36956,39137,
+29575,23435,24730,26494,28126,35359,35494,36865,38924,21047,63856,28753,30862,
+37782,34928,37335,20462,21463,22013,22234,22402,22781,23234,23432,23723,23744,
+24101,24833,25101,25163,25480,25628,25910,25976,27193,27530,27700,27929,28465,
+29159,29417,29560,29703,29874,30246,30561,31168,31319,31466,31929,32143,32172,
+32353,32670,33065,33585,33936,34010,34282,34966,35504,
+35728,36664,36930,36995,37228,37526,37561,38539,38567,38568,38614,38656,38920,
+39318,39635,39706,21460,22654,22809,23408,23487,28113,28506,29087,29729,29881,
+32901,33789,24033,24455,24490,24642,26092,26642,26991,27219,27529,27957,28147,
+29667,30462,30636,31565,32020,33059,33308,33600,34036,34147,35426,35524,37255,
+37662,38918,39348,25100,34899,36848,37477,23815,23847,23913,29791,33181,34664,
+28629,25342,32722,35126,35186,19998,20056,20711,21213,21319,25215,26119,32361,
+34821,38494,20365,21273,22070,22987,23204,23608,23630,23629,24066,24337,24643,
+26045,26159,26178,26558,26612,29468,30690,31034,32709,33940,33997,35222,35430,
+35433,35553,35925,35962,22516,23508,24335,24687,25325,26893,27542,28252,29060,
+31698,34645,35672,36606,39135,39166,20280,20353,20449,21627,23072,23480,24892,
+26032,26216,29180,30003,31070,32051,33102,33251,33688,34218,34254,34563,35338,
+36523,36763,63857,36805,22833,23460,23526,24713,23529,23563,24515,27777,63858,
+28145,28683,29978,33455,35574,20160,21313,63859,38617,27663,20126,20420,20818,
+21854,23077,23784,25105,29273,33469,33706,34558,34905,35357,38463,38597,39187,
+40201,40285,22538,23731,23997,24132,24801,24853,25569,27138,28197,37122,37716,
+38990,39952,40823,23433,23736,25353,26191,26696,30524,38593,38797,38996,39839,
+26017,35585,36555,38332,21813,23721,24022,24245,26263,30284,33780,38343,22739,
+25276,29390,40232,20208,22830,24591,26171,27523,31207,40230,21395,21696,22467,
+23830,24859,26326,28079,30861,33406,38552,38724,21380,25212,25494,28082,32266,
+33099,38989,27387,32588,40367,40474,20063,20539,20918,
+22812,24825,25590,26928,29242,32822,63860,37326,24369,63861,63862,32004,33509,
+33903,33979,34277,36493,63863,20335,63864,63865,22756,23363,24665,25562,25880,
+25965,26264,63866,26954,27171,27915,28673,29036,30162,30221,31155,31344,63867,
+32650,63868,35140,63869,35731,37312,38525,63870,39178,22276,24481,26044,28417,
+30208,31142,35486,39341,39770,40812,20740,25014,25233,27277,33222,20547,22576,
+24422,28937,35328,35578,23420,34326,20474,20796,22196,22852,25513,28153,23978,
+26989,20870,20104,20313,63871,63872,63873,22914,63874,63875,27487,27741,63876,
+29877,30998,63877,33287,33349,33593,36671,36701,63878,39192,63879,63880,63881,
+20134,63882,22495,24441,26131,63883,63884,30123,32377,35695,63885,36870,39515,
+22181,22567,23032,23071,23476,63886,24310,63887,63888,25424,25403,63889,26941,
+27783,27839,28046,28051,28149,28436,63890,28895,28982,29017,63891,29123,29141,
+63892,30799,30831,63893,31605,32227,63894,32303,63895,34893,36575,63896,63897,
+63898,37467,63899,40182,63900,63901,63902,24709,28037,63903,29105,63904,63905,
+38321,21421,63906,63907,63908,26579,63909,28814,28976,29744,33398,33490,63910,
+38331,39653,40573,26308,63911,29121,33865,63912,63913,22603,63914,63915,23992,
+24433,63916,26144,26254,27001,27054,27704,27891,28214,28481,28634,28699,28719,
+29008,29151,29552,63917,29787,63918,29908,30408,31310,32403,63919,63920,33521,
+35424,36814,63921,37704,63922,38681,63923,63924,20034,20522,63925,21000,21473,
+26355,27757,28618,29450,30591,31330,33454,34269,34306,63926,35028,35427,35709,
+35947,63927,37555,63928,38675,38928,20116,20237,20425,
+20658,21320,21566,21555,21978,22626,22714,22887,23067,23524,24735,63929,25034,
+25942,26111,26212,26791,27738,28595,28879,29100,29522,31613,34568,35492,39986,
+40711,23627,27779,29508,29577,37434,28331,29797,30239,31337,32277,34314,20800,
+22725,25793,29934,29973,30320,32705,37013,38605,39252,28198,29926,31401,31402,
+33253,34521,34680,35355,23113,23436,23451,26785,26880,28003,29609,29715,29740,
+30871,32233,32747,33048,33109,33694,35916,38446,38929,26352,24448,26106,26505,
+27754,29579,20525,23043,27498,30702,22806,23916,24013,29477,30031,63930,63931,
+20709,20985,22575,22829,22934,23002,23525,63932,63933,23970,25303,25622,25747,
+25854,63934,26332,63935,27208,63936,29183,29796,63937,31368,31407,32327,32350,
+32768,33136,63938,34799,35201,35616,36953,63939,36992,39250,24958,27442,28020,
+32287,35109,36785,20433,20653,20887,21191,22471,22665,23481,24248,24898,27029,
+28044,28263,28342,29076,29794,29992,29996,32883,33592,33993,36362,37780,37854,
+63940,20110,20305,20598,20778,21448,21451,21491,23431,23507,23588,24858,24962,
+26100,29275,29591,29760,30402,31056,31121,31161,32006,32701,33419,34261,34398,
+36802,36935,37109,37354,38533,38632,38633,21206,24423,26093,26161,26671,29020,
+31286,37057,38922,20113,63941,27218,27550,28560,29065,32792,33464,34131,36939,
+38549,38642,38907,34074,39729,20112,29066,38596,20803,21407,21729,22291,22290,
+22435,23195,23236,23491,24616,24895,25588,27781,27961,28274,28304,29232,29503,
+29783,33489,34945,36677,36960,63942,38498,39000,40219,26376,36234,37470,20301,
+20553,20702,21361,22285,22996,23041,23561,24944,26256,
+28205,29234,29771,32239,32963,33806,33894,34111,34655,34907,35096,35586,36949,
+38859,39759,20083,20369,20754,20842,63943,21807,21929,23418,23461,24188,24189,
+24254,24736,24799,24840,24841,25540,25912,26377,63944,26580,26586,63945,26977,
+26978,27833,27943,63946,28216,63947,28641,29494,29495,63948,29788,30001,63949,
+30290,63950,63951,32173,33278,33848,35029,35480,35547,35565,36400,36418,36938,
+36926,36986,37193,37321,37742,63952,63953,22537,63954,27603,32905,32946,63955,
+63956,20801,22891,23609,63957,63958,28516,29607,32996,36103,63959,37399,38287,
+63960,63961,63962,63963,32895,25102,28700,32104,34701,63964,22432,24681,24903,
+27575,35518,37504,38577,20057,21535,28139,34093,38512,38899,39150,25558,27875,
+37009,20957,25033,33210,40441,20381,20506,20736,23452,24847,25087,25836,26885,
+27589,30097,30691,32681,33380,34191,34811,34915,35516,35696,37291,20108,20197,
+20234,63965,63966,22839,23016,63967,24050,24347,24411,24609,63968,63969,63970,
+63971,29246,29669,63972,30064,30157,63973,31227,63974,32780,32819,32900,33505,
+33617,63975,63976,36029,36019,36999,63977,63978,39156,39180,63979,63980,28727,
+30410,32714,32716,32764,35610,20154,20161,20995,21360,63981,21693,22240,23035,
+23493,24341,24525,28270,63982,63983,32106,33589,63984,34451,35469,63985,38765,
+38775,63986,63987,19968,20314,20350,22777,26085,28322,36920,37808,39353,20219,
+22764,22922,23001,24641,63988,63989,31252,63990,33615,36035,20837,21316,63991,
+63992,63993,20173,21097,23381,33471,20180,21050,21672,22985,23039,23376,23383,
+23388,24675,24904,28363,28825,29038,29574,29943,30133,
+30913,32043,32773,33258,33576,34071,34249,35566,36039,38604,20316,21242,22204,
+26027,26152,28796,28856,29237,32189,33421,37196,38592,40306,23409,26855,27544,
+28538,30430,23697,26283,28507,31668,31786,34870,38620,19976,20183,21280,22580,
+22715,22767,22892,23559,24115,24196,24373,25484,26290,26454,27167,27299,27404,
+28479,29254,63994,29520,29835,31456,31911,33144,33247,33255,33674,33900,34083,
+34196,34255,35037,36115,37292,38263,38556,20877,21705,22312,23472,25165,26448,
+26685,26771,28221,28371,28797,32289,35009,36001,36617,40779,40782,29229,31631,
+35533,37658,20295,20302,20786,21632,22992,24213,25269,26485,26990,27159,27822,
+28186,29401,29482,30141,31672,32053,33511,33785,33879,34295,35419,36015,36487,
+36889,37048,38606,40799,21219,21514,23265,23490,25688,25973,28404,29380,63995,
+30340,31309,31515,31821,32318,32735,33659,35627,36042,36196,36321,36447,36842,
+36857,36969,37841,20291,20346,20659,20840,20856,21069,21098,22625,22652,22880,
+23560,23637,24283,24731,25136,26643,27583,27656,28593,29006,29728,30000,30008,
+30033,30322,31564,31627,31661,31686,32399,35438,36670,36681,37439,37523,37666,
+37931,38651,39002,39019,39198,20999,25130,25240,27993,30308,31434,31680,32118,
+21344,23742,24215,28472,28857,31896,38673,39822,40670,25509,25722,34678,19969,
+20117,20141,20572,20597,21576,22979,23450,24128,24237,24311,24449,24773,25402,
+25919,25972,26060,26230,26232,26622,26984,27273,27491,27712,28096,28136,28191,
+28254,28702,28833,29582,29693,30010,30555,30855,31118,31243,31357,31934,32142,
+33351,35330,35562,35998,37165,37194,37336,37478,37580,
+37664,38662,38742,38748,38914,40718,21046,21137,21884,22564,24093,24351,24716,
+25552,26799,28639,31085,31532,33229,34234,35069,35576,36420,37261,38500,38555,
+38717,38988,40778,20430,20806,20939,21161,22066,24340,24427,25514,25805,26089,
+26177,26362,26361,26397,26781,26839,27133,28437,28526,29031,29157,29226,29866,
+30522,31062,31066,31199,31264,31381,31895,31967,32068,32368,32903,34299,34468,
+35412,35519,36249,36481,36896,36973,37347,38459,38613,40165,26063,31751,36275,
+37827,23384,23562,21330,25305,29469,20519,23447,24478,24752,24939,26837,28121,
+29742,31278,32066,32156,32305,33131,36394,36405,37758,37912,20304,22352,24038,
+24231,25387,32618,20027,20303,20367,20570,23005,32964,21610,21608,22014,22863,
+23449,24030,24282,26205,26417,26609,26666,27880,27954,28234,28557,28855,29664,
+30087,31820,32002,32044,32162,33311,34523,35387,35461,36208,36490,36659,36913,
+37198,37202,37956,39376,31481,31909,20426,20737,20934,22472,23535,23803,26201,
+27197,27994,28310,28652,28940,30063,31459,34850,36897,36981,38603,39423,33537,
+20013,20210,34886,37325,21373,27355,26987,27713,33914,22686,24974,26366,25327,
+28893,29969,30151,32338,33976,35657,36104,20043,21482,21675,22320,22336,24535,
+25345,25351,25711,25903,26088,26234,26525,26547,27490,27744,27802,28460,30693,
+30757,31049,31063,32025,32930,33026,33267,33437,33463,34584,35468,63996,36100,
+36286,36978,30452,31257,31287,32340,32887,21767,21972,22645,25391,25634,26185,
+26187,26733,27035,27524,27941,28337,29645,29800,29857,30043,30137,30433,30494,
+30603,31206,32265,32285,33275,34095,34967,35386,36049,
+36587,36784,36914,37805,38499,38515,38663,20356,21489,23018,23241,24089,26702,
+29894,30142,31209,31378,33187,34541,36074,36300,36845,26015,26389,63997,22519,
+28503,32221,36655,37878,38598,24501,25074,28548,19988,20376,20511,21449,21983,
+23919,24046,27425,27492,30923,31642,63998,36425,36554,36974,25417,25662,30528,
+31364,37679,38015,40810,25776,28591,29158,29864,29914,31428,31762,32386,31922,
+32408,35738,36106,38013,39184,39244,21049,23519,25830,26413,32046,20717,21443,
+22649,24920,24921,25082,26028,31449,35730,35734,20489,20513,21109,21809,23100,
+24288,24432,24884,25950,26124,26166,26274,27085,28356,28466,29462,30241,31379,
+33081,33369,33750,33980,20661,22512,23488,23528,24425,25505,30758,32181,33756,
+34081,37319,37365,20874,26613,31574,36012,20932,22971,24765,34389,20508,63999,
+21076,23610,24957,25114,25299,25842,26021,28364,30240,33034,36448,38495,38587,
+20191,21315,21912,22825,24029,25797,27849,28154,29588,31359,33307,34214,36068,
+36368,36983,37351,38369,38433,38854,20984,21746,21894,24505,25764,28552,32180,
+36639,36685,37941,20681,23574,27838,28155,29979,30651,31805,31844,35449,35522,
+22558,22974,24086,25463,29266,30090,30571,35548,36028,36626,24307,26228,28152,
+32893,33729,35531,38737,39894,64000,21059,26367,28053,28399,32224,35558,36910,
+36958,39636,21021,21119,21736,24980,25220,25307,26786,26898,26970,27189,28818,
+28966,30813,30977,30990,31186,31245,32918,33400,33493,33609,34121,35970,36229,
+37218,37259,37294,20419,22225,29165,30679,34560,35320,23544,24534,26449,37032,
+21474,22618,23541,24740,24961,25696,32317,32880,34085,
+37507,25774,20652,23828,26368,22684,25277,25512,26894,27000,27166,28267,30394,
+31179,33467,33833,35535,36264,36861,37138,37195,37276,37648,37656,37786,38619,
+39478,39949,19985,30044,31069,31482,31569,31689,32302,33988,36441,36468,36600,
+36880,26149,26943,29763,20986,26414,40668,20805,24544,27798,34802,34909,34935,
+24756,33205,33795,36101,21462,21561,22068,23094,23601,28810,32736,32858,33030,
+33261,36259,37257,39519,40434,20596,20164,21408,24827,28204,23652,20360,20516,
+21988,23769,24159,24677,26772,27835,28100,29118,30164,30196,30305,31258,31305,
+32199,32251,32622,33268,34473,36636,38601,39347,40786,21063,21189,39149,35242,
+19971,26578,28422,20405,23522,26517,27784,28024,29723,30759,37341,37756,34756,
+31204,31281,24555,20182,21668,21822,22702,22949,24816,25171,25302,26422,26965,
+33333,38464,39345,39389,20524,21331,21828,22396,64001,25176,64002,25826,26219,
+26589,28609,28655,29730,29752,35351,37944,21585,22022,22374,24392,24986,27470,
+28760,28845,32187,35477,22890,33067,25506,30472,32829,36010,22612,25645,27067,
+23445,24081,28271,64003,34153,20812,21488,22826,24608,24907,27526,27760,27888,
+31518,32974,33492,36294,37040,39089,64004,25799,28580,25745,25860,20814,21520,
+22303,35342,24927,26742,64005,30171,31570,32113,36890,22534,27084,33151,35114,
+36864,38969,20600,22871,22956,25237,36879,39722,24925,29305,38358,22369,23110,
+24052,25226,25773,25850,26487,27874,27966,29228,29750,30772,32631,33453,36315,
+38935,21028,22338,26495,29256,29923,36009,36774,37393,38442,20843,21485,25420,
+20329,21764,24726,25943,27803,28031,29260,29437,31255,
+35207,35997,24429,28558,28921,33192,24846,20415,20559,25153,29255,31687,32232,
+32745,36941,38829,39449,36022,22378,24179,26544,33805,35413,21536,23318,24163,
+24290,24330,25987,32954,34109,38281,38491,20296,21253,21261,21263,21638,21754,
+22275,24067,24598,25243,25265,25429,64006,27873,28006,30129,30770,32990,33071,
+33502,33889,33970,34957,35090,36875,37610,39165,39825,24133,26292,26333,28689,
+29190,64007,20469,21117,24426,24915,26451,27161,28418,29922,31080,34920,35961,
+39111,39108,39491,21697,31263,26963,35575,35914,39080,39342,24444,25259,30130,
+30382,34987,36991,38466,21305,24380,24517,27852,29644,30050,30091,31558,33534,
+39325,20047,36924,19979,20309,21414,22799,24264,26160,27827,29781,33655,34662,
+36032,36944,38686,39957,22737,23416,34384,35604,40372,23506,24680,24717,26097,
+27735,28450,28579,28698,32597,32752,38289,38290,38480,38867,21106,36676,20989,
+21547,21688,21859,21898,27323,28085,32216,33382,37532,38519,40569,21512,21704,
+30418,34532,38308,38356,38492,20130,20233,23022,23270,24055,24658,25239,26477,
+26689,27782,28207,32568,32923,33322,64008,64009,38917,20133,20565,21683,22419,
+22874,23401,23475,25032,26999,28023,28707,34809,35299,35442,35559,36994,39405,
+39608,21182,26680,20502,24184,26447,33607,34892,20139,21521,22190,29670,37141,
+38911,39177,39255,39321,22099,22687,34395,35377,25010,27382,29563,36562,27463,
+38570,39511,22869,29184,36203,38761,20436,23796,24358,25080,26203,27883,28843,
+29572,29625,29694,30505,30541,32067,32098,32291,33335,34898,64010,36066,37449,
+39023,23377,31348,34880,38913,23244,20448,21332,22846,
+23805,25406,28025,29433,33029,33031,33698,37583,38960,20136,20804,21009,22411,
+24418,27842,28366,28677,28752,28847,29074,29673,29801,33610,34722,34913,36872,
+37026,37795,39336,20846,24407,24800,24935,26291,34137,36426,37295,38795,20046,
+20114,21628,22741,22778,22909,23733,24359,25142,25160,26122,26215,27627,28009,
+28111,28246,28408,28564,28640,28649,28765,29392,29733,29786,29920,30355,31068,
+31946,32286,32993,33446,33899,33983,34382,34399,34676,35703,35946,37804,38912,
+39013,24785,25110,37239,23130,26127,28151,28222,29759,39746,24573,24794,31503,
+21700,24344,27742,27859,27946,28888,32005,34425,35340,40251,21270,21644,23301,
+27194,28779,30069,31117,31166,33457,33775,35441,35649,36008,38772,64011,25844,
+25899,30906,30907,31339,20024,21914,22864,23462,24187,24739,25563,27489,26213,
+26707,28185,29029,29872,32008,36996,39529,39973,27963,28369,29502,35905,38346,
+20976,24140,24488,24653,24822,24880,24908,26179,26180,27045,27841,28255,28361,
+28514,29004,29852,30343,31681,31783,33618,34647,36945,38541,40643,21295,22238,
+24315,24458,24674,24724,25079,26214,26371,27292,28142,28590,28784,29546,32362,
+33214,33588,34516,35496,36036,21123,29554,23446,27243,37892,21742,22150,23389,
+25928,25989,26313,26783,28045,28102,29243,32948,37237,39501,20399,20505,21402,
+21518,21564,21897,21957,24127,24460,26429,29030,29661,36869,21211,21235,22628,
+22734,28932,29071,29179,34224,35347,26248,34216,21927,26244,29002,33841,21321,
+21913,27585,24409,24509,25582,26249,28999,35569,36637,40638,20241,25658,28875,
+30054,34407,24676,35662,40440,20807,20982,21256,27958,
+33016,40657,26133,27427,28824,30165,21507,23673,32007,35350,27424,27453,27462,
+21560,24688,27965,32725,33288,20694,20958,21916,22123,22221,23020,23305,24076,
+24985,24984,25137,26206,26342,29081,29113,29114,29351,31143,31232,32690,35440,
libc/musl/src/locale/langinfo.c
@@ -0,0 +1,73 @@
+#include <locale.h>
+#include <langinfo.h>
+#include "locale_impl.h"
+
+static const char c_time[] =
+	"Sun\0" "Mon\0" "Tue\0" "Wed\0" "Thu\0" "Fri\0" "Sat\0"
+	"Sunday\0" "Monday\0" "Tuesday\0" "Wednesday\0"
+	"Thursday\0" "Friday\0" "Saturday\0"
+	"Jan\0" "Feb\0" "Mar\0" "Apr\0" "May\0" "Jun\0"
+	"Jul\0" "Aug\0" "Sep\0" "Oct\0" "Nov\0" "Dec\0"
+	"January\0"   "February\0" "March\0"    "April\0"
+	"May\0"       "June\0"     "July\0"     "August\0"
+	"September\0" "October\0"  "November\0" "December\0"
+	"AM\0" "PM\0"
+	"%a %b %e %T %Y\0"
+	"%m/%d/%y\0"
+	"%H:%M:%S\0"
+	"%I:%M:%S %p\0"
+	"\0"
+	"\0"
+	"%m/%d/%y\0"
+	"0123456789\0"
+	"%a %b %e %T %Y\0"
+	"%H:%M:%S";
+
+static const char c_messages[] = "^[yY]\0" "^[nN]\0" "yes\0" "no";
+static const char c_numeric[] = ".\0" "";
+
+char *__nl_langinfo_l(nl_item item, locale_t loc)
+{
+	int cat = item >> 16;
+	int idx = item & 65535;
+	const char *str;
+
+	if (item == CODESET) return loc->cat[LC_CTYPE] ? "UTF-8" : "ASCII";
+
+	/* _NL_LOCALE_NAME extension */
+	if (idx == 65535 && cat < LC_ALL)
+		return loc->cat[cat] ? (char *)loc->cat[cat]->name : "C";
+	
+	switch (cat) {
+	case LC_NUMERIC:
+		if (idx > 1) return "";
+		str = c_numeric;
+		break;
+	case LC_TIME:
+		if (idx > 0x31) return "";
+		str = c_time;
+		break;
+	case LC_MONETARY:
+		if (idx > 0) return "";
+		str = "";
+		break;
+	case LC_MESSAGES:
+		if (idx > 3) return "";
+		str = c_messages;
+		break;
+	default:
+		return "";
+	}
+
+	for (; idx; idx--, str++) for (; *str; str++);
+	if (cat != LC_NUMERIC && *str) str = LCTRANS(str, cat, loc);
+	return (char *)str;
+}
+
+char *__nl_langinfo(nl_item item)
+{
+	return __nl_langinfo_l(item, CURRENT_LOCALE);
+}
+
+weak_alias(__nl_langinfo, nl_langinfo);
+weak_alias(__nl_langinfo_l, nl_langinfo_l);
libc/musl/src/locale/legacychars.h
@@ -0,0 +1,40 @@
+256,257,258,259,260,261,262,263,264,265,266,267,268,269,270,271,272,273,274,
+275,278,279,280,281,282,283,284,285,286,287,288,289,290,291,292,293,294,295,
+296,297,298,299,302,303,304,305,308,309,310,311,312,313,314,315,316,317,318,
+321,322,323,324,325,326,327,328,330,331,332,333,336,337,338,339,340,341,342,
+343,344,345,346,347,348,349,350,351,352,353,354,355,356,357,358,359,360,361,
+362,363,364,365,366,367,368,369,370,371,372,373,374,375,376,377,378,379,380,
+381,382,402,416,417,431,432,536,537,538,539,710,711,728,729,731,732,733,768,
+769,771,777,803,890,900,901,902,904,905,906,908,910,911,912,913,914,915,916,
+917,918,919,920,921,922,923,924,925,926,927,928,929,931,932,933,934,935,936,
+937,938,939,940,941,942,943,944,945,946,947,948,949,950,951,952,953,954,955,
+956,957,958,959,960,961,962,963,964,965,966,967,968,969,970,971,972,973,974,
+1025,1026,1027,1028,1029,1030,1031,1032,1033,1034,1035,1036,1038,1039,1040,
+1041,1042,1043,1044,1045,1046,1047,1048,1049,1050,1051,1052,1053,1054,1055,
+1056,1057,1058,1059,1060,1061,1062,1063,1064,1065,1066,1067,1068,1069,1070,
+1071,
+1072,1073,1074,1075,1076,1077,1078,1079,1080,1081,1082,1083,1084,1085,1086,
+1087,1088,1089,1090,1091,1092,1093,1094,1095,1096,1097,1098,1099,1100,1101,
+1102,1103,1105,1106,1107,1108,1109,1110,1111,1112,1113,1114,1115,1116,1118,
+1119,1168,1169,1456,1457,1458,1459,1460,1461,1462,1463,1464,1465,1467,1468,
+1469,1470,1471,1472,1473,1474,1475,1488,1489,1490,1491,1492,1493,1494,1495,
+1496,1497,1498,1499,1500,1501,1502,1503,1504,1505,1506,1507,1508,1509,1510,
+1511,1512,1513,1514,1520,1521,1522,1523,1524,1548,1563,1567,1569,1570,1571,
+1572,1573,1574,1575,1576,1577,1578,1579,1580,1581,1582,1583,1584,1585,1586,
+1587,1588,1589,1590,1591,1592,1593,1594,1600,1601,1602,1603,1604,1605,1606,
+1607,1608,1609,1610,1611,1612,1613,1614,1615,1616,1617,1618,1657,1662,1670,
+1672,1681,1688,1705,1711,1722,1726,1729,1746,3585,3586,3587,3588,3589,3590,
+3591,3592,3593,3594,3595,3596,3597,3598,3599,3600,3601,3602,3603,3604,3605,
+3606,3607,3608,3609,3610,3611,3612,3613,3614,3615,3616,3617,3618,3619,3620,
+3621,3622,3623,3624,3625,3626,3627,3628,3629,3630,3631,3632,3633,3634,3635,
+3636,3637,3638,3639,3640,3641,3642,3647,3648,3649,3650,3651,3652,3653,3654,
+3655,3656,3657,3658,3659,3660,3661,3662,3663,3664,3665,3666,3667,3668,3669,
+3670,3671,3672,3673,3674,3675,7682,7683,7690,7691,7710,7711,7744,7745,7766,
+7767,
+7776,7777,7786,7787,7808,7809,7810,7811,7812,7813,7922,7923,8204,8205,8206,
+8207,8211,8212,8213,8215,8216,8217,8218,8220,8221,8222,8224,8225,8226,8230,
+8240,8249,8250,8319,8359,8362,8363,8364,8367,8470,8482,8729,8730,8734,8745,
+8776,8801,8804,8805,8976,8992,8993,9472,9474,9484,9488,9492,9496,9500,9508,
+9516,9524,9532,9552,9553,9554,9555,9556,9557,9558,9559,9560,9561,9562,9563,
+9564,9565,9566,9567,9568,9569,9570,9571,9572,9573,9574,9575,9576,9577,9578,
+9579,9580,9600,9604,9608,9612,9616,9617,9618,9619,9632,
libc/musl/src/locale/locale_map.c
@@ -0,0 +1,113 @@
+#include <locale.h>
+#include <string.h>
+#include <sys/mman.h>
+#include "locale_impl.h"
+#include "libc.h"
+#include "lock.h"
+
+const char *__lctrans_impl(const char *msg, const struct __locale_map *lm)
+{
+	const char *trans = 0;
+	if (lm) trans = __mo_lookup(lm->map, lm->map_size, msg);
+	return trans ? trans : msg;
+}
+
+static const char envvars[][12] = {
+	"LC_CTYPE",
+	"LC_NUMERIC",
+	"LC_TIME",
+	"LC_COLLATE",
+	"LC_MONETARY",
+	"LC_MESSAGES",
+};
+
+const struct __locale_map *__get_locale(int cat, const char *val)
+{
+	static volatile int lock[1];
+	static void *volatile loc_head;
+	const struct __locale_map *p;
+	struct __locale_map *new = 0;
+	const char *path = 0, *z;
+	char buf[256];
+	size_t l, n;
+
+	if (!*val) {
+		(val = getenv("LC_ALL")) && *val ||
+		(val = getenv(envvars[cat])) && *val ||
+		(val = getenv("LANG")) && *val ||
+		(val = "C.UTF-8");
+	}
+
+	/* Limit name length and forbid leading dot or any slashes. */
+	for (n=0; n<LOCALE_NAME_MAX && val[n] && val[n]!='/'; n++);
+	if (val[0]=='.' || val[n]) val = "C.UTF-8";
+	int builtin = (val[0]=='C' && !val[1])
+		|| !strcmp(val, "C.UTF-8")
+		|| !strcmp(val, "POSIX");
+
+	if (builtin) {
+		if (cat == LC_CTYPE && val[1]=='.')
+			return (void *)&__c_dot_utf8;
+		return 0;
+	}
+
+	for (p=loc_head; p; p=p->next)
+		if (!strcmp(val, p->name)) return p;
+
+	LOCK(lock);
+
+	for (p=loc_head; p; p=p->next)
+		if (!strcmp(val, p->name)) {
+			UNLOCK(lock);
+			return p;
+		}
+
+	if (!libc.secure) path = getenv("MUSL_LOCPATH");
+	/* FIXME: add a default path? */
+
+	if (path) for (; *path; path=z+!!*z) {
+		z = __strchrnul(path, ':');
+		l = z - path - !!*z;
+		if (l >= sizeof buf - n - 2) continue;
+		memcpy(buf, path, l);
+		buf[l] = '/';
+		memcpy(buf+l+1, val, n);
+		buf[l+1+n] = 0;
+		size_t map_size;
+		const void *map = __map_file(buf, &map_size);
+		if (map) {
+			new = malloc(sizeof *new);
+			if (!new) {
+				__munmap((void *)map, map_size);
+				break;
+			}
+			new->map = map;
+			new->map_size = map_size;
+			memcpy(new->name, val, n);
+			new->name[n] = 0;
+			new->next = loc_head;
+			loc_head = new;
+			break;
+		}
+	}
+
+	/* If no locale definition was found, make a locale map
+	 * object anyway to store the name, which is kept for the
+	 * sake of being able to do message translations at the
+	 * application level. */
+	if (!new && (new = malloc(sizeof *new))) {
+		new->map = __c_dot_utf8.map;
+		new->map_size = __c_dot_utf8.map_size;
+		memcpy(new->name, val, n);
+		new->name[n] = 0;
+		new->next = loc_head;
+		loc_head = new;
+	}
+
+	/* For LC_CTYPE, never return a null pointer unless the
+	 * requested name was "C" or "POSIX". */
+	if (!new && cat == LC_CTYPE) new = (void *)&__c_dot_utf8;
+
+	UNLOCK(lock);
+	return new;
+}
libc/musl/src/locale/localeconv.c
@@ -0,0 +1,34 @@
+#include <locale.h>
+#include <limits.h>
+
+static const struct lconv posix_lconv = {
+	.decimal_point = ".",
+	.thousands_sep = "",
+	.grouping = "",
+	.int_curr_symbol = "",
+	.currency_symbol = "",
+	.mon_decimal_point = "",
+	.mon_thousands_sep = "",
+	.mon_grouping = "",
+	.positive_sign = "",
+	.negative_sign = "",
+	.int_frac_digits = CHAR_MAX,
+	.frac_digits = CHAR_MAX,
+	.p_cs_precedes = CHAR_MAX,
+	.p_sep_by_space = CHAR_MAX,
+	.n_cs_precedes = CHAR_MAX,
+	.n_sep_by_space = CHAR_MAX,
+	.p_sign_posn = CHAR_MAX,
+	.n_sign_posn = CHAR_MAX,
+	.int_p_cs_precedes = CHAR_MAX,
+	.int_p_sep_by_space = CHAR_MAX,
+	.int_n_cs_precedes = CHAR_MAX,
+	.int_n_sep_by_space = CHAR_MAX,
+	.int_p_sign_posn = CHAR_MAX,
+	.int_n_sign_posn = CHAR_MAX,
+};
+
+struct lconv *localeconv(void)
+{
+	return (void *)&posix_lconv;
+}
libc/musl/src/locale/newlocale.c
@@ -0,0 +1,58 @@
+#include <stdlib.h>
+#include <string.h>
+#include <pthread.h>
+#include "locale_impl.h"
+
+static pthread_once_t default_locale_once;
+static struct __locale_struct default_locale, default_ctype_locale;
+
+static void default_locale_init(void)
+{
+	for (int i=0; i<LC_ALL; i++)
+		default_locale.cat[i] = __get_locale(i, "");
+	default_ctype_locale.cat[LC_CTYPE] = default_locale.cat[LC_CTYPE];
+}
+
+int __loc_is_allocated(locale_t loc)
+{
+	return loc && loc != C_LOCALE && loc != UTF8_LOCALE
+		&& loc != &default_locale && loc != &default_ctype_locale;
+}
+
+locale_t __newlocale(int mask, const char *name, locale_t loc)
+{
+	struct __locale_struct tmp;
+
+	for (int i=0; i<LC_ALL; i++) {
+		tmp.cat[i] = (!(mask & (1<<i)) && loc) ? loc->cat[i] :
+			__get_locale(i, (mask & (1<<i)) ? name : "");
+		if (tmp.cat[i] == LOC_MAP_FAILED)
+			return 0;
+	}
+
+	/* For locales with allocated storage, modify in-place. */
+	if (__loc_is_allocated(loc)) {
+		*loc = tmp;
+		return loc;
+	}
+
+	/* Otherwise, first see if we can use one of the builtin locales.
+	 * This makes the common usage case for newlocale, getting a C locale
+	 * with predictable behavior, very fast, and more importantly, fail-safe. */
+	if (!memcmp(&tmp, C_LOCALE, sizeof tmp)) return C_LOCALE;
+	if (!memcmp(&tmp, UTF8_LOCALE, sizeof tmp)) return UTF8_LOCALE;
+
+	/* And provide builtins for the initial default locale, and a
+	 * variant of the C locale honoring the default locale's encoding. */
+	pthread_once(&default_locale_once, default_locale_init);
+	if (!memcmp(&tmp, &default_locale, sizeof tmp)) return &default_locale;
+	if (!memcmp(&tmp, &default_ctype_locale, sizeof tmp))
+		return &default_ctype_locale;
+
+	/* If no builtin locale matched, attempt to allocate and copy. */
+	if ((loc = malloc(sizeof *loc))) *loc = tmp;
+
+	return loc;
+}
+
+weak_alias(__newlocale, newlocale);
libc/musl/src/locale/pleval.c
@@ -0,0 +1,158 @@
+#include <stdlib.h>
+#include <ctype.h>
+#include "pleval.h"
+
+/*
+grammar:
+
+Start = Expr ';'
+Expr  = Or | Or '?' Expr ':' Expr
+Or    = And | Or '||' And
+And   = Eq | And '&&' Eq
+Eq    = Rel | Eq '==' Rel | Eq '!=' Rel
+Rel   = Add | Rel '<=' Add | Rel '>=' Add | Rel '<' Add | Rel '>' Add
+Add   = Mul | Add '+' Mul | Add '-' Mul
+Mul   = Prim | Mul '*' Prim | Mul '/' Prim | Mul '%' Prim
+Prim  = '(' Expr ')' | '!' Prim | decimal | 'n'
+
+internals:
+
+recursive descent expression evaluator with stack depth limit.
+for binary operators an operator-precedence parser is used.
+eval* functions store the result of the parsed subexpression
+and return a pointer to the next non-space character.
+*/
+
+struct st {
+	unsigned long r;
+	unsigned long n;
+	int op;
+};
+
+static const char *skipspace(const char *s)
+{
+	while (isspace(*s)) s++;
+	return s;
+}
+
+static const char *evalexpr(struct st *st, const char *s, int d);
+
+static const char *evalprim(struct st *st, const char *s, int d)
+{
+	char *e;
+	if (--d < 0) return "";
+	s = skipspace(s);
+	if (isdigit(*s)) {
+		st->r = strtoul(s, &e, 10);
+		if (e == s || st->r == -1) return "";
+		return skipspace(e);
+	}
+	if (*s == 'n') {
+		st->r = st->n;
+		return skipspace(s+1);
+	}
+	if (*s == '(') {
+		s = evalexpr(st, s+1, d);
+		if (*s != ')') return "";
+		return skipspace(s+1);
+	}
+	if (*s == '!') {
+		s = evalprim(st, s+1, d);
+		st->r = !st->r;
+		return s;
+	}
+	return "";
+}
+
+static int binop(struct st *st, int op, unsigned long left)
+{
+	unsigned long a = left, b = st->r;
+	switch (op) {
+	case 0: st->r = a||b; return 0;
+	case 1: st->r = a&&b; return 0;
+	case 2: st->r = a==b; return 0;
+	case 3: st->r = a!=b; return 0;
+	case 4: st->r = a>=b; return 0;
+	case 5: st->r = a<=b; return 0;
+	case 6: st->r = a>b; return 0;
+	case 7: st->r = a<b; return 0;
+	case 8: st->r = a+b; return 0;
+	case 9: st->r = a-b; return 0;
+	case 10: st->r = a*b; return 0;
+	case 11: if (b) {st->r = a%b; return 0;} return 1;
+	case 12: if (b) {st->r = a/b; return 0;} return 1;
+	}
+	return 1;
+}
+
+static const char *parseop(struct st *st, const char *s)
+{
+	static const char opch[11] = "|&=!><+-*%/";
+	static const char opch2[6] = "|&====";
+	int i;
+	for (i=0; i<11; i++)
+		if (*s == opch[i]) {
+			/* note: >,< are accepted with or without = */
+			if (i<6 && s[1] == opch2[i]) {
+				st->op = i;
+				return s+2;
+			}
+			if (i>=4) {
+				st->op = i+2;
+				return s+1;
+			}
+			break;
+		}
+	st->op = 13;
+	return s;
+}
+
+static const char *evalbinop(struct st *st, const char *s, int minprec, int d)
+{
+	static const char prec[14] = {1,2,3,3,4,4,4,4,5,5,6,6,6,0};
+	unsigned long left;
+	int op;
+	d--;
+	s = evalprim(st, s, d);
+	s = parseop(st, s);
+	for (;;) {
+		/*
+		st->r (left hand side value) and st->op are now set,
+		get the right hand side or back out if op has low prec,
+		if op was missing then prec[op]==0
+		*/
+		op = st->op;
+		if (prec[op] <= minprec)
+			return s;
+		left = st->r;
+		s = evalbinop(st, s, prec[op], d);
+		if (binop(st, op, left))
+			return "";
+	}
+}
+
+static const char *evalexpr(struct st *st, const char *s, int d)
+{
+	unsigned long a, b;
+	if (--d < 0)
+		return "";
+	s = evalbinop(st, s, 0, d);
+	if (*s != '?')
+		return s;
+	a = st->r;
+	s = evalexpr(st, s+1, d);
+	if (*s != ':')
+		return "";
+	b = st->r;
+	s = evalexpr(st, s+1, d);
+	st->r = a ? b : st->r;
+	return s;
+}
+
+unsigned long __pleval(const char *s, unsigned long n)
+{
+	struct st st;
+	st.n = n;
+	s = evalexpr(&st, s, 100);
+	return *s == ';' ? st.r : -1;
+}
libc/musl/src/locale/pleval.h
@@ -0,0 +1,8 @@
+#ifndef PLEVAL_H
+#define PLEVAL_H
+
+#include <features.h>
+
+hidden unsigned long __pleval(const char *, unsigned long);
+
+#endif
libc/musl/src/locale/revjis.h
@@ -0,0 +1,515 @@
+31,80,81,87,14,299,74,61,12,344,62,63,1280,1281,1282,1283,1284,1285,1286,1287,
+1288,1289,1290,1291,1292,1293,1294,1295,1296,1297,1298,1299,1300,1301,1302,
+1303,1312,1313,1314,1315,1316,1317,1318,1319,1320,1321,1322,1323,1324,1325,
+1326,1327,1328,1329,1330,1331,1332,1333,1334,1335,1542,1536,1537,1538,1539,
+1540,1541,1543,1544,1545,1546,1547,1548,1549,1550,1551,1552,1553,1554,1555,
+1556,1557,1558,1559,1560,1561,1562,1563,1564,1565,1566,1567,1568,1584,1585,
+1586,1587,1588,1589,1591,1592,1593,1594,1595,1596,1597,1598,1599,1600,1601,
+1602,1603,1604,1605,1606,1607,1608,1609,1610,1611,1612,1613,1614,1615,1616,
+1590,29,28,33,37,38,39,40,342,343,36,35,338,75,76,263,77,337,266,267,265,268,
+300,301,302,318,303,319,281,282,60,324,326,70,315,297,298,288,287,328,329,71,
+327,325,321,65,320,68,69,322,323,285,286,283,284,316,317,1792,1803,1793,1804,
+1794,1805,1795,1806,1797,1808,1796,1807,1798,1819,1814,1809,1800,1821,1816,
+1811,1799,1815,1820,1810,1801,1817,1822,1812,1802,1818,1823,1813,258,257,260,
+259,262,261,256,93,90,92,91,349,89,88,73,72,341,340,339,0,1,2,22,24,25,26,49,
+50,51,52,53,54,55,56,57,58,264,269,43,44,32,
+768,769,770,771,772,773,774,775,776,777,778,779,780,781,782,783,784,785,786,
+787,788,789,790,791,792,793,794,795,796,797,798,799,800,801,802,803,804,805,
+806,807,808,809,810,811,812,813,814,815,816,817,818,819,820,821,822,823,824,
+825,826,827,828,829,830,831,832,833,834,835,836,837,838,839,840,841,842,843,
+844,845,846,847,848,849,850,10,11,20,21,1024,1025,1026,1027,1028,1029,1030,
+1031,1032,1033,1034,1035,1036,1037,1038,1039,1040,1041,1042,1043,1044,1045,
+1046,1047,1048,1049,1050,1051,1052,1053,1054,1055,1056,1057,1058,1059,1060,
+1061,1062,1063,1064,1065,1066,1067,1068,1069,1070,1071,1072,1073,1074,1075,
+1076,1077,1078,1079,1080,1081,1082,1083,1084,1085,1086,1087,1088,1089,1090,
+1091,1092,1093,1094,1095,1096,1097,1098,1099,1100,1101,1102,1103,1104,1105,
+1106,1107,1108,1109,5,27,18,19,3915,8793,6934,10843,7493,6671,7492,4379,10291,
+11294,12033,4110,4685,12034,7939,12577,5173,10521,7494,11549,10529,12035,8773,
+12036,5465,12037,4924,8719,6982,12038,12039,12040,9748,5174,9750,9538,5922,
+10770,18472,12041,7495,12042,4372,5444,5967,11080,13573,11343,9564,4868,5140,
+12043,12044,11546,11292,8263,12046,6741,9554,12049,4125,5950,5949,3909,11818,
+11817,6418,3840,12050,12051,12052,10771,12053,5969,3910,10833,5211,5212,5213,
+9025,11547,12054,12055,12056,7724,7193,7725,12061,12059,12060,5175,6402,4431,
+12058,12057,10504,6693,6692,8477,12062,10292,8006,23,12063,12065,8516,11584,
+3881,12064,4381,5411,8774,5710,12066,9731,4938,12067,3882,5951,4939,10329,
+10001,5176,4432,12102,9248,9803,12069,10011,11585,7692,6694,6742,4383,9008,
+8705,12073,3883,9026,7194,6419,11267,8493,4382,12072,11293,12068,12070,6477,
+12071,13315,12079,12082,12080,4385,10522,12074,12078,5970,6695,4869,12083,
+12075,11586,6743,12076,12081,12084,12077,5376,3884,5377,4384,13316,10840,
+10317,5971,7694,11542,10551,5655,8452,4419,7218,12088,12093,12091,12086,8462,
+12089,12092,12090,10556,12087,7693,10834,12094,12095,7171,12108,9775,10261,
+12103,10575,4373,12107,12101,12110,8241,5923,9787,16166,12109,9276,12098,5973,
+5972,12096,6969,12104,10574,8748,12100,5712,12097,12105,12099,11568,12106,
+11808,5445,5711,12111,12112,12116,3885,10543,12115,12114,12118,12117,9027,
+5713,12119,6948,8453,9028,5461,12120,5141,12121,12123,10772,5701,6672,10070,
+12122,6436,11298,12125,12290,12124,6435,7260,5656,12291,5422,12288,12289,9486,
+8283,5378,10796,12292,11548,12293,12296,12294,8237,12295,12297,12299,12298,
+10535,5142,12301,12302,4366,12300,6995,12305,12304,12303,12085,12306,7261,
+12307,11268,11064,12309,12308,12311,12310,12312,12313,3923,5908,5658,7195,
+8794,5379,8007,5974,6221,12315,11047,9253,6744,12314,12316,9277,4692,12317,
+9565,8211,12319,12320,9995,5975,11802,12321,5381,10523,8469,5456,
+9236,5714,12322,12323,9537,4158,12326,6492,12325,6437,12327,17741,12328,10784,
+12329,12330,12331,7496,6955,4870,12334,12332,11036,12333,10297,12335,12336,
+12337,9278,12341,12339,12340,12338,6466,12342,11081,11587,12343,7943,12344,
+7225,12345,8795,11550,9279,12580,12346,21252,5412,12347,10813,7239,8539,12349,
+9539,12350,12351,4621,12352,5382,9515,4185,7215,9984,12353,9280,7726,12354,
+10507,7993,4865,4872,12355,12357,5657,12356,11602,7240,10012,10539,12358,
+11351,12359,12360,9309,12361,7944,6493,5715,12362,6696,6222,9029,12364,8454,
+6478,12365,12366,8207,12363,12368,10773,6211,12367,5716,6461,9804,12371,12369,
+10330,7497,12378,4675,12372,12370,8238,12374,12373,4643,5695,12379,11532,
+12375,12380,12377,12376,11566,5976,4386,11603,7252,9271,6212,12545,12546,
+11588,11786,12548,5977,12547,4622,12549,10805,8987,11269,10552,12550,20276,
+9487,12551,4873,11026,7424,12552,10566,12556,7945,12553,5423,12554,4874,5645,
+12557,12558,12559,12560,6970,5978,11069,11079,9558,10576,12561,12562,12564,
+12566,12565,12567,4380,10795,6491,12568,8248,7425,5384,12569,10042,12570,
+12571,12572,12573,10243,5447,3908,9502,12574,7196,8008,12576,12575,7426,5952,
+12578,10013,12579,10043,8467,8525,5383,9549,8720,9805,10797,12581,8009,5652,
+12582,12583,4107,3924,4940,8455,5168,11344,12586,4374,12585,5385,12587,11088,
+12588,11569,5979,5909,12589,12591,12590,7742,4120,4157,12592,12593,5910,12594,
+5197,6673,12595,10835,6420,5177,11270,8239,10014,7004,7206,6983,
+6996,7253,10015,12598,4130,8240,5980,5924,5446,12602,8704,8541,5386,7427,
+12603,12601,4387,8517,6935,6698,4101,4687,6213,6697,12604,12605,5160,4645,
+6214,5159,9022,4100,9488,11037,6144,11352,9254,5981,5646,12614,5442,10793,
+10044,12613,4925,12608,12609,12611,12612,5178,7744,10508,12610,12606,5954,
+12607,11779,10577,9031,5953,6223,12615,9532,12619,7005,6997,12622,12620,11010,
+12617,12626,12621,12624,5925,11038,12625,12627,12629,6479,11809,12618,12616,
+12628,12623,12631,12802,12633,12637,12800,12634,12829,6472,4624,12632,12804,
+3925,12803,3844,10281,12801,12635,12630,12636,6439,12805,3926,12814,12806,
+12807,7428,10824,12812,12811,9230,12813,12810,4115,6421,7695,12808,9281,12809,
+3841,12819,11266,7430,12825,12824,12815,8482,12816,8526,12821,7429,12818,
+11075,5659,12822,12823,12820,12826,12817,12832,12837,12833,12828,12838,8208,
+12840,6145,12830,8796,12834,12827,4876,4941,4676,12835,12831,5717,12841,12839,
+8242,5161,5387,12836,5459,4131,12845,12843,13062,12848,12842,12846,12844,6699,
+12847,12850,12855,12853,12852,8721,4388,12849,12851,7431,4114,12854,4413,
+12865,7515,12861,12859,12860,12862,4124,8216,12856,12857,4697,12864,4942,
+12867,12863,12866,10509,9524,10007,12869,12868,4644,12870,12873,12872,12871,
+9752,12874,12875,12877,12876,12879,12882,12880,12878,12881,12883,12884,12885,
+12886,12887,12324,7003,6700,4434,3927,8739,12888,6403,3886,7741,12889,5926,
+6224,12891,12890,10559,12892,13056,12893,13057,13058,5718,4159,13059,13061,
+13060,
+13063,9273,13064,3860,6462,5660,8750,13065,13066,13068,13069,6467,5424,10774,
+13067,13070,6432,6146,13074,6404,8722,13071,9017,13075,7745,13073,13076,5662,
+13077,13078,6147,4639,13080,13081,13082,13079,13072,13083,13084,10819,7498,
+13086,13087,13085,13089,9751,3911,10293,13090,7516,6936,9788,4943,6474,10808,
+9489,5719,8494,13088,13091,8483,13092,13093,13095,9032,4877,21248,4160,10578,
+7499,9255,6469,13101,10524,11580,4435,13097,8217,13100,9282,9256,9283,10008,
+9004,6440,13096,4181,9237,13098,13094,7727,13102,7213,5388,13103,10567,8284,
+8997,13105,10798,13106,13111,10510,13110,13104,13107,13109,6405,10536,13112,
+8740,4436,7500,13114,13113,6215,13115,13117,13116,13119,13108,13121,13120,
+13118,6701,7728,8243,13122,7963,3916,9795,9018,13124,13123,13125,13126,13127,
+13128,10544,13129,4389,13130,11291,4623,12584,7207,8478,13131,11082,11027,
+13133,8518,9238,8479,10294,13134,13135,4186,6937,13136,3887,13137,13138,4161,
+4944,9535,10579,13142,8244,13141,5663,10810,13140,9284,13144,13143,13146,
+13145,4187,13147,7432,13149,8708,13148,10514,7254,9274,13312,6148,13313,9728,
+10045,11056,9732,13322,5143,11300,11022,13579,13314,13317,8484,10775,9257,
+13318,10820,6441,7433,13319,6703,6702,3864,5927,7946,3888,13323,13324,13321,
+4119,4878,13320,11044,10256,3847,3928,6704,3889,3842,13329,13327,11035,13330,
+13328,13326,7696,13325,10553,5955,13334,13335,7434,13331,11787,9771,13333,
+6406,13336,10295,13337,13332,11034,9789,13338,10257,13339,13343,
+13340,4390,13342,6938,13341,5720,13355,13348,13345,8771,13344,13346,13347,
+13349,13350,4945,13352,13351,13353,7501,13356,9019,4132,13354,13357,13358,
+13361,13359,13360,6705,13362,6149,13363,6745,8471,13364,13365,6713,6150,11057,
+5127,5928,13366,4663,13367,8472,13368,13570,13369,13370,13371,13373,13374,
+13375,8527,4102,6984,3873,8246,4879,6932,6151,9285,7168,4880,8775,9033,3863,
+5144,10580,6945,5169,8010,6939,11271,13376,5179,6442,4625,4162,7435,4391,
+13377,11301,7208,6979,13378,4946,9521,11016,13379,13380,10296,13382,4871,5462,
+13381,4881,7697,13386,6656,4392,13385,13383,13387,13384,9738,15148,7698,13388,
+11551,13389,13391,8797,13390,7938,6746,8495,6998,10324,8011,6956,13392,7436,
+13393,13394,3890,8473,7729,13395,9490,7437,7438,13396,8012,7439,13397,13398,
+11071,13399,5413,7169,13400,13401,6971,7691,9555,7731,10071,9729,5416,13402,
+5198,13403,5469,9518,4367,6706,13404,13569,13568,5468,13405,9239,8463,9258,
+6951,8247,11353,13571,13572,9525,6674,13574,13575,13576,4947,13577,13578,4363,
+8218,4931,13580,11015,8497,4664,13582,13584,4926,13581,13583,13586,13585,
+13587,13588,9500,5389,4420,13589,13594,13592,10582,10581,9286,13591,7219,
+13590,7761,13595,6473,13601,13602,13596,4626,13597,13606,13605,13604,13600,
+13599,13603,10583,13610,13607,13609,11345,13608,13598,7762,13611,6422,13612,
+13613,13616,13615,13614,9287,13593,13622,13618,13617,13619,13620,13623,11589,
+13624,13621,13625,4927,13626,13628,13627,13629,13630,8013,7170,
+7235,8258,6152,6423,6153,5199,13631,6424,5929,13632,11013,9762,13633,6154,
+4875,8710,5425,6707,10298,10016,13634,4948,13637,8960,13636,13635,13638,9034,
+7746,6708,7977,8498,5121,8961,13639,13640,7502,10776,13643,13642,13641,10332,
+13650,10809,13644,13646,10826,13645,13647,9991,13648,10525,13649,4882,10526,
+9742,13651,13652,6155,4883,13653,5911,11299,11272,4949,13655,8962,6156,7440,
+10046,7441,7255,9035,10584,9240,6157,10299,13656,9272,6433,5930,9036,3874,
+7245,6158,11302,13657,13658,9776,13659,11606,11788,13661,13660,4646,13824,
+13827,13828,13826,10271,7442,13830,13829,13825,13831,13832,13833,13836,13834,
+13835,13837,4163,9037,13838,5721,4437,9749,13839,9562,10554,13840,11789,13841,
+10527,13844,12032,12048,6927,9556,13845,5180,8963,3929,13846,10501,6159,8751,
+9038,11086,5912,5931,13847,13848,13854,6980,8964,5390,13849,10250,8741,13850,
+13851,5391,13852,13853,13855,9301,13856,13857,13858,13843,13842,13859,5664,
+10246,6443,10262,8965,10282,13860,7443,4133,13861,13862,11089,10047,13865,
+4188,7947,13864,13863,5665,8499,13869,13867,13866,11526,5956,7256,13868,9259,
+7197,9503,13872,13871,13870,13873,5957,13874,10331,7226,13875,10072,9504,8966,
+9231,13876,5130,7699,10251,4950,9733,13877,6709,10777,10778,4189,13882,8776,
+13879,4438,14092,13881,9743,13880,13878,6233,13884,13890,13896,13888,9275,
+13893,10300,13887,13892,11590,6710,8500,13885,5181,13895,7948,4164,13889,4439,
+13894,5392,13891,13897,13899,13909,13907,13904,13903,11607,
+13905,5393,6160,7257,13912,13898,13902,13886,4441,13906,13908,8752,6407,4375,
+13900,13911,13910,5394,8456,4677,5666,13901,13913,13916,14080,6940,14086,9039,
+13914,14084,4440,14082,14083,13917,14081,5958,11273,4884,4152,14085,9753,3852,
+10048,13883,14091,14095,11076,14088,9288,14093,7503,14094,9526,11814,14090,
+14096,6234,7978,3891,14089,14087,8249,13915,6675,8485,14108,8250,14103,14100,
+14101,6981,14104,14107,14102,7172,14105,14099,11099,11098,14109,14110,3892,
+14098,5457,3845,4885,14106,14114,14113,14118,14119,14117,14120,14112,14116,
+14121,14122,14111,6747,14115,8501,6161,14097,7700,14135,10568,14125,14126,
+14127,14134,14133,10844,4886,14131,5668,4627,14128,11543,14130,3893,14132,
+14123,14129,14136,5667,14124,11324,11274,14139,14143,8285,11608,14144,14141,
+14138,14137,14142,10511,9491,5669,14145,14140,14146,5722,4368,14154,4887,
+14152,14153,6408,14151,14149,14148,14155,14147,14157,4442,14159,14158,8967,
+14162,14160,14150,5723,14161,14165,14164,14166,14163,14167,14168,14169,10569,
+14171,14170,7198,7949,4421,4443,14172,3870,7979,14173,19234,14336,5696,14337,
+8014,14338,14339,5145,14340,14341,14342,8502,5932,11072,10779,7241,14343,8015,
+19740,10049,6985,6444,14344,8486,10502,8528,14347,14345,14348,14346,14349,
+10512,3862,10301,10050,14350,14353,7444,5146,14351,14358,7445,14352,9763,
+11325,14354,14355,14359,9289,14356,6162,7997,14373,10003,8529,10051,14604,
+10585,9040,10836,14362,4352,8777,14371,8723,14365,14372,14367,14374,14370,
+14369,9806,14363,
+4444,14361,5200,8530,14357,14360,6163,7994,7446,14368,9777,5201,4647,4678,
+7680,14376,14381,14377,5724,14382,6657,6216,7173,14364,6748,14379,6711,14380,
+3875,14375,8968,5202,5395,14378,3846,6434,7701,9041,10035,14384,8253,8457,
+6666,14385,14387,14383,10560,8988,8251,10586,6957,14399,14398,7767,5725,14392,
+7448,9543,9744,14390,8252,6999,14395,7447,14389,14394,9778,14388,5632,4668,
+14396,11530,6445,8724,14393,7995,6164,7747,4165,8219,14391,5156,5670,9006,
+14397,8254,14400,14402,8470,14408,14403,14405,10272,9042,14406,11275,11303,
+4888,3853,14404,14401,4951,4166,14407,11304,14411,8474,14418,14412,14409,
+14416,14386,14413,14417,10017,9290,14410,14414,5671,6480,7996,14422,9221,
+14419,10815,14420,14421,11053,7937,5697,14428,6676,14425,14424,9745,9492,9232,
+14426,14427,10318,9764,6658,8016,10799,4648,14596,14429,11305,14598,14594,
+14595,8255,14593,14366,14597,14592,14602,14603,9222,14605,6659,14600,5147,
+14606,14599,14610,14609,14608,14611,14613,7504,14612,14616,14614,14615,14415,
+14618,14617,14423,14619,14607,6712,14620,14621,14623,14622,14624,4445,6165,
+10587,7950,5933,14626,14629,10289,5182,14628,14627,9779,14630,5396,14632,
+14631,4889,6677,9527,5672,7763,14633,7951,9223,10302,14634,14635,14636,10519,
+13372,7973,10283,6455,10052,10018,9260,11552,14638,6959,14639,3861,5427,7980,
+10303,14640,6689,8742,6714,7702,14641,10588,4182,6715,14644,14642,14645,11544,
+14643,8026,14646,8465,14647,4953,14649,14648,14650,14651,4954,9563,
+8725,5195,6716,8256,7227,3855,14652,4353,14656,6166,14655,6410,7449,14654,
+7450,11039,6409,3894,7981,14661,7952,4134,7220,10821,6481,7451,7942,14660,
+14658,14659,8778,14853,14665,6749,6167,14663,14664,7703,14662,6670,14667,
+14666,14671,14672,14668,4609,14669,14670,10036,10304,5673,14673,7953,7452,
+8753,5414,14674,14678,4394,14675,14677,14676,7242,8743,3876,14679,14680,8969,
+11600,6690,10570,10780,14849,14682,14685,14684,14681,14848,9533,14683,14850,
+7243,14851,11306,9815,14852,14854,14855,14856,5417,4135,6168,14857,14858,7248,
+8257,12599,8221,8220,8503,6438,12113,5709,11276,10589,10333,14859,6482,8990,
+14860,11790,10781,8970,14861,4955,14862,14863,11065,11011,10837,10811,6660,
+14865,6986,10800,14867,14870,14869,4952,5183,14866,14868,14871,7768,11354,
+3880,6463,8475,6972,7506,14874,9261,14872,8458,14873,7505,11068,14875,14876,
+11335,14881,6169,9780,14878,9291,14653,14657,5166,9766,14880,7453,10019,14886,
+10073,14877,14883,14882,7982,10828,11570,10822,4395,6717,11815,14885,7764,
+14884,14879,5934,14891,14889,4396,14887,14893,14899,8487,10528,14901,10241,
+14900,9807,10782,4890,8022,7199,9010,11277,14896,14895,14897,14894,14902,
+14892,14890,14898,14888,8779,11095,6949,6483,6425,10830,4640,9005,9513,4136,
+8017,7955,5641,14904,6170,4699,14906,4691,14912,14909,8018,4650,6411,4649,
+6446,14907,5700,5674,9292,14905,3877,14908,14910,5420,5643,4891,5162,14913,
+6488,10832,6678,14914,10255,14926,4370,14915,14932,14916,11553,14923,
+9790,14931,14918,3859,14920,6171,14922,14921,14917,14928,7454,13132,5959,
+11355,14919,9043,4610,6412,14911,14927,4672,14925,14929,9293,4957,15121,11048,
+14934,4956,14941,10783,15104,15106,15110,14936,8713,9294,15114,14939,15111,
+15105,7704,15115,7954,15113,4892,11823,14933,15109,3895,14935,11033,14940,
+7681,8998,14930,15108,7769,15118,4688,5888,15120,14937,15119,15112,14938,
+15116,15117,15134,9517,15107,15130,15132,9015,11307,10325,15127,8489,15133,
+8222,15124,15137,15136,9550,15135,9545,15139,15126,5415,15129,7228,9791,15131,
+5418,15123,15125,15122,11791,4665,15128,15138,4628,6470,4156,15155,11792,
+15158,7705,15157,15156,15153,15141,15170,15140,15159,15151,15146,15143,15144,
+15152,21249,15149,6172,8999,8259,15147,15142,15145,11308,10825,15150,15160,
+15168,15161,15174,15172,15167,15166,9007,8260,15164,15162,15169,15175,10068,
+15181,15176,15179,15173,8787,10263,15163,15171,7455,11054,15191,15178,5889,
+4354,4670,15154,7456,15183,15190,7000,4689,8717,15180,15185,15189,5397,5163,
+15187,5120,9514,15186,15188,15182,15184,4671,8744,15195,15193,5960,15192,
+15360,14903,15194,15196,15197,15371,15367,14924,15366,15365,15362,15177,15364,
+15363,15369,11781,15372,5466,15368,15370,9990,15373,15377,15374,11346,15375,
+15165,15378,15379,4116,15381,5702,6912,5428,4355,11326,15383,15382,15385,5148,
+5429,4893,15388,15387,15389,4397,8726,15390,4894,15392,15391,15393,15394,
+15395,6718,7956,6400,10319,10561,11811,6740,6447,11601,15396,15397,6719,15398,
+15399,15401,15400,10807,
+7229,6987,6691,15402,15404,7682,15403,15405,15406,15407,15408,15409,15411,
+15410,15412,4356,8745,15413,6661,4651,15414,9249,13099,5122,15415,15416,10571,
+10823,9510,15417,10053,10074,11058,15418,15420,15419,15422,15421,15424,6720,
+11024,15425,15426,5123,15427,15429,15428,7748,10264,4137,10020,9044,7200,5184,
+10021,6925,15431,4895,4183,9553,15430,6173,8754,15432,15440,15433,8480,5185,
+15441,5703,5124,15439,15437,15434,11327,8991,9528,15435,15443,15442,5634,4364,
+6426,15436,15438,10806,8531,10838,15451,15452,4398,10503,11100,15616,6914,
+7457,15447,15453,4167,5398,15444,15449,8019,9808,10054,15446,10752,15448,
+15619,15617,15450,10753,9767,5186,9220,8780,15620,15618,8504,15445,4138,11309,
+15631,15630,8021,15627,11339,9493,15621,8996,4139,6174,15624,7174,15629,15628,
+15623,15626,4679,15625,9768,11533,7507,8020,15637,15635,10284,15632,15634,
+4121,6175,11793,4636,10305,11328,4611,7706,15636,15641,7458,11279,15638,15633,
+15639,11581,9298,9505,4629,4148,15645,15648,11554,11331,15655,15649,15646,
+11571,15652,7209,15654,15659,9296,15657,15651,8727,15658,15647,15653,15660,
+3931,15650,15661,7707,7230,10500,6413,15642,15656,9241,7957,4680,6448,7459,
+15644,7201,5675,15643,15665,7244,5913,15680,15674,5203,9262,15669,15678,3854,
+4113,4376,15671,8459,15662,15664,6176,15681,15676,15668,15675,11018,15673,
+15677,5935,7460,8728,15667,11278,15670,15663,9297,15666,15672,11824,6941,
+10845,15682,9997,15694,5914,7231,15684,11534,6177,15697,3917,15695,15683,
+15689,15691,11310,15686,9229,15688,15696,15690,11046,15685,6913,15709,4681,
+15687,15692,15693,8523,8505,15701,15707,15705,9224,15874,15702,15703,15679,
+5208,10265,6942,6230,11794,15699,15873,4168,8261,9816,4896,11609,11008,9009,
+15706,15708,8209,15872,15704,15698,4898,5704,15886,15881,8023,4674,7232,15890,
+15883,8971,15880,9016,15915,15877,15876,15885,15879,15878,15884,7936,15875,
+15887,15888,4897,15893,15892,15894,15897,9250,15891,15895,5698,8536,15889,
+9754,15896,15901,15899,15902,15905,15898,6217,9735,15640,11347,15900,15904,
+8532,15903,15882,20040,15908,15912,15910,15906,15907,15911,15909,10285,15917,
+15914,15913,15916,9523,15918,8788,8524,7940,15919,15921,15920,15700,15922,
+9542,15923,4399,9299,4612,5187,6973,6449,11782,7749,4169,15925,15924,15928,
+8729,15931,15926,15930,15929,9247,3896,11604,15933,4103,15935,15934,15932,
+15927,10754,15937,15936,4170,15939,10513,15938,11028,7462,8210,7461,11610,
+15945,8024,15941,15946,4171,15944,9792,15940,15943,7463,10032,15947,6960,8025,
+15950,15942,5638,15948,11311,15951,21253,7214,15952,15953,9741,15955,15956,
+9746,9300,15958,15960,11572,15957,15959,4172,15954,12858,15961,8262,6679,
+15963,15962,7683,12600,15964,16128,15949,15965,16129,9817,16130,16131,16132,
+16133,9021,16135,16134,16136,16137,6974,10306,11083,16138,16139,8245,6915,
+16140,16141,16142,10545,10022,16143,9782,8972,16144,4422,5196,11045,11029,
+4371,11795,10801,10505,7958,16145,9506,5890,16146,6451,16148,16147,16149,
+16150,16151,5149,16152,16153,
+5891,10023,16155,7508,16154,5399,16156,16158,16157,16159,5936,16160,5448,8223,
+6236,16162,16163,16161,6988,9511,5400,16165,8715,16164,11796,9793,16168,16170,
+16167,11059,16169,16171,11555,16175,16174,8789,9740,5892,16173,16172,11280,
+11281,16176,4173,6229,6721,16177,16178,16180,7202,16182,16181,16183,4652,
+16185,16184,16187,16186,5915,11527,5419,4357,5449,4928,11591,16189,16191,
+16192,4400,16188,6680,8992,16190,16195,6989,16193,5661,10024,16194,16221,
+16200,5916,5188,16197,11356,11535,8533,16199,16201,11573,5430,10075,9769,
+16202,16204,16207,16203,16206,5961,4140,16208,7759,16205,11579,16211,21251,
+16209,16212,16198,16210,6427,16213,16214,11357,16215,16216,16196,16217,4899,
+6916,16218,16219,16220,4122,16384,10266,16385,4867,16386,16387,16388,16390,
+16391,16389,10290,16393,16392,16395,16394,16396,16397,16399,16398,6232,16401,
+16400,4900,7730,9243,16402,7959,6681,4184,16403,11312,10562,16404,9251,11282,
+6178,7708,8746,12563,8973,4423,16405,16406,16411,16409,16408,14625,4613,16407,
+3897,9993,10025,11536,16412,16410,8763,7941,9994,10252,16414,11531,5676,16415,
+16413,10037,16416,16417,3898,7509,16422,16419,9548,16418,5125,16425,16420,
+16421,16424,16423,10244,8225,8224,5150,16426,16427,16428,16430,16429,4149,
+16438,10055,16432,16434,16436,7709,16437,16435,6943,16431,16433,10273,7464,
+16440,16439,16441,6917,6414,9302,16442,9002,16444,11520,16443,8264,16449,
+16451,16452,8755,16450,16447,16445,16446,16448,16455,16453,16454,16456,16458,
+16459,16460,16461,16457,
+16463,16462,16464,11556,16467,16465,16466,4929,11101,10537,16469,16468,16470,
+16471,16475,16472,16473,16474,16476,16477,16640,16641,16642,9998,9263,16643,
+9809,10259,16644,16645,9225,4614,6179,16646,16647,16648,6664,16650,16649,
+16651,16652,10056,16653,16654,21064,16655,16656,16657,6669,16658,9781,10814,
+4141,4150,16659,16661,16660,9295,7960,15384,16662,11040,16663,4901,10038,
+16664,16665,16666,11067,11060,8989,8265,16668,7233,7465,16671,16670,16669,
+10076,4902,5896,16677,16674,7710,11025,16673,16675,16676,16672,16678,16679,
+8974,4930,8772,16680,16681,16684,7750,9507,16685,10802,16682,16683,16688,
+16687,16686,16690,16689,16691,16693,16692,10540,7221,11557,16694,9494,16695,
+16696,16700,16698,16699,16697,16701,16702,16703,16704,11030,16705,11087,16706,
+8749,9801,5450,8730,16707,5401,7983,16708,6428,16709,16710,5893,6452,16712,
+9269,6453,5165,10755,9770,9270,6203,16714,7466,11537,6180,5894,9986,16716,
+16718,5962,16717,9045,16720,4630,16715,10057,4111,6475,11825,16719,16721,
+10538,7992,16723,16724,16722,4653,16730,16729,6918,16731,16726,16732,16727,
+10039,16725,16728,16897,16896,10816,16733,3914,16899,16898,7467,16900,8226,
+16902,16901,16903,16711,16713,16905,16904,6919,11592,6961,16906,5654,5151,
+5126,6722,11283,16912,16911,8227,16908,16910,7210,7711,16909,16907,9737,7468,
+10267,6454,9303,16913,16914,16936,5431,11804,8212,16915,4401,9046,10496,16916,
+5209,16917,16919,16920,9736,16921,16922,16923,5432,4402,9508,7175,6723,16924,
+7176,4393,10274,16925,
+10058,8228,16928,16929,9800,7712,16926,8768,16927,7469,3899,5128,16930,9047,
+16931,7974,11020,10242,16932,16933,8756,11558,16935,16934,6990,16937,3919,
+16940,16938,4403,5677,16939,6181,6225,10565,16941,10803,16943,7984,4142,4377,
+3851,16942,16944,16945,7510,16946,4654,16948,5705,5189,16949,5460,16950,8027,
+9516,7999,6484,16951,8769,8266,16953,16955,16952,16954,5633,16956,5637,5190,
+11313,16958,16959,4109,16962,4693,16961,16960,16964,16957,16965,11528,16966,
+16967,13139,16969,16968,16970,16971,11540,16972,20302,7470,16973,16974,7222,
+9495,16975,8711,16976,8731,16977,5380,12318,8764,6930,4903,16978,17153,16981,
+5191,16980,17155,16979,7471,16983,16984,9226,16985,4669,7737,10307,16987,8519,
+16982,16986,16988,6490,17157,10253,9989,9304,5433,17156,17154,10004,16989,
+8765,9306,9305,6485,17175,17159,17161,17164,17165,17162,17163,17160,17158,
+17152,10542,4404,17172,17169,17174,17173,9810,11014,6682,17167,17176,17171,
+17170,17166,17168,4904,8732,8028,9985,17181,9987,8000,17178,10030,17182,10546,
+8762,17177,17179,17180,17183,6947,9509,17188,17187,17184,11797,17193,17197,
+17194,17190,17191,17196,17185,12596,17192,17186,17195,17201,4905,17198,17199,
+17200,17203,17202,10069,17204,11611,10572,17209,17206,17205,7985,17208,17210,
+17207,17214,17211,17212,17189,17213,17215,17216,10533,17217,11073,5421,5640,
+17218,10515,7751,11023,17219,11538,9811,8229,9747,7212,3871,17224,17222,17220,
+4864,7472,17225,17223,17221,17229,17228,17227,17226,17230,17231,7961,17232,
+17234,
+17233,5937,8215,17236,9307,17235,17237,10516,8267,6182,17238,11559,17240,
+17241,17242,17243,6724,17244,5678,5193,5129,17408,11090,6183,17245,17411,
+11077,9755,10258,7234,17410,6962,6184,6725,5192,10517,17409,8230,10785,6486,
+6726,9020,17414,11582,6456,17415,7713,17417,7473,6415,17416,7177,5917,8231,
+17412,17418,17413,5679,17421,17425,5706,17420,17429,6185,11340,3867,17426,
+5194,17423,17424,9308,17422,17419,4615,8003,5895,17431,17428,17430,17427,5680,
+8466,17432,8269,17445,17441,17435,17439,7001,3900,17434,17442,17446,6186,
+11061,9013,17436,17444,17433,8733,17438,3868,11049,17437,5434,10059,8268,
+11567,7246,17485,17447,8029,17443,17448,17450,9048,17453,17449,10547,4906,
+11050,3901,17452,11612,17451,4174,9547,17454,17461,17455,17462,17458,9818,
+6953,17460,17457,17463,17456,7203,10756,7211,17459,17471,17467,17470,17468,
+17472,17466,17440,7986,10026,17469,17464,8192,5681,7178,7684,8213,17475,17477,
+17478,17474,17476,17465,17473,17481,17480,10841,5642,17479,17483,17482,17486,
+17488,6683,17484,17489,17490,17491,17497,9242,17493,17492,17494,17495,17496,
+17498,17499,4907,17500,17501,17664,17665,17666,17667,17668,17669,17671,17670,
+17672,17673,17674,17677,17675,17676,6464,5682,8757,10002,7247,9772,10060,
+17678,14156,17679,17681,11332,17680,17683,17682,11314,17684,10077,17685,17688,
+17687,17686,17689,5649,8193,5152,17693,17690,17691,17694,17695,17692,4104,
+4358,17697,17698,17699,11329,7179,17701,17700,7752,17702,17703,17704,4932,
+4908,17705,17706,10812,11330,
+11315,11798,6188,17709,6963,17708,17710,6920,8496,17711,6187,11062,17712,
+17713,17714,17715,17716,6921,11084,17718,8734,17717,17720,17719,17721,7962,
+17722,17723,10520,17724,8270,17725,17726,11613,17729,17728,17727,8975,17730,
+7685,17731,17732,11799,17733,17734,17736,17735,9988,9560,11805,9992,17738,
+7474,10249,17739,17737,4909,5939,6727,10061,5897,10786,17742,17740,6189,6190,
+3912,6471,9784,3902,17747,8735,9783,8506,17749,17745,17748,17743,17746,10757,
+5940,3932,17744,17751,17752,9496,5402,17925,9756,6728,5403,7975,11813,11021,
+17750,7987,5170,17753,17755,17754,17756,8709,9757,8976,17922,17921,17757,7732,
+10308,17924,17923,6191,11826,17940,17928,17929,6991,17927,6231,17926,17930,
+8977,10497,8194,8507,17934,17935,17931,17932,17933,6192,17941,17937,10309,
+10827,10247,17936,17939,17938,10787,17942,17943,8214,17944,17946,17950,17947,
+17945,9758,17948,17949,4369,17956,17951,17952,17953,8448,17955,17954,17957,
+17958,17959,7714,4424,17960,11574,6922,7180,6729,8758,17961,17962,4112,17963,
+17964,17965,17966,17967,5404,14601,17968,8004,17969,6954,17970,12047,17971,
+10557,4923,8195,7223,10320,7181,17972,6193,17973,10027,17987,17975,8488,9812,
+5918,17974,8196,17976,9049,17978,17977,17980,17979,17981,17983,17982,4910,
+17984,17985,17986,6416,11560,17988,7686,4175,17989,17990,17991,3921,17992,
+17993,10310,6950,17995,4616,3857,17994,17997,9773,7715,4405,10758,5692,5435,
+17996,4425,4866,4176,18001,11593,8508,10275,18013,4406,18011,18009,18000,
+17998,17999,
+6978,5451,8790,9520,4144,18003,18002,18008,18004,18007,11055,18006,4407,4700,
+18010,18012,5683,18178,18187,18188,3850,18195,3920,18186,18185,18180,18179,
+18177,18176,8770,8538,18182,18181,18184,8271,5684,4128,18183,6194,8272,18201,
+18202,4408,4365,18199,18189,18197,18204,18198,18196,18005,18194,18190,4911,
+18192,18203,18193,18205,18191,9819,11336,18200,18222,18214,7770,5157,5436,
+18209,4410,7475,18212,6457,9264,18217,10573,18208,4409,5941,10248,18218,18206,
+18215,18225,18210,18211,9497,18216,18213,10759,18219,3903,18207,18221,18220,
+9802,18227,18238,4701,18241,18223,18228,11341,18237,11316,11529,8791,4682,
+10321,18243,9472,3856,18236,18232,8273,18226,18234,18239,9739,3849,18231,
+18240,10327,18235,18230,7476,7182,6923,11063,10278,18246,18255,18233,4694,
+7511,18244,18249,8274,18245,18252,8766,18253,11317,18242,4631,18248,18251,
+11019,18254,18247,18250,10760,11776,18258,18265,18257,6946,18224,10541,11009,
+18264,18263,18259,18260,4117,18262,18256,9012,18261,3933,8449,10530,18266,
+18432,10040,18269,7477,6952,18434,5405,18435,10328,18268,18229,18267,11822,
+9473,10322,18442,18448,18449,18436,9813,18446,18438,18440,18450,18439,18443,
+4177,9540,18444,18447,18437,8197,18441,6662,7716,5647,11091,11096,7249,18454,
+18452,11821,18451,11348,18453,18455,18456,18459,18457,9474,18458,10028,18445,
+7250,18460,18465,8275,18464,18433,18466,8232,18461,18463,18462,15376,15361,
+18468,18467,11349,16667,18469,18470,18471,5942,5171,18473,12348,5204,11545,
+5458,18474,18475,8781,18476,
+9561,3865,4418,18481,18482,18477,6684,18478,9761,18479,18480,18490,18484,
+18487,18483,18485,18486,6967,18488,8736,5685,4641,18491,4638,18496,18492,
+18495,10009,18493,18494,10279,10041,18497,8540,18507,18503,4426,18501,10761,
+18502,18499,18500,18505,18508,18506,18504,18498,8759,18515,11017,18513,18514,
+18509,18511,18512,18510,8005,11800,18519,18520,18688,7689,18522,18525,18517,
+18516,18689,4411,18523,18690,18524,18521,8978,18518,9799,18694,11290,18693,
+18692,18701,18695,18703,11333,18706,18697,18698,18702,18705,18704,18696,18699,
+18716,18709,18707,18708,18713,18714,4617,5153,18712,18691,18711,18715,18710,
+18717,18719,18718,18721,18720,18489,18725,18722,18723,18724,18726,5707,18728,
+18727,7183,6195,15622,18729,7216,4632,18730,4145,7478,18731,6196,18732,3904,
+10268,18733,7753,18740,18737,8782,18738,18735,5437,18734,18741,5653,8509,
+18747,18743,8468,18742,18745,18736,18746,18748,10062,18744,18749,18751,5938,
+18739,3872,18750,6458,11605,18752,18753,8276,11521,18754,11284,18755,18756,
+10563,18757,6431,11522,18762,18763,7479,18761,11334,18758,18760,7964,7773,
+18759,18764,10498,18766,18765,4683,10762,18767,18779,18769,18770,18771,18772,
+18776,18777,18775,18773,18768,18774,18778,20246,4359,18781,5438,18780,18945,
+18944,18947,18946,18948,7184,18949,18950,18951,7965,11318,18952,10499,9765,
+18953,18954,5898,5131,18955,6730,9760,18956,4655,18957,18959,11350,18958,7717,
+18960,18961,18962,4912,18963,18964,18965,18966,4656,18967,18968,18969,4433,
+7687,18970,18971,18972,5919,9050,18973,
+5686,7733,18976,9475,18975,5648,18974,8534,5132,18977,18978,7480,5708,18979,
+10763,7998,5205,11092,8233,18980,7718,8783,7481,18981,18984,18985,6429,8481,
+18983,7482,10269,18982,6731,4146,18989,5687,6733,6732,11820,18988,18987,8198,
+5164,11810,4633,7483,18986,18991,18992,18990,5943,11295,6734,9734,18995,7967,
+8737,11285,18998,5963,7966,18994,18999,5964,18996,18997,18993,8001,9512,8718,
+4412,10063,5154,8979,19002,19000,8747,7968,4913,19001,7738,11561,11807,19003,
+19014,8980,19013,19010,19018,19011,19007,9051,19006,19004,11264,6735,19008,
+19005,19012,7251,5920,8537,10788,4153,3905,9476,19016,19015,9541,19020,19009,
+19019,19021,5899,19017,6197,6964,19022,11319,19025,19028,19026,10260,19023,
+5439,19027,19029,19033,19030,19032,19031,19034,6928,19036,19035,10311,19200,
+5688,19037,19201,19202,5155,17696,7512,19203,5965,19204,19205,6685,14637,
+19206,19207,7185,19208,19209,19210,19211,19212,8714,19213,19215,19214,9477,
+19216,10764,19217,19218,19219,19220,9529,7484,19221,6218,12045,19222,19223,
+10270,19224,19232,19225,19227,19226,19228,10789,19229,19230,19231,19233,4620,
+9030,10312,6465,6198,10286,4414,10029,19236,4914,7988,19235,19240,8792,11074,
+19238,19239,5133,19241,9794,8510,10064,9244,19237,10790,4427,19243,11783,8993,
+11812,6736,19242,8464,19259,8199,9559,10287,19246,6686,6737,7485,9796,5900,
+19245,19244,10313,6944,9265,19248,19249,6199,19247,19250,19251,19253,8450,
+19252,4933,19255,19254,19256,19258,19260,19261,7989,6958,19262,4657,
+19263,8277,19264,19265,10314,5134,19266,8981,4154,19267,6992,7765,8460,19270,
+19269,19268,19276,19274,19271,19273,19272,19275,5206,19279,7990,19280,5944,
+19277,19278,11784,8982,8200,19281,19284,19282,19283,11320,9478,19287,19285,
+19286,19288,19464,19291,19292,19290,19289,9052,19456,19460,19457,19293,19458,
+19459,19466,19461,7991,19463,19465,19462,19468,7186,19467,19469,19470,19473,
+19472,19471,19475,19474,11093,19477,19476,19478,19479,19481,19480,7719,19482,
+5452,19483,19485,19486,19487,19484,19488,6965,19489,5135,5650,5901,19490,9551,
+9245,19491,19494,6931,19493,19492,5689,19495,4658,19497,6459,19496,19505,
+19499,19501,10564,19498,19500,19504,19502,5136,19503,19506,9785,11575,7187,
+19507,11265,19509,19508,19512,11296,19511,4684,19510,19515,19514,19513,9233,
+19516,19517,19518,6219,5636,19519,19520,19521,7720,19522,6924,19523,19524,
+12544,12381,19525,17487,19526,8707,7690,9759,19527,10548,9011,6237,8712,4105,
+10839,7734,5693,5440,10549,19528,19530,19529,4415,9557,19531,9814,9234,19532,
+7217,19534,11041,19549,19536,19537,9000,8511,8278,9479,19535,5172,19544,19541,
+19716,9480,8767,19538,9053,9266,19539,19543,7743,9798,9003,7969,19542,8461,
+8451,19540,3848,11777,19545,8512,7188,7721,19547,19546,3918,19548,10254,19718,
+9530,7754,8760,5463,19717,11286,4126,10550,4416,19712,19713,19714,19715,9498,
+8706,3906,19719,19720,21250,8476,19721,4178,8235,5902,11321,19722,9227,8279,
+6966,19723,19726,7236,19724,8202,8201,3907,11562,19728,10065,19730,19729,
+19727,16963,4915,19533,19732,19731,19733,11287,9536,10765,19734,6968,19735,
+19736,19737,9216,3913,6200,11801,19741,5651,19738,19739,10323,4659,11288,5406,
+9267,19742,19743,19744,9217,19746,19745,9522,19747,7189,6975,9786,8784,6993,
+7755,19748,19749,7740,19750,19751,19752,11342,7190,19754,19753,6201,6226,6687,
+19757,7237,19756,19755,8520,5966,7970,9999,7192,19758,7486,19761,19759,19760,
+19763,19762,7513,19764,19765,19766,10031,6450,6976,19767,19768,11523,7204,
+11085,11563,19769,5441,19770,9218,19773,4695,7722,19771,19772,9023,10804,5467,
+19775,19776,19774,19778,9534,4642,19782,19779,19781,19777,20014,19780,11594,
+5945,19790,9235,19785,19788,19786,19791,19792,19784,19797,4179,19783,9996,
+19787,7487,6202,10791,5443,7205,9499,8204,19795,19789,19794,11042,8983,19796,
+19793,8203,19800,19799,19798,10766,7258,19801,10558,4147,10277,8785,5207,
+19803,6204,6667,19802,7756,7757,19968,19970,7514,19969,19971,5426,10276,6977,
+11778,19805,6487,11806,19973,19972,19974,19804,9544,9268,9014,19979,8738,
+19975,19976,5644,19978,5903,19977,7488,4696,19983,6430,8280,9001,4634,19981,
+19982,8994,19980,19984,19990,19993,19992,9228,19985,19986,19989,19991,5407,
+19994,19988,19987,19998,19999,20000,19997,19996,7489,9481,19995,20004,20002,
+20003,20001,8535,20005,20006,20008,4916,20007,11097,20019,20009,20012,20010,
+20011,20013,20015,20016,20017,20020,20018,20021,20023,20022,8984,11078,20024,
+8205,20025,10531,20026,4618,4123,4918,4917,20027,20028,20029,20030,20031,4919,
+4660,6205,10005,20033,20032,20034,4155,20037,20036,20035,20038,20041,3878,
+20039,20043,20042,20045,20044,20046,9485,20047,20048,20050,20049,10315,20051,
+20052,6468,20053,20054,10792,8234,3843,8490,20055,10316,20058,20056,6206,
+20057,5921,10532,20060,20224,20061,20225,4096,7735,7259,4920,20226,9797,20228,
+4097,20227,8995,11564,9482,20059,11525,5904,11322,5464,11539,5639,8513,17920,
+20229,4619,7758,4661,20231,20232,20230,5699,6460,7490,4098,11576,20234,19725,
+20233,20237,20235,20236,20238,20239,11595,20240,20241,7976,10010,7772,4934,
+11289,4428,7191,5946,20244,20243,6738,20245,20242,6663,20249,18700,12597,7766,
+20247,11524,9552,4106,8002,6933,10518,4127,11596,11338,20250,9252,7002,20251,
+20252,7723,20253,11597,20248,20255,20257,20256,20254,20258,20259,8281,4417,
+20260,11031,20261,20262,11785,14864,20263,20264,20265,20269,20266,20267,20268,
+20270,7971,11094,7972,20271,10066,20272,21042,11051,20273,20274,20275,4662,
+20277,7736,20278,5635,20279,20283,20281,20282,4690,20280,20284,20285,3879,
+20286,20287,7491,20288,5158,20291,20290,20289,19024,10555,20292,20293,20294,
+20295,20296,20297,4921,20298,20299,9730,20301,4378,20304,20303,4099,5408,
+10534,8985,6401,6207,7238,7739,20306,20305,11297,4935,10033,9531,7771,11565,
+5690,20309,20308,10794,9483,4143,20310,20307,10288,11337,20311,20312,20314,
+8521,4666,4667,20313,4936,5905,4937,9246,11583,5947,20315,20316,20317,20480,
+20482,20481,10326,20483,20484,20485,20486,20488,20487,20489,10067,17707,7688,
+5137,20490,
+20491,12555,15386,10034,3930,3866,6739,10767,7517,20492,11070,20493,11323,
+4129,6688,20494,4429,20495,20496,20498,20499,20501,20497,20500,4922,20502,
+20503,20504,20505,20506,20508,20507,20510,20513,20509,20511,20512,20514,5409,
+6994,20515,20516,6208,20517,4637,9774,20518,20519,8761,9546,20520,9820,8491,
+4151,5453,5454,8786,20525,5455,4430,20524,20522,20523,20521,20535,20526,20527,
+20528,20529,20531,20530,7224,20532,20534,5138,20533,8282,5906,20536,8492,
+20537,9484,20538,20543,20541,20540,20542,20539,20545,20544,20547,5410,20546,
+20548,20549,20551,20550,20552,20554,20553,6235,20555,20556,4635,20557,20558,
+7760,20559,20560,20561,20562,6209,20563,20564,20565,20566,20567,10000,20569,
+10245,20570,20568,20572,20571,20573,20736,20737,20738,20739,20740,20741,20742,
+20743,20744,20745,20746,20747,20748,20749,15380,20750,17239,5139,4608,6417,
+20752,20751,11012,20754,20755,20753,20756,10817,20757,5210,11780,20758,20760,
+3869,20761,10506,20759,20762,20763,20764,20765,20766,10829,6668,6489,8206,
+20767,20770,20768,20771,5968,20769,20772,20773,20774,20778,6665,8515,20779,
+20776,20775,20777,5694,20783,20782,20781,3858,20793,20789,20790,20786,20792,
+20788,4673,11819,20791,20787,20785,20784,20795,20798,20797,20796,10280,20794,
+3922,20799,20801,4686,20780,4118,20803,20802,20800,8716,10831,11577,20804,
+20805,20806,20807,20808,8986,20809,10006,20814,20810,20811,10768,11043,9519,
+20815,20816,9501,20813,20812,4361,20824,20823,4180,20821,20820,20818,4698,
+20817,6929,4360,6210,20827,20826,20825,
+20822,20828,20829,20996,20995,20997,4108,20992,20993,6227,11032,20994,10769,
+21002,20998,21003,21000,20999,5691,21004,21005,21006,21001,20819,21007,9024,
+21011,21012,21010,21009,21015,21008,21013,21014,21017,21016,21019,21020,21021,
+11816,21018,8522,6476,21022,21023,21024,21025,21026,5907,21027,21028,6926,
+21029,21030,21031,21032,21035,21033,11803,21034,11598,21036,11578,21037,9821,
+21038,21040,21041,21039,6220,11052,10818,13654,15423,10842,4362,21043,5167,
+21044,21045,21046,6228,21047,16179,11066,8514,21048,21050,21049,21051,21052,
+21053,21054,21055,21056,21057,21058,21059,21060,21061,21062,21063,9219,5948,
+21065,8236,21066,21067,10240,21068,21069,16918,19257,20300,21070,21071,21073,
+21074,21075,11599,21072,21076,21077,21079,21078,21081,21082,21080,11541,21083,
+21084,16947,21085,9,83,79,82,84,41,42,85,59,3,4,30,527,528,529,530,531,532,
+533,534,535,536,6,7,66,64,67,8,86,544,545,546,547,548,549,550,551,552,553,554,
+555,556,557,558,559,560,561,562,563,564,565,566,567,568,569,45,46,15,17,13,
+576,577,578,579,580,581,582,583,584,585,586,587,588,589,590,591,592,593,594,
+595,596,597,598,599,600,601,47,34,48,16,78,
libc/musl/src/locale/setlocale.c
@@ -0,0 +1,79 @@
+#include <locale.h>
+#include <stdlib.h>
+#include <string.h>
+#include "locale_impl.h"
+#include "libc.h"
+#include "lock.h"
+
+static char buf[LC_ALL*(LOCALE_NAME_MAX+1)];
+
+char *setlocale(int cat, const char *name)
+{
+	static volatile int lock[1];
+	const struct __locale_map *lm;
+
+	if ((unsigned)cat > LC_ALL) return 0;
+
+	LOCK(lock);
+
+	/* For LC_ALL, setlocale is required to return a string which
+	 * encodes the current setting for all categories. The format of
+	 * this string is unspecified, and only the following code, which
+	 * performs both the serialization and deserialization, depends
+	 * on the format, so it can easily be changed if needed. */
+	if (cat == LC_ALL) {
+		int i;
+		if (name) {
+			struct __locale_struct tmp_locale;
+			char part[LOCALE_NAME_MAX+1] = "C.UTF-8";
+			const char *p = name;
+			for (i=0; i<LC_ALL; i++) {
+				const char *z = __strchrnul(p, ';');
+				if (z-p <= LOCALE_NAME_MAX) {
+					memcpy(part, p, z-p);
+					part[z-p] = 0;
+					if (*z) p = z+1;
+				}
+				lm = __get_locale(i, part);
+				if (lm == LOC_MAP_FAILED) {
+					UNLOCK(lock);
+					return 0;
+				}
+				tmp_locale.cat[i] = lm;
+			}
+			libc.global_locale = tmp_locale;
+		}
+		char *s = buf;
+		const char *part;
+		int same = 0;
+		for (i=0; i<LC_ALL; i++) {
+			const struct __locale_map *lm =
+				libc.global_locale.cat[i];
+			if (lm == libc.global_locale.cat[0]) same++;
+			part = lm ? lm->name : "C";
+			size_t l = strlen(part);
+			memcpy(s, part, l);
+			s[l] = ';';
+			s += l+1;
+		}
+		*--s = 0;
+		UNLOCK(lock);
+		return same==LC_ALL ? (char *)part : buf;
+	}
+
+	if (name) {
+		lm = __get_locale(cat, name);
+		if (lm == LOC_MAP_FAILED) {
+			UNLOCK(lock);
+			return 0;
+		}
+		libc.global_locale.cat[cat] = lm;
+	} else {
+		lm = libc.global_locale.cat[cat];
+	}
+	char *ret = lm ? (char *)lm->name : "C";
+
+	UNLOCK(lock);
+
+	return ret;
+}
libc/musl/src/locale/strcoll.c
@@ -0,0 +1,15 @@
+#include <string.h>
+#include <locale.h>
+#include "locale_impl.h"
+
+int __strcoll_l(const char *l, const char *r, locale_t loc)
+{
+	return strcmp(l, r);
+}
+
+int strcoll(const char *l, const char *r)
+{
+	return __strcoll_l(l, r, CURRENT_LOCALE);
+}
+
+weak_alias(__strcoll_l, strcoll_l);
libc/musl/src/locale/strfmon.c
@@ -0,0 +1,101 @@
+#include <stdio.h>
+#include <ctype.h>
+#include <stdarg.h>
+#include <monetary.h>
+#include <errno.h>
+#include "locale_impl.h"
+
+static ssize_t vstrfmon_l(char *s, size_t n, locale_t loc, const char *fmt, va_list ap)
+{
+	size_t l;
+	double x;
+	int fill, nogrp, negpar, nosym, left, intl;
+	int lp, rp, w, fw;
+	char *s0=s;
+	for (; n && *fmt; ) {
+		if (*fmt != '%') {
+		literal:
+			*s++ = *fmt++;
+			n--;
+			continue;
+		}
+		fmt++;
+		if (*fmt == '%') goto literal;
+
+		fill = ' ';
+		nogrp = 0;
+		negpar = 0;
+		nosym = 0;
+		left = 0;
+		for (; ; fmt++) {
+			switch (*fmt) {
+			case '=':
+				fill = *++fmt;
+				continue;
+			case '^':
+				nogrp = 1;
+				continue;
+			case '(':
+				negpar = 1;
+			case '+':
+				continue;
+			case '!':
+				nosym = 1;
+				continue;
+			case '-':
+				left = 1;
+				continue;
+			}
+			break;
+		}
+
+		for (fw=0; isdigit(*fmt); fmt++)
+			fw = 10*fw + (*fmt-'0');
+		lp = 0;
+		rp = 2;
+		if (*fmt=='#') for (lp=0, fmt++; isdigit(*fmt); fmt++)
+			lp = 10*lp + (*fmt-'0');
+		if (*fmt=='.') for (rp=0, fmt++; isdigit(*fmt); fmt++)
+			rp = 10*rp + (*fmt-'0');
+
+		intl = *fmt++ == 'i';
+
+		w = lp + 1 + rp;
+		if (!left && fw>w) w = fw;
+
+		x = va_arg(ap, double);
+		l = snprintf(s, n, "%*.*f", w, rp, x);
+		if (l >= n) {
+			errno = E2BIG;
+			return -1;
+		}
+		s += l;
+		n -= l;
+	}
+	return s-s0;
+}
+
+ssize_t strfmon_l(char *restrict s, size_t n, locale_t loc, const char *restrict fmt, ...)
+{
+	va_list ap;
+	ssize_t ret;
+
+	va_start(ap, fmt);
+	ret = vstrfmon_l(s, n, loc, fmt, ap);
+	va_end(ap);
+
+	return ret;
+}
+
+
+ssize_t strfmon(char *restrict s, size_t n, const char *restrict fmt, ...)
+{
+	va_list ap;
+	ssize_t ret;
+
+	va_start(ap, fmt);
+	ret = vstrfmon_l(s, n, CURRENT_LOCALE, fmt, ap);
+	va_end(ap);
+
+	return ret;
+}
libc/musl/src/locale/strxfrm.c
@@ -0,0 +1,18 @@
+#include <string.h>
+#include <locale.h>
+#include "locale_impl.h"
+
+/* collate only by code points */
+size_t __strxfrm_l(char *restrict dest, const char *restrict src, size_t n, locale_t loc)
+{
+	size_t l = strlen(src);
+	if (n > l) strcpy(dest, src);
+	return l;
+}
+
+size_t strxfrm(char *restrict dest, const char *restrict src, size_t n)
+{
+	return __strxfrm_l(dest, src, n, CURRENT_LOCALE);
+}
+
+weak_alias(__strxfrm_l, strxfrm_l);
libc/musl/src/locale/textdomain.c
@@ -0,0 +1,42 @@
+#include <libintl.h>
+#include <string.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <limits.h>
+
+static char *current_domain;
+
+char *__gettextdomain()
+{
+	return current_domain ? current_domain : "messages";
+}
+
+char *textdomain(const char *domainname)
+{
+	if (!domainname) return __gettextdomain();
+
+	size_t domlen = strlen(domainname);
+	if (domlen > NAME_MAX) {
+		errno = EINVAL;
+		return 0;
+	}
+
+	if (!current_domain) {
+		current_domain = malloc(NAME_MAX+1);
+		if (!current_domain) return 0;
+	}
+
+	memcpy(current_domain, domainname, domlen+1);
+
+	return current_domain;
+}
+
+char *gettext(const char *msgid)
+{
+	return dgettext(0, msgid);
+}
+
+char *ngettext(const char *msgid1, const char *msgid2, unsigned long int n)
+{
+	return dngettext(0, msgid1, msgid2, n);
+}
libc/musl/src/locale/uselocale.c
@@ -0,0 +1,16 @@
+#include "locale_impl.h"
+#include "pthread_impl.h"
+#include "libc.h"
+
+locale_t __uselocale(locale_t new)
+{
+	pthread_t self = __pthread_self();
+	locale_t old = self->locale;
+	locale_t global = &libc.global_locale;
+
+	if (new) self->locale = new == LC_GLOBAL_LOCALE ? global : new;
+
+	return old == global ? LC_GLOBAL_LOCALE : old;
+}
+
+weak_alias(__uselocale, uselocale);
libc/musl/src/locale/wcscoll.c
@@ -0,0 +1,16 @@
+#include <wchar.h>
+#include <locale.h>
+#include "locale_impl.h"
+
+/* FIXME: stub */
+int __wcscoll_l(const wchar_t *l, const wchar_t *r, locale_t locale)
+{
+	return wcscmp(l, r);
+}
+
+int wcscoll(const wchar_t *l, const wchar_t *r)
+{
+	return __wcscoll_l(l, r, CURRENT_LOCALE);
+}
+
+weak_alias(__wcscoll_l, wcscoll_l);
libc/musl/src/locale/wcsxfrm.c
@@ -0,0 +1,23 @@
+#include <wchar.h>
+#include <locale.h>
+#include "locale_impl.h"
+
+/* collate only by code points */
+size_t __wcsxfrm_l(wchar_t *restrict dest, const wchar_t *restrict src, size_t n, locale_t loc)
+{
+	size_t l = wcslen(src);
+	if (l < n) {
+		wmemcpy(dest, src, l+1);
+	} else if (n) {
+		wmemcpy(dest, src, n-1);
+		dest[n-1] = 0;
+	}
+	return l;
+}
+
+size_t wcsxfrm(wchar_t *restrict dest, const wchar_t *restrict src, size_t n)
+{
+	return __wcsxfrm_l(dest, src, n, CURRENT_LOCALE);
+}
+
+weak_alias(__wcsxfrm_l, wcsxfrm_l);
libc/musl/src/malloc/aligned_alloc.c
@@ -0,0 +1,7 @@
+#include <stdlib.h>
+#include "malloc_impl.h"
+
+void *aligned_alloc(size_t align, size_t len)
+{
+	return __memalign(align, len);
+}
libc/musl/src/malloc/DESIGN
@@ -0,0 +1,22 @@
+
+
+In principle, this memory allocator is roughly equivalent to Doug
+Lea's dlmalloc with fine-grained locking.
+
+
+
+malloc:
+
+Uses a freelist binned by chunk size, with a bitmap to optimize
+searching for the smallest non-empty bin which can satisfy an
+allocation. If no free chunks are available, it creates a new chunk of
+the requested size and attempts to merge it with any existing free
+chunk immediately below the newly created chunk.
+
+Whether the chunk was obtained from a bin or newly created, it's
+likely to be larger than the requested allocation. malloc always
+finishes its work by passing the new chunk to realloc, which will
+split it into two chunks and free the tail portion.
+
+
+
libc/musl/src/malloc/expand_heap.c
@@ -0,0 +1,71 @@
+#include <limits.h>
+#include <stdint.h>
+#include <errno.h>
+#include <sys/mman.h>
+#include "libc.h"
+#include "syscall.h"
+#include "malloc_impl.h"
+
+/* This function returns true if the interval [old,new]
+ * intersects the 'len'-sized interval below &libc.auxv
+ * (interpreted as the main-thread stack) or below &b
+ * (the current stack). It is used to defend against
+ * buggy brk implementations that can cross the stack. */
+
+static int traverses_stack_p(uintptr_t old, uintptr_t new)
+{
+	const uintptr_t len = 8<<20;
+	uintptr_t a, b;
+
+	b = (uintptr_t)libc.auxv;
+	a = b > len ? b-len : 0;
+	if (new>a && old<b) return 1;
+
+	b = (uintptr_t)&b;
+	a = b > len ? b-len : 0;
+	if (new>a && old<b) return 1;
+
+	return 0;
+}
+
+/* Expand the heap in-place if brk can be used, or otherwise via mmap,
+ * using an exponential lower bound on growth by mmap to make
+ * fragmentation asymptotically irrelevant. The size argument is both
+ * an input and an output, since the caller needs to know the size
+ * allocated, which will be larger than requested due to page alignment
+ * and mmap minimum size rules. The caller is responsible for locking
+ * to prevent concurrent calls. */
+
+void *__expand_heap(size_t *pn)
+{
+	static uintptr_t brk;
+	static unsigned mmap_step;
+	size_t n = *pn;
+
+	if (n > SIZE_MAX/2 - PAGE_SIZE) {
+		errno = ENOMEM;
+		return 0;
+	}
+	n += -n & PAGE_SIZE-1;
+
+	if (!brk) {
+		brk = __syscall(SYS_brk, 0);
+		brk += -brk & PAGE_SIZE-1;
+	}
+
+	if (n < SIZE_MAX-brk && !traverses_stack_p(brk, brk+n)
+	    && __syscall(SYS_brk, brk+n)==brk+n) {
+		*pn = n;
+		brk += n;
+		return (void *)(brk-n);
+	}
+
+	size_t min = (size_t)PAGE_SIZE << mmap_step/2;
+	if (n < min) n = min;
+	void *area = __mmap(0, n, PROT_READ|PROT_WRITE,
+		MAP_PRIVATE|MAP_ANONYMOUS, -1, 0);
+	if (area == MAP_FAILED) return 0;
+	*pn = n;
+	mmap_step++;
+	return area;
+}
libc/musl/src/malloc/lite_malloc.c
@@ -0,0 +1,59 @@
+#include <stdlib.h>
+#include <stdint.h>
+#include <limits.h>
+#include <errno.h>
+#include "lock.h"
+#include "malloc_impl.h"
+
+#define ALIGN 16
+
+static void *__simple_malloc(size_t n)
+{
+	static char *cur, *end;
+	static volatile int lock[1];
+	size_t align=1, pad;
+	void *p;
+
+	if (!n) n++;
+	while (align<n && align<ALIGN)
+		align += align;
+
+	LOCK(lock);
+
+	pad = -(uintptr_t)cur & align-1;
+
+	if (n <= SIZE_MAX/2 + ALIGN) n += pad;
+
+	if (n > end-cur) {
+		size_t m = n;
+		char *new = __expand_heap(&m);
+		if (!new) {
+			UNLOCK(lock);
+			return 0;
+		}
+		if (new != end) {
+			cur = new;
+			n -= pad;
+			pad = 0;
+		}
+		end = new + m;
+	}
+
+	p = cur + pad;
+	cur += n;
+	UNLOCK(lock);
+	return p;
+}
+
+weak_alias(__simple_malloc, malloc);
+
+static void *__simple_calloc(size_t m, size_t n)
+{
+	if (n && m > (size_t)-1/n) {
+		errno = ENOMEM;
+		return 0;
+	}
+	return __simple_malloc(n * m);
+}
+
+weak_alias(__simple_calloc, calloc);
libc/musl/src/malloc/malloc.c
@@ -0,0 +1,548 @@
+#define _GNU_SOURCE
+#include <stdlib.h>
+#include <string.h>
+#include <limits.h>
+#include <stdint.h>
+#include <errno.h>
+#include <sys/mman.h>
+#include "libc.h"
+#include "atomic.h"
+#include "pthread_impl.h"
+#include "malloc_impl.h"
+
+#if defined(__GNUC__) && defined(__PIC__)
+#define inline inline __attribute__((always_inline))
+#endif
+
+static struct {
+	volatile uint64_t binmap;
+	struct bin bins[64];
+	volatile int free_lock[2];
+} mal;
+
+int __malloc_replaced;
+
+/* Synchronization tools */
+
+static inline void lock(volatile int *lk)
+{
+	if (libc.threads_minus_1)
+		while(a_swap(lk, 1)) __wait(lk, lk+1, 1, 1);
+}
+
+static inline void unlock(volatile int *lk)
+{
+	if (lk[0]) {
+		a_store(lk, 0);
+		if (lk[1]) __wake(lk, 1, 1);
+	}
+}
+
+static inline void lock_bin(int i)
+{
+	lock(mal.bins[i].lock);
+	if (!mal.bins[i].head)
+		mal.bins[i].head = mal.bins[i].tail = BIN_TO_CHUNK(i);
+}
+
+static inline void unlock_bin(int i)
+{
+	unlock(mal.bins[i].lock);
+}
+
+static int first_set(uint64_t x)
+{
+#if 1
+	return a_ctz_64(x);
+#else
+	static const char debruijn64[64] = {
+		0, 1, 2, 53, 3, 7, 54, 27, 4, 38, 41, 8, 34, 55, 48, 28,
+		62, 5, 39, 46, 44, 42, 22, 9, 24, 35, 59, 56, 49, 18, 29, 11,
+		63, 52, 6, 26, 37, 40, 33, 47, 61, 45, 43, 21, 23, 58, 17, 10,
+		51, 25, 36, 32, 60, 20, 57, 16, 50, 31, 19, 15, 30, 14, 13, 12
+	};
+	static const char debruijn32[32] = {
+		0, 1, 23, 2, 29, 24, 19, 3, 30, 27, 25, 11, 20, 8, 4, 13,
+		31, 22, 28, 18, 26, 10, 7, 12, 21, 17, 9, 6, 16, 5, 15, 14
+	};
+	if (sizeof(long) < 8) {
+		uint32_t y = x;
+		if (!y) {
+			y = x>>32;
+			return 32 + debruijn32[(y&-y)*0x076be629 >> 27];
+		}
+		return debruijn32[(y&-y)*0x076be629 >> 27];
+	}
+	return debruijn64[(x&-x)*0x022fdd63cc95386dull >> 58];
+#endif
+}
+
+static const unsigned char bin_tab[60] = {
+	            32,33,34,35,36,36,37,37,38,38,39,39,
+	40,40,40,40,41,41,41,41,42,42,42,42,43,43,43,43,
+	44,44,44,44,44,44,44,44,45,45,45,45,45,45,45,45,
+	46,46,46,46,46,46,46,46,47,47,47,47,47,47,47,47,
+};
+
+static int bin_index(size_t x)
+{
+	x = x / SIZE_ALIGN - 1;
+	if (x <= 32) return x;
+	if (x < 512) return bin_tab[x/8-4];
+	if (x > 0x1c00) return 63;
+	return bin_tab[x/128-4] + 16;
+}
+
+static int bin_index_up(size_t x)
+{
+	x = x / SIZE_ALIGN - 1;
+	if (x <= 32) return x;
+	x--;
+	if (x < 512) return bin_tab[x/8-4] + 1;
+	return bin_tab[x/128-4] + 17;
+}
+
+#if 0
+void __dump_heap(int x)
+{
+	struct chunk *c;
+	int i;
+	for (c = (void *)mal.heap; CHUNK_SIZE(c); c = NEXT_CHUNK(c))
+		fprintf(stderr, "base %p size %zu (%d) flags %d/%d\n",
+			c, CHUNK_SIZE(c), bin_index(CHUNK_SIZE(c)),
+			c->csize & 15,
+			NEXT_CHUNK(c)->psize & 15);
+	for (i=0; i<64; i++) {
+		if (mal.bins[i].head != BIN_TO_CHUNK(i) && mal.bins[i].head) {
+			fprintf(stderr, "bin %d: %p\n", i, mal.bins[i].head);
+			if (!(mal.binmap & 1ULL<<i))
+				fprintf(stderr, "missing from binmap!\n");
+		} else if (mal.binmap & 1ULL<<i)
+			fprintf(stderr, "binmap wrongly contains %d!\n", i);
+	}
+}
+#endif
+
+static struct chunk *expand_heap(size_t n)
+{
+	static int heap_lock[2];
+	static void *end;
+	void *p;
+	struct chunk *w;
+
+	/* The argument n already accounts for the caller's chunk
+	 * overhead needs, but if the heap can't be extended in-place,
+	 * we need room for an extra zero-sized sentinel chunk. */
+	n += SIZE_ALIGN;
+
+	lock(heap_lock);
+
+	p = __expand_heap(&n);
+	if (!p) {
+		unlock(heap_lock);
+		return 0;
+	}
+
+	/* If not just expanding existing space, we need to make a
+	 * new sentinel chunk below the allocated space. */
+	if (p != end) {
+		/* Valid/safe because of the prologue increment. */
+		n -= SIZE_ALIGN;
+		p = (char *)p + SIZE_ALIGN;
+		w = MEM_TO_CHUNK(p);
+		w->psize = 0 | C_INUSE;
+	}
+
+	/* Record new heap end and fill in footer. */
+	end = (char *)p + n;
+	w = MEM_TO_CHUNK(end);
+	w->psize = n | C_INUSE;
+	w->csize = 0 | C_INUSE;
+
+	/* Fill in header, which may be new or may be replacing a
+	 * zero-size sentinel header at the old end-of-heap. */
+	w = MEM_TO_CHUNK(p);
+	w->csize = n | C_INUSE;
+
+	unlock(heap_lock);
+
+	return w;
+}
+
+static int adjust_size(size_t *n)
+{
+	/* Result of pointer difference must fit in ptrdiff_t. */
+	if (*n-1 > PTRDIFF_MAX - SIZE_ALIGN - PAGE_SIZE) {
+		if (*n) {
+			errno = ENOMEM;
+			return -1;
+		} else {
+			*n = SIZE_ALIGN;
+			return 0;
+		}
+	}
+	*n = (*n + OVERHEAD + SIZE_ALIGN - 1) & SIZE_MASK;
+	return 0;
+}
+
+static void unbin(struct chunk *c, int i)
+{
+	if (c->prev == c->next)
+		a_and_64(&mal.binmap, ~(1ULL<<i));
+	c->prev->next = c->next;
+	c->next->prev = c->prev;
+	c->csize |= C_INUSE;
+	NEXT_CHUNK(c)->psize |= C_INUSE;
+}
+
+static int alloc_fwd(struct chunk *c)
+{
+	int i;
+	size_t k;
+	while (!((k=c->csize) & C_INUSE)) {
+		i = bin_index(k);
+		lock_bin(i);
+		if (c->csize == k) {
+			unbin(c, i);
+			unlock_bin(i);
+			return 1;
+		}
+		unlock_bin(i);
+	}
+	return 0;
+}
+
+static int alloc_rev(struct chunk *c)
+{
+	int i;
+	size_t k;
+	while (!((k=c->psize) & C_INUSE)) {
+		i = bin_index(k);
+		lock_bin(i);
+		if (c->psize == k) {
+			unbin(PREV_CHUNK(c), i);
+			unlock_bin(i);
+			return 1;
+		}
+		unlock_bin(i);
+	}
+	return 0;
+}
+
+
+/* pretrim - trims a chunk _prior_ to removing it from its bin.
+ * Must be called with i as the ideal bin for size n, j the bin
+ * for the _free_ chunk self, and bin j locked. */
+static int pretrim(struct chunk *self, size_t n, int i, int j)
+{
+	size_t n1;
+	struct chunk *next, *split;
+
+	/* We cannot pretrim if it would require re-binning. */
+	if (j < 40) return 0;
+	if (j < i+3) {
+		if (j != 63) return 0;
+		n1 = CHUNK_SIZE(self);
+		if (n1-n <= MMAP_THRESHOLD) return 0;
+	} else {
+		n1 = CHUNK_SIZE(self);
+	}
+	if (bin_index(n1-n) != j) return 0;
+
+	next = NEXT_CHUNK(self);
+	split = (void *)((char *)self + n);
+
+	split->prev = self->prev;
+	split->next = self->next;
+	split->prev->next = split;
+	split->next->prev = split;
+	split->psize = n | C_INUSE;
+	split->csize = n1-n;
+	next->psize = n1-n;
+	self->csize = n | C_INUSE;
+	return 1;
+}
+
+static void trim(struct chunk *self, size_t n)
+{
+	size_t n1 = CHUNK_SIZE(self);
+	struct chunk *next, *split;
+
+	if (n >= n1 - DONTCARE) return;
+
+	next = NEXT_CHUNK(self);
+	split = (void *)((char *)self + n);
+
+	split->psize = n | C_INUSE;
+	split->csize = n1-n | C_INUSE;
+	next->psize = n1-n | C_INUSE;
+	self->csize = n | C_INUSE;
+
+	__bin_chunk(split);
+}
+
+void *malloc(size_t n)
+{
+	struct chunk *c;
+	int i, j;
+
+	if (adjust_size(&n) < 0) return 0;
+
+	if (n > MMAP_THRESHOLD) {
+		size_t len = n + OVERHEAD + PAGE_SIZE - 1 & -PAGE_SIZE;
+		char *base = __mmap(0, len, PROT_READ|PROT_WRITE,
+			MAP_PRIVATE|MAP_ANONYMOUS, -1, 0);
+		if (base == (void *)-1) return 0;
+		c = (void *)(base + SIZE_ALIGN - OVERHEAD);
+		c->csize = len - (SIZE_ALIGN - OVERHEAD);
+		c->psize = SIZE_ALIGN - OVERHEAD;
+		return CHUNK_TO_MEM(c);
+	}
+
+	i = bin_index_up(n);
+	for (;;) {
+		uint64_t mask = mal.binmap & -(1ULL<<i);
+		if (!mask) {
+			c = expand_heap(n);
+			if (!c) return 0;
+			if (alloc_rev(c)) {
+				struct chunk *x = c;
+				c = PREV_CHUNK(c);
+				NEXT_CHUNK(x)->psize = c->csize =
+					x->csize + CHUNK_SIZE(c);
+			}
+			break;
+		}
+		j = first_set(mask);
+		lock_bin(j);
+		c = mal.bins[j].head;
+		if (c != BIN_TO_CHUNK(j)) {
+			if (!pretrim(c, n, i, j)) unbin(c, j);
+			unlock_bin(j);
+			break;
+		}
+		unlock_bin(j);
+	}
+
+	/* Now patch up in case we over-allocated */
+	trim(c, n);
+
+	return CHUNK_TO_MEM(c);
+}
+
+static size_t mal0_clear(char *p, size_t pagesz, size_t n)
+{
+#ifdef __GNUC__
+	typedef uint64_t __attribute__((__may_alias__)) T;
+#else
+	typedef unsigned char T;
+#endif
+	char *pp = p + n;
+	size_t i = (uintptr_t)pp & (pagesz - 1);
+	for (;;) {
+		pp = memset(pp - i, 0, i);
+		if (pp - p < pagesz) return pp - p;
+		for (i = pagesz; i; i -= 2*sizeof(T), pp -= 2*sizeof(T))
+		        if (((T *)pp)[-1] | ((T *)pp)[-2])
+				break;
+	}
+}
+
+void *calloc(size_t m, size_t n)
+{
+	if (n && m > (size_t)-1/n) {
+		errno = ENOMEM;
+		return 0;
+	}
+	n *= m;
+	void *p = malloc(n);
+	if (!p) return p;
+	if (!__malloc_replaced) {
+		if (IS_MMAPPED(MEM_TO_CHUNK(p)))
+			return p;
+		if (n >= PAGE_SIZE)
+			n = mal0_clear(p, PAGE_SIZE, n);
+	}
+	return memset(p, 0, n);
+}
+
+void *realloc(void *p, size_t n)
+{
+	struct chunk *self, *next;
+	size_t n0, n1;
+	void *new;
+
+	if (!p) return malloc(n);
+
+	if (adjust_size(&n) < 0) return 0;
+
+	self = MEM_TO_CHUNK(p);
+	n1 = n0 = CHUNK_SIZE(self);
+
+	if (IS_MMAPPED(self)) {
+		size_t extra = self->psize;
+		char *base = (char *)self - extra;
+		size_t oldlen = n0 + extra;
+		size_t newlen = n + extra;
+		/* Crash on realloc of freed chunk */
+		if (extra & 1) a_crash();
+		if (newlen < PAGE_SIZE && (new = malloc(n-OVERHEAD))) {
+			n0 = n;
+			goto copy_free_ret;
+		}
+		newlen = (newlen + PAGE_SIZE-1) & -PAGE_SIZE;
+		if (oldlen == newlen) return p;
+		base = __mremap(base, oldlen, newlen, MREMAP_MAYMOVE);
+		if (base == (void *)-1)
+			goto copy_realloc;
+		self = (void *)(base + extra);
+		self->csize = newlen - extra;
+		return CHUNK_TO_MEM(self);
+	}
+
+	next = NEXT_CHUNK(self);
+
+	/* Crash on corrupted footer (likely from buffer overflow) */
+	if (next->psize != self->csize) a_crash();
+
+	/* Merge adjacent chunks if we need more space. This is not
+	 * a waste of time even if we fail to get enough space, because our
+	 * subsequent call to free would otherwise have to do the merge. */
+	if (n > n1 && alloc_fwd(next)) {
+		n1 += CHUNK_SIZE(next);
+		next = NEXT_CHUNK(next);
+	}
+	/* FIXME: find what's wrong here and reenable it..? */
+	if (0 && n > n1 && alloc_rev(self)) {
+		self = PREV_CHUNK(self);
+		n1 += CHUNK_SIZE(self);
+	}
+	self->csize = n1 | C_INUSE;
+	next->psize = n1 | C_INUSE;
+
+	/* If we got enough space, split off the excess and return */
+	if (n <= n1) {
+		//memmove(CHUNK_TO_MEM(self), p, n0-OVERHEAD);
+		trim(self, n);
+		return CHUNK_TO_MEM(self);
+	}
+
+copy_realloc:
+	/* As a last resort, allocate a new chunk and copy to it. */
+	new = malloc(n-OVERHEAD);
+	if (!new) return 0;
+copy_free_ret:
+	memcpy(new, p, n0-OVERHEAD);
+	free(CHUNK_TO_MEM(self));
+	return new;
+}
+
+void __bin_chunk(struct chunk *self)
+{
+	struct chunk *next = NEXT_CHUNK(self);
+	size_t final_size, new_size, size;
+	int reclaim=0;
+	int i;
+
+	final_size = new_size = CHUNK_SIZE(self);
+
+	/* Crash on corrupted footer (likely from buffer overflow) */
+	if (next->psize != self->csize) a_crash();
+
+	for (;;) {
+		if (self->psize & next->csize & C_INUSE) {
+			self->csize = final_size | C_INUSE;
+			next->psize = final_size | C_INUSE;
+			i = bin_index(final_size);
+			lock_bin(i);
+			lock(mal.free_lock);
+			if (self->psize & next->csize & C_INUSE)
+				break;
+			unlock(mal.free_lock);
+			unlock_bin(i);
+		}
+
+		if (alloc_rev(self)) {
+			self = PREV_CHUNK(self);
+			size = CHUNK_SIZE(self);
+			final_size += size;
+			if (new_size+size > RECLAIM && (new_size+size^size) > size)
+				reclaim = 1;
+		}
+
+		if (alloc_fwd(next)) {
+			size = CHUNK_SIZE(next);
+			final_size += size;
+			if (new_size+size > RECLAIM && (new_size+size^size) > size)
+				reclaim = 1;
+			next = NEXT_CHUNK(next);
+		}
+	}
+
+	if (!(mal.binmap & 1ULL<<i))
+		a_or_64(&mal.binmap, 1ULL<<i);
+
+	self->csize = final_size;
+	next->psize = final_size;
+	unlock(mal.free_lock);
+
+	self->next = BIN_TO_CHUNK(i);
+	self->prev = mal.bins[i].tail;
+	self->next->prev = self;
+	self->prev->next = self;
+
+	/* Replace middle of large chunks with fresh zero pages */
+	if (reclaim) {
+		uintptr_t a = (uintptr_t)self + SIZE_ALIGN+PAGE_SIZE-1 & -PAGE_SIZE;
+		uintptr_t b = (uintptr_t)next - SIZE_ALIGN & -PAGE_SIZE;
+#if 1
+		__madvise((void *)a, b-a, MADV_DONTNEED);
+#else
+		__mmap((void *)a, b-a, PROT_READ|PROT_WRITE,
+			MAP_PRIVATE|MAP_ANONYMOUS|MAP_FIXED, -1, 0);
+#endif
+	}
+
+	unlock_bin(i);
+}
+
+static void unmap_chunk(struct chunk *self)
+{
+	size_t extra = self->psize;
+	char *base = (char *)self - extra;
+	size_t len = CHUNK_SIZE(self) + extra;
+	/* Crash on double free */
+	if (extra & 1) a_crash();
+	__munmap(base, len);
+}
+
+void free(void *p)
+{
+	if (!p) return;
+
+	struct chunk *self = MEM_TO_CHUNK(p);
+
+	if (IS_MMAPPED(self))
+		unmap_chunk(self);
+	else
+		__bin_chunk(self);
+}
+
+void __malloc_donate(char *start, char *end)
+{
+	size_t align_start_up = (SIZE_ALIGN-1) & (-(uintptr_t)start - OVERHEAD);
+	size_t align_end_down = (SIZE_ALIGN-1) & (uintptr_t)end;
+
+	/* Getting past this condition ensures that the padding for alignment
+	 * and header overhead will not overflow and will leave a nonzero
+	 * multiple of SIZE_ALIGN bytes between start and end. */
+	if (end - start <= OVERHEAD + align_start_up + align_end_down)
+		return;
+	start += align_start_up + OVERHEAD;
+	end   -= align_end_down;
+
+	struct chunk *c = MEM_TO_CHUNK(start), *n = MEM_TO_CHUNK(end);
+	c->psize = n->csize = C_INUSE;
+	c->csize = n->psize = C_INUSE | (end-start);
+	__bin_chunk(c);
+}
libc/musl/src/malloc/malloc_usable_size.c
@@ -0,0 +1,9 @@
+#include <malloc.h>
+#include "malloc_impl.h"
+ 
+hidden void *(*const __realloc_dep)(void *, size_t) = realloc;
+
+size_t malloc_usable_size(void *p)
+{
+	return p ? CHUNK_SIZE(MEM_TO_CHUNK(p)) - OVERHEAD : 0;
+}
libc/musl/src/malloc/memalign.c
@@ -0,0 +1,54 @@
+#include <stdlib.h>
+#include <stdint.h>
+#include <errno.h>
+#include "malloc_impl.h"
+
+void *__memalign(size_t align, size_t len)
+{
+	unsigned char *mem, *new;
+
+	if ((align & -align) != align) {
+		errno = EINVAL;
+		return 0;
+	}
+
+	if (len > SIZE_MAX - align || __malloc_replaced) {
+		errno = ENOMEM;
+		return 0;
+	}
+
+	if (align <= SIZE_ALIGN)
+		return malloc(len);
+
+	if (!(mem = malloc(len + align-1)))
+		return 0;
+
+	new = (void *)((uintptr_t)mem + align-1 & -align);
+	if (new == mem) return mem;
+
+	struct chunk *c = MEM_TO_CHUNK(mem);
+	struct chunk *n = MEM_TO_CHUNK(new);
+
+	if (IS_MMAPPED(c)) {
+		/* Apply difference between aligned and original
+		 * address to the "extra" field of mmapped chunk. */
+		n->psize = c->psize + (new-mem);
+		n->csize = c->csize - (new-mem);
+		return new;
+	}
+
+	struct chunk *t = NEXT_CHUNK(c);
+
+	/* Split the allocated chunk into two chunks. The aligned part
+	 * that will be used has the size in its footer reduced by the
+	 * difference between the aligned and original addresses, and
+	 * the resulting size copied to its header. A new header and
+	 * footer are written for the split-off part to be freed. */
+	n->psize = c->csize = C_INUSE | (new-mem);
+	n->csize = t->psize -= new-mem;
+
+	__bin_chunk(c);
+	return new;
+}
+
+weak_alias(__memalign, memalign);
libc/musl/src/malloc/posix_memalign.c
@@ -0,0 +1,12 @@
+#include <stdlib.h>
+#include <errno.h>
+#include "malloc_impl.h"
+
+int posix_memalign(void **res, size_t align, size_t len)
+{
+	if (align < sizeof(void *)) return EINVAL;
+	void *mem = __memalign(align, len);
+	if (!mem) return errno;
+	*res = mem;
+	return 0;
+}
libc/musl/src/math/aarch64/ceil.c
@@ -0,0 +1,7 @@
+#include <math.h>
+
+double ceil(double x)
+{
+	__asm__ ("frintp %d0, %d1" : "=w"(x) : "w"(x));
+	return x;
+}
libc/musl/src/math/aarch64/ceilf.c
@@ -0,0 +1,7 @@
+#include <math.h>
+
+float ceilf(float x)
+{
+	__asm__ ("frintp %s0, %s1" : "=w"(x) : "w"(x));
+	return x;
+}
libc/musl/src/math/aarch64/fabs.c
@@ -0,0 +1,7 @@
+#include <math.h>
+
+double fabs(double x)
+{
+	__asm__ ("fabs %d0, %d1" : "=w"(x) : "w"(x));
+	return x;
+}
libc/musl/src/math/aarch64/fabsf.c
@@ -0,0 +1,7 @@
+#include <math.h>
+
+float fabsf(float x)
+{
+	__asm__ ("fabs %s0, %s1" : "=w"(x) : "w"(x));
+	return x;
+}
libc/musl/src/math/aarch64/floor.c
@@ -0,0 +1,7 @@
+#include <math.h>
+
+double floor(double x)
+{
+	__asm__ ("frintm %d0, %d1" : "=w"(x) : "w"(x));
+	return x;
+}
libc/musl/src/math/aarch64/floorf.c
@@ -0,0 +1,7 @@
+#include <math.h>
+
+float floorf(float x)
+{
+	__asm__ ("frintm %s0, %s1" : "=w"(x) : "w"(x));
+	return x;
+}
libc/musl/src/math/aarch64/fma.c
@@ -0,0 +1,7 @@
+#include <math.h>
+
+double fma(double x, double y, double z)
+{
+	__asm__ ("fmadd %d0, %d1, %d2, %d3" : "=w"(x) : "w"(x), "w"(y), "w"(z));
+	return x;
+}
libc/musl/src/math/aarch64/fmaf.c
@@ -0,0 +1,7 @@
+#include <math.h>
+
+float fmaf(float x, float y, float z)
+{
+	__asm__ ("fmadd %s0, %s1, %s2, %s3" : "=w"(x) : "w"(x), "w"(y), "w"(z));
+	return x;
+}
libc/musl/src/math/aarch64/fmax.c
@@ -0,0 +1,7 @@
+#include <math.h>
+
+double fmax(double x, double y)
+{
+	__asm__ ("fmaxnm %d0, %d1, %d2" : "=w"(x) : "w"(x), "w"(y));
+	return x;
+}
libc/musl/src/math/aarch64/fmaxf.c
@@ -0,0 +1,7 @@
+#include <math.h>
+
+float fmaxf(float x, float y)
+{
+	__asm__ ("fmaxnm %s0, %s1, %s2" : "=w"(x) : "w"(x), "w"(y));
+	return x;
+}
libc/musl/src/math/aarch64/fmin.c
@@ -0,0 +1,7 @@
+#include <math.h>
+
+double fmin(double x, double y)
+{
+	__asm__ ("fminnm %d0, %d1, %d2" : "=w"(x) : "w"(x), "w"(y));
+	return x;
+}
libc/musl/src/math/aarch64/fminf.c
@@ -0,0 +1,7 @@
+#include <math.h>
+
+float fminf(float x, float y)
+{
+	__asm__ ("fminnm %s0, %s1, %s2" : "=w"(x) : "w"(x), "w"(y));
+	return x;
+}
libc/musl/src/math/aarch64/llrint.c
@@ -0,0 +1,10 @@
+#include <math.h>
+
+long long llrint(double x)
+{
+	long long n;
+	__asm__ (
+		"frintx %d1, %d1\n"
+		"fcvtzs %x0, %d1\n" : "=r"(n), "+w"(x));
+	return n;
+}
libc/musl/src/math/aarch64/llrintf.c
@@ -0,0 +1,10 @@
+#include <math.h>
+
+long long llrintf(float x)
+{
+	long long n;
+	__asm__ (
+		"frintx %s1, %s1\n"
+		"fcvtzs %x0, %s1\n" : "=r"(n), "+w"(x));
+	return n;
+}
libc/musl/src/math/aarch64/llround.c
@@ -0,0 +1,8 @@
+#include <math.h>
+
+long long llround(double x)
+{
+	long long n;
+	__asm__ ("fcvtas %x0, %d1" : "=r"(n) : "w"(x));
+	return n;
+}
libc/musl/src/math/aarch64/llroundf.c
@@ -0,0 +1,8 @@
+#include <math.h>
+
+long long llroundf(float x)
+{
+	long long n;
+	__asm__ ("fcvtas %x0, %s1" : "=r"(n) : "w"(x));
+	return n;
+}
libc/musl/src/math/aarch64/lrint.c
@@ -0,0 +1,10 @@
+#include <math.h>
+
+long lrint(double x)
+{
+	long n;
+	__asm__ (
+		"frintx %d1, %d1\n"
+		"fcvtzs %x0, %d1\n" : "=r"(n), "+w"(x));
+	return n;
+}
libc/musl/src/math/aarch64/lrintf.c
@@ -0,0 +1,10 @@
+#include <math.h>
+
+long lrintf(float x)
+{
+	long n;
+	__asm__ (
+		"frintx %s1, %s1\n"
+		"fcvtzs %x0, %s1\n" : "=r"(n), "+w"(x));
+	return n;
+}
libc/musl/src/math/aarch64/lround.c
@@ -0,0 +1,8 @@
+#include <math.h>
+
+long lround(double x)
+{
+	long n;
+	__asm__ ("fcvtas %x0, %d1" : "=r"(n) : "w"(x));
+	return n;
+}
libc/musl/src/math/aarch64/lroundf.c
@@ -0,0 +1,8 @@
+#include <math.h>
+
+long lroundf(float x)
+{
+	long n;
+	__asm__ ("fcvtas %x0, %s1" : "=r"(n) : "w"(x));
+	return n;
+}
libc/musl/src/math/aarch64/nearbyint.c
@@ -0,0 +1,7 @@
+#include <math.h>
+
+double nearbyint(double x)
+{
+	__asm__ ("frinti %d0, %d1" : "=w"(x) : "w"(x));
+	return x;
+}
libc/musl/src/math/aarch64/nearbyintf.c
@@ -0,0 +1,7 @@
+#include <math.h>
+
+float nearbyintf(float x)
+{
+	__asm__ ("frinti %s0, %s1" : "=w"(x) : "w"(x));
+	return x;
+}
libc/musl/src/math/aarch64/rint.c
@@ -0,0 +1,7 @@
+#include <math.h>
+
+double rint(double x)
+{
+	__asm__ ("frintx %d0, %d1" : "=w"(x) : "w"(x));
+	return x;
+}
libc/musl/src/math/aarch64/rintf.c
@@ -0,0 +1,7 @@
+#include <math.h>
+
+float rintf(float x)
+{
+	__asm__ ("frintx %s0, %s1" : "=w"(x) : "w"(x));
+	return x;
+}
libc/musl/src/math/aarch64/round.c
@@ -0,0 +1,7 @@
+#include <math.h>
+
+double round(double x)
+{
+	__asm__ ("frinta %d0, %d1" : "=w"(x) : "w"(x));
+	return x;
+}
libc/musl/src/math/aarch64/roundf.c
@@ -0,0 +1,7 @@
+#include <math.h>
+
+float roundf(float x)
+{
+	__asm__ ("frinta %s0, %s1" : "=w"(x) : "w"(x));
+	return x;
+}
libc/musl/src/math/aarch64/sqrt.c
@@ -0,0 +1,7 @@
+#include <math.h>
+
+double sqrt(double x)
+{
+	__asm__ ("fsqrt %d0, %d1" : "=w"(x) : "w"(x));
+	return x;
+}
libc/musl/src/math/aarch64/sqrtf.c
@@ -0,0 +1,7 @@
+#include <math.h>
+
+float sqrtf(float x)
+{
+	__asm__ ("fsqrt %s0, %s1" : "=w"(x) : "w"(x));
+	return x;
+}
libc/musl/src/math/aarch64/trunc.c
@@ -0,0 +1,7 @@
+#include <math.h>
+
+double trunc(double x)
+{
+	__asm__ ("frintz %d0, %d1" : "=w"(x) : "w"(x));
+	return x;
+}
libc/musl/src/math/aarch64/truncf.c
@@ -0,0 +1,7 @@
+#include <math.h>
+
+float truncf(float x)
+{
+	__asm__ ("frintz %s0, %s1" : "=w"(x) : "w"(x));
+	return x;
+}
libc/musl/src/math/arm/fabs.c
@@ -0,0 +1,15 @@
+#include <math.h>
+
+#if __ARM_PCS_VFP
+
+double fabs(double x)
+{
+	__asm__ ("vabs.f64 %P0, %P1" : "=w"(x) : "w"(x));
+	return x;
+}
+
+#else
+
+#include "../fabs.c"
+
+#endif
libc/musl/src/math/arm/fabsf.c
@@ -0,0 +1,15 @@
+#include <math.h>
+
+#if __ARM_PCS_VFP && !BROKEN_VFP_ASM
+
+float fabsf(float x)
+{
+	__asm__ ("vabs.f32 %0, %1" : "=t"(x) : "t"(x));
+	return x;
+}
+
+#else
+
+#include "../fabsf.c"
+
+#endif
libc/musl/src/math/arm/fma.c
@@ -0,0 +1,15 @@
+#include <math.h>
+
+#if __ARM_FEATURE_FMA && __ARM_FP&8 && !__SOFTFP__
+
+double fma(double x, double y, double z)
+{
+	__asm__ ("vfma.f64 %P0, %P1, %P2" : "+w"(z) : "w"(x), "w"(y));
+	return z;
+}
+
+#else
+
+#include "../fma.c"
+
+#endif
libc/musl/src/math/arm/fmaf.c
@@ -0,0 +1,15 @@
+#include <math.h>
+
+#if __ARM_FEATURE_FMA && __ARM_FP&4 && !__SOFTFP__ && !BROKEN_VFP_ASM
+
+float fmaf(float x, float y, float z)
+{
+	__asm__ ("vfma.f32 %0, %1, %2" : "+t"(z) : "t"(x), "t"(y));
+	return z;
+}
+
+#else
+
+#include "../fmaf.c"
+
+#endif
libc/musl/src/math/arm/sqrt.c
@@ -0,0 +1,15 @@
+#include <math.h>
+
+#if __ARM_PCS_VFP || (__VFP_FP__ && !__SOFTFP__)
+
+double sqrt(double x)
+{
+	__asm__ ("vsqrt.f64 %P0, %P1" : "=w"(x) : "w"(x));
+	return x;
+}
+
+#else
+
+#include "../sqrt.c"
+
+#endif
libc/musl/src/math/arm/sqrtf.c
@@ -0,0 +1,15 @@
+#include <math.h>
+
+#if (__ARM_PCS_VFP || (__VFP_FP__ && !__SOFTFP__)) && !BROKEN_VFP_ASM
+
+float sqrtf(float x)
+{
+	__asm__ ("vsqrt.f32 %0, %1" : "=t"(x) : "t"(x));
+	return x;
+}
+
+#else
+
+#include "../sqrtf.c"
+
+#endif
libc/musl/src/math/i386/__invtrigl.s
libc/musl/src/math/i386/acos.s
@@ -0,0 +1,28 @@
+# use acos(x) = atan2(fabs(sqrt((1-x)*(1+x))), x)
+
+.global acosf
+.type acosf,@function
+acosf:
+	flds 4(%esp)
+	jmp 1f
+
+.global acosl
+.type acosl,@function
+acosl:
+	fldt 4(%esp)
+	jmp 1f
+
+.global acos
+.type acos,@function
+acos:
+	fldl 4(%esp)
+1:	fld %st(0)
+	fld1
+	fsub %st(0),%st(1)
+	fadd %st(2)
+	fmulp
+	fsqrt
+	fabs         # fix sign of zero (matters in downward rounding mode)
+	fxch %st(1)
+	fpatan
+	ret
libc/musl/src/math/i386/acosf.s
@@ -0,0 +1,1 @@
+# see acos.s
libc/musl/src/math/i386/acosl.s
@@ -0,0 +1,1 @@
+# see acos.s
libc/musl/src/math/i386/asin.s
@@ -0,0 +1,45 @@
+.global asinf
+.type asinf,@function
+asinf:
+	flds 4(%esp)
+	mov 4(%esp),%eax
+	add %eax,%eax
+	cmp $0x01000000,%eax
+	jae 1f
+		# subnormal x, return x with underflow
+	fnstsw %ax
+	and $16,%ax
+	jnz 2f
+	fld %st(0)
+	fmul %st(1)
+	fstps 4(%esp)
+2:	ret
+
+.global asinl
+.type asinl,@function
+asinl:
+	fldt 4(%esp)
+	jmp 1f
+
+.global asin
+.type asin,@function
+asin:
+	fldl 4(%esp)
+	mov 8(%esp),%eax
+	add %eax,%eax
+	cmp $0x00200000,%eax
+	jae 1f
+		# subnormal x, return x with underflow
+	fnstsw %ax
+	and $16,%ax
+	jnz 2f
+	fsts 4(%esp)
+2:	ret
+1:	fld %st(0)
+	fld1
+	fsub %st(0),%st(1)
+	fadd %st(2)
+	fmulp
+	fsqrt
+	fpatan
+	ret
libc/musl/src/math/i386/asinf.s
@@ -0,0 +1,1 @@
+# see asin.s
libc/musl/src/math/i386/asinl.s
@@ -0,0 +1,1 @@
+# see asin.s
libc/musl/src/math/i386/atan.s
@@ -0,0 +1,17 @@
+.global atan
+.type atan,@function
+atan:
+	fldl 4(%esp)
+	mov 8(%esp),%eax
+	add %eax,%eax
+	cmp $0x00200000,%eax
+	jb 1f
+	fld1
+	fpatan
+	ret
+		# subnormal x, return x with underflow
+1:	fnstsw %ax
+	and $16,%ax
+	jnz 2f
+	fsts 4(%esp)
+2:	ret
libc/musl/src/math/i386/atan2.s
@@ -0,0 +1,17 @@
+.global atan2
+.type atan2,@function
+atan2:
+	fldl 4(%esp)
+	fldl 12(%esp)
+	fpatan
+	fstl 4(%esp)
+	mov 8(%esp),%eax
+	add %eax,%eax
+	cmp $0x00200000,%eax
+	jae 1f
+		# subnormal x, return x with underflow
+	fnstsw %ax
+	and $16,%ax
+	jnz 1f
+	fsts 4(%esp)
+1:	ret
libc/musl/src/math/i386/atan2f.s
@@ -0,0 +1,19 @@
+.global atan2f
+.type atan2f,@function
+atan2f:
+	flds 4(%esp)
+	flds 8(%esp)
+	fpatan
+	fsts 4(%esp)
+	mov 4(%esp),%eax
+	add %eax,%eax
+	cmp $0x01000000,%eax
+	jae 1f
+		# subnormal x, return x with underflow
+	fnstsw %ax
+	and $16,%ax
+	jnz 1f
+	fld %st(0)
+	fmul %st(1)
+	fstps 4(%esp)
+1:	ret
libc/musl/src/math/i386/atan2l.s
@@ -0,0 +1,7 @@
+.global atan2l
+.type atan2l,@function
+atan2l:
+	fldt 4(%esp)
+	fldt 16(%esp)
+	fpatan
+	ret
libc/musl/src/math/i386/atanf.s
@@ -0,0 +1,19 @@
+.global atanf
+.type atanf,@function
+atanf:
+	flds 4(%esp)
+	mov 4(%esp),%eax
+	add %eax,%eax
+	cmp $0x01000000,%eax
+	jb 1f
+	fld1
+	fpatan
+	ret
+		# subnormal x, return x with underflow
+1:	fnstsw %ax
+	and $16,%ax
+	jnz 2f
+	fld %st(0)
+	fmul %st(1)
+	fstps 4(%esp)
+2:	ret
libc/musl/src/math/i386/atanl.s
@@ -0,0 +1,7 @@
+.global atanl
+.type atanl,@function
+atanl:
+	fldt 4(%esp)
+	fld1
+	fpatan
+	ret
libc/musl/src/math/i386/ceil.s
@@ -0,0 +1,1 @@
+# see floor.s
libc/musl/src/math/i386/ceilf.s
@@ -0,0 +1,1 @@
+# see floor.s
libc/musl/src/math/i386/ceill.s
@@ -0,0 +1,1 @@
+# see floor.s
libc/musl/src/math/i386/exp.s
@@ -0,0 +1,152 @@
+.global expm1f
+.type expm1f,@function
+expm1f:
+	flds 4(%esp)
+	mov 4(%esp),%eax
+	add %eax,%eax
+	cmp $0x01000000,%eax
+	jae 1f
+		# subnormal x, return x with underflow
+	fnstsw %ax
+	and $16,%ax
+	jnz 2f
+	fld %st(0)
+	fmul %st(1)
+	fstps 4(%esp)
+2:	ret
+
+.global expm1l
+.type expm1l,@function
+expm1l:
+	fldt 4(%esp)
+	jmp 1f
+
+.global expm1
+.type expm1,@function
+expm1:
+	fldl 4(%esp)
+	mov 8(%esp),%eax
+	add %eax,%eax
+	cmp $0x00200000,%eax
+	jae 1f
+		# subnormal x, return x with underflow
+	fnstsw %ax
+	and $16,%ax
+	jnz 2f
+	fsts 4(%esp)
+2:	ret
+1:	fldl2e
+	fmulp
+	mov $0xc2820000,%eax
+	push %eax
+	flds (%esp)
+	pop %eax
+	fucomp %st(1)
+	fnstsw %ax
+	sahf
+	fld1
+	jb 1f
+		# x*log2e < -65, return -1 without underflow
+	fstp %st(1)
+	fchs
+	ret
+1:	fld %st(1)
+	fabs
+	fucom %st(1)
+	fnstsw %ax
+	fstp %st(0)
+	fstp %st(0)
+	sahf
+	ja 1f
+	f2xm1
+	ret
+1:	call 1f
+	fld1
+	fsubrp
+	ret
+
+.global exp2f
+.type exp2f,@function
+exp2f:
+	flds 4(%esp)
+	jmp 1f
+
+.global exp2l
+.global __exp2l
+.hidden __exp2l
+.type exp2l,@function
+exp2l:
+__exp2l:
+	fldt 4(%esp)
+	jmp 1f
+
+.global expf
+.type expf,@function
+expf:
+	flds 4(%esp)
+	jmp 2f
+
+.global exp
+.type exp,@function
+exp:
+	fldl 4(%esp)
+2:	fldl2e
+	fmulp
+	jmp 1f
+
+.global exp2
+.type exp2,@function
+exp2:
+	fldl 4(%esp)
+1:	sub $12,%esp
+	fld %st(0)
+	fstpt (%esp)
+	mov 8(%esp),%ax
+	and $0x7fff,%ax
+	cmp $0x3fff+13,%ax
+	jb 4f             # |x| < 8192
+	cmp $0x3fff+15,%ax
+	jae 3f            # |x| >= 32768
+	fsts (%esp)
+	cmpl $0xc67ff800,(%esp)
+	jb 2f             # x > -16382
+	movl $0x5f000000,(%esp)
+	flds (%esp)       # 0x1p63
+	fld %st(1)
+	fsub %st(1)
+	faddp
+	fucomp %st(1)
+	fnstsw
+	sahf
+	je 2f             # x - 0x1p63 + 0x1p63 == x
+	movl $1,(%esp)
+	flds (%esp)       # 0x1p-149
+	fdiv %st(1)
+	fstps (%esp)      # raise underflow
+2:	fld1
+	fld %st(1)
+	frndint
+	fxch %st(2)
+	fsub %st(2)       # st(0)=x-rint(x), st(1)=1, st(2)=rint(x)
+	f2xm1
+	faddp             # 2^(x-rint(x))
+1:	fscale
+	fstp %st(1)
+	add $12,%esp
+	ret
+3:	xor %eax,%eax
+4:	cmp $0x3fff-64,%ax
+	fld1
+	jb 1b             # |x| < 0x1p-64
+	fstpt (%esp)
+	fistl 8(%esp)
+	fildl 8(%esp)
+	fsubrp %st(1)
+	addl $0x3fff,8(%esp)
+	f2xm1
+	fld1
+	faddp             # 2^(x-rint(x))
+	fldt (%esp)       # 2^rint(x)
+	fmulp
+	add $12,%esp
+	ret
libc/musl/src/math/i386/exp2.s
@@ -0,0 +1,1 @@
+# see exp.s
libc/musl/src/math/i386/exp2f.s
@@ -0,0 +1,1 @@
+# see exp.s
libc/musl/src/math/i386/exp2l.s
@@ -0,0 +1,1 @@
+# see exp.s
libc/musl/src/math/i386/expf.s
@@ -0,0 +1,1 @@
+# see exp.s
libc/musl/src/math/i386/expl.s
@@ -0,0 +1,101 @@
+# exp(x) = 2^hi + 2^hi (2^lo - 1)
+# where hi+lo = log2e*x with 128bit precision
+# exact log2e*x calculation depends on nearest rounding mode
+# using the exact multiplication method of Dekker and Veltkamp
+
+.global expl
+.type expl,@function
+expl:
+	fldt 4(%esp)
+
+		# interesting case: 0x1p-32 <= |x| < 16384
+		# check if (exponent|0x8000) is in [0xbfff-32, 0xbfff+13]
+	mov 12(%esp), %ax
+	or $0x8000, %ax
+	sub $0xbfdf, %ax
+	cmp $45, %ax
+	jbe 2f
+	test %ax, %ax
+	fld1
+	js 1f
+		# if |x|>=0x1p14 or nan return 2^trunc(x)
+	fscale
+	fstp %st(1)
+	ret
+		# if |x|<0x1p-32 return 1+x
+1:	faddp
+	ret
+
+		# should be 0x1.71547652b82fe178p0L == 0x3fff b8aa3b29 5c17f0bc
+		# it will be wrong on non-nearest rounding mode
+2:	fldl2e
+	subl $44, %esp
+		# hi = log2e_hi*x
+		# 2^hi = exp2l(hi)
+	fmul %st(1),%st
+	fld %st(0)
+	fstpt (%esp)
+	fstpt 16(%esp)
+	fstpt 32(%esp)
+.hidden __exp2l
+	call __exp2l
+		# if 2^hi == inf return 2^hi
+	fld %st(0)
+	fstpt (%esp)
+	cmpw $0x7fff, 8(%esp)
+	je 1f
+	fldt 32(%esp)
+	fldt 16(%esp)
+		# fpu stack: 2^hi x hi
+		# exact mult: x*log2e
+	fld %st(1)
+		# c = 0x1p32+1
+	pushl $0x41f00000
+	pushl $0x00100000
+	fldl (%esp)
+		# xh = x - c*x + c*x
+		# xl = x - xh
+	fmulp
+	fld %st(2)
+	fsub %st(1), %st
+	faddp
+	fld %st(2)
+	fsub %st(1), %st
+		# yh = log2e_hi - c*log2e_hi + c*log2e_hi
+	pushl $0x3ff71547
+	pushl $0x65200000
+	fldl (%esp)
+		# fpu stack: 2^hi x hi xh xl yh
+		# lo = hi - xh*yh + xl*yh
+	fld %st(2)
+	fmul %st(1), %st
+	fsubp %st, %st(4)
+	fmul %st(1), %st
+	faddp %st, %st(3)
+		# yl = log2e_hi - yh
+	pushl $0x3de705fc
+	pushl $0x2f000000
+	fldl (%esp)
+		# fpu stack: 2^hi x lo xh xl yl
+		# lo += xh*yl + xl*yl
+	fmul %st, %st(2)
+	fmulp %st, %st(1)
+	fxch %st(2)
+	faddp
+	faddp
+		# log2e_lo
+	pushl $0xbfbe
+	pushl $0x82f0025f
+	pushl $0x2dc582ee
+	fldt (%esp)
+	addl $36,%esp
+		# fpu stack: 2^hi x lo log2e_lo
+		# lo += log2e_lo*x
+		# return 2^hi + 2^hi (2^lo - 1)
+	fmulp %st, %st(2)
+	faddp
+	f2xm1
+	fmul %st(1), %st
+	faddp
+1:	addl $44, %esp
+	ret
libc/musl/src/math/i386/expm1.s
@@ -0,0 +1,1 @@
+# see exp.s
libc/musl/src/math/i386/expm1f.s
@@ -0,0 +1,1 @@
+# see exp.s
libc/musl/src/math/i386/expm1l.s
@@ -0,0 +1,1 @@
+# see exp.s
libc/musl/src/math/i386/fabs.s
@@ -0,0 +1,6 @@
+.global fabs
+.type fabs,@function
+fabs:
+	fldl 4(%esp)
+	fabs
+	ret
libc/musl/src/math/i386/fabsf.s
@@ -0,0 +1,6 @@
+.global fabsf
+.type fabsf,@function
+fabsf:
+	flds 4(%esp)
+	fabs
+	ret
libc/musl/src/math/i386/fabsl.s
@@ -0,0 +1,6 @@
+.global fabsl
+.type fabsl,@function
+fabsl:
+	fldt 4(%esp)
+	fabs
+	ret
libc/musl/src/math/i386/floor.s
@@ -0,0 +1,67 @@
+.global floorf
+.type floorf,@function
+floorf:
+	flds 4(%esp)
+	jmp 1f
+
+.global floorl
+.type floorl,@function
+floorl:
+	fldt 4(%esp)
+	jmp 1f
+
+.global floor
+.type floor,@function
+floor:
+	fldl 4(%esp)
+1:	mov $0x7,%al
+1:	fstcw 4(%esp)
+	mov 5(%esp),%ah
+	mov %al,5(%esp)
+	fldcw 4(%esp)
+	frndint
+	mov %ah,5(%esp)
+	fldcw 4(%esp)
+	ret
+
+.global ceil
+.type ceil,@function
+ceil:
+	fldl 4(%esp)
+	mov $0xb,%al
+	jmp 1b
+
+.global ceilf
+.type ceilf,@function
+ceilf:
+	flds 4(%esp)
+	mov $0xb,%al
+	jmp 1b
+
+.global ceill
+.type ceill,@function
+ceill:
+	fldt 4(%esp)
+	mov $0xb,%al
+	jmp 1b
+
+.global trunc
+.type trunc,@function
+trunc:
+	fldl 4(%esp)
+	mov $0xf,%al
+	jmp 1b
+
+.global truncf
+.type truncf,@function
+truncf:
+	flds 4(%esp)
+	mov $0xf,%al
+	jmp 1b
+
+.global truncl
+.type truncl,@function
+truncl:
+	fldt 4(%esp)
+	mov $0xf,%al
+	jmp 1b
libc/musl/src/math/i386/floorf.s
@@ -0,0 +1,1 @@
+# see floor.s
libc/musl/src/math/i386/floorl.s
@@ -0,0 +1,1 @@
+# see floor.s
libc/musl/src/math/i386/fmod.s
@@ -0,0 +1,11 @@
+.global fmod
+.type fmod,@function
+fmod:
+	fldl 12(%esp)
+	fldl 4(%esp)
+1:	fprem
+	fnstsw %ax
+	sahf
+	jp 1b
+	fstp %st(1)
+	ret
libc/musl/src/math/i386/fmodf.s
@@ -0,0 +1,11 @@
+.global fmodf
+.type fmodf,@function
+fmodf:
+	flds 8(%esp)
+	flds 4(%esp)
+1:	fprem
+	fnstsw %ax
+	sahf
+	jp 1b
+	fstp %st(1)
+	ret
libc/musl/src/math/i386/fmodl.s
@@ -0,0 +1,11 @@
+.global fmodl
+.type fmodl,@function
+fmodl:
+	fldt 16(%esp)
+	fldt 4(%esp)
+1:	fprem
+	fnstsw %ax
+	sahf
+	jp 1b
+	fstp %st(1)
+	ret
libc/musl/src/math/i386/hypot.s
@@ -0,0 +1,45 @@
+.global hypot
+.type hypot,@function
+hypot:
+	mov 8(%esp),%eax
+	mov 16(%esp),%ecx
+	add %eax,%eax
+	add %ecx,%ecx
+	and %eax,%ecx
+	cmp $0xffe00000,%ecx
+	jae 2f
+	or 4(%esp),%eax
+	jnz 1f
+	fldl 12(%esp)
+	fabs
+	ret
+1:	mov 16(%esp),%eax
+	add %eax,%eax
+	or 12(%esp),%eax
+	jnz 1f
+	fldl 4(%esp)
+	fabs
+	ret
+1:	fldl 4(%esp)
+	fld %st(0)
+	fmulp
+	fldl 12(%esp)
+	fld %st(0)
+	fmulp
+	faddp
+	fsqrt
+	ret
+2:	sub $0xffe00000,%eax
+	or 4(%esp),%eax
+	jnz 1f
+	fldl 4(%esp)
+	fabs
+	ret
+1:	mov 16(%esp),%eax
+	add %eax,%eax
+	sub $0xffe00000,%eax
+	or 12(%esp),%eax
+	fldl 12(%esp)
+	jnz 1f
+	fabs
+1:	ret
libc/musl/src/math/i386/hypotf.s
@@ -0,0 +1,42 @@
+.global hypotf
+.type hypotf,@function
+hypotf:
+	mov 4(%esp),%eax
+	mov 8(%esp),%ecx
+	add %eax,%eax
+	add %ecx,%ecx
+	and %eax,%ecx
+	cmp $0xff000000,%ecx
+	jae 2f
+	test %eax,%eax
+	jnz 1f
+	flds 8(%esp)
+	fabs
+	ret
+1:	mov 8(%esp),%eax
+	add %eax,%eax
+	jnz 1f
+	flds 4(%esp)
+	fabs
+	ret
+1:	flds 4(%esp)
+	fld %st(0)
+	fmulp
+	flds 8(%esp)
+	fld %st(0)
+	fmulp
+	faddp
+	fsqrt
+	ret
+2:	cmp $0xff000000,%eax
+	jnz 1f
+	flds 4(%esp)
+	fabs
+	ret
+1:	mov 8(%esp),%eax
+	add %eax,%eax
+	cmp $0xff000000,%eax
+	flds 8(%esp)
+	jnz 1f
+	fabs
+1:	ret
libc/musl/src/math/i386/ldexp.s
@@ -0,0 +1,1 @@
+# see scalbn.s
libc/musl/src/math/i386/ldexpf.s
@@ -0,0 +1,1 @@
+# see scalbnf.s
libc/musl/src/math/i386/ldexpl.s
@@ -0,0 +1,1 @@
+# see scalbnl.s
libc/musl/src/math/i386/llrint.s
@@ -0,0 +1,8 @@
+.global llrint
+.type llrint,@function
+llrint:
+	fldl 4(%esp)
+	fistpll 4(%esp)
+	mov 4(%esp),%eax
+	mov 8(%esp),%edx
+	ret
libc/musl/src/math/i386/llrintf.s
@@ -0,0 +1,9 @@
+.global llrintf
+.type llrintf,@function
+llrintf:
+	sub $8,%esp
+	flds 12(%esp)
+	fistpll (%esp)
+	pop %eax
+	pop %edx
+	ret
libc/musl/src/math/i386/llrintl.s
@@ -0,0 +1,8 @@
+.global llrintl
+.type llrintl,@function
+llrintl:
+	fldt 4(%esp)
+	fistpll 4(%esp)
+	mov 4(%esp),%eax
+	mov 8(%esp),%edx
+	ret
libc/musl/src/math/i386/log.s
@@ -0,0 +1,7 @@
+.global log
+.type log,@function
+log:
+	fldln2
+	fldl 4(%esp)
+	fyl2x
+	ret
libc/musl/src/math/i386/log10.s
@@ -0,0 +1,7 @@
+.global log10
+.type log10,@function
+log10:
+	fldlg2
+	fldl 4(%esp)
+	fyl2x
+	ret
libc/musl/src/math/i386/log10f.s
@@ -0,0 +1,7 @@
+.global log10f
+.type log10f,@function
+log10f:
+	fldlg2
+	flds 4(%esp)
+	fyl2x
+	ret
libc/musl/src/math/i386/log10l.s
@@ -0,0 +1,7 @@
+.global log10l
+.type log10l,@function
+log10l:
+	fldlg2
+	fldt 4(%esp)
+	fyl2x
+	ret
libc/musl/src/math/i386/log1p.s
@@ -0,0 +1,24 @@
+.global log1p
+.type log1p,@function
+log1p:
+	mov 8(%esp),%eax
+	fldln2
+	and $0x7fffffff,%eax
+	fldl 4(%esp)
+	cmp $0x3fd28f00,%eax
+	ja 1f
+	cmp $0x00100000,%eax
+	jb 2f
+	fyl2xp1
+	ret
+1:	fld1
+	faddp
+	fyl2x
+	ret
+		# subnormal x, return x with underflow
+2:	fnstsw %ax
+	and $16,%ax
+	jnz 1f
+	fsts 4(%esp)
+	fstp %st(1)
+1:	ret
libc/musl/src/math/i386/log1pf.s
@@ -0,0 +1,25 @@
+.global log1pf
+.type log1pf,@function
+log1pf:
+	mov 4(%esp),%eax
+	fldln2
+	and $0x7fffffff,%eax
+	flds 4(%esp)
+	cmp $0x3e940000,%eax
+	ja 1f
+	cmp $0x00800000,%eax
+	jb 2f
+	fyl2xp1
+	ret
+1:	fld1
+	faddp
+	fyl2x
+	ret
+		# subnormal x, return x with underflow
+2:	fnstsw %ax
+	and $16,%ax
+	jnz 1f
+	fxch
+	fmul %st(1)
+	fstps 4(%esp)
+1:	ret
libc/musl/src/math/i386/log1pl.s
@@ -0,0 +1,15 @@
+.global log1pl
+.type log1pl,@function
+log1pl:
+	mov 10(%esp),%eax
+	fldln2
+	and $0x7fffffff,%eax
+	fldt 4(%esp)
+	cmp $0x3ffd9400,%eax
+	ja 1f
+	fyl2xp1
+	ret
+1:	fld1
+	faddp
+	fyl2x
+	ret
libc/musl/src/math/i386/log2.s
@@ -0,0 +1,7 @@
+.global log2
+.type log2,@function
+log2:
+	fld1
+	fldl 4(%esp)
+	fyl2x
+	ret
libc/musl/src/math/i386/log2f.s
@@ -0,0 +1,7 @@
+.global log2f
+.type log2f,@function
+log2f:
+	fld1
+	flds 4(%esp)
+	fyl2x
+	ret
libc/musl/src/math/i386/log2l.s
@@ -0,0 +1,7 @@
+.global log2l
+.type log2l,@function
+log2l:
+	fld1
+	fldt 4(%esp)
+	fyl2x
+	ret
libc/musl/src/math/i386/logf.s
@@ -0,0 +1,7 @@
+.global logf
+.type logf,@function
+logf:
+	fldln2
+	flds 4(%esp)
+	fyl2x
+	ret
libc/musl/src/math/i386/logl.s
@@ -0,0 +1,7 @@
+.global logl
+.type logl,@function
+logl:
+	fldln2
+	fldt 4(%esp)
+	fyl2x
+	ret
libc/musl/src/math/i386/lrint.s
@@ -0,0 +1,7 @@
+.global lrint
+.type lrint,@function
+lrint:
+	fldl 4(%esp)
+	fistpl 4(%esp)
+	mov 4(%esp),%eax
+	ret
libc/musl/src/math/i386/lrintf.s
@@ -0,0 +1,7 @@
+.global lrintf
+.type lrintf,@function
+lrintf:
+	flds 4(%esp)
+	fistpl 4(%esp)
+	mov 4(%esp),%eax
+	ret
libc/musl/src/math/i386/lrintl.s
@@ -0,0 +1,7 @@
+.global lrintl
+.type lrintl,@function
+lrintl:
+	fldt 4(%esp)
+	fistpl 4(%esp)
+	mov 4(%esp),%eax
+	ret
libc/musl/src/math/i386/remainder.s
@@ -0,0 +1,14 @@
+.global remainder
+.type remainder,@function
+remainder:
+.weak drem
+.type drem,@function
+drem:
+	fldl 12(%esp)
+	fldl 4(%esp)
+1:	fprem1
+	fnstsw %ax
+	sahf
+	jp 1b
+	fstp %st(1)
+	ret
libc/musl/src/math/i386/remainderf.s
@@ -0,0 +1,14 @@
+.global remainderf
+.type remainderf,@function
+remainderf:
+.weak dremf
+.type dremf,@function
+dremf:
+	flds 8(%esp)
+	flds 4(%esp)
+1:	fprem1
+	fnstsw %ax
+	sahf
+	jp 1b
+	fstp %st(1)
+	ret
libc/musl/src/math/i386/remainderl.s
@@ -0,0 +1,11 @@
+.global remainderl
+.type remainderl,@function
+remainderl:
+	fldt 16(%esp)
+	fldt 4(%esp)
+1:	fprem1
+	fnstsw %ax
+	sahf
+	jp 1b
+	fstp %st(1)
+	ret
libc/musl/src/math/i386/remquo.s
@@ -0,0 +1,50 @@
+.global remquof
+.type remquof,@function
+remquof:
+	mov 12(%esp),%ecx
+	flds 8(%esp)
+	flds 4(%esp)
+	mov 11(%esp),%dh
+	xor 7(%esp),%dh
+	jmp 1f
+
+.global remquol
+.type remquol,@function
+remquol:
+	mov 28(%esp),%ecx
+	fldt 16(%esp)
+	fldt 4(%esp)
+	mov 25(%esp),%dh
+	xor 13(%esp),%dh
+	jmp 1f
+
+.global remquo
+.type remquo,@function
+remquo:
+	mov 20(%esp),%ecx
+	fldl 12(%esp)
+	fldl 4(%esp)
+	mov 19(%esp),%dh
+	xor 11(%esp),%dh
+1:	fprem1
+	fnstsw %ax
+	sahf
+	jp 1b
+	fstp %st(1)
+	mov %ah,%dl
+	shr %dl
+	and $1,%dl
+	mov %ah,%al
+	shr $5,%al
+	and $2,%al
+	or %al,%dl
+	mov %ah,%al
+	shl $2,%al
+	and $4,%al
+	or %al,%dl
+	test %dh,%dh
+	jns 1f
+	neg %dl
+1:	movsbl %dl,%edx
+	mov %edx,(%ecx)
+	ret
libc/musl/src/math/i386/remquof.s
@@ -0,0 +1,1 @@
+# see remquo.s
libc/musl/src/math/i386/remquol.s
@@ -0,0 +1,1 @@
+# see remquo.s
libc/musl/src/math/i386/rint.s
@@ -0,0 +1,6 @@
+.global rint
+.type rint,@function
+rint:
+	fldl 4(%esp)
+	frndint
+	ret
libc/musl/src/math/i386/rintf.s
@@ -0,0 +1,6 @@
+.global rintf
+.type rintf,@function
+rintf:
+	flds 4(%esp)
+	frndint
+	ret
libc/musl/src/math/i386/rintl.s
@@ -0,0 +1,6 @@
+.global rintl
+.type rintl,@function
+rintl:
+	fldt 4(%esp)
+	frndint
+	ret
libc/musl/src/math/i386/scalbln.s
@@ -0,0 +1,1 @@
+# see scalbn.s
libc/musl/src/math/i386/scalblnf.s
@@ -0,0 +1,1 @@
+# see scalbnf.s
libc/musl/src/math/i386/scalblnl.s
@@ -0,0 +1,1 @@
+# see scalbnl.s
libc/musl/src/math/i386/scalbn.s
@@ -0,0 +1,33 @@
+.global ldexp
+.type ldexp,@function
+ldexp:
+	nop
+
+.global scalbln
+.type scalbln,@function
+scalbln:
+	nop
+
+.global scalbn
+.type scalbn,@function
+scalbn:
+	mov 12(%esp),%eax
+	add $0x3ffe,%eax
+	cmp $0x7ffd,%eax
+	jb 1f
+	sub $0x3ffe,%eax
+	sar $31,%eax
+	xor $0xfff,%eax
+	add $0x3ffe,%eax
+1:	inc %eax
+	fldl 4(%esp)
+	mov %eax,12(%esp)
+	mov $0x80000000,%eax
+	mov %eax,8(%esp)
+	xor %eax,%eax
+	mov %eax,4(%esp)
+	fldt 4(%esp)
+	fmulp
+	fstpl 4(%esp)
+	fldl 4(%esp)
+	ret
libc/musl/src/math/i386/scalbnf.s
@@ -0,0 +1,32 @@
+.global ldexpf
+.type ldexpf,@function
+ldexpf:
+	nop
+
+.global scalblnf
+.type scalblnf,@function
+scalblnf:
+	nop
+
+.global scalbnf
+.type scalbnf,@function
+scalbnf:
+	mov 8(%esp),%eax
+	add $0x3fe,%eax
+	cmp $0x7fd,%eax
+	jb 1f
+	sub $0x3fe,%eax
+	sar $31,%eax
+	xor $0x1ff,%eax
+	add $0x3fe,%eax
+1:	inc %eax
+	shl $20,%eax
+	flds 4(%esp)
+	mov %eax,8(%esp)
+	xor %eax,%eax
+	mov %eax,4(%esp)
+	fldl 4(%esp)
+	fmulp
+	fstps 4(%esp)
+	flds 4(%esp)
+	ret
libc/musl/src/math/i386/scalbnl.s
@@ -0,0 +1,32 @@
+.global ldexpl
+.type ldexpl,@function
+ldexpl:
+	nop
+
+.global scalblnl
+.type scalblnl,@function
+scalblnl:
+	nop
+
+.global scalbnl
+.type scalbnl,@function
+scalbnl:
+	mov 16(%esp),%eax
+	add $0x3ffe,%eax
+	cmp $0x7ffd,%eax
+	jae 1f
+	inc %eax
+	fldt 4(%esp)
+	mov %eax,12(%esp)
+	mov $0x80000000,%eax
+	mov %eax,8(%esp)
+	xor %eax,%eax
+	mov %eax,4(%esp)
+	fldt 4(%esp)
+	fmulp
+	ret
+1:	fildl 16(%esp)
+	fldt 4(%esp)
+	fscale
+	fstp %st(1)
+	ret
libc/musl/src/math/i386/sqrt.s
@@ -0,0 +1,21 @@
+.global sqrt
+.type sqrt,@function
+sqrt:	fldl 4(%esp)
+	fsqrt
+	fnstsw %ax
+	sub $12,%esp
+	fld %st(0)
+	fstpt (%esp)
+	mov (%esp),%ecx
+	and $0x7ff,%ecx
+	cmp $0x400,%ecx
+	jnz 1f
+	and $0x200,%eax
+	sub $0x100,%eax
+	sub %eax,(%esp)
+	fstp %st(0)
+	fldt (%esp)
+1:	add $12,%esp
+	fstpl 4(%esp)
+	fldl 4(%esp)
+	ret
libc/musl/src/math/i386/sqrtf.s
@@ -0,0 +1,7 @@
+.global sqrtf
+.type sqrtf,@function
+sqrtf:	flds 4(%esp)
+	fsqrt
+	fstps 4(%esp)
+	flds 4(%esp)
+	ret
libc/musl/src/math/i386/sqrtl.s
@@ -0,0 +1,5 @@
+.global sqrtl
+.type sqrtl,@function
+sqrtl:	fldt 4(%esp)
+	fsqrt
+	ret
libc/musl/src/math/i386/trunc.s
@@ -0,0 +1,1 @@
+# see floor.s
libc/musl/src/math/i386/truncf.s
@@ -0,0 +1,1 @@
+# see floor.s
libc/musl/src/math/i386/truncl.s
@@ -0,0 +1,1 @@
+# see floor.s
libc/musl/src/math/powerpc/fabs.c
@@ -0,0 +1,15 @@
+#include <math.h>
+
+#ifdef _SOFT_FLOAT
+
+#include "../fabs.c"
+
+#else
+
+double fabs(double x)
+{
+	__asm__ ("fabs %0, %1" : "=d"(x) : "d"(x));
+	return x;
+}
+
+#endif
libc/musl/src/math/powerpc/fabsf.c
@@ -0,0 +1,15 @@
+#include <math.h>
+
+#ifdef _SOFT_FLOAT
+
+#include "../fabsf.c"
+
+#else
+
+float fabsf(float x)
+{
+	__asm__ ("fabs %0, %1" : "=f"(x) : "f"(x));
+	return x;
+}
+
+#endif
libc/musl/src/math/powerpc/fma.c
@@ -0,0 +1,15 @@
+#include <math.h>
+
+#ifdef _SOFT_FLOAT
+
+#include "../fma.c"
+
+#else
+
+double fma(double x, double y, double z)
+{
+	__asm__("fmadd %0, %1, %2, %3" : "=d"(x) : "d"(x), "d"(y), "d"(z));
+	return x;
+}
+
+#endif
libc/musl/src/math/powerpc/fmaf.c
@@ -0,0 +1,15 @@
+#include <math.h>
+
+#ifdef _SOFT_FLOAT
+
+#include "../fmaf.c"
+
+#else
+
+float fmaf(float x, float y, float z)
+{
+	__asm__("fmadds %0, %1, %2, %3" : "=f"(x) : "f"(x), "f"(y), "f"(z));
+	return x;
+}
+
+#endif
libc/musl/src/math/powerpc/sqrt.c
@@ -0,0 +1,15 @@
+#include <math.h>
+
+#if !defined _SOFT_FLOAT && defined _ARCH_PPCSQ
+
+double sqrt(double x)
+{
+	__asm__ ("fsqrt %0, %1\n" : "=d" (x) : "d" (x));
+	return x;
+}
+
+#else
+
+#include "../sqrt.c"
+
+#endif
libc/musl/src/math/powerpc/sqrtf.c
@@ -0,0 +1,15 @@
+#include <math.h>
+
+#if !defined _SOFT_FLOAT && defined _ARCH_PPCSQ
+
+float sqrtf(float x)
+{
+	__asm__ ("fsqrts %0, %1\n" : "=f" (x) : "f" (x));
+	return x;
+}
+
+#else
+
+#include "../sqrtf.c"
+
+#endif
libc/musl/src/math/powerpc64/ceil.c
@@ -0,0 +1,15 @@
+#include <math.h>
+
+#ifdef _ARCH_PWR5X
+
+double ceil(double x)
+{
+	__asm__ ("frip %0, %1" : "=d"(x) : "d"(x));
+	return x;
+}
+
+#else
+
+#include "../ceil.c"
+
+#endif
libc/musl/src/math/powerpc64/ceilf.c
@@ -0,0 +1,15 @@
+#include <math.h>
+
+#ifdef _ARCH_PWR5X
+
+float ceilf(float x)
+{
+	__asm__ ("frip %0, %1" : "=f"(x) : "f"(x));
+	return x;
+}
+
+#else
+
+#include "../ceilf.c"
+
+#endif
libc/musl/src/math/powerpc64/fabs.c
@@ -0,0 +1,7 @@
+#include <math.h>
+
+double fabs(double x)
+{
+	__asm__ ("fabs %0, %1" : "=d"(x) : "d"(x));
+	return x;
+}
libc/musl/src/math/powerpc64/fabsf.c
@@ -0,0 +1,7 @@
+#include <math.h>
+
+float fabsf(float x)
+{
+	__asm__ ("fabs %0, %1" : "=f"(x) : "f"(x));
+	return x;
+}
libc/musl/src/math/powerpc64/floor.c
@@ -0,0 +1,15 @@
+#include <math.h>
+
+#ifdef _ARCH_PWR5X
+
+double floor(double x)
+{
+	__asm__ ("frim %0, %1" : "=d"(x) : "d"(x));
+	return x;
+}
+
+#else
+
+#include "../floor.c"
+
+#endif
libc/musl/src/math/powerpc64/floorf.c
@@ -0,0 +1,15 @@
+#include <math.h>
+
+#ifdef _ARCH_PWR5X
+
+float floorf(float x)
+{
+	__asm__ ("frim %0, %1" : "=f"(x) : "f"(x));
+	return x;
+}
+
+#else
+
+#include "../floorf.c"
+
+#endif
libc/musl/src/math/powerpc64/fma.c
@@ -0,0 +1,7 @@
+#include <math.h>
+
+double fma(double x, double y, double z)
+{
+	__asm__ ("fmadd %0, %1, %2, %3" : "=d"(x) : "d"(x), "d"(y), "d"(z));
+	return x;
+}
libc/musl/src/math/powerpc64/fmaf.c
@@ -0,0 +1,7 @@
+#include <math.h>
+
+float fmaf(float x, float y, float z)
+{
+	__asm__ ("fmadds %0, %1, %2, %3" : "=f"(x) : "f"(x), "f"(y), "f"(z));
+	return x;
+}
libc/musl/src/math/powerpc64/fmax.c
@@ -0,0 +1,15 @@
+#include <math.h>
+
+#ifdef __VSX__
+
+double fmax(double x, double y)
+{
+	__asm__ ("xsmaxdp %x0, %x1, %x2" : "=ws"(x) : "ws"(x), "ws"(y));
+	return x;
+}
+
+#else
+
+#include "../fmax.c"
+
+#endif
libc/musl/src/math/powerpc64/fmaxf.c
@@ -0,0 +1,15 @@
+#include <math.h>
+
+#ifdef __VSX__
+
+float fmaxf(float x, float y)
+{
+	__asm__ ("xsmaxdp %x0, %x1, %x2" : "=ww"(x) : "ww"(x), "ww"(y));
+	return x;
+}
+
+#else
+
+#include "../fmaxf.c"
+
+#endif
libc/musl/src/math/powerpc64/fmin.c
@@ -0,0 +1,15 @@
+#include <math.h>
+
+#ifdef __VSX__
+
+double fmin(double x, double y)
+{
+	__asm__ ("xsmindp %x0, %x1, %x2" : "=ws"(x) : "ws"(x), "ws"(y));
+	return x;
+}
+
+#else
+
+#include "../fmin.c"
+
+#endif
libc/musl/src/math/powerpc64/fminf.c
@@ -0,0 +1,15 @@
+#include <math.h>
+
+#ifdef __VSX__
+
+float fminf(float x, float y)
+{
+	__asm__ ("xsmindp %x0, %x1, %x2" : "=ww"(x) : "ww"(x), "ww"(y));
+	return x;
+}
+
+#else
+
+#include "../fminf.c"
+
+#endif
libc/musl/src/math/powerpc64/lrint.c
@@ -0,0 +1,16 @@
+#include <math.h>
+
+#ifdef _ARCH_PWR5X
+
+long lrint(double x)
+{
+	long n;
+	__asm__ ("fctid %0, %1" : "=d"(n) : "d"(x));
+	return n;
+}
+
+#else
+
+#include "../lrint.c"
+
+#endif
libc/musl/src/math/powerpc64/lrintf.c
@@ -0,0 +1,16 @@
+#include <math.h>
+
+#ifdef _ARCH_PWR5X
+
+long lrintf(float x)
+{
+	long n;
+	__asm__ ("fctid %0, %1" : "=d"(n) : "f"(x));
+	return n;
+}
+
+#else
+
+#include "../lrintf.c"
+
+#endif
libc/musl/src/math/powerpc64/lround.c
@@ -0,0 +1,18 @@
+#include <math.h>
+
+#ifdef __VSX__
+
+long lround(double x)
+{
+	long n;
+	__asm__ (
+		"xsrdpi %1, %1\n"
+		"fctid %0, %1\n" : "=d"(n), "+d"(x));
+	return n;
+}
+
+#else
+
+#include "../lround.c"
+
+#endif
libc/musl/src/math/powerpc64/lroundf.c
@@ -0,0 +1,18 @@
+#include <math.h>
+
+#ifdef __VSX__
+
+long lroundf(float x)
+{
+	long n;
+	__asm__ (
+		"xsrdpi %1, %1\n"
+		"fctid %0, %1\n" : "=d"(n), "+f"(x));
+	return n;
+}
+
+#else
+
+#include "../lroundf.c"
+
+#endif
libc/musl/src/math/powerpc64/round.c
@@ -0,0 +1,15 @@
+#include <math.h>
+
+#ifdef _ARCH_PWR5X
+
+double round(double x)
+{
+	__asm__ ("frin %0, %1" : "=d"(x) : "d"(x));
+	return x;
+}
+
+#else
+
+#include "../round.c"
+
+#endif
libc/musl/src/math/powerpc64/roundf.c
@@ -0,0 +1,15 @@
+#include <math.h>
+
+#ifdef _ARCH_PWR5X
+
+float roundf(float x)
+{
+	__asm__ ("frin %0, %1" : "=f"(x) : "f"(x));
+	return x;
+}
+
+#else
+
+#include "../roundf.c"
+
+#endif
libc/musl/src/math/powerpc64/sqrt.c
@@ -0,0 +1,7 @@
+#include <math.h>
+
+double sqrt(double x)
+{
+	__asm__ ("fsqrt %0, %1" : "=d"(x) : "d"(x));
+	return x;
+}
libc/musl/src/math/powerpc64/sqrtf.c
@@ -0,0 +1,7 @@
+#include <math.h>
+
+float sqrtf(float x)
+{
+	__asm__ ("fsqrts %0, %1" : "=f"(x) : "f"(x));
+	return x;
+}
libc/musl/src/math/powerpc64/trunc.c
@@ -0,0 +1,15 @@
+#include <math.h>
+
+#ifdef _ARCH_PWR5X
+
+double trunc(double x)
+{
+	__asm__ ("friz %0, %1" : "=d"(x) : "d"(x));
+	return x;
+}
+
+#else
+
+#include "../trunc.c"
+
+#endif
libc/musl/src/math/powerpc64/truncf.c
@@ -0,0 +1,15 @@
+#include <math.h>
+
+#ifdef _ARCH_PWR5X
+
+float truncf(float x)
+{
+	__asm__ ("friz %0, %1" : "=f"(x) : "f"(x));
+	return x;
+}
+
+#else
+
+#include "../truncf.c"
+
+#endif
libc/musl/src/math/s390x/ceil.c
@@ -0,0 +1,15 @@
+#include <math.h>
+
+#if defined(__HTM__) || __ARCH__ >= 9
+
+double ceil(double x)
+{
+	__asm__ ("fidbra %0, 6, %1, 4" : "=f"(x) : "f"(x));
+	return x;
+}
+
+#else
+
+#include "../ceil.c"
+
+#endif
libc/musl/src/math/s390x/ceilf.c
@@ -0,0 +1,15 @@
+#include <math.h>
+
+#if defined(__HTM__) || __ARCH__ >= 9
+
+float ceilf(float x)
+{
+	__asm__ ("fiebra %0, 6, %1, 4" : "=f"(x) : "f"(x));
+	return x;
+}
+
+#else
+
+#include "../ceilf.c"
+
+#endif
libc/musl/src/math/s390x/ceill.c
@@ -0,0 +1,15 @@
+#include <math.h>
+
+#if defined(__HTM__) || __ARCH__ >= 9
+
+long double ceill(long double x)
+{
+	__asm__ ("fixbra %0, 6, %1, 4" : "=f"(x) : "f"(x));
+	return x;
+}
+
+#else
+
+#include "../ceill.c"
+
+#endif
libc/musl/src/math/s390x/fabs.c
@@ -0,0 +1,15 @@
+#include <math.h>
+
+#if defined(__HTM__) || __ARCH__ >= 9
+
+double fabs(double x)
+{
+	__asm__ ("lpdbr %0, %1" : "=f"(x) : "f"(x));
+	return x;
+}
+
+#else
+
+#include "../fabs.c"
+
+#endif
libc/musl/src/math/s390x/fabsf.c
@@ -0,0 +1,15 @@
+#include <math.h>
+
+#if defined(__HTM__) || __ARCH__ >= 9
+
+float fabsf(float x)
+{
+	__asm__ ("lpebr %0, %1" : "=f"(x) : "f"(x));
+	return x;
+}
+
+#else
+
+#include "../fabsf.c"
+
+#endif
libc/musl/src/math/s390x/fabsl.c
@@ -0,0 +1,15 @@
+#include <math.h>
+
+#if defined(__HTM__) || __ARCH__ >= 9
+
+long double fabsl(long double x)
+{
+	__asm__ ("lpxbr %0, %1" : "=f"(x) : "f"(x));
+	return x;
+}
+
+#else
+
+#include "../fabsl.c"
+
+#endif
libc/musl/src/math/s390x/floor.c
@@ -0,0 +1,15 @@
+#include <math.h>
+
+#if defined(__HTM__) || __ARCH__ >= 9
+
+double floor(double x)
+{
+	__asm__ ("fidbra %0, 7, %1, 4" : "=f"(x) : "f"(x));
+	return x;
+}
+
+#else
+
+#include "../floor.c"
+
+#endif
libc/musl/src/math/s390x/floorf.c
@@ -0,0 +1,15 @@
+#include <math.h>
+
+#if defined(__HTM__) || __ARCH__ >= 9
+
+float floorf(float x)
+{
+	__asm__ ("fiebra %0, 7, %1, 4" : "=f"(x) : "f"(x));
+	return x;
+}
+
+#else
+
+#include "../floorf.c"
+
+#endif
libc/musl/src/math/s390x/floorl.c
@@ -0,0 +1,15 @@
+#include <math.h>
+
+#if defined(__HTM__) || __ARCH__ >= 9
+
+long double floorl(long double x)
+{
+	__asm__ ("fixbra %0, 7, %1, 4" : "=f"(x) : "f"(x));
+	return x;
+}
+
+#else
+
+#include "../floorl.c"
+
+#endif
libc/musl/src/math/s390x/fma.c
@@ -0,0 +1,7 @@
+#include <math.h>
+
+double fma(double x, double y, double z)
+{
+	__asm__ ("madbr %0, %1, %2" : "+f"(z) : "f"(x), "f"(y));
+	return z;
+}
libc/musl/src/math/s390x/fmaf.c
@@ -0,0 +1,7 @@
+#include <math.h>
+
+float fmaf(float x, float y, float z)
+{
+	__asm__ ("maebr %0, %1, %2" : "+f"(z) : "f"(x), "f"(y));
+	return z;
+}
libc/musl/src/math/s390x/nearbyint.c
@@ -0,0 +1,15 @@
+#include <math.h>
+
+#if defined(__HTM__) || __ARCH__ >= 9
+
+double nearbyint(double x)
+{
+	__asm__ ("fidbra %0, 0, %1, 4" : "=f"(x) : "f"(x));
+	return x;
+}
+
+#else
+
+#include "../nearbyint.c"
+
+#endif
libc/musl/src/math/s390x/nearbyintf.c
@@ -0,0 +1,15 @@
+#include <math.h>
+
+#if defined(__HTM__) || __ARCH__ >= 9
+
+float nearbyintf(float x)
+{
+	__asm__ ("fiebra %0, 0, %1, 4" : "=f"(x) : "f"(x));
+	return x;
+}
+
+#else
+
+#include "../nearbyintf.c"
+
+#endif
libc/musl/src/math/s390x/nearbyintl.c
@@ -0,0 +1,15 @@
+#include <math.h>
+
+#if defined(__HTM__) || __ARCH__ >= 9
+
+long double nearbyintl(long double x)
+{
+	__asm__ ("fixbra %0, 0, %1, 4" : "=f"(x) : "f"(x));
+	return x;
+}
+
+#else
+
+#include "../nearbyintl.c"
+
+#endif
libc/musl/src/math/s390x/rint.c
@@ -0,0 +1,15 @@
+#include <math.h>
+
+#if defined(__HTM__) || __ARCH__ >= 9
+
+double rint(double x)
+{
+	__asm__ ("fidbr %0, 0, %1" : "=f"(x) : "f"(x));
+	return x;
+}
+
+#else
+
+#include "../rint.c"
+
+#endif
libc/musl/src/math/s390x/rintf.c
@@ -0,0 +1,15 @@
+#include <math.h>
+
+#if defined(__HTM__) || __ARCH__ >= 9
+
+float rintf(float x)
+{
+	__asm__ ("fiebr %0, 0, %1" : "=f"(x) : "f"(x));
+	return x;
+}
+
+#else
+
+#include "../rintf.c"
+
+#endif
libc/musl/src/math/s390x/rintl.c
@@ -0,0 +1,15 @@
+#include <math.h>
+
+#if defined(__HTM__) || __ARCH__ >= 9
+
+long double rintl(long double x)
+{
+	__asm__ ("fixbr %0, 0, %1" : "=f"(x) : "f"(x));
+	return x;
+}
+
+#else
+
+#include "../rintl.c"
+
+#endif
libc/musl/src/math/s390x/round.c
@@ -0,0 +1,15 @@
+#include <math.h>
+
+#if defined(__HTM__) || __ARCH__ >= 9
+
+double round(double x)
+{
+	__asm__ ("fidbra %0, 1, %1, 4" : "=f"(x) : "f"(x));
+	return x;
+}
+
+#else
+
+#include "../round.c"
+
+#endif
libc/musl/src/math/s390x/roundf.c
@@ -0,0 +1,15 @@
+#include <math.h>
+
+#if defined(__HTM__) || __ARCH__ >= 9
+
+float roundf(float x)
+{
+	__asm__ ("fiebra %0, 1, %1, 4" : "=f"(x) : "f"(x));
+	return x;
+}
+
+#else
+
+#include "../roundf.c"
+
+#endif
libc/musl/src/math/s390x/roundl.c
@@ -0,0 +1,15 @@
+#include <math.h>
+
+#if defined(__HTM__) || __ARCH__ >= 9
+
+long double roundl(long double x)
+{
+	__asm__ ("fixbra %0, 1, %1, 4" : "=f"(x) : "f"(x));
+	return x;
+}
+
+#else
+
+#include "../roundl.c"
+
+#endif
libc/musl/src/math/s390x/sqrt.c
@@ -0,0 +1,15 @@
+#include <math.h>
+
+#if defined(__HTM__) || __ARCH__ >= 9
+
+double sqrt(double x)
+{
+	__asm__ ("sqdbr %0, %1" : "=f"(x) : "f"(x));
+	return x;
+}
+
+#else
+
+#include "../sqrt.c"
+
+#endif
libc/musl/src/math/s390x/sqrtf.c
@@ -0,0 +1,15 @@
+#include <math.h>
+
+#if defined(__HTM__) || __ARCH__ >= 9
+
+float sqrtf(float x)
+{
+	__asm__ ("sqebr %0, %1" : "=f"(x) : "f"(x));
+	return x;
+}
+
+#else
+
+#include "../sqrtf.c"
+
+#endif
libc/musl/src/math/s390x/sqrtl.c
@@ -0,0 +1,15 @@
+#include <math.h>
+
+#if defined(__HTM__) || __ARCH__ >= 9
+
+long double sqrtl(long double x)
+{
+	__asm__ ("sqxbr %0, %1" : "=f"(x) : "f"(x));
+	return x;
+}
+
+#else
+
+#include "../sqrtl.c"
+
+#endif
libc/musl/src/math/s390x/trunc.c
@@ -0,0 +1,15 @@
+#include <math.h>
+
+#if defined(__HTM__) || __ARCH__ >= 9
+
+double trunc(double x)
+{
+	__asm__ ("fidbra %0, 5, %1, 4" : "=f"(x) : "f"(x));
+	return x;
+}
+
+#else
+
+#include "../trunc.c"
+
+#endif
libc/musl/src/math/s390x/truncf.c
@@ -0,0 +1,15 @@
+#include <math.h>
+
+#if defined(__HTM__) || __ARCH__ >= 9
+
+float truncf(float x)
+{
+	__asm__ ("fiebra %0, 5, %1, 4" : "=f"(x) : "f"(x));
+	return x;
+}
+
+#else
+
+#include "../truncf.c"
+
+#endif
libc/musl/src/math/s390x/truncl.c
@@ -0,0 +1,15 @@
+#include <math.h>
+
+#if defined(__HTM__) || __ARCH__ >= 9
+
+long double truncl(long double x)
+{
+	__asm__ ("fixbra %0, 5, %1, 4" : "=f"(x) : "f"(x));
+	return x;
+}
+
+#else
+
+#include "../truncl.c"
+
+#endif
libc/musl/src/math/x32/__invtrigl.s
libc/musl/src/math/x32/acosl.s
@@ -0,0 +1,16 @@
+# see ../i386/acos.s
+
+.global acosl
+.type acosl,@function
+acosl:
+	fldt 8(%esp)
+1:	fld %st(0)
+	fld1
+	fsub %st(0),%st(1)
+	fadd %st(2)
+	fmulp
+	fsqrt
+	fabs
+	fxch %st(1)
+	fpatan
+	ret
libc/musl/src/math/x32/asinl.s
@@ -0,0 +1,12 @@
+.global asinl
+.type asinl,@function
+asinl:
+	fldt 8(%esp)
+1:	fld %st(0)
+	fld1
+	fsub %st(0),%st(1)
+	fadd %st(2)
+	fmulp
+	fsqrt
+	fpatan
+	ret
libc/musl/src/math/x32/atan2l.s
@@ -0,0 +1,7 @@
+.global atan2l
+.type atan2l,@function
+atan2l:
+	fldt 8(%esp)
+	fldt 24(%esp)
+	fpatan
+	ret
libc/musl/src/math/x32/atanl.s
@@ -0,0 +1,7 @@
+.global atanl
+.type atanl,@function
+atanl:
+	fldt 8(%esp)
+	fld1
+	fpatan
+	ret
libc/musl/src/math/x32/ceill.s
@@ -0,0 +1,1 @@
+# see floorl.s
libc/musl/src/math/x32/exp2l.s
@@ -0,0 +1,83 @@
+.global expm1l
+.type expm1l,@function
+expm1l:
+	fldt 8(%esp)
+	fldl2e
+	fmulp
+	movl $0xc2820000,-4(%esp)
+	flds -4(%esp)
+	fucomip %st(1),%st
+	fld1
+	jb 1f
+		# x*log2e <= -65, return -1 without underflow
+	fstp %st(1)
+	fchs
+	ret
+1:	fld %st(1)
+	fabs
+	fucomip %st(1),%st
+	fstp %st(0)
+	ja 1f
+	f2xm1
+	ret
+1:	push %rax
+	call 1f
+	pop %rax
+	fld1
+	fsubrp
+	ret
+
+.global exp2l
+.type exp2l,@function
+exp2l:
+	fldt 8(%esp)
+1:	fld %st(0)
+	sub $16,%esp
+	fstpt (%esp)
+	mov 8(%esp),%ax
+	and $0x7fff,%ax
+	cmp $0x3fff+13,%ax
+	jb 4f             # |x| < 8192
+	cmp $0x3fff+15,%ax
+	jae 3f            # |x| >= 32768
+	fsts (%esp)
+	cmpl $0xc67ff800,(%esp)
+	jb 2f             # x > -16382
+	movl $0x5f000000,(%esp)
+	flds (%esp)       # 0x1p63
+	fld %st(1)
+	fsub %st(1)
+	faddp
+	fucomip %st(1),%st
+	je 2f             # x - 0x1p63 + 0x1p63 == x
+	movl $1,(%esp)
+	flds (%esp)       # 0x1p-149
+	fdiv %st(1)
+	fstps (%esp)      # raise underflow
+2:	fld1
+	fld %st(1)
+	frndint
+	fxch %st(2)
+	fsub %st(2)       # st(0)=x-rint(x), st(1)=1, st(2)=rint(x)
+	f2xm1
+	faddp             # 2^(x-rint(x))
+1:	fscale
+	fstp %st(1)
+	add $16,%esp
+	ret
+3:	xor %eax,%eax
+4:	cmp $0x3fff-64,%ax
+	fld1
+	jb 1b             # |x| < 0x1p-64
+	fstpt (%esp)
+	fistl 8(%esp)
+	fildl 8(%esp)
+	fsubrp %st(1)
+	addl $0x3fff,8(%esp)
+	f2xm1
+	fld1
+	faddp             # 2^(x-rint(x))
+	fldt (%esp)       # 2^rint(x)
+	fmulp
+	add $16,%esp
+	ret
libc/musl/src/math/x32/expl.s
@@ -0,0 +1,101 @@
+# exp(x) = 2^hi + 2^hi (2^lo - 1)
+# where hi+lo = log2e*x with 128bit precision
+# exact log2e*x calculation depends on nearest rounding mode
+# using the exact multiplication method of Dekker and Veltkamp
+
+.global expl
+.type expl,@function
+expl:
+	fldt 8(%esp)
+
+		# interesting case: 0x1p-32 <= |x| < 16384
+		# check if (exponent|0x8000) is in [0xbfff-32, 0xbfff+13]
+	mov 16(%esp), %ax
+	or $0x8000, %ax
+	sub $0xbfdf, %ax
+	cmp $45, %ax
+	jbe 2f
+	test %ax, %ax
+	fld1
+	js 1f
+		# if |x|>=0x1p14 or nan return 2^trunc(x)
+	fscale
+	fstp %st(1)
+	ret
+		# if |x|<0x1p-32 return 1+x
+1:	faddp
+	ret
+
+		# should be 0x1.71547652b82fe178p0L == 0x3fff b8aa3b29 5c17f0bc
+		# it will be wrong on non-nearest rounding mode
+2:	fldl2e
+	sub $48, %esp
+		# hi = log2e_hi*x
+		# 2^hi = exp2l(hi)
+	fmul %st(1),%st
+	fld %st(0)
+	fstpt (%esp)
+	fstpt 16(%esp)
+	fstpt 32(%esp)
+	call exp2l@PLT
+		# if 2^hi == inf return 2^hi
+	fld %st(0)
+	fstpt (%esp)
+	cmpw $0x7fff, 8(%esp)
+	je 1f
+	fldt 32(%esp)
+	fldt 16(%esp)
+		# fpu stack: 2^hi x hi
+		# exact mult: x*log2e
+	fld %st(1)
+		# c = 0x1p32+1
+	movq $0x41f0000000100000,%rax
+	pushq %rax
+	fldl (%esp)
+		# xh = x - c*x + c*x
+		# xl = x - xh
+	fmulp
+	fld %st(2)
+	fsub %st(1), %st
+	faddp
+	fld %st(2)
+	fsub %st(1), %st
+		# yh = log2e_hi - c*log2e_hi + c*log2e_hi
+	movq $0x3ff7154765200000,%rax
+	pushq %rax
+	fldl (%esp)
+		# fpu stack: 2^hi x hi xh xl yh
+		# lo = hi - xh*yh + xl*yh
+	fld %st(2)
+	fmul %st(1), %st
+	fsubp %st, %st(4)
+	fmul %st(1), %st
+	faddp %st, %st(3)
+		# yl = log2e_hi - yh
+	movq $0x3de705fc2f000000,%rax
+	pushq %rax
+	fldl (%esp)
+		# fpu stack: 2^hi x lo xh xl yl
+		# lo += xh*yl + xl*yl
+	fmul %st, %st(2)
+	fmulp %st, %st(1)
+	fxch %st(2)
+	faddp
+	faddp
+		# log2e_lo
+	movq $0xbfbe,%rax
+	pushq %rax
+	movq $0x82f0025f2dc582ee,%rax
+	pushq %rax
+	fldt (%esp)
+	add $40,%esp
+		# fpu stack: 2^hi x lo log2e_lo
+		# lo += log2e_lo*x
+		# return 2^hi + 2^hi (2^lo - 1)
+	fmulp %st, %st(2)
+	faddp
+	f2xm1
+	fmul %st(1), %st
+	faddp
+1:	add $48, %esp
+	ret
libc/musl/src/math/x32/expm1l.s
@@ -0,0 +1,1 @@
+# see exp2l.s
libc/musl/src/math/x32/fabs.s
@@ -0,0 +1,9 @@
+.global fabs
+.type fabs,@function
+fabs:
+	xor %eax,%eax
+	dec %rax
+	shr %rax
+	movq %rax,%xmm1
+	andpd %xmm1,%xmm0
+	ret
libc/musl/src/math/x32/fabsf.s
@@ -0,0 +1,7 @@
+.global fabsf
+.type fabsf,@function
+fabsf:
+	mov $0x7fffffff,%eax
+	movq %rax,%xmm1
+	andps %xmm1,%xmm0
+	ret
libc/musl/src/math/x32/fabsl.s
@@ -0,0 +1,6 @@
+.global fabsl
+.type fabsl,@function
+fabsl:
+	fldt 8(%esp)
+	fabs
+	ret
libc/musl/src/math/x32/floorl.s
@@ -0,0 +1,27 @@
+.global floorl
+.type floorl,@function
+floorl:
+	fldt 8(%esp)
+1:	mov $0x7,%al
+1:	fstcw 8(%esp)
+	mov 9(%esp),%ah
+	mov %al,9(%esp)
+	fldcw 8(%esp)
+	frndint
+	mov %ah,9(%esp)
+	fldcw 8(%esp)
+	ret
+
+.global ceill
+.type ceill,@function
+ceill:
+	fldt 8(%esp)
+	mov $0xb,%al
+	jmp 1b
+
+.global truncl
+.type truncl,@function
+truncl:
+	fldt 8(%esp)
+	mov $0xf,%al
+	jmp 1b
libc/musl/src/math/x32/fma.c
@@ -0,0 +1,23 @@
+#include <math.h>
+
+#if __FMA__
+
+double fma(double x, double y, double z)
+{
+	__asm__ ("vfmadd132sd %1, %2, %0" : "+x" (x) : "x" (y), "x" (z));
+	return x;
+}
+
+#elif __FMA4__
+
+double fma(double x, double y, double z)
+{
+	__asm__ ("vfmaddsd %3, %2, %1, %0" : "=x" (x) : "x" (x), "x" (y), "x" (z));
+	return x;
+}
+
+#else
+
+#include "../fma.c"
+
+#endif
libc/musl/src/math/x32/fmaf.c
@@ -0,0 +1,23 @@
+#include <math.h>
+
+#if __FMA__
+
+float fmaf(float x, float y, float z)
+{
+	__asm__ ("vfmadd132ss %1, %2, %0" : "+x" (x) : "x" (y), "x" (z));
+	return x;
+}
+
+#elif __FMA4__
+
+float fmaf(float x, float y, float z)
+{
+	__asm__ ("vfmaddss %3, %2, %1, %0" : "=x" (x) : "x" (x), "x" (y), "x" (z));
+	return x;
+}
+
+#else
+
+#include "../fmaf.c"
+
+#endif
libc/musl/src/math/x32/fmodl.s
@@ -0,0 +1,11 @@
+.global fmodl
+.type fmodl,@function
+fmodl:
+	fldt 24(%esp)
+	fldt 8(%esp)
+1:	fprem
+	fnstsw %ax
+	testb $4,%ah
+	jnz 1b
+	fstp %st(1)
+	ret
libc/musl/src/math/x32/llrint.s
@@ -0,0 +1,5 @@
+.global llrint
+.type llrint,@function
+llrint:
+	cvtsd2si %xmm0,%rax
+	ret
libc/musl/src/math/x32/llrintf.s
@@ -0,0 +1,5 @@
+.global llrintf
+.type llrintf,@function
+llrintf:
+	cvtss2si %xmm0,%rax
+	ret
libc/musl/src/math/x32/llrintl.s
@@ -0,0 +1,7 @@
+.global llrintl
+.type llrintl,@function
+llrintl:
+	fldt 8(%esp)
+	fistpll 8(%esp)
+	mov 8(%esp),%rax
+	ret
libc/musl/src/math/x32/log10l.s
@@ -0,0 +1,7 @@
+.global log10l
+.type log10l,@function
+log10l:
+	fldlg2
+	fldt 8(%esp)
+	fyl2x
+	ret
libc/musl/src/math/x32/log1pl.s
@@ -0,0 +1,15 @@
+.global log1pl
+.type log1pl,@function
+log1pl:
+	mov 14(%esp),%eax
+	fldln2
+	and $0x7fffffff,%eax
+	fldt 8(%esp)
+	cmp $0x3ffd9400,%eax
+	ja 1f
+	fyl2xp1
+	ret
+1:	fld1
+	faddp
+	fyl2x
+	ret
libc/musl/src/math/x32/log2l.s
@@ -0,0 +1,7 @@
+.global log2l
+.type log2l,@function
+log2l:
+	fld1
+	fldt 8(%esp)
+	fyl2x
+	ret
libc/musl/src/math/x32/logl.s
@@ -0,0 +1,7 @@
+.global logl
+.type logl,@function
+logl:
+	fldln2
+	fldt 8(%esp)
+	fyl2x
+	ret
libc/musl/src/math/x32/lrint.s
@@ -0,0 +1,5 @@
+.global lrint
+.type lrint,@function
+lrint:
+	cvtsd2si %xmm0,%rax
+	ret
libc/musl/src/math/x32/lrintf.s
@@ -0,0 +1,5 @@
+.global lrintf
+.type lrintf,@function
+lrintf:
+	cvtss2si %xmm0,%rax
+	ret
libc/musl/src/math/x32/lrintl.s
@@ -0,0 +1,7 @@
+.global lrintl
+.type lrintl,@function
+lrintl:
+	fldt 8(%esp)
+	fistpll 8(%esp)
+	mov 8(%esp),%rax
+	ret
libc/musl/src/math/x32/remainderl.s
@@ -0,0 +1,11 @@
+.global remainderl
+.type remainderl,@function
+remainderl:
+	fldt 24(%esp)
+	fldt 8(%esp)
+1:	fprem1
+	fnstsw %ax
+	testb $4,%ah
+	jnz 1b
+	fstp %st(1)
+	ret
libc/musl/src/math/x32/rintl.s
@@ -0,0 +1,6 @@
+.global rintl
+.type rintl,@function
+rintl:
+	fldt 8(%esp)
+	frndint
+	ret
libc/musl/src/math/x32/sqrt.s
@@ -0,0 +1,4 @@
+.global sqrt
+.type sqrt,@function
+sqrt:	sqrtsd %xmm0, %xmm0
+	ret
libc/musl/src/math/x32/sqrtf.s
@@ -0,0 +1,4 @@
+.global sqrtf
+.type sqrtf,@function
+sqrtf:  sqrtss %xmm0, %xmm0
+	ret
libc/musl/src/math/x32/sqrtl.s
@@ -0,0 +1,5 @@
+.global sqrtl
+.type sqrtl,@function
+sqrtl:	fldt 8(%esp)
+	fsqrt
+	ret
libc/musl/src/math/x32/truncl.s
@@ -0,0 +1,1 @@
+# see floorl.s
libc/musl/src/math/x86_64/__invtrigl.s
libc/musl/src/math/x86_64/acosl.s
@@ -0,0 +1,16 @@
+# see ../i386/acos.s
+
+.global acosl
+.type acosl,@function
+acosl:
+	fldt 8(%rsp)
+1:	fld %st(0)
+	fld1
+	fsub %st(0),%st(1)
+	fadd %st(2)
+	fmulp
+	fsqrt
+	fabs
+	fxch %st(1)
+	fpatan
+	ret
libc/musl/src/math/x86_64/asinl.s
@@ -0,0 +1,12 @@
+.global asinl
+.type asinl,@function
+asinl:
+	fldt 8(%rsp)
+1:	fld %st(0)
+	fld1
+	fsub %st(0),%st(1)
+	fadd %st(2)
+	fmulp
+	fsqrt
+	fpatan
+	ret
libc/musl/src/math/x86_64/atan2l.s
@@ -0,0 +1,7 @@
+.global atan2l
+.type atan2l,@function
+atan2l:
+	fldt 8(%rsp)
+	fldt 24(%rsp)
+	fpatan
+	ret
libc/musl/src/math/x86_64/atanl.s
@@ -0,0 +1,7 @@
+.global atanl
+.type atanl,@function
+atanl:
+	fldt 8(%rsp)
+	fld1
+	fpatan
+	ret
libc/musl/src/math/x86_64/ceill.s
@@ -0,0 +1,1 @@
+# see floorl.s
libc/musl/src/math/x86_64/exp2l.s
@@ -0,0 +1,83 @@
+.global expm1l
+.type expm1l,@function
+expm1l:
+	fldt 8(%rsp)
+	fldl2e
+	fmulp
+	movl $0xc2820000,-4(%rsp)
+	flds -4(%rsp)
+	fucomip %st(1),%st
+	fld1
+	jb 1f
+		# x*log2e <= -65, return -1 without underflow
+	fstp %st(1)
+	fchs
+	ret
+1:	fld %st(1)
+	fabs
+	fucomip %st(1),%st
+	fstp %st(0)
+	ja 1f
+	f2xm1
+	ret
+1:	push %rax
+	call 1f
+	pop %rax
+	fld1
+	fsubrp
+	ret
+
+.global exp2l
+.type exp2l,@function
+exp2l:
+	fldt 8(%rsp)
+1:	fld %st(0)
+	sub $16,%rsp
+	fstpt (%rsp)
+	mov 8(%rsp),%ax
+	and $0x7fff,%ax
+	cmp $0x3fff+13,%ax
+	jb 4f             # |x| < 8192
+	cmp $0x3fff+15,%ax
+	jae 3f            # |x| >= 32768
+	fsts (%rsp)
+	cmpl $0xc67ff800,(%rsp)
+	jb 2f             # x > -16382
+	movl $0x5f000000,(%rsp)
+	flds (%rsp)       # 0x1p63
+	fld %st(1)
+	fsub %st(1)
+	faddp
+	fucomip %st(1),%st
+	je 2f             # x - 0x1p63 + 0x1p63 == x
+	movl $1,(%rsp)
+	flds (%rsp)       # 0x1p-149
+	fdiv %st(1)
+	fstps (%rsp)      # raise underflow
+2:	fld1
+	fld %st(1)
+	frndint
+	fxch %st(2)
+	fsub %st(2)       # st(0)=x-rint(x), st(1)=1, st(2)=rint(x)
+	f2xm1
+	faddp             # 2^(x-rint(x))
+1:	fscale
+	fstp %st(1)
+	add $16,%rsp
+	ret
+3:	xor %eax,%eax
+4:	cmp $0x3fff-64,%ax
+	fld1
+	jb 1b             # |x| < 0x1p-64
+	fstpt (%rsp)
+	fistl 8(%rsp)
+	fildl 8(%rsp)
+	fsubrp %st(1)
+	addl $0x3fff,8(%rsp)
+	f2xm1
+	fld1
+	faddp             # 2^(x-rint(x))
+	fldt (%rsp)       # 2^rint(x)
+	fmulp
+	add $16,%rsp
+	ret
libc/musl/src/math/x86_64/expl.s
@@ -0,0 +1,101 @@
+# exp(x) = 2^hi + 2^hi (2^lo - 1)
+# where hi+lo = log2e*x with 128bit precision
+# exact log2e*x calculation depends on nearest rounding mode
+# using the exact multiplication method of Dekker and Veltkamp
+
+.global expl
+.type expl,@function
+expl:
+	fldt 8(%rsp)
+
+		# interesting case: 0x1p-32 <= |x| < 16384
+		# check if (exponent|0x8000) is in [0xbfff-32, 0xbfff+13]
+	mov 16(%rsp), %ax
+	or $0x8000, %ax
+	sub $0xbfdf, %ax
+	cmp $45, %ax
+	jbe 2f
+	test %ax, %ax
+	fld1
+	js 1f
+		# if |x|>=0x1p14 or nan return 2^trunc(x)
+	fscale
+	fstp %st(1)
+	ret
+		# if |x|<0x1p-32 return 1+x
+1:	faddp
+	ret
+
+		# should be 0x1.71547652b82fe178p0L == 0x3fff b8aa3b29 5c17f0bc
+		# it will be wrong on non-nearest rounding mode
+2:	fldl2e
+	subq $48, %rsp
+		# hi = log2e_hi*x
+		# 2^hi = exp2l(hi)
+	fmul %st(1),%st
+	fld %st(0)
+	fstpt (%rsp)
+	fstpt 16(%rsp)
+	fstpt 32(%rsp)
+	call exp2l@PLT
+		# if 2^hi == inf return 2^hi
+	fld %st(0)
+	fstpt (%rsp)
+	cmpw $0x7fff, 8(%rsp)
+	je 1f
+	fldt 32(%rsp)
+	fldt 16(%rsp)
+		# fpu stack: 2^hi x hi
+		# exact mult: x*log2e
+	fld %st(1)
+		# c = 0x1p32+1
+	movq $0x41f0000000100000,%rax
+	pushq %rax
+	fldl (%rsp)
+		# xh = x - c*x + c*x
+		# xl = x - xh
+	fmulp
+	fld %st(2)
+	fsub %st(1), %st
+	faddp
+	fld %st(2)
+	fsub %st(1), %st
+		# yh = log2e_hi - c*log2e_hi + c*log2e_hi
+	movq $0x3ff7154765200000,%rax
+	pushq %rax
+	fldl (%rsp)
+		# fpu stack: 2^hi x hi xh xl yh
+		# lo = hi - xh*yh + xl*yh
+	fld %st(2)
+	fmul %st(1), %st
+	fsubp %st, %st(4)
+	fmul %st(1), %st
+	faddp %st, %st(3)
+		# yl = log2e_hi - yh
+	movq $0x3de705fc2f000000,%rax
+	pushq %rax
+	fldl (%rsp)
+		# fpu stack: 2^hi x lo xh xl yl
+		# lo += xh*yl + xl*yl
+	fmul %st, %st(2)
+	fmulp %st, %st(1)
+	fxch %st(2)
+	faddp
+	faddp
+		# log2e_lo
+	movq $0xbfbe,%rax
+	pushq %rax
+	movq $0x82f0025f2dc582ee,%rax
+	pushq %rax
+	fldt (%rsp)
+	addq $40,%rsp
+		# fpu stack: 2^hi x lo log2e_lo
+		# lo += log2e_lo*x
+		# return 2^hi + 2^hi (2^lo - 1)
+	fmulp %st, %st(2)
+	faddp
+	f2xm1
+	fmul %st(1), %st
+	faddp
+1:	addq $48, %rsp
+	ret
libc/musl/src/math/x86_64/expm1l.s
@@ -0,0 +1,1 @@
+# see exp2l.s
libc/musl/src/math/x86_64/fabs.s
@@ -0,0 +1,9 @@
+.global fabs
+.type fabs,@function
+fabs:
+	xor %eax,%eax
+	dec %rax
+	shr %rax
+	movq %rax,%xmm1
+	andpd %xmm1,%xmm0
+	ret
libc/musl/src/math/x86_64/fabsf.s
@@ -0,0 +1,7 @@
+.global fabsf
+.type fabsf,@function
+fabsf:
+	mov $0x7fffffff,%eax
+	movq %rax,%xmm1
+	andps %xmm1,%xmm0
+	ret
libc/musl/src/math/x86_64/fabsl.s
@@ -0,0 +1,6 @@
+.global fabsl
+.type fabsl,@function
+fabsl:
+	fldt 8(%rsp)
+	fabs
+	ret
libc/musl/src/math/x86_64/floorl.s
@@ -0,0 +1,27 @@
+.global floorl
+.type floorl,@function
+floorl:
+	fldt 8(%rsp)
+1:	mov $0x7,%al
+1:	fstcw 8(%rsp)
+	mov 9(%rsp),%ah
+	mov %al,9(%rsp)
+	fldcw 8(%rsp)
+	frndint
+	mov %ah,9(%rsp)
+	fldcw 8(%rsp)
+	ret
+
+.global ceill
+.type ceill,@function
+ceill:
+	fldt 8(%rsp)
+	mov $0xb,%al
+	jmp 1b
+
+.global truncl
+.type truncl,@function
+truncl:
+	fldt 8(%rsp)
+	mov $0xf,%al
+	jmp 1b
libc/musl/src/math/x86_64/fma.c
@@ -0,0 +1,23 @@
+#include <math.h>
+
+#if __FMA__
+
+double fma(double x, double y, double z)
+{
+	__asm__ ("vfmadd132sd %1, %2, %0" : "+x" (x) : "x" (y), "x" (z));
+	return x;
+}
+
+#elif __FMA4__
+
+double fma(double x, double y, double z)
+{
+	__asm__ ("vfmaddsd %3, %2, %1, %0" : "=x" (x) : "x" (x), "x" (y), "x" (z));
+	return x;
+}
+
+#else
+
+#include "../fma.c"
+
+#endif
libc/musl/src/math/x86_64/fmaf.c
@@ -0,0 +1,23 @@
+#include <math.h>
+
+#if __FMA__
+
+float fmaf(float x, float y, float z)
+{
+	__asm__ ("vfmadd132ss %1, %2, %0" : "+x" (x) : "x" (y), "x" (z));
+	return x;
+}
+
+#elif __FMA4__
+
+float fmaf(float x, float y, float z)
+{
+	__asm__ ("vfmaddss %3, %2, %1, %0" : "=x" (x) : "x" (x), "x" (y), "x" (z));
+	return x;
+}
+
+#else
+
+#include "../fmaf.c"
+
+#endif
libc/musl/src/math/x86_64/fmodl.s
@@ -0,0 +1,11 @@
+.global fmodl
+.type fmodl,@function
+fmodl:
+	fldt 24(%rsp)
+	fldt 8(%rsp)
+1:	fprem
+	fnstsw %ax
+	testb $4,%ah
+	jnz 1b
+	fstp %st(1)
+	ret
libc/musl/src/math/x86_64/llrint.s
@@ -0,0 +1,5 @@
+.global llrint
+.type llrint,@function
+llrint:
+	cvtsd2si %xmm0,%rax
+	ret
libc/musl/src/math/x86_64/llrintf.s
@@ -0,0 +1,5 @@
+.global llrintf
+.type llrintf,@function
+llrintf:
+	cvtss2si %xmm0,%rax
+	ret
libc/musl/src/math/x86_64/llrintl.s
@@ -0,0 +1,7 @@
+.global llrintl
+.type llrintl,@function
+llrintl:
+	fldt 8(%rsp)
+	fistpll 8(%rsp)
+	mov 8(%rsp),%rax
+	ret
libc/musl/src/math/x86_64/log10l.s
@@ -0,0 +1,7 @@
+.global log10l
+.type log10l,@function
+log10l:
+	fldlg2
+	fldt 8(%rsp)
+	fyl2x
+	ret
libc/musl/src/math/x86_64/log1pl.s
@@ -0,0 +1,15 @@
+.global log1pl
+.type log1pl,@function
+log1pl:
+	mov 14(%rsp),%eax
+	fldln2
+	and $0x7fffffff,%eax
+	fldt 8(%rsp)
+	cmp $0x3ffd9400,%eax
+	ja 1f
+	fyl2xp1
+	ret
+1:	fld1
+	faddp
+	fyl2x
+	ret
libc/musl/src/math/x86_64/log2l.s
@@ -0,0 +1,7 @@
+.global log2l
+.type log2l,@function
+log2l:
+	fld1
+	fldt 8(%rsp)
+	fyl2x
+	ret
libc/musl/src/math/x86_64/logl.s
@@ -0,0 +1,7 @@
+.global logl
+.type logl,@function
+logl:
+	fldln2
+	fldt 8(%rsp)
+	fyl2x
+	ret
libc/musl/src/math/x86_64/lrint.s
@@ -0,0 +1,5 @@
+.global lrint
+.type lrint,@function
+lrint:
+	cvtsd2si %xmm0,%rax
+	ret
libc/musl/src/math/x86_64/lrintf.s
@@ -0,0 +1,5 @@
+.global lrintf
+.type lrintf,@function
+lrintf:
+	cvtss2si %xmm0,%rax
+	ret
libc/musl/src/math/x86_64/lrintl.s
@@ -0,0 +1,7 @@
+.global lrintl
+.type lrintl,@function
+lrintl:
+	fldt 8(%rsp)
+	fistpll 8(%rsp)
+	mov 8(%rsp),%rax
+	ret
libc/musl/src/math/x86_64/remainderl.s
@@ -0,0 +1,11 @@
+.global remainderl
+.type remainderl,@function
+remainderl:
+	fldt 24(%rsp)
+	fldt 8(%rsp)
+1:	fprem1
+	fnstsw %ax
+	testb $4,%ah
+	jnz 1b
+	fstp %st(1)
+	ret
libc/musl/src/math/x86_64/rintl.s
@@ -0,0 +1,6 @@
+.global rintl
+.type rintl,@function
+rintl:
+	fldt 8(%rsp)
+	frndint
+	ret
libc/musl/src/math/x86_64/sqrt.s
@@ -0,0 +1,4 @@
+.global sqrt
+.type sqrt,@function
+sqrt:	sqrtsd %xmm0, %xmm0
+	ret
libc/musl/src/math/x86_64/sqrtf.s
@@ -0,0 +1,4 @@
+.global sqrtf
+.type sqrtf,@function
+sqrtf:  sqrtss %xmm0, %xmm0
+	ret
libc/musl/src/math/x86_64/sqrtl.s
@@ -0,0 +1,5 @@
+.global sqrtl
+.type sqrtl,@function
+sqrtl:	fldt 8(%rsp)
+	fsqrt
+	ret
libc/musl/src/math/x86_64/truncl.s
@@ -0,0 +1,1 @@
+# see floorl.s
libc/musl/src/math/__cos.c
@@ -0,0 +1,71 @@
+/* origin: FreeBSD /usr/src/lib/msun/src/k_cos.c */
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunSoft, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+/*
+ * __cos( x,  y )
+ * kernel cos function on [-pi/4, pi/4], pi/4 ~ 0.785398164
+ * Input x is assumed to be bounded by ~pi/4 in magnitude.
+ * Input y is the tail of x.
+ *
+ * Algorithm
+ *      1. Since cos(-x) = cos(x), we need only to consider positive x.
+ *      2. if x < 2^-27 (hx<0x3e400000 0), return 1 with inexact if x!=0.
+ *      3. cos(x) is approximated by a polynomial of degree 14 on
+ *         [0,pi/4]
+ *                                       4            14
+ *              cos(x) ~ 1 - x*x/2 + C1*x + ... + C6*x
+ *         where the remez error is
+ *
+ *      |              2     4     6     8     10    12     14 |     -58
+ *      |cos(x)-(1-.5*x +C1*x +C2*x +C3*x +C4*x +C5*x  +C6*x  )| <= 2
+ *      |                                                      |
+ *
+ *                     4     6     8     10    12     14
+ *      4. let r = C1*x +C2*x +C3*x +C4*x +C5*x  +C6*x  , then
+ *             cos(x) ~ 1 - x*x/2 + r
+ *         since cos(x+y) ~ cos(x) - sin(x)*y
+ *                        ~ cos(x) - x*y,
+ *         a correction term is necessary in cos(x) and hence
+ *              cos(x+y) = 1 - (x*x/2 - (r - x*y))
+ *         For better accuracy, rearrange to
+ *              cos(x+y) ~ w + (tmp + (r-x*y))
+ *         where w = 1 - x*x/2 and tmp is a tiny correction term
+ *         (1 - x*x/2 == w + tmp exactly in infinite precision).
+ *         The exactness of w + tmp in infinite precision depends on w
+ *         and tmp having the same precision as x.  If they have extra
+ *         precision due to compiler bugs, then the extra precision is
+ *         only good provided it is retained in all terms of the final
+ *         expression for cos().  Retention happens in all cases tested
+ *         under FreeBSD, so don't pessimize things by forcibly clipping
+ *         any extra precision in w.
+ */
+
+#include "libm.h"
+
+static const double
+C1  =  4.16666666666666019037e-02, /* 0x3FA55555, 0x5555554C */
+C2  = -1.38888888888741095749e-03, /* 0xBF56C16C, 0x16C15177 */
+C3  =  2.48015872894767294178e-05, /* 0x3EFA01A0, 0x19CB1590 */
+C4  = -2.75573143513906633035e-07, /* 0xBE927E4F, 0x809C52AD */
+C5  =  2.08757232129817482790e-09, /* 0x3E21EE9E, 0xBDB4B1C4 */
+C6  = -1.13596475577881948265e-11; /* 0xBDA8FAE9, 0xBE8838D4 */
+
+double __cos(double x, double y)
+{
+	double_t hz,z,r,w;
+
+	z  = x*x;
+	w  = z*z;
+	r  = z*(C1+z*(C2+z*C3)) + w*w*(C4+z*(C5+z*C6));
+	hz = 0.5*z;
+	w  = 1.0-hz;
+	return w + (((1.0-w)-hz) + (z*r-x*y));
+}
libc/musl/src/math/__cosdf.c
@@ -0,0 +1,35 @@
+/* origin: FreeBSD /usr/src/lib/msun/src/k_cosf.c */
+/*
+ * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.
+ * Debugged and optimized by Bruce D. Evans.
+ */
+/*
+ * ====================================================
+ * 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 "libm.h"
+
+/* |cos(x) - c(x)| < 2**-34.1 (~[-5.37e-11, 5.295e-11]). */
+static const double
+C0  = -0x1ffffffd0c5e81.0p-54, /* -0.499999997251031003120 */
+C1  =  0x155553e1053a42.0p-57, /*  0.0416666233237390631894 */
+C2  = -0x16c087e80f1e27.0p-62, /* -0.00138867637746099294692 */
+C3  =  0x199342e0ee5069.0p-68; /*  0.0000243904487962774090654 */
+
+float __cosdf(double x)
+{
+	double_t r, w, z;
+
+	/* Try to optimize for parallel evaluation as in __tandf.c. */
+	z = x*x;
+	w = z*z;
+	r = C2+z*C3;
+	return ((1.0+z*C0) + w*C1) + (w*z)*r;
+}
libc/musl/src/math/__cosl.c
@@ -0,0 +1,96 @@
+/* origin: FreeBSD /usr/src/lib/msun/ld80/k_cosl.c */
+/* origin: FreeBSD /usr/src/lib/msun/ld128/k_cosl.c */
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ * Copyright (c) 2008 Steven G. Kargl, David Schultz, Bruce D. Evans.
+ *
+ * Developed at SunSoft, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+
+
+#include "libm.h"
+
+#if (LDBL_MANT_DIG == 64 || LDBL_MANT_DIG == 113) && LDBL_MAX_EXP == 16384
+#if LDBL_MANT_DIG == 64
+/*
+ * ld80 version of __cos.c.  See __cos.c for most comments.
+ */
+/*
+ * Domain [-0.7854, 0.7854], range ~[-2.43e-23, 2.425e-23]:
+ * |cos(x) - c(x)| < 2**-75.1
+ *
+ * The coefficients of c(x) were generated by a pari-gp script using
+ * a Remez algorithm that searches for the best higher coefficients
+ * after rounding leading coefficients to a specified precision.
+ *
+ * Simpler methods like Chebyshev or basic Remez barely suffice for
+ * cos() in 64-bit precision, because we want the coefficient of x^2
+ * to be precisely -0.5 so that multiplying by it is exact, and plain
+ * rounding of the coefficients of a good polynomial approximation only
+ * gives this up to about 64-bit precision.  Plain rounding also gives
+ * a mediocre approximation for the coefficient of x^4, but a rounding
+ * error of 0.5 ulps for this coefficient would only contribute ~0.01
+ * ulps to the final error, so this is unimportant.  Rounding errors in
+ * higher coefficients are even less important.
+ *
+ * In fact, coefficients above the x^4 one only need to have 53-bit
+ * precision, and this is more efficient.  We get this optimization
+ * almost for free from the complications needed to search for the best
+ * higher coefficients.
+ */
+static const long double
+C1 =  0.0416666666666666666136L;        /*  0xaaaaaaaaaaaaaa9b.0p-68 */
+static const double
+C2 = -0.0013888888888888874,            /* -0x16c16c16c16c10.0p-62 */
+C3 =  0.000024801587301571716,          /*  0x1a01a01a018e22.0p-68 */
+C4 = -0.00000027557319215507120,        /* -0x127e4fb7602f22.0p-74 */
+C5 =  0.0000000020876754400407278,      /*  0x11eed8caaeccf1.0p-81 */
+C6 = -1.1470297442401303e-11,           /* -0x19393412bd1529.0p-89 */
+C7 =  4.7383039476436467e-14;           /*  0x1aac9d9af5c43e.0p-97 */
+#define POLY(z) (z*(C1+z*(C2+z*(C3+z*(C4+z*(C5+z*(C6+z*C7)))))))
+#elif LDBL_MANT_DIG == 113
+/*
+ * ld128 version of __cos.c.  See __cos.c for most comments.
+ */
+/*
+ * Domain [-0.7854, 0.7854], range ~[-1.80e-37, 1.79e-37]:
+ * |cos(x) - c(x))| < 2**-122.0
+ *
+ * 113-bit precision requires more care than 64-bit precision, since
+ * simple methods give a minimax polynomial with coefficient for x^2
+ * that is 1 ulp below 0.5, but we want it to be precisely 0.5.  See
+ * above for more details.
+ */
+static const long double
+C1 =  0.04166666666666666666666666666666658424671L,
+C2 = -0.001388888888888888888888888888863490893732L,
+C3 =  0.00002480158730158730158730158600795304914210L,
+C4 = -0.2755731922398589065255474947078934284324e-6L,
+C5 =  0.2087675698786809897659225313136400793948e-8L,
+C6 = -0.1147074559772972315817149986812031204775e-10L,
+C7 =  0.4779477332386808976875457937252120293400e-13L;
+static const double
+C8 = -0.1561920696721507929516718307820958119868e-15,
+C9 =  0.4110317413744594971475941557607804508039e-18,
+C10 = -0.8896592467191938803288521958313920156409e-21,
+C11 =  0.1601061435794535138244346256065192782581e-23;
+#define POLY(z) (z*(C1+z*(C2+z*(C3+z*(C4+z*(C5+z*(C6+z*(C7+ \
+	z*(C8+z*(C9+z*(C10+z*C11)))))))))))
+#endif
+
+long double __cosl(long double x, long double y)
+{
+	long double hz,z,r,w;
+
+	z  = x*x;
+	r  = POLY(z);
+	hz = 0.5*z;
+	w  = 1.0-hz;
+	return w + (((1.0-w)-hz) + (z*r-x*y));
+}
+#endif
libc/musl/src/math/__expo2.c
@@ -0,0 +1,16 @@
+#include "libm.h"
+
+/* k is such that k*ln2 has minimal relative error and x - kln2 > log(DBL_MIN) */
+static const int k = 2043;
+static const double kln2 = 0x1.62066151add8bp+10;
+
+/* exp(x)/2 for x >= log(DBL_MAX), slightly better than 0.5*exp(x/2)*exp(x/2) */
+double __expo2(double x)
+{
+	double scale;
+
+	/* note that k is odd and scale*scale overflows */
+	INSERT_WORDS(scale, (uint32_t)(0x3ff + k/2) << 20, 0);
+	/* exp(x - k ln2) * 2**(k-1) */
+	return exp(x - kln2) * scale * scale;
+}
libc/musl/src/math/__expo2f.c
@@ -0,0 +1,16 @@
+#include "libm.h"
+
+/* k is such that k*ln2 has minimal relative error and x - kln2 > log(FLT_MIN) */
+static const int k = 235;
+static const float kln2 = 0x1.45c778p+7f;
+
+/* expf(x)/2 for x >= log(FLT_MAX), slightly better than 0.5f*expf(x/2)*expf(x/2) */
+float __expo2f(float x)
+{
+	float scale;
+
+	/* note that k is odd and scale*scale overflows */
+	SET_FLOAT_WORD(scale, (uint32_t)(0x7f + k/2) << 23);
+	/* exp(x - k ln2) * 2**(k-1) */
+	return expf(x - kln2) * scale * scale;
+}
libc/musl/src/math/__fpclassify.c
@@ -0,0 +1,11 @@
+#include <math.h>
+#include <stdint.h>
+
+int __fpclassify(double x)
+{
+	union {double f; uint64_t i;} u = {x};
+	int e = u.i>>52 & 0x7ff;
+	if (!e) return u.i<<1 ? FP_SUBNORMAL : FP_ZERO;
+	if (e==0x7ff) return u.i<<12 ? FP_NAN : FP_INFINITE;
+	return FP_NORMAL;
+}
libc/musl/src/math/__fpclassifyf.c
@@ -0,0 +1,11 @@
+#include <math.h>
+#include <stdint.h>
+
+int __fpclassifyf(float x)
+{
+	union {float f; uint32_t i;} u = {x};
+	int e = u.i>>23 & 0xff;
+	if (!e) return u.i<<1 ? FP_SUBNORMAL : FP_ZERO;
+	if (e==0xff) return u.i<<9 ? FP_NAN : FP_INFINITE;
+	return FP_NORMAL;
+}
libc/musl/src/math/__fpclassifyl.c
@@ -0,0 +1,42 @@
+#include "libm.h"
+
+#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024
+int __fpclassifyl(long double x)
+{
+	return __fpclassify(x);
+}
+#elif LDBL_MANT_DIG == 64 && LDBL_MAX_EXP == 16384
+int __fpclassifyl(long double x)
+{
+	union ldshape u = {x};
+	int e = u.i.se & 0x7fff;
+	int msb = u.i.m>>63;
+	if (!e && !msb)
+		return u.i.m ? FP_SUBNORMAL : FP_ZERO;
+	if (e == 0x7fff) {
+		/* The x86 variant of 80-bit extended precision only admits
+		 * one representation of each infinity, with the mantissa msb
+		 * necessarily set. The version with it clear is invalid/nan.
+		 * The m68k variant, however, allows either, and tooling uses
+		 * the version with it clear. */
+		if (__BYTE_ORDER == __LITTLE_ENDIAN && !msb)
+			return FP_NAN;
+		return u.i.m << 1 ? FP_NAN : FP_INFINITE;
+	}
+	if (!msb)
+		return FP_NAN;
+	return FP_NORMAL;
+}
+#elif LDBL_MANT_DIG == 113 && LDBL_MAX_EXP == 16384
+int __fpclassifyl(long double x)
+{
+	union ldshape u = {x};
+	int e = u.i.se & 0x7fff;
+	u.i.se = 0;
+	if (!e)
+		return u.i2.lo | u.i2.hi ? FP_SUBNORMAL : FP_ZERO;
+	if (e == 0x7fff)
+		return u.i2.lo | u.i2.hi ? FP_NAN : FP_INFINITE;
+	return FP_NORMAL;
+}
+#endif
libc/musl/src/math/__invtrigl.c
@@ -0,0 +1,63 @@
+#include <float.h>
+#include "__invtrigl.h"
+
+#if LDBL_MANT_DIG == 64 && LDBL_MAX_EXP == 16384
+static const long double
+pS0 =  1.66666666666666666631e-01L,
+pS1 = -4.16313987993683104320e-01L,
+pS2 =  3.69068046323246813704e-01L,
+pS3 = -1.36213932016738603108e-01L,
+pS4 =  1.78324189708471965733e-02L,
+pS5 = -2.19216428382605211588e-04L,
+pS6 = -7.10526623669075243183e-06L,
+qS1 = -2.94788392796209867269e+00L,
+qS2 =  3.27309890266528636716e+00L,
+qS3 = -1.68285799854822427013e+00L,
+qS4 =  3.90699412641738801874e-01L,
+qS5 = -3.14365703596053263322e-02L;
+
+const long double pio2_hi = 1.57079632679489661926L;
+const long double pio2_lo = -2.50827880633416601173e-20L;
+
+/* used in asinl() and acosl() */
+/* R(x^2) is a rational approximation of (asin(x)-x)/x^3 with Remez algorithm */
+long double __invtrigl_R(long double z)
+{
+	long double p, q;
+	p = z*(pS0+z*(pS1+z*(pS2+z*(pS3+z*(pS4+z*(pS5+z*pS6))))));
+	q = 1.0+z*(qS1+z*(qS2+z*(qS3+z*(qS4+z*qS5))));
+	return p/q;
+}
+#elif LDBL_MANT_DIG == 113 && LDBL_MAX_EXP == 16384
+static const long double
+pS0 =  1.66666666666666666666666666666700314e-01L,
+pS1 = -7.32816946414566252574527475428622708e-01L,
+pS2 =  1.34215708714992334609030036562143589e+00L,
+pS3 = -1.32483151677116409805070261790752040e+00L,
+pS4 =  7.61206183613632558824485341162121989e-01L,
+pS5 = -2.56165783329023486777386833928147375e-01L,
+pS6 =  4.80718586374448793411019434585413855e-02L,
+pS7 = -4.42523267167024279410230886239774718e-03L,
+pS8 =  1.44551535183911458253205638280410064e-04L,
+pS9 = -2.10558957916600254061591040482706179e-07L,
+qS1 = -4.84690167848739751544716485245697428e+00L,
+qS2 =  9.96619113536172610135016921140206980e+00L,
+qS3 = -1.13177895428973036660836798461641458e+01L,
+qS4 =  7.74004374389488266169304117714658761e+00L,
+qS5 = -3.25871986053534084709023539900339905e+00L,
+qS6 =  8.27830318881232209752469022352928864e-01L,
+qS7 = -1.18768052702942805423330715206348004e-01L,
+qS8 =  8.32600764660522313269101537926539470e-03L,
+qS9 = -1.99407384882605586705979504567947007e-04L;
+
+const long double pio2_hi = 1.57079632679489661923132169163975140L;
+const long double pio2_lo = 4.33590506506189051239852201302167613e-35L;
+
+long double __invtrigl_R(long double z)
+{
+	long double p, q;
+	p = z*(pS0+z*(pS1+z*(pS2+z*(pS3+z*(pS4+z*(pS5+z*(pS6+z*(pS7+z*(pS8+z*pS9)))))))));
+	q = 1.0+z*(qS1+z*(qS2+z*(qS3+z*(qS4+z*(qS5+z*(qS6+z*(qS7+z*(qS8+z*qS9))))))));
+	return p/q;
+}
+#endif
libc/musl/src/math/__invtrigl.h
@@ -0,0 +1,8 @@
+#include <features.h>
+
+/* shared by acosl, asinl and atan2l */
+#define pio2_hi __pio2_hi
+#define pio2_lo __pio2_lo
+hidden extern const long double pio2_hi, pio2_lo;
+
+hidden long double __invtrigl_R(long double z);
libc/musl/src/math/__polevll.c
@@ -0,0 +1,93 @@
+/* origin: OpenBSD /usr/src/lib/libm/src/polevll.c */
+/*
+ * Copyright (c) 2008 Stephen L. Moshier <steve@moshier.net>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+/*
+ *      Evaluate polynomial
+ *
+ *
+ * SYNOPSIS:
+ *
+ * int N;
+ * long double x, y, coef[N+1], polevl[];
+ *
+ * y = polevll( x, coef, N );
+ *
+ *
+ * DESCRIPTION:
+ *
+ * Evaluates polynomial of degree N:
+ *
+ *                     2          N
+ * y  =  C  + C x + C x  +...+ C x
+ *        0    1     2          N
+ *
+ * Coefficients are stored in reverse order:
+ *
+ * coef[0] = C  , ..., coef[N] = C  .
+ *            N                   0
+ *
+ *  The function p1evll() assumes that coef[N] = 1.0 and is
+ * omitted from the array.  Its calling arguments are
+ * otherwise the same as polevll().
+ *
+ *
+ * SPEED:
+ *
+ * In the interest of speed, there are no checks for out
+ * of bounds arithmetic.  This routine is used by most of
+ * the functions in the library.  Depending on available
+ * equipment features, the user may wish to rewrite the
+ * program in microcode or assembly language.
+ *
+ */
+
+#include "libm.h"
+
+#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024
+#else
+/*
+ * Polynomial evaluator:
+ *  P[0] x^n  +  P[1] x^(n-1)  +  ...  +  P[n]
+ */
+long double __polevll(long double x, const long double *P, int n)
+{
+	long double y;
+
+	y = *P++;
+	do {
+		y = y * x + *P++;
+	} while (--n);
+
+	return y;
+}
+
+/*
+ * Polynomial evaluator:
+ *  x^n  +  P[0] x^(n-1)  +  P[1] x^(n-2)  +  ...  +  P[n]
+ */
+long double __p1evll(long double x, const long double *P, int n)
+{
+	long double y;
+
+	n -= 1;
+	y = x + *P++;
+	do {
+		y = y * x + *P++;
+	} while (--n);
+
+	return y;
+}
+#endif
libc/musl/src/math/__rem_pio2.c
@@ -0,0 +1,177 @@
+/* origin: FreeBSD /usr/src/lib/msun/src/e_rem_pio2.c */
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunSoft, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ *
+ * Optimized by Bruce D. Evans.
+ */
+/* __rem_pio2(x,y)
+ *
+ * return the remainder of x rem pi/2 in y[0]+y[1]
+ * use __rem_pio2_large() for large x
+ */
+
+#include "libm.h"
+
+#if FLT_EVAL_METHOD==0 || FLT_EVAL_METHOD==1
+#define EPS DBL_EPSILON
+#elif FLT_EVAL_METHOD==2
+#define EPS LDBL_EPSILON
+#endif
+
+/*
+ * 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)
+ */
+static const double
+toint   = 1.5/EPS,
+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 */
+
+/* caller must handle the case when reduction is not needed: |x| ~<= pi/4 */
+int __rem_pio2(double x, double *y)
+{
+	union {double f; uint64_t i;} u = {x};
+	double_t z,w,t,r,fn;
+	double tx[3],ty[2];
+	uint32_t ix;
+	int sign, n, ex, ey, i;
+
+	sign = u.i>>63;
+	ix = u.i>>32 & 0x7fffffff;
+	if (ix <= 0x400f6a7a) {  /* |x| ~<= 5pi/4 */
+		if ((ix & 0xfffff) == 0x921fb)  /* |x| ~= pi/2 or 2pi/2 */
+			goto medium;  /* cancellation -- use medium case */
+		if (ix <= 0x4002d97c) {  /* |x| ~<= 3pi/4 */
+			if (!sign) {
+				z = x - pio2_1;  /* one round good to 85 bits */
+				y[0] = z - pio2_1t;
+				y[1] = (z-y[0]) - pio2_1t;
+				return 1;
+			} else {
+				z = x + pio2_1;
+				y[0] = z + pio2_1t;
+				y[1] = (z-y[0]) + pio2_1t;
+				return -1;
+			}
+		} else {
+			if (!sign) {
+				z = x - 2*pio2_1;
+				y[0] = z - 2*pio2_1t;
+				y[1] = (z-y[0]) - 2*pio2_1t;
+				return 2;
+			} else {
+				z = x + 2*pio2_1;
+				y[0] = z + 2*pio2_1t;
+				y[1] = (z-y[0]) + 2*pio2_1t;
+				return -2;
+			}
+		}
+	}
+	if (ix <= 0x401c463b) {  /* |x| ~<= 9pi/4 */
+		if (ix <= 0x4015fdbc) {  /* |x| ~<= 7pi/4 */
+			if (ix == 0x4012d97c)  /* |x| ~= 3pi/2 */
+				goto medium;
+			if (!sign) {
+				z = x - 3*pio2_1;
+				y[0] = z - 3*pio2_1t;
+				y[1] = (z-y[0]) - 3*pio2_1t;
+				return 3;
+			} else {
+				z = x + 3*pio2_1;
+				y[0] = z + 3*pio2_1t;
+				y[1] = (z-y[0]) + 3*pio2_1t;
+				return -3;
+			}
+		} else {
+			if (ix == 0x401921fb)  /* |x| ~= 4pi/2 */
+				goto medium;
+			if (!sign) {
+				z = x - 4*pio2_1;
+				y[0] = z - 4*pio2_1t;
+				y[1] = (z-y[0]) - 4*pio2_1t;
+				return 4;
+			} else {
+				z = x + 4*pio2_1;
+				y[0] = z + 4*pio2_1t;
+				y[1] = (z-y[0]) + 4*pio2_1t;
+				return -4;
+			}
+		}
+	}
+	if (ix < 0x413921fb) {  /* |x| ~< 2^20*(pi/2), medium size */
+medium:
+		/* rint(x/(pi/2)), Assume round-to-nearest. */
+		fn = (double_t)x*invpio2 + toint - toint;
+		n = (int32_t)fn;
+		r = x - fn*pio2_1;
+		w = fn*pio2_1t;  /* 1st round, good to 85 bits */
+		y[0] = r - w;
+		u.f = y[0];
+		ey = u.i>>52 & 0x7ff;
+		ex = ix>>20;
+		if (ex - ey > 16) { /* 2nd round, good to 118 bits */
+			t = r;
+			w = fn*pio2_2;
+			r = t - w;
+			w = fn*pio2_2t - ((t-r)-w);
+			y[0] = r - w;
+			u.f = y[0];
+			ey = u.i>>52 & 0x7ff;
+			if (ex - ey > 49) {  /* 3rd round, good to 151 bits, covers all cases */
+				t = r;
+				w = fn*pio2_3;
+				r = t - w;
+				w = fn*pio2_3t - ((t-r)-w);
+				y[0] = r - w;
+			}
+		}
+		y[1] = (r - y[0]) - w;
+		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) */
+	u.f = x;
+	u.i &= (uint64_t)-1>>12;
+	u.i |= (uint64_t)(0x3ff + 23)<<52;
+	z = u.f;
+	for (i=0; i < 2; i++) {
+		tx[i] = (double)(int32_t)z;
+		z     = (z-tx[i])*0x1p24;
+	}
+	tx[i] = z;
+	/* skip zero terms, first term is non-zero */
+	while (tx[i] == 0.0)
+		i--;
+	n = __rem_pio2_large(tx,ty,(int)(ix>>20)-(0x3ff+23),i+1,1);
+	if (sign) {
+		y[0] = -ty[0];
+		y[1] = -ty[1];
+		return -n;
+	}
+	y[0] = ty[0];
+	y[1] = ty[1];
+	return n;
+}
libc/musl/src/math/__rem_pio2_large.c
@@ -0,0 +1,442 @@
+/* origin: FreeBSD /usr/src/lib/msun/src/k_rem_pio2.c */
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunSoft, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+/*
+ * __rem_pio2_large(x,y,e0,nx,prec)
+ * double x[],y[]; int e0,nx,prec;
+ *
+ * __rem_pio2_large 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
+ *              precison, 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]. Must be <= 16360 or you need to
+ *              expand the ipio2 table.
+ *
+ *      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)
+ *
+ * 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 minimum and recommended value
+ *              for jk is 3,4,4,6 for single, double, extended, and quad.
+ *              jk+1 must be 2 larger than you might expect so that our
+ *              recomputation test works. (Up to 24 bits in the integer
+ *              part (the 24 bits of it that we compute) and 23 bits in
+ *              the fraction part may be lost to cancelation before we
+ *              recompute.)
+ *
+ *      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 "libm.h"
+
+static const int init_jk[] = {3,4,4,6}; /* initial value for jk */
+
+/*
+ * Table of constants for 2/pi, 396 Hex digits (476 decimal) of 2/pi
+ *
+ *              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)).
+ *
+ * NB: This table must have at least (e0-3)/24 + jk terms.
+ *     For quad precision (e0 <= 16360, jk = 6), this is 686.
+ */
+static const int32_t ipio2[] = {
+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,
+
+#if LDBL_MAX_EXP > 1024
+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,
+#endif
+};
+
+static const double PIo2[] = {
+  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 */
+};
+
+int __rem_pio2_large(double *x, double *y, int e0, int nx, int prec)
+{
+	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 ? 0.0 : (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)(0x1p-24*z);
+		iq[i] = (int32_t)(z - 0x1p24*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 = 1.0 - z;
+			if (carry != 0)
+				z -= scalbn(1.0,q0);
+		}
+	}
+
+	/* check if recomputation is needed */
+	if (z == 0.0) {
+		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 >= 0x1p24) {
+			fw = (double)(int32_t)(0x1p-24*z);
+			iq[jz] = (int32_t)(z - 0x1p24*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(1.0,q0);
+	for (i=jz; i>=0; i--) {
+		q[i] = fw*(double)iq[i];
+		fw *= 0x1p-24;
+	}
+
+	/* 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];
+		// TODO: drop excess precision here once double_t is used
+		fw = (double)fw;
+		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;
+}
libc/musl/src/math/__rem_pio2f.c
@@ -0,0 +1,75 @@
+/* origin: FreeBSD /usr/src/lib/msun/src/e_rem_pio2f.c */
+/*
+ * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.
+ * Debugged and optimized by Bruce D. Evans.
+ */
+/*
+ * ====================================================
+ * 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.
+ * ====================================================
+ */
+/* __rem_pio2f(x,y)
+ *
+ * return the remainder of x rem pi/2 in *y
+ * use double precision for everything except passing x
+ * use __rem_pio2_large() for large x
+ */
+
+#include "libm.h"
+
+#if FLT_EVAL_METHOD==0 || FLT_EVAL_METHOD==1
+#define EPS DBL_EPSILON
+#elif FLT_EVAL_METHOD==2
+#define EPS LDBL_EPSILON
+#endif
+
+/*
+ * invpio2:  53 bits of 2/pi
+ * pio2_1:   first 25 bits of pi/2
+ * pio2_1t:  pi/2 - pio2_1
+ */
+static const double
+toint   = 1.5/EPS,
+invpio2 = 6.36619772367581382433e-01, /* 0x3FE45F30, 0x6DC9C883 */
+pio2_1  = 1.57079631090164184570e+00, /* 0x3FF921FB, 0x50000000 */
+pio2_1t = 1.58932547735281966916e-08; /* 0x3E5110b4, 0x611A6263 */
+
+int __rem_pio2f(float x, double *y)
+{
+	union {float f; uint32_t i;} u = {x};
+	double tx[1],ty[1];
+	double_t fn;
+	uint32_t ix;
+	int n, sign, e0;
+
+	ix = u.i & 0x7fffffff;
+	/* 25+53 bit pi is good enough for medium size */
+	if (ix < 0x4dc90fdb) {  /* |x| ~< 2^28*(pi/2), medium size */
+		/* Use a specialized rint() to get fn.  Assume round-to-nearest. */
+		fn = (double_t)x*invpio2 + toint - toint;
+		n  = (int32_t)fn;
+		*y = x - fn*pio2_1 - fn*pio2_1t;
+		return n;
+	}
+	if(ix>=0x7f800000) {  /* x is inf or NaN */
+		*y = x-x;
+		return 0;
+	}
+	/* scale x into [2^23, 2^24-1] */
+	sign = u.i>>31;
+	e0 = (ix>>23) - (0x7f+23);  /* e0 = ilogb(|x|)-23, positive */
+	u.i = ix - (e0<<23);
+	tx[0] = u.f;
+	n  =  __rem_pio2_large(tx,ty,e0,1,0);
+	if (sign) {
+		*y = -ty[0];
+		return -n;
+	}
+	*y = ty[0];
+	return n;
+}
libc/musl/src/math/__rem_pio2l.c
@@ -0,0 +1,141 @@
+/* origin: FreeBSD /usr/src/lib/msun/ld80/e_rem_pio2.c */
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ * Copyright (c) 2008 Steven G. Kargl, David Schultz, Bruce D. Evans.
+ *
+ * Developed at SunSoft, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ *
+ * Optimized by Bruce D. Evans.
+ */
+#include "libm.h"
+#if (LDBL_MANT_DIG == 64 || LDBL_MANT_DIG == 113) && LDBL_MAX_EXP == 16384
+/* ld80 and ld128 version of __rem_pio2(x,y)
+ *
+ * return the remainder of x rem pi/2 in y[0]+y[1]
+ * use __rem_pio2_large() for large x
+ */
+
+static const long double toint = 1.5/LDBL_EPSILON;
+
+#if LDBL_MANT_DIG == 64
+/* u ~< 0x1p25*pi/2 */
+#define SMALL(u) (((u.i.se & 0x7fffU)<<16 | u.i.m>>48) < ((0x3fff + 25)<<16 | 0x921f>>1 | 0x8000))
+#define QUOBITS(x) ((uint32_t)(int32_t)x & 0x7fffffff)
+#define ROUND1 22
+#define ROUND2 61
+#define NX 3
+#define NY 2
+/*
+ * invpio2:  64 bits of 2/pi
+ * pio2_1:   first  39 bits of pi/2
+ * pio2_1t:  pi/2 - pio2_1
+ * pio2_2:   second 39 bits of pi/2
+ * pio2_2t:  pi/2 - (pio2_1+pio2_2)
+ * pio2_3:   third  39 bits of pi/2
+ * pio2_3t:  pi/2 - (pio2_1+pio2_2+pio2_3)
+ */
+static const double
+pio2_1 =  1.57079632679597125389e+00, /* 0x3FF921FB, 0x54444000 */
+pio2_2 = -1.07463465549783099519e-12, /* -0x12e7b967674000.0p-92 */
+pio2_3 =  6.36831716351370313614e-25; /*  0x18a2e037074000.0p-133 */
+static const long double
+invpio2 =  6.36619772367581343076e-01L, /*  0xa2f9836e4e44152a.0p-64 */
+pio2_1t = -1.07463465549719416346e-12L, /* -0x973dcb3b399d747f.0p-103 */
+pio2_2t =  6.36831716351095013979e-25L, /*  0xc51701b839a25205.0p-144 */
+pio2_3t = -2.75299651904407171810e-37L; /* -0xbb5bf6c7ddd660ce.0p-185 */
+#elif LDBL_MANT_DIG == 113
+/* u ~< 0x1p45*pi/2 */
+#define SMALL(u) (((u.i.se & 0x7fffU)<<16 | u.i.top) < ((0x3fff + 45)<<16 | 0x921f))
+#define QUOBITS(x) ((uint32_t)(int64_t)x & 0x7fffffff)
+#define ROUND1 51
+#define ROUND2 119
+#define NX 5
+#define NY 3
+static const long double
+invpio2 =  6.3661977236758134307553505349005747e-01L,	/*  0x145f306dc9c882a53f84eafa3ea6a.0p-113 */
+pio2_1  =  1.5707963267948966192292994253909555e+00L,	/*  0x1921fb54442d18469800000000000.0p-112 */
+pio2_1t =  2.0222662487959507323996846200947577e-21L,	/*  0x13198a2e03707344a4093822299f3.0p-181 */
+pio2_2  =  2.0222662487959507323994779168837751e-21L,	/*  0x13198a2e03707344a400000000000.0p-181 */
+pio2_2t =  2.0670321098263988236496903051604844e-43L,	/*  0x127044533e63a0105df531d89cd91.0p-254 */
+pio2_3  =  2.0670321098263988236499468110329591e-43L,	/*  0x127044533e63a0105e00000000000.0p-254 */
+pio2_3t = -2.5650587247459238361625433492959285e-65L;	/* -0x159c4ec64ddaeb5f78671cbfb2210.0p-327 */
+#endif
+
+int __rem_pio2l(long double x, long double *y)
+{
+	union ldshape u,uz;
+	long double z,w,t,r,fn;
+	double tx[NX],ty[NY];
+	int ex,ey,n,i;
+
+	u.f = x;
+	ex = u.i.se & 0x7fff;
+	if (SMALL(u)) {
+		/* rint(x/(pi/2)), Assume round-to-nearest. */
+		fn = x*invpio2 + toint - toint;
+		n = QUOBITS(fn);
+		r = x-fn*pio2_1;
+		w = fn*pio2_1t;  /* 1st round good to 102/180 bits (ld80/ld128) */
+		y[0] = r-w;
+		u.f = y[0];
+		ey = u.i.se & 0x7fff;
+		if (ex - ey > ROUND1) {  /* 2nd iteration needed, good to 141/248 (ld80/ld128) */
+			t = r;
+			w = fn*pio2_2;
+			r = t-w;
+			w = fn*pio2_2t-((t-r)-w);
+			y[0] = r-w;
+			u.f = y[0];
+			ey = u.i.se & 0x7fff;
+			if (ex - ey > ROUND2) {  /* 3rd iteration, good to 180/316 bits */
+				t = r; /* will cover all possible cases (not verified for ld128) */
+				w = fn*pio2_3;
+				r = t-w;
+				w = fn*pio2_3t-((t-r)-w);
+				y[0] = r-w;
+			}
+		}
+		y[1] = (r - y[0]) - w;
+		return n;
+	}
+	/*
+	 * all other (large) arguments
+	 */
+	if (ex == 0x7fff) {                /* x is inf or NaN */
+		y[0] = y[1] = x - x;
+		return 0;
+	}
+	/* set z = scalbn(|x|,-ilogb(x)+23) */
+	uz.f = x;
+	uz.i.se = 0x3fff + 23;
+	z = uz.f;
+	for (i=0; i < NX - 1; i++) {
+		tx[i] = (double)(int32_t)z;
+		z     = (z-tx[i])*0x1p24;
+	}
+	tx[i] = z;
+	while (tx[i] == 0)
+		i--;
+	n = __rem_pio2_large(tx, ty, ex-0x3fff-23, i+1, NY);
+	w = ty[1];
+	if (NY == 3)
+		w += ty[2];
+	r = ty[0] + w;
+	/* TODO: for ld128 this does not follow the recommendation of the
+	comments of __rem_pio2_large which seem wrong if |ty[0]| > |ty[1]+ty[2]| */
+	w -= r - ty[0];
+	if (u.i.se >> 15) {
+		y[0] = -r;
+		y[1] = -w;
+		return -n;
+	}
+	y[0] = r;
+	y[1] = w;
+	return n;
+}
+#endif
libc/musl/src/math/__signbit.c
@@ -0,0 +1,13 @@
+#include "libm.h"
+
+// FIXME: macro in math.h
+int __signbit(double x)
+{
+	union {
+		double d;
+		uint64_t i;
+	} y = { x };
+	return y.i>>63;
+}
+
+
libc/musl/src/math/__signbitf.c
@@ -0,0 +1,11 @@
+#include "libm.h"
+
+// FIXME: macro in math.h
+int __signbitf(float x)
+{
+	union {
+		float f;
+		uint32_t i;
+	} y = { x };
+	return y.i>>31;
+}
libc/musl/src/math/__signbitl.c
@@ -0,0 +1,14 @@
+#include "libm.h"
+
+#if (LDBL_MANT_DIG == 64 || LDBL_MANT_DIG == 113) && LDBL_MAX_EXP == 16384
+int __signbitl(long double x)
+{
+	union ldshape u = {x};
+	return u.i.se >> 15;
+}
+#elif LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024
+int __signbitl(long double x)
+{
+	return __signbit(x);
+}
+#endif
libc/musl/src/math/__sin.c
@@ -0,0 +1,64 @@
+/* origin: FreeBSD /usr/src/lib/msun/src/k_sin.c */
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunSoft, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+/* __sin( x, y, iy)
+ * kernel sin function on ~[-pi/4, pi/4] (except on -0), pi/4 ~ 0.7854
+ * Input x is assumed to be bounded by ~pi/4 in magnitude.
+ * Input y is the tail of x.
+ * Input iy indicates whether y is 0. (if iy=0, y assume to be 0).
+ *
+ * Algorithm
+ *      1. Since sin(-x) = -sin(x), we need only to consider positive x.
+ *      2. Callers must return sin(-0) = -0 without calling here since our
+ *         odd polynomial is not evaluated in a way that preserves -0.
+ *         Callers may do the optimization sin(x) ~ x for tiny x.
+ *      3. sin(x) is approximated by a polynomial of degree 13 on
+ *         [0,pi/4]
+ *                               3            13
+ *              sin(x) ~ x + S1*x + ... + S6*x
+ *         where
+ *
+ *      |sin(x)         2     4     6     8     10     12  |     -58
+ *      |----- - (1+S1*x +S2*x +S3*x +S4*x +S5*x  +S6*x   )| <= 2
+ *      |  x                                               |
+ *
+ *      4. sin(x+y) = sin(x) + sin'(x')*y
+ *                  ~ sin(x) + (1-x*x/2)*y
+ *         For better accuracy, let
+ *                   3      2      2      2      2
+ *              r = x *(S2+x *(S3+x *(S4+x *(S5+x *S6))))
+ *         then                   3    2
+ *              sin(x) = x + (S1*x + (x *(r-y/2)+y))
+ */
+
+#include "libm.h"
+
+static const double
+S1  = -1.66666666666666324348e-01, /* 0xBFC55555, 0x55555549 */
+S2  =  8.33333333332248946124e-03, /* 0x3F811111, 0x1110F8A6 */
+S3  = -1.98412698298579493134e-04, /* 0xBF2A01A0, 0x19C161D5 */
+S4  =  2.75573137070700676789e-06, /* 0x3EC71DE3, 0x57B1FE7D */
+S5  = -2.50507602534068634195e-08, /* 0xBE5AE5E6, 0x8A2B9CEB */
+S6  =  1.58969099521155010221e-10; /* 0x3DE5D93A, 0x5ACFD57C */
+
+double __sin(double x, double y, int iy)
+{
+	double_t z,r,v,w;
+
+	z = x*x;
+	w = z*z;
+	r = S2 + z*(S3 + z*S4) + z*w*(S5 + z*S6);
+	v = z*x;
+	if (iy == 0)
+		return x + v*(S1 + z*r);
+	else
+		return x - ((z*(0.5*y - v*r) - y) - v*S1);
+}
libc/musl/src/math/__sindf.c
@@ -0,0 +1,36 @@
+/* origin: FreeBSD /usr/src/lib/msun/src/k_sinf.c */
+/*
+ * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.
+ * Optimized by Bruce D. Evans.
+ */
+/*
+ * ====================================================
+ * 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 "libm.h"
+
+/* |sin(x)/x - s(x)| < 2**-37.5 (~[-4.89e-12, 4.824e-12]). */
+static const double
+S1 = -0x15555554cbac77.0p-55, /* -0.166666666416265235595 */
+S2 =  0x111110896efbb2.0p-59, /*  0.0083333293858894631756 */
+S3 = -0x1a00f9e2cae774.0p-65, /* -0.000198393348360966317347 */
+S4 =  0x16cd878c3b46a7.0p-71; /*  0.0000027183114939898219064 */
+
+float __sindf(double x)
+{
+	double_t r, s, w, z;
+
+	/* Try to optimize for parallel evaluation as in __tandf.c. */
+	z = x*x;
+	w = z*z;
+	r = S3 + z*S4;
+	s = z*x;
+	return (x + s*(S1 + z*S2)) + s*w*r;
+}
libc/musl/src/math/__sinl.c
@@ -0,0 +1,78 @@
+/* origin: FreeBSD /usr/src/lib/msun/ld80/k_sinl.c */
+/* origin: FreeBSD /usr/src/lib/msun/ld128/k_sinl.c */
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ * Copyright (c) 2008 Steven G. Kargl, David Schultz, Bruce D. Evans.
+ *
+ * Developed at SunSoft, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+
+#include "libm.h"
+
+#if (LDBL_MANT_DIG == 64 || LDBL_MANT_DIG == 113) && LDBL_MAX_EXP == 16384
+#if LDBL_MANT_DIG == 64
+/*
+ * ld80 version of __sin.c.  See __sin.c for most comments.
+ */
+/*
+ * Domain [-0.7854, 0.7854], range ~[-1.89e-22, 1.915e-22]
+ * |sin(x)/x - s(x)| < 2**-72.1
+ *
+ * See __cosl.c for more details about the polynomial.
+ */
+static const long double
+S1 = -0.166666666666666666671L;   /* -0xaaaaaaaaaaaaaaab.0p-66 */
+static const double
+S2 =  0.0083333333333333332,      /*  0x11111111111111.0p-59 */
+S3 = -0.00019841269841269427,     /* -0x1a01a01a019f81.0p-65 */
+S4 =  0.0000027557319223597490,   /*  0x171de3a55560f7.0p-71 */
+S5 = -0.000000025052108218074604, /* -0x1ae64564f16cad.0p-78 */
+S6 =  1.6059006598854211e-10,     /*  0x161242b90243b5.0p-85 */
+S7 = -7.6429779983024564e-13,     /* -0x1ae42ebd1b2e00.0p-93 */
+S8 =  2.6174587166648325e-15;     /*  0x179372ea0b3f64.0p-101 */
+#define POLY(z) (S2+z*(S3+z*(S4+z*(S5+z*(S6+z*(S7+z*S8))))))
+#elif LDBL_MANT_DIG == 113
+/*
+ * ld128 version of __sin.c.  See __sin.c for most comments.
+ */
+/*
+ * Domain [-0.7854, 0.7854], range ~[-1.53e-37, 1.659e-37]
+ * |sin(x)/x - s(x)| < 2**-122.1
+ *
+ * See __cosl.c for more details about the polynomial.
+ */
+static const long double
+S1 = -0.16666666666666666666666666666666666606732416116558L,
+S2 =  0.0083333333333333333333333333333331135404851288270047L,
+S3 = -0.00019841269841269841269841269839935785325638310428717L,
+S4 =  0.27557319223985890652557316053039946268333231205686e-5L,
+S5 = -0.25052108385441718775048214826384312253862930064745e-7L,
+S6 =  0.16059043836821614596571832194524392581082444805729e-9L,
+S7 = -0.76471637318198151807063387954939213287488216303768e-12L,
+S8 =  0.28114572543451292625024967174638477283187397621303e-14L;
+static const double
+S9  = -0.82206352458348947812512122163446202498005154296863e-17,
+S10 =  0.19572940011906109418080609928334380560135358385256e-19,
+S11 = -0.38680813379701966970673724299207480965452616911420e-22,
+S12 =  0.64038150078671872796678569586315881020659912139412e-25;
+#define POLY(z) (S2+z*(S3+z*(S4+z*(S5+z*(S6+z*(S7+z*(S8+ \
+	z*(S9+z*(S10+z*(S11+z*S12))))))))))
+#endif
+
+long double __sinl(long double x, long double y, int iy)
+{
+	long double z,r,v;
+
+	z = x*x;
+	v = z*x;
+	r = POLY(z);
+	if (iy == 0)
+		return x+v*(S1+z*r);
+	return x-((z*(0.5*y-v*r)-y)-v*S1);
+}
+#endif
libc/musl/src/math/__tan.c
@@ -0,0 +1,110 @@
+/* origin: FreeBSD /usr/src/lib/msun/src/k_tan.c */
+/*
+ * ====================================================
+ * Copyright 2004 Sun Microsystems, Inc.  All Rights Reserved.
+ *
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+/* __tan( x, y, k )
+ * kernel tan function on ~[-pi/4, pi/4] (except on -0), pi/4 ~ 0.7854
+ * Input x is assumed to be bounded by ~pi/4 in magnitude.
+ * Input y is the tail of x.
+ * Input odd indicates whether tan (if odd = 0) or -1/tan (if odd = 1) is returned.
+ *
+ * Algorithm
+ *      1. Since tan(-x) = -tan(x), we need only to consider positive x.
+ *      2. Callers must return tan(-0) = -0 without calling here since our
+ *         odd polynomial is not evaluated in a way that preserves -0.
+ *         Callers may do the optimization tan(x) ~ x for tiny x.
+ *      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 "libm.h"
+
+static const double T[] = {
+             3.33333333333334091986e-01, /* 3FD55555, 55555563 */
+             1.33333333333201242699e-01, /* 3FC11111, 1110FE7A */
+             5.39682539762260521377e-02, /* 3FABA1BA, 1BB341FE */
+             2.18694882948595424599e-02, /* 3F9664F4, 8406D637 */
+             8.86323982359930005737e-03, /* 3F8226E3, E96E8493 */
+             3.59207910759131235356e-03, /* 3F6D6D22, C9560328 */
+             1.45620945432529025516e-03, /* 3F57DBC8, FEE08315 */
+             5.88041240820264096874e-04, /* 3F4344D8, F2F26501 */
+             2.46463134818469906812e-04, /* 3F3026F7, 1A8D1068 */
+             7.81794442939557092300e-05, /* 3F147E88, A03792A6 */
+             7.14072491382608190305e-05, /* 3F12B80F, 32F0A7E9 */
+            -1.85586374855275456654e-05, /* BEF375CB, DB605373 */
+             2.59073051863633712884e-05, /* 3EFB2A70, 74BF7AD4 */
+},
+pio4 =       7.85398163397448278999e-01, /* 3FE921FB, 54442D18 */
+pio4lo =     3.06161699786838301793e-17; /* 3C81A626, 33145C07 */
+
+double __tan(double x, double y, int odd)
+{
+	double_t z, r, v, w, s, a;
+	double w0, a0;
+	uint32_t hx;
+	int big, sign;
+
+	GET_HIGH_WORD(hx,x);
+	big = (hx&0x7fffffff) >= 0x3FE59428; /* |x| >= 0.6744 */
+	if (big) {
+		sign = hx>>31;
+		if (sign) {
+			x = -x;
+			y = -y;
+		}
+		x = (pio4 - x) + (pio4lo - y);
+		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) + s*T[0];
+	w = x + r;
+	if (big) {
+		s = 1 - 2*odd;
+		v = s - 2.0 * (x + (r - w*w/(w + s)));
+		return sign ? -v : v;
+	}
+	if (!odd)
+		return w;
+	/* -1.0/(x+r) has up to 2ulp error, so compute it accurately */
+	w0 = w;
+	SET_LOW_WORD(w0, 0);
+	v = r - (w0 - x);       /* w0+v = r+x */
+	a0 = a = -1.0 / w;
+	SET_LOW_WORD(a0, 0);
+	return a0 + a*(1.0 + a0*w0 + a0*v);
+}
libc/musl/src/math/__tandf.c
@@ -0,0 +1,54 @@
+/* origin: FreeBSD /usr/src/lib/msun/src/k_tanf.c */
+/*
+ * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.
+ * Optimized by Bruce D. Evans.
+ */
+/*
+ * ====================================================
+ * Copyright 2004 Sun Microsystems, Inc.  All Rights Reserved.
+ *
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+
+#include "libm.h"
+
+/* |tan(x)/x - t(x)| < 2**-25.5 (~[-2e-08, 2e-08]). */
+static const double T[] = {
+  0x15554d3418c99f.0p-54, /* 0.333331395030791399758 */
+  0x1112fd38999f72.0p-55, /* 0.133392002712976742718 */
+  0x1b54c91d865afe.0p-57, /* 0.0533812378445670393523 */
+  0x191df3908c33ce.0p-58, /* 0.0245283181166547278873 */
+  0x185dadfcecf44e.0p-61, /* 0.00297435743359967304927 */
+  0x1362b9bf971bcd.0p-59, /* 0.00946564784943673166728 */
+};
+
+float __tandf(double x, int odd)
+{
+	double_t z,r,w,s,t,u;
+
+	z = x*x;
+	/*
+	 * Split up the polynomial into small independent terms to give
+	 * opportunities for parallel evaluation.  The chosen splitting is
+	 * micro-optimized for Athlons (XP, X64).  It costs 2 multiplications
+	 * relative to Horner's method on sequential machines.
+	 *
+	 * We add the small terms from lowest degree up for efficiency on
+	 * non-sequential machines (the lowest degree terms tend to be ready
+	 * earlier).  Apart from this, we don't care about order of
+	 * operations, and don't need to to care since we have precision to
+	 * spare.  However, the chosen splitting is good for accuracy too,
+	 * and would give results as accurate as Horner's method if the
+	 * small terms were added from highest degree down.
+	 */
+	r = T[4] + z*T[5];
+	t = T[2] + z*T[3];
+	w = z*z;
+	s = z*x;
+	u = T[0] + z*T[1];
+	r = (x + s*u) + (s*w)*(t + w*r);
+	return odd ? -1.0/r : r;
+}
libc/musl/src/math/__tanl.c
@@ -0,0 +1,143 @@
+/* origin: FreeBSD /usr/src/lib/msun/ld80/k_tanl.c */
+/* origin: FreeBSD /usr/src/lib/msun/ld128/k_tanl.c */
+/*
+ * ====================================================
+ * Copyright 2004 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright (c) 2008 Steven G. Kargl, David Schultz, Bruce D. Evans.
+ *
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+
+#include "libm.h"
+
+#if (LDBL_MANT_DIG == 64 || LDBL_MANT_DIG == 113) && LDBL_MAX_EXP == 16384
+#if LDBL_MANT_DIG == 64
+/*
+ * ld80 version of __tan.c.  See __tan.c for most comments.
+ */
+/*
+ * Domain [-0.67434, 0.67434], range ~[-2.25e-22, 1.921e-22]
+ * |tan(x)/x - t(x)| < 2**-71.9
+ *
+ * See __cosl.c for more details about the polynomial.
+ */
+static const long double
+T3 =  0.333333333333333333180L,         /*  0xaaaaaaaaaaaaaaa5.0p-65 */
+T5 =  0.133333333333333372290L,         /*  0x88888888888893c3.0p-66 */
+T7 =  0.0539682539682504975744L,        /*  0xdd0dd0dd0dc13ba2.0p-68 */
+pio4   =  0.785398163397448309628L,     /*  0xc90fdaa22168c235.0p-64 */
+pio4lo = -1.25413940316708300586e-20L;  /* -0xece675d1fc8f8cbb.0p-130 */
+static const double
+T9  =  0.021869488536312216,            /*  0x1664f4882cc1c2.0p-58 */
+T11 =  0.0088632355256619590,           /*  0x1226e355c17612.0p-59 */
+T13 =  0.0035921281113786528,           /*  0x1d6d3d185d7ff8.0p-61 */
+T15 =  0.0014558334756312418,           /*  0x17da354aa3f96b.0p-62 */
+T17 =  0.00059003538700862256,          /*  0x13559358685b83.0p-63 */
+T19 =  0.00023907843576635544,          /*  0x1f56242026b5be.0p-65 */
+T21 =  0.000097154625656538905,         /*  0x1977efc26806f4.0p-66 */
+T23 =  0.000038440165747303162,         /*  0x14275a09b3ceac.0p-67 */
+T25 =  0.000018082171885432524,         /*  0x12f5e563e5487e.0p-68 */
+T27 =  0.0000024196006108814377,        /*  0x144c0d80cc6896.0p-71 */
+T29 =  0.0000078293456938132840,        /*  0x106b59141a6cb3.0p-69 */
+T31 = -0.0000032609076735050182,        /* -0x1b5abef3ba4b59.0p-71 */
+T33 =  0.0000023261313142559411;        /*  0x13835436c0c87f.0p-71 */
+#define RPOLY(w) (T5 + w * (T9 + w * (T13 + w * (T17 + w * (T21 + \
+	w * (T25 + w * (T29 + w * T33)))))))
+#define VPOLY(w) (T7 + w * (T11 + w * (T15 + w * (T19 + w * (T23 + \
+	w * (T27 + w * T31))))))
+#elif LDBL_MANT_DIG == 113
+/*
+ * ld128 version of __tan.c.  See __tan.c for most comments.
+ */
+/*
+ * Domain [-0.67434, 0.67434], range ~[-3.37e-36, 1.982e-37]
+ * |tan(x)/x - t(x)| < 2**-117.8 (XXX should be ~1e-37)
+ *
+ * See __cosl.c for more details about the polynomial.
+ */
+static const long double
+T3 = 0x1.5555555555555555555555555553p-2L,
+T5 = 0x1.1111111111111111111111111eb5p-3L,
+T7 = 0x1.ba1ba1ba1ba1ba1ba1ba1b694cd6p-5L,
+T9 = 0x1.664f4882c10f9f32d6bbe09d8bcdp-6L,
+T11 = 0x1.226e355e6c23c8f5b4f5762322eep-7L,
+T13 = 0x1.d6d3d0e157ddfb5fed8e84e27b37p-9L,
+T15 = 0x1.7da36452b75e2b5fce9ee7c2c92ep-10L,
+T17 = 0x1.355824803674477dfcf726649efep-11L,
+T19 = 0x1.f57d7734d1656e0aceb716f614c2p-13L,
+T21 = 0x1.967e18afcb180ed942dfdc518d6cp-14L,
+T23 = 0x1.497d8eea21e95bc7e2aa79b9f2cdp-15L,
+T25 = 0x1.0b132d39f055c81be49eff7afd50p-16L,
+T27 = 0x1.b0f72d33eff7bfa2fbc1059d90b6p-18L,
+T29 = 0x1.5ef2daf21d1113df38d0fbc00267p-19L,
+T31 = 0x1.1c77d6eac0234988cdaa04c96626p-20L,
+T33 = 0x1.cd2a5a292b180e0bdd701057dfe3p-22L,
+T35 = 0x1.75c7357d0298c01a31d0a6f7d518p-23L,
+T37 = 0x1.2f3190f4718a9a520f98f50081fcp-24L,
+pio4 = 0x1.921fb54442d18469898cc51701b8p-1L,
+pio4lo = 0x1.cd129024e088a67cc74020bbea60p-116L;
+static const double
+T39 =  0.000000028443389121318352,	/*  0x1e8a7592977938.0p-78 */
+T41 =  0.000000011981013102001973,	/*  0x19baa1b1223219.0p-79 */
+T43 =  0.0000000038303578044958070,	/*  0x107385dfb24529.0p-80 */
+T45 =  0.0000000034664378216909893,	/*  0x1dc6c702a05262.0p-81 */
+T47 = -0.0000000015090641701997785,	/* -0x19ecef3569ebb6.0p-82 */
+T49 =  0.0000000029449552300483952,	/*  0x194c0668da786a.0p-81 */
+T51 = -0.0000000022006995706097711,	/* -0x12e763b8845268.0p-81 */
+T53 =  0.0000000015468200913196612,	/*  0x1a92fc98c29554.0p-82 */
+T55 = -0.00000000061311613386849674,	/* -0x151106cbc779a9.0p-83 */
+T57 =  1.4912469681508012e-10;		/*  0x147edbdba6f43a.0p-85 */
+#define RPOLY(w) (T5 + w * (T9 + w * (T13 + w * (T17 + w * (T21 + \
+	w * (T25 + w * (T29 + w * (T33 + w * (T37 + w * (T41 + \
+	w * (T45 + w * (T49 + w * (T53 + w * T57)))))))))))))
+#define VPOLY(w) (T7 + w * (T11 + w * (T15 + w * (T19 + w * (T23 + \
+	w * (T27 + w * (T31 + w * (T35 + w * (T39 + w * (T43 + \
+	w * (T47 + w * (T51 + w * T55))))))))))))
+#endif
+
+long double __tanl(long double x, long double y, int odd) {
+	long double z, r, v, w, s, a, t;
+	int big, sign;
+
+	big = fabsl(x) >= 0.67434;
+	if (big) {
+		sign = 0;
+		if (x < 0) {
+			sign = 1;
+			x = -x;
+			y = -y;
+		}
+		x = (pio4 - x) + (pio4lo - y);
+		y = 0.0;
+	}
+	z = x * x;
+	w = z * z;
+	r = RPOLY(w);
+	v = z * VPOLY(w);
+	s = z * x;
+	r = y + z * (s * (r + v) + y) + T3 * s;
+	w = x + r;
+	if (big) {
+		s = 1 - 2*odd;
+		v = s - 2.0 * (x + (r - w * w / (w + s)));
+		return sign ? -v : v;
+	}
+	if (!odd)
+		return w;
+	/*
+	 * if allow error up to 2 ulp, simply return
+	 * -1.0 / (x+r) here
+	 */
+	/* compute -1.0 / (x+r) accurately */
+	z = w;
+	z = z + 0x1p32 - 0x1p32;
+	v = r - (z - x);        /* z+v = r+x */
+	t = a = -1.0 / w;       /* a = -1.0/w */
+	t = t + 0x1p32 - 0x1p32;
+	s = 1.0 + t * z;
+	return t + a * (s + t * v);
+}
+#endif
libc/musl/src/math/acos.c
@@ -0,0 +1,101 @@
+/* origin: FreeBSD /usr/src/lib/msun/src/e_acos.c */
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunSoft, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+/* acos(x)
+ * Method :
+ *      acos(x)  = pi/2 - asin(x)
+ *      acos(-x) = pi/2 + asin(x)
+ * For |x|<=0.5
+ *      acos(x) = pi/2 - (x + x*x^2*R(x^2))     (see asin.c)
+ * For x>0.5
+ *      acos(x) = pi/2 - (pi/2 - 2asin(sqrt((1-x)/2)))
+ *              = 2asin(sqrt((1-x)/2))
+ *              = 2s + 2s*z*R(z)        ...z=(1-x)/2, s=sqrt(z)
+ *              = 2f + (2c + 2s*z*R(z))
+ *     where f=hi part of s, and c = (z-f*f)/(s+f) is the correction term
+ *     for f so that f+c ~ sqrt(z).
+ * For x<-0.5
+ *      acos(x) = pi - 2asin(sqrt((1-|x|)/2))
+ *              = pi - 0.5*(s+s*z*R(z)), where z=(1-|x|)/2,s=sqrt(z)
+ *
+ * Special cases:
+ *      if x is NaN, return x itself;
+ *      if |x|>1, return NaN with invalid signal.
+ *
+ * Function needed: sqrt
+ */
+
+#include "libm.h"
+
+static const double
+pio2_hi = 1.57079632679489655800e+00, /* 0x3FF921FB, 0x54442D18 */
+pio2_lo = 6.12323399573676603587e-17, /* 0x3C91A626, 0x33145C07 */
+pS0 =  1.66666666666666657415e-01, /* 0x3FC55555, 0x55555555 */
+pS1 = -3.25565818622400915405e-01, /* 0xBFD4D612, 0x03EB6F7D */
+pS2 =  2.01212532134862925881e-01, /* 0x3FC9C155, 0x0E884455 */
+pS3 = -4.00555345006794114027e-02, /* 0xBFA48228, 0xB5688F3B */
+pS4 =  7.91534994289814532176e-04, /* 0x3F49EFE0, 0x7501B288 */
+pS5 =  3.47933107596021167570e-05, /* 0x3F023DE1, 0x0DFDF709 */
+qS1 = -2.40339491173441421878e+00, /* 0xC0033A27, 0x1C8A2D4B */
+qS2 =  2.02094576023350569471e+00, /* 0x40002AE5, 0x9C598AC8 */
+qS3 = -6.88283971605453293030e-01, /* 0xBFE6066C, 0x1B8D0159 */
+qS4 =  7.70381505559019352791e-02; /* 0x3FB3B8C5, 0xB12E9282 */
+
+static double R(double z)
+{
+	double_t p, q;
+	p = z*(pS0+z*(pS1+z*(pS2+z*(pS3+z*(pS4+z*pS5)))));
+	q = 1.0+z*(qS1+z*(qS2+z*(qS3+z*qS4)));
+	return p/q;
+}
+
+double acos(double x)
+{
+	double z,w,s,c,df;
+	uint32_t hx,ix;
+
+	GET_HIGH_WORD(hx, x);
+	ix = hx & 0x7fffffff;
+	/* |x| >= 1 or nan */
+	if (ix >= 0x3ff00000) {
+		uint32_t lx;
+
+		GET_LOW_WORD(lx,x);
+		if ((ix-0x3ff00000 | lx) == 0) {
+			/* acos(1)=0, acos(-1)=pi */
+			if (hx >> 31)
+				return 2*pio2_hi + 0x1p-120f;
+			return 0;
+		}
+		return 0/(x-x);
+	}
+	/* |x| < 0.5 */
+	if (ix < 0x3fe00000) {
+		if (ix <= 0x3c600000)  /* |x| < 2**-57 */
+			return pio2_hi + 0x1p-120f;
+		return pio2_hi - (x - (pio2_lo-x*R(x*x)));
+	}
+	/* x < -0.5 */
+	if (hx >> 31) {
+		z = (1.0+x)*0.5;
+		s = sqrt(z);
+		w = R(z)*s-pio2_lo;
+		return 2*(pio2_hi - (s+w));
+	}
+	/* x > 0.5 */
+	z = (1.0-x)*0.5;
+	s = sqrt(z);
+	df = s;
+	SET_LOW_WORD(df,0);
+	c = (z-df*df)/(s+df);
+	w = R(z)*s+c;
+	return 2*(df+w);
+}
libc/musl/src/math/acosf.c
@@ -0,0 +1,71 @@
+/* origin: FreeBSD /usr/src/lib/msun/src/e_acosf.c */
+/*
+ * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.
+ */
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunPro, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+
+#include "libm.h"
+
+static const float
+pio2_hi = 1.5707962513e+00, /* 0x3fc90fda */
+pio2_lo = 7.5497894159e-08, /* 0x33a22168 */
+pS0 =  1.6666586697e-01,
+pS1 = -4.2743422091e-02,
+pS2 = -8.6563630030e-03,
+qS1 = -7.0662963390e-01;
+
+static float R(float z)
+{
+	float_t p, q;
+	p = z*(pS0+z*(pS1+z*pS2));
+	q = 1.0f+z*qS1;
+	return p/q;
+}
+
+float acosf(float x)
+{
+	float z,w,s,c,df;
+	uint32_t hx,ix;
+
+	GET_FLOAT_WORD(hx, x);
+	ix = hx & 0x7fffffff;
+	/* |x| >= 1 or nan */
+	if (ix >= 0x3f800000) {
+		if (ix == 0x3f800000) {
+			if (hx >> 31)
+				return 2*pio2_hi + 0x1p-120f;
+			return 0;
+		}
+		return 0/(x-x);
+	}
+	/* |x| < 0.5 */
+	if (ix < 0x3f000000) {
+		if (ix <= 0x32800000) /* |x| < 2**-26 */
+			return pio2_hi + 0x1p-120f;
+		return pio2_hi - (x - (pio2_lo-x*R(x*x)));
+	}
+	/* x < -0.5 */
+	if (hx >> 31) {
+		z = (1+x)*0.5f;
+		s = sqrtf(z);
+		w = R(z)*s-pio2_lo;
+		return 2*(pio2_hi - (s+w));
+	}
+	/* x > 0.5 */
+	z = (1-x)*0.5f;
+	s = sqrtf(z);
+	GET_FLOAT_WORD(hx,s);
+	SET_FLOAT_WORD(df,hx&0xfffff000);
+	c = (z-df*df)/(s+df);
+	w = R(z)*s+c;
+	return 2*(df+w);
+}
libc/musl/src/math/acosh.c
@@ -0,0 +1,24 @@
+#include "libm.h"
+
+#if FLT_EVAL_METHOD==2
+#undef sqrt
+#define sqrt sqrtl
+#endif
+
+/* acosh(x) = log(x + sqrt(x*x-1)) */
+double acosh(double x)
+{
+	union {double f; uint64_t i;} u = {.f = x};
+	unsigned e = u.i >> 52 & 0x7ff;
+
+	/* x < 1 domain error is handled in the called functions */
+
+	if (e < 0x3ff + 1)
+		/* |x| < 2, up to 2ulp error in [1,1.125] */
+		return log1p(x-1 + sqrt((x-1)*(x-1)+2*(x-1)));
+	if (e < 0x3ff + 26)
+		/* |x| < 0x1p26 */
+		return log(2*x - 1/(x+sqrt(x*x-1)));
+	/* |x| >= 0x1p26 or nan */
+	return log(x) + 0.693147180559945309417232121458176568;
+}
libc/musl/src/math/acoshf.c
@@ -0,0 +1,26 @@
+#include "libm.h"
+
+#if FLT_EVAL_METHOD==2
+#undef sqrtf
+#define sqrtf sqrtl
+#elif FLT_EVAL_METHOD==1
+#undef sqrtf
+#define sqrtf sqrt
+#endif
+
+/* acosh(x) = log(x + sqrt(x*x-1)) */
+float acoshf(float x)
+{
+	union {float f; uint32_t i;} u = {x};
+	uint32_t a = u.i & 0x7fffffff;
+
+	if (a < 0x3f800000+(1<<23))
+		/* |x| < 2, invalid if x < 1 or nan */
+		/* up to 2ulp error in [1,1.125] */
+		return log1pf(x-1 + sqrtf((x-1)*(x-1)+2*(x-1)));
+	if (a < 0x3f800000+(12<<23))
+		/* |x| < 0x1p12 */
+		return logf(2*x - 1/(x+sqrtf(x*x-1)));
+	/* x >= 0x1p12 */
+	return logf(x) + 0.693147180559945309417232121458176568f;
+}
libc/musl/src/math/acoshl.c
@@ -0,0 +1,29 @@
+#include "libm.h"
+
+#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024
+long double acoshl(long double x)
+{
+	return acosh(x);
+}
+#elif LDBL_MANT_DIG == 64 && LDBL_MAX_EXP == 16384
+/* acosh(x) = log(x + sqrt(x*x-1)) */
+long double acoshl(long double x)
+{
+	union ldshape u = {x};
+	int e = u.i.se & 0x7fff;
+
+	if (e < 0x3fff + 1)
+		/* |x| < 2, invalid if x < 1 or nan */
+		return log1pl(x-1 + sqrtl((x-1)*(x-1)+2*(x-1)));
+	if (e < 0x3fff + 32)
+		/* |x| < 0x1p32 */
+		return logl(2*x - 1/(x+sqrtl(x*x-1)));
+	return logl(x) + 0.693147180559945309417232121458176568L;
+}
+#elif LDBL_MANT_DIG == 113 && LDBL_MAX_EXP == 16384
+// TODO: broken implementation to make things compile
+long double acoshl(long double x)
+{
+	return acosh(x);
+}
+#endif
libc/musl/src/math/acosl.c
@@ -0,0 +1,67 @@
+/* origin: FreeBSD /usr/src/lib/msun/src/e_acosl.c */
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunSoft, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+/*
+ * See comments in acos.c.
+ * Converted to long double by David Schultz <das@FreeBSD.ORG>.
+ */
+
+#include "libm.h"
+
+#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024
+long double acosl(long double x)
+{
+	return acos(x);
+}
+#elif (LDBL_MANT_DIG == 64 || LDBL_MANT_DIG == 113) && LDBL_MAX_EXP == 16384
+#include "__invtrigl.h"
+#if LDBL_MANT_DIG == 64
+#define CLEARBOTTOM(u) (u.i.m &= -1ULL << 32)
+#elif LDBL_MANT_DIG == 113
+#define CLEARBOTTOM(u) (u.i.lo = 0)
+#endif
+
+long double acosl(long double x)
+{
+	union ldshape u = {x};
+	long double z, s, c, f;
+	uint16_t e = u.i.se & 0x7fff;
+
+	/* |x| >= 1 or nan */
+	if (e >= 0x3fff) {
+		if (x == 1)
+			return 0;
+		if (x == -1)
+			return 2*pio2_hi + 0x1p-120f;
+		return 0/(x-x);
+	}
+	/* |x| < 0.5 */
+	if (e < 0x3fff - 1) {
+		if (e < 0x3fff - LDBL_MANT_DIG - 1)
+			return pio2_hi + 0x1p-120f;
+		return pio2_hi - (__invtrigl_R(x*x)*x - pio2_lo + x);
+	}
+	/* x < -0.5 */
+	if (u.i.se >> 15) {
+		z = (1 + x)*0.5;
+		s = sqrtl(z);
+		return 2*(pio2_hi - (__invtrigl_R(z)*s - pio2_lo + s));
+	}
+	/* x > 0.5 */
+	z = (1 - x)*0.5;
+	s = sqrtl(z);
+	u.f = s;
+	CLEARBOTTOM(u);
+	f = u.f;
+	c = (z - f*f)/(s + f);
+	return 2*(__invtrigl_R(z)*s + c + f);
+}
+#endif
libc/musl/src/math/asin.c
@@ -0,0 +1,107 @@
+/* origin: FreeBSD /usr/src/lib/msun/src/e_asin.c */
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunSoft, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+/* 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)
+ *      where
+ *              R(x^2) is a rational approximation of (asin(x)-x)/x^3
+ *      and its remez error is bounded by
+ *              |(asin(x)-x)/x^3 - R(x^2)| < 2^(-58.75)
+ *
+ *      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 "libm.h"
+
+static const double
+pio2_hi = 1.57079632679489655800e+00, /* 0x3FF921FB, 0x54442D18 */
+pio2_lo = 6.12323399573676603587e-17, /* 0x3C91A626, 0x33145C07 */
+/* coefficients for R(x^2) */
+pS0 =  1.66666666666666657415e-01, /* 0x3FC55555, 0x55555555 */
+pS1 = -3.25565818622400915405e-01, /* 0xBFD4D612, 0x03EB6F7D */
+pS2 =  2.01212532134862925881e-01, /* 0x3FC9C155, 0x0E884455 */
+pS3 = -4.00555345006794114027e-02, /* 0xBFA48228, 0xB5688F3B */
+pS4 =  7.91534994289814532176e-04, /* 0x3F49EFE0, 0x7501B288 */
+pS5 =  3.47933107596021167570e-05, /* 0x3F023DE1, 0x0DFDF709 */
+qS1 = -2.40339491173441421878e+00, /* 0xC0033A27, 0x1C8A2D4B */
+qS2 =  2.02094576023350569471e+00, /* 0x40002AE5, 0x9C598AC8 */
+qS3 = -6.88283971605453293030e-01, /* 0xBFE6066C, 0x1B8D0159 */
+qS4 =  7.70381505559019352791e-02; /* 0x3FB3B8C5, 0xB12E9282 */
+
+static double R(double z)
+{
+	double_t p, q;
+	p = z*(pS0+z*(pS1+z*(pS2+z*(pS3+z*(pS4+z*pS5)))));
+	q = 1.0+z*(qS1+z*(qS2+z*(qS3+z*qS4)));
+	return p/q;
+}
+
+double asin(double x)
+{
+	double z,r,s;
+	uint32_t hx,ix;
+
+	GET_HIGH_WORD(hx, x);
+	ix = hx & 0x7fffffff;
+	/* |x| >= 1 or nan */
+	if (ix >= 0x3ff00000) {
+		uint32_t lx;
+		GET_LOW_WORD(lx, x);
+		if ((ix-0x3ff00000 | lx) == 0)
+			/* asin(1) = +-pi/2 with inexact */
+			return x*pio2_hi + 0x1p-120f;
+		return 0/(x-x);
+	}
+	/* |x| < 0.5 */
+	if (ix < 0x3fe00000) {
+		/* if 0x1p-1022 <= |x| < 0x1p-26, avoid raising underflow */
+		if (ix < 0x3e500000 && ix >= 0x00100000)
+			return x;
+		return x + x*R(x*x);
+	}
+	/* 1 > |x| >= 0.5 */
+	z = (1 - fabs(x))*0.5;
+	s = sqrt(z);
+	r = R(z);
+	if (ix >= 0x3fef3333) {  /* if |x| > 0.975 */
+		x = pio2_hi-(2*(s+s*r)-pio2_lo);
+	} else {
+		double f,c;
+		/* f+c = sqrt(z) */
+		f = s;
+		SET_LOW_WORD(f,0);
+		c = (z-f*f)/(s+f);
+		x = 0.5*pio2_hi - (2*s*r - (pio2_lo-2*c) - (0.5*pio2_hi-2*f));
+	}
+	if (hx >> 31)
+		return -x;
+	return x;
+}
libc/musl/src/math/asinf.c
@@ -0,0 +1,61 @@
+/* origin: FreeBSD /usr/src/lib/msun/src/e_asinf.c */
+/*
+ * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.
+ */
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunPro, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+#include "libm.h"
+
+static const double
+pio2 = 1.570796326794896558e+00;
+
+static const float
+/* coefficients for R(x^2) */
+pS0 =  1.6666586697e-01,
+pS1 = -4.2743422091e-02,
+pS2 = -8.6563630030e-03,
+qS1 = -7.0662963390e-01;
+
+static float R(float z)
+{
+	float_t p, q;
+	p = z*(pS0+z*(pS1+z*pS2));
+	q = 1.0f+z*qS1;
+	return p/q;
+}
+
+float asinf(float x)
+{
+	double s;
+	float z;
+	uint32_t hx,ix;
+
+	GET_FLOAT_WORD(hx, x);
+	ix = hx & 0x7fffffff;
+	if (ix >= 0x3f800000) {  /* |x| >= 1 */
+		if (ix == 0x3f800000)  /* |x| == 1 */
+			return x*pio2 + 0x1p-120f;  /* asin(+-1) = +-pi/2 with inexact */
+		return 0/(x-x);  /* asin(|x|>1) is NaN */
+	}
+	if (ix < 0x3f000000) {  /* |x| < 0.5 */
+		/* if 0x1p-126 <= |x| < 0x1p-12, avoid raising underflow */
+		if (ix < 0x39800000 && ix >= 0x00800000)
+			return x;
+		return x + x*R(x*x);
+	}
+	/* 1 > |x| >= 0.5 */
+	z = (1 - fabsf(x))*0.5f;
+	s = sqrt(z);
+	x = pio2 - 2*(s+s*R(z));
+	if (hx >> 31)
+		return -x;
+	return x;
+}
libc/musl/src/math/asinh.c
@@ -0,0 +1,28 @@
+#include "libm.h"
+
+/* asinh(x) = sign(x)*log(|x|+sqrt(x*x+1)) ~= x - x^3/6 + o(x^5) */
+double asinh(double x)
+{
+	union {double f; uint64_t i;} u = {.f = x};
+	unsigned e = u.i >> 52 & 0x7ff;
+	unsigned s = u.i >> 63;
+
+	/* |x| */
+	u.i &= (uint64_t)-1/2;
+	x = u.f;
+
+	if (e >= 0x3ff + 26) {
+		/* |x| >= 0x1p26 or inf or nan */
+		x = log(x) + 0.693147180559945309417232121458176568;
+	} else if (e >= 0x3ff + 1) {
+		/* |x| >= 2 */
+		x = log(2*x + 1/(sqrt(x*x+1)+x));
+	} else if (e >= 0x3ff - 26) {
+		/* |x| >= 0x1p-26, up to 1.6ulp error in [0.125,0.5] */
+		x = log1p(x + x*x/(sqrt(x*x+1)+1));
+	} else {
+		/* |x| < 0x1p-26, raise inexact if x != 0 */
+		FORCE_EVAL(x + 0x1p120f);
+	}
+	return s ? -x : x;
+}
libc/musl/src/math/asinhf.c
@@ -0,0 +1,28 @@
+#include "libm.h"
+
+/* asinh(x) = sign(x)*log(|x|+sqrt(x*x+1)) ~= x - x^3/6 + o(x^5) */
+float asinhf(float x)
+{
+	union {float f; uint32_t i;} u = {.f = x};
+	uint32_t i = u.i & 0x7fffffff;
+	unsigned s = u.i >> 31;
+
+	/* |x| */
+	u.i = i;
+	x = u.f;
+
+	if (i >= 0x3f800000 + (12<<23)) {
+		/* |x| >= 0x1p12 or inf or nan */
+		x = logf(x) + 0.693147180559945309417232121458176568f;
+	} else if (i >= 0x3f800000 + (1<<23)) {
+		/* |x| >= 2 */
+		x = logf(2*x + 1/(sqrtf(x*x+1)+x));
+	} else if (i >= 0x3f800000 - (12<<23)) {
+		/* |x| >= 0x1p-12, up to 1.6ulp error in [0.125,0.5] */
+		x = log1pf(x + x*x/(sqrtf(x*x+1)+1));
+	} else {
+		/* |x| < 0x1p-12, raise inexact if x!=0 */
+		FORCE_EVAL(x + 0x1p120f);
+	}
+	return s ? -x : x;
+}
libc/musl/src/math/asinhl.c
@@ -0,0 +1,41 @@
+#include "libm.h"
+
+#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024
+long double asinhl(long double x)
+{
+	return asinh(x);
+}
+#elif LDBL_MANT_DIG == 64 && LDBL_MAX_EXP == 16384
+/* asinh(x) = sign(x)*log(|x|+sqrt(x*x+1)) ~= x - x^3/6 + o(x^5) */
+long double asinhl(long double x)
+{
+	union ldshape u = {x};
+	unsigned e = u.i.se & 0x7fff;
+	unsigned s = u.i.se >> 15;
+
+	/* |x| */
+	u.i.se = e;
+	x = u.f;
+
+	if (e >= 0x3fff + 32) {
+		/* |x| >= 0x1p32 or inf or nan */
+		x = logl(x) + 0.693147180559945309417232121458176568L;
+	} else if (e >= 0x3fff + 1) {
+		/* |x| >= 2 */
+		x = logl(2*x + 1/(sqrtl(x*x+1)+x));
+	} else if (e >= 0x3fff - 32) {
+		/* |x| >= 0x1p-32 */
+		x = log1pl(x + x*x/(sqrtl(x*x+1)+1));
+	} else {
+		/* |x| < 0x1p-32, raise inexact if x!=0 */
+		FORCE_EVAL(x + 0x1p120f);
+	}
+	return s ? -x : x;
+}
+#elif LDBL_MANT_DIG == 113 && LDBL_MAX_EXP == 16384
+// TODO: broken implementation to make things compile
+long double asinhl(long double x)
+{
+	return asinh(x);
+}
+#endif
libc/musl/src/math/asinl.c
@@ -0,0 +1,71 @@
+/* origin: FreeBSD /usr/src/lib/msun/src/e_asinl.c */
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunSoft, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+/*
+ * See comments in asin.c.
+ * Converted to long double by David Schultz <das@FreeBSD.ORG>.
+ */
+
+#include "libm.h"
+
+#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024
+long double asinl(long double x)
+{
+	return asin(x);
+}
+#elif (LDBL_MANT_DIG == 64 || LDBL_MANT_DIG == 113) && LDBL_MAX_EXP == 16384
+#include "__invtrigl.h"
+#if LDBL_MANT_DIG == 64
+#define CLOSETO1(u) (u.i.m>>56 >= 0xf7)
+#define CLEARBOTTOM(u) (u.i.m &= -1ULL << 32)
+#elif LDBL_MANT_DIG == 113
+#define CLOSETO1(u) (u.i.top >= 0xee00)
+#define CLEARBOTTOM(u) (u.i.lo = 0)
+#endif
+
+long double asinl(long double x)
+{
+	union ldshape u = {x};
+	long double z, r, s;
+	uint16_t e = u.i.se & 0x7fff;
+	int sign = u.i.se >> 15;
+
+	if (e >= 0x3fff) {   /* |x| >= 1 or nan */
+		/* asin(+-1)=+-pi/2 with inexact */
+		if (x == 1 || x == -1)
+			return x*pio2_hi + 0x1p-120f;
+		return 0/(x-x);
+	}
+	if (e < 0x3fff - 1) {  /* |x| < 0.5 */
+		if (e < 0x3fff - (LDBL_MANT_DIG+1)/2) {
+			/* return x with inexact if x!=0 */
+			FORCE_EVAL(x + 0x1p120f);
+			return x;
+		}
+		return x + x*__invtrigl_R(x*x);
+	}
+	/* 1 > |x| >= 0.5 */
+	z = (1.0 - fabsl(x))*0.5;
+	s = sqrtl(z);
+	r = __invtrigl_R(z);
+	if (CLOSETO1(u)) {
+		x = pio2_hi - (2*(s+s*r)-pio2_lo);
+	} else {
+		long double f, c;
+		u.f = s;
+		CLEARBOTTOM(u);
+		f = u.f;
+		c = (z - f*f)/(s + f);
+		x = 0.5*pio2_hi-(2*s*r - (pio2_lo-2*c) - (0.5*pio2_hi-2*f));
+	}
+	return sign ? -x : x;
+}
+#endif
libc/musl/src/math/atan.c
@@ -0,0 +1,116 @@
+/* origin: FreeBSD /usr/src/lib/msun/src/s_atan.c */
+/*
+ * ====================================================
+ * 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.
+ * ====================================================
+ */
+/* atan(x)
+ * Method
+ *   1. Reduce x to positive by atan(x) = -atan(-x).
+ *   2. According to the integer k=4t+0.25 chopped, t=x, the argument
+ *      is further reduced to one of the following intervals and the
+ *      arctangent of t is evaluated by the corresponding formula:
+ *
+ *      [0,7/16]      atan(x) = t-t^3*(a1+t^2*(a2+...(a10+t^2*a11)...)
+ *      [7/16,11/16]  atan(x) = atan(1/2) + atan( (t-0.5)/(1+t/2) )
+ *      [11/16.19/16] atan(x) = atan( 1 ) + atan( (t-1)/(1+t) )
+ *      [19/16,39/16] atan(x) = atan(3/2) + atan( (t-1.5)/(1+1.5t) )
+ *      [39/16,INF]   atan(x) = atan(INF) + atan( -1/t )
+ *
+ * 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 "libm.h"
+
+static const double atanhi[] = {
+  4.63647609000806093515e-01, /* atan(0.5)hi 0x3FDDAC67, 0x0561BB4F */
+  7.85398163397448278999e-01, /* atan(1.0)hi 0x3FE921FB, 0x54442D18 */
+  9.82793723247329054082e-01, /* atan(1.5)hi 0x3FEF730B, 0xD281F69B */
+  1.57079632679489655800e+00, /* atan(inf)hi 0x3FF921FB, 0x54442D18 */
+};
+
+static const double atanlo[] = {
+  2.26987774529616870924e-17, /* atan(0.5)lo 0x3C7A2B7F, 0x222F65E2 */
+  3.06161699786838301793e-17, /* atan(1.0)lo 0x3C81A626, 0x33145C07 */
+  1.39033110312309984516e-17, /* atan(1.5)lo 0x3C700788, 0x7AF0CBBD */
+  6.12323399573676603587e-17, /* atan(inf)lo 0x3C91A626, 0x33145C07 */
+};
+
+static const double aT[] = {
+  3.33333333333329318027e-01, /* 0x3FD55555, 0x5555550D */
+ -1.99999999998764832476e-01, /* 0xBFC99999, 0x9998EBC4 */
+  1.42857142725034663711e-01, /* 0x3FC24924, 0x920083FF */
+ -1.11111104054623557880e-01, /* 0xBFBC71C6, 0xFE231671 */
+  9.09088713343650656196e-02, /* 0x3FB745CD, 0xC54C206E */
+ -7.69187620504482999495e-02, /* 0xBFB3B0F2, 0xAF749A6D */
+  6.66107313738753120669e-02, /* 0x3FB10D66, 0xA0D03D51 */
+ -5.83357013379057348645e-02, /* 0xBFADDE2D, 0x52DEFD9A */
+  4.97687799461593236017e-02, /* 0x3FA97B4B, 0x24760DEB */
+ -3.65315727442169155270e-02, /* 0xBFA2B444, 0x2C6A6C2F */
+  1.62858201153657823623e-02, /* 0x3F90AD3A, 0xE322DA11 */
+};
+
+double atan(double x)
+{
+	double_t w,s1,s2,z;
+	uint32_t ix,sign;
+	int id;
+
+	GET_HIGH_WORD(ix, x);
+	sign = ix >> 31;
+	ix &= 0x7fffffff;
+	if (ix >= 0x44100000) {   /* if |x| >= 2^66 */
+		if (isnan(x))
+			return x;
+		z = atanhi[3] + 0x1p-120f;
+		return sign ? -z : z;
+	}
+	if (ix < 0x3fdc0000) {    /* |x| < 0.4375 */
+		if (ix < 0x3e400000) {  /* |x| < 2^-27 */
+			if (ix < 0x00100000)
+				/* raise underflow for subnormal x */
+				FORCE_EVAL((float)x);
+			return x;
+		}
+		id = -1;
+	} else {
+		x = fabs(x);
+		if (ix < 0x3ff30000) {  /* |x| < 1.1875 */
+			if (ix < 0x3fe60000) {  /*  7/16 <= |x| < 11/16 */
+				id = 0;
+				x = (2.0*x-1.0)/(2.0+x);
+			} else {                /* 11/16 <= |x| < 19/16 */
+				id = 1;
+				x = (x-1.0)/(x+1.0);
+			}
+		} else {
+			if (ix < 0x40038000) {  /* |x| < 2.4375 */
+				id = 2;
+				x = (x-1.5)/(1.0+1.5*x);
+			} else {                /* 2.4375 <= |x| < 2^66 */
+				id = 3;
+				x = -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);
+	z = atanhi[id] - (x*(s1+s2) - atanlo[id] - x);
+	return sign ? -z : z;
+}
libc/musl/src/math/atan2.c
@@ -0,0 +1,107 @@
+/* origin: FreeBSD /usr/src/lib/msun/src/e_atan2.c */
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunSoft, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ *
+ */
+/* atan2(y,x)
+ * Method :
+ *      1. Reduce y to positive by atan2(y,x)=-atan2(-y,x).
+ *      2. Reduce x to positive by (if x and y are unexceptional):
+ *              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 "libm.h"
+
+static const double
+pi     = 3.1415926535897931160E+00, /* 0x400921FB, 0x54442D18 */
+pi_lo  = 1.2246467991473531772E-16; /* 0x3CA1A626, 0x33145C07 */
+
+double atan2(double y, double x)
+{
+	double z;
+	uint32_t m,lx,ly,ix,iy;
+
+	if (isnan(x) || isnan(y))
+		return x+y;
+	EXTRACT_WORDS(ix, lx, x);
+	EXTRACT_WORDS(iy, ly, y);
+	if ((ix-0x3ff00000 | lx) == 0)  /* x = 1.0 */
+		return atan(y);
+	m = ((iy>>31)&1) | ((ix>>30)&2);  /* 2*sign(x)+sign(y) */
+	ix = ix & 0x7fffffff;
+	iy = iy & 0x7fffffff;
+
+	/* when y = 0 */
+	if ((iy|ly) == 0) {
+		switch(m) {
+		case 0:
+		case 1: return y;   /* atan(+-0,+anything)=+-0 */
+		case 2: return  pi; /* atan(+0,-anything) = pi */
+		case 3: return -pi; /* atan(-0,-anything) =-pi */
+		}
+	}
+	/* when x = 0 */
+	if ((ix|lx) == 0)
+		return m&1 ? -pi/2 : pi/2;
+	/* when x is INF */
+	if (ix == 0x7ff00000) {
+		if (iy == 0x7ff00000) {
+			switch(m) {
+			case 0: return  pi/4;   /* atan(+INF,+INF) */
+			case 1: return -pi/4;   /* atan(-INF,+INF) */
+			case 2: return  3*pi/4; /* atan(+INF,-INF) */
+			case 3: return -3*pi/4; /* atan(-INF,-INF) */
+			}
+		} else {
+			switch(m) {
+			case 0: return  0.0; /* atan(+...,+INF) */
+			case 1: return -0.0; /* atan(-...,+INF) */
+			case 2: return  pi;  /* atan(+...,-INF) */
+			case 3: return -pi;  /* atan(-...,-INF) */
+			}
+		}
+	}
+	/* |y/x| > 0x1p64 */
+	if (ix+(64<<20) < iy || iy == 0x7ff00000)
+		return m&1 ? -pi/2 : pi/2;
+
+	/* z = atan(|y/x|) without spurious underflow */
+	if ((m&2) && iy+(64<<20) < ix)  /* |y/x| < 0x1p-64, x<0 */
+		z = 0;
+	else
+		z = atan(fabs(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(-,-) */
+	}
+}
libc/musl/src/math/atan2f.c
@@ -0,0 +1,83 @@
+/* origin: FreeBSD /usr/src/lib/msun/src/e_atan2f.c */
+/*
+ * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.
+ */
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunPro, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+
+#include "libm.h"
+
+static const float
+pi     = 3.1415927410e+00, /* 0x40490fdb */
+pi_lo  = -8.7422776573e-08; /* 0xb3bbbd2e */
+
+float atan2f(float y, float x)
+{
+	float z;
+	uint32_t m,ix,iy;
+
+	if (isnan(x) || isnan(y))
+		return x+y;
+	GET_FLOAT_WORD(ix, x);
+	GET_FLOAT_WORD(iy, y);
+	if (ix == 0x3f800000)  /* x=1.0 */
+		return atanf(y);
+	m = ((iy>>31)&1) | ((ix>>30)&2);  /* 2*sign(x)+sign(y) */
+	ix &= 0x7fffffff;
+	iy &= 0x7fffffff;
+
+	/* when y = 0 */
+	if (iy == 0) {
+		switch (m) {
+		case 0:
+		case 1: return y;   /* atan(+-0,+anything)=+-0 */
+		case 2: return  pi; /* atan(+0,-anything) = pi */
+		case 3: return -pi; /* atan(-0,-anything) =-pi */
+		}
+	}
+	/* when x = 0 */
+	if (ix == 0)
+		return m&1 ? -pi/2 : pi/2;
+	/* when x is INF */
+	if (ix == 0x7f800000) {
+		if (iy == 0x7f800000) {
+			switch (m) {
+			case 0: return  pi/4; /* atan(+INF,+INF) */
+			case 1: return -pi/4; /* atan(-INF,+INF) */
+			case 2: return 3*pi/4;  /*atan(+INF,-INF)*/
+			case 3: return -3*pi/4; /*atan(-INF,-INF)*/
+			}
+		} else {
+			switch (m) {
+			case 0: return  0.0f;    /* atan(+...,+INF) */
+			case 1: return -0.0f;    /* atan(-...,+INF) */
+			case 2: return  pi; /* atan(+...,-INF) */
+			case 3: return -pi; /* atan(-...,-INF) */
+			}
+		}
+	}
+	/* |y/x| > 0x1p26 */
+	if (ix+(26<<23) < iy || iy == 0x7f800000)
+		return m&1 ? -pi/2 : pi/2;
+
+	/* z = atan(|y/x|) with correct underflow */
+	if ((m&2) && iy+(26<<23) < ix)  /*|y/x| < 0x1p-26, x < 0 */
+		z = 0.0;
+	else
+		z = atanf(fabsf(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(-,-) */
+	}
+}
libc/musl/src/math/atan2l.c
@@ -0,0 +1,85 @@
+/* origin: FreeBSD /usr/src/lib/msun/src/e_atan2l.c */
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunSoft, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ *
+ */
+/*
+ * See comments in atan2.c.
+ * Converted to long double by David Schultz <das@FreeBSD.ORG>.
+ */
+
+#include "libm.h"
+
+#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024
+long double atan2l(long double y, long double x)
+{
+	return atan2(y, x);
+}
+#elif (LDBL_MANT_DIG == 64 || LDBL_MANT_DIG == 113) && LDBL_MAX_EXP == 16384
+#include "__invtrigl.h"
+
+long double atan2l(long double y, long double x)
+{
+	union ldshape ux, uy;
+	long double z;
+	int m, ex, ey;
+
+	if (isnan(x) || isnan(y))
+		return x+y;
+	if (x == 1)
+		return atanl(y);
+	ux.f = x;
+	uy.f = y;
+	ex = ux.i.se & 0x7fff;
+	ey = uy.i.se & 0x7fff;
+	m = 2*(ux.i.se>>15) | uy.i.se>>15;
+	if (y == 0) {
+		switch(m) {
+		case 0:
+		case 1: return y;           /* atan(+-0,+anything)=+-0 */
+		case 2: return  2*pio2_hi;  /* atan(+0,-anything) = pi */
+		case 3: return -2*pio2_hi;  /* atan(-0,-anything) =-pi */
+		}
+	}
+	if (x == 0)
+		return m&1 ? -pio2_hi : pio2_hi;
+	if (ex == 0x7fff) {
+		if (ey == 0x7fff) {
+			switch(m) {
+			case 0: return  pio2_hi/2;   /* atan(+INF,+INF) */
+			case 1: return -pio2_hi/2;   /* atan(-INF,+INF) */
+			case 2: return  1.5*pio2_hi; /* atan(+INF,-INF) */
+			case 3: return -1.5*pio2_hi; /* atan(-INF,-INF) */
+			}
+		} else {
+			switch(m) {
+			case 0: return  0.0;        /* atan(+...,+INF) */
+			case 1: return -0.0;        /* atan(-...,+INF) */
+			case 2: return  2*pio2_hi;  /* atan(+...,-INF) */
+			case 3: return -2*pio2_hi;  /* atan(-...,-INF) */
+			}
+		}
+	}
+	if (ex+120 < ey || ey == 0x7fff)
+		return m&1 ? -pio2_hi : pio2_hi;
+	/* z = atan(|y/x|) without spurious underflow */
+	if ((m&2) && ey+120 < ex)  /* |y/x| < 0x1p-120, x<0 */
+		z = 0.0;
+	else
+		z = atanl(fabsl(y/x));
+	switch (m) {
+	case 0: return z;               /* atan(+,+) */
+	case 1: return -z;              /* atan(-,+) */
+	case 2: return 2*pio2_hi-(z-2*pio2_lo); /* atan(+,-) */
+	default: /* case 3 */
+		return (z-2*pio2_lo)-2*pio2_hi; /* atan(-,-) */
+	}
+}
+#endif
libc/musl/src/math/atanf.c
@@ -0,0 +1,94 @@
+/* origin: FreeBSD /usr/src/lib/msun/src/s_atanf.c */
+/*
+ * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.
+ */
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunPro, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+
+
+#include "libm.h"
+
+static const float atanhi[] = {
+  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 */
+};
+
+static const float atanlo[] = {
+  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 */
+};
+
+static const float aT[] = {
+  3.3333328366e-01,
+ -1.9999158382e-01,
+  1.4253635705e-01,
+ -1.0648017377e-01,
+  6.1687607318e-02,
+};
+
+float atanf(float x)
+{
+	float_t w,s1,s2,z;
+	uint32_t ix,sign;
+	int id;
+
+	GET_FLOAT_WORD(ix, x);
+	sign = ix>>31;
+	ix &= 0x7fffffff;
+	if (ix >= 0x4c800000) {  /* if |x| >= 2**26 */
+		if (isnan(x))
+			return x;
+		z = atanhi[3] + 0x1p-120f;
+		return sign ? -z : z;
+	}
+	if (ix < 0x3ee00000) {   /* |x| < 0.4375 */
+		if (ix < 0x39800000) {  /* |x| < 2**-12 */
+			if (ix < 0x00800000)
+				/* raise underflow for subnormal x */
+				FORCE_EVAL(x*x);
+			return x;
+		}
+		id = -1;
+	} else {
+		x = fabsf(x);
+		if (ix < 0x3f980000) {  /* |x| < 1.1875 */
+			if (ix < 0x3f300000) {  /*  7/16 <= |x| < 11/16 */
+				id = 0;
+				x = (2.0f*x - 1.0f)/(2.0f + x);
+			} else {                /* 11/16 <= |x| < 19/16 */
+				id = 1;
+				x = (x - 1.0f)/(x + 1.0f);
+			}
+		} else {
+			if (ix < 0x401c0000) {  /* |x| < 2.4375 */
+				id = 2;
+				x = (x - 1.5f)/(1.0f + 1.5f*x);
+			} else {                /* 2.4375 <= |x| < 2**26 */
+				id = 3;
+				x = -1.0f/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]));
+	s2 = w*(aT[1]+w*aT[3]);
+	if (id < 0)
+		return x - x*(s1+s2);
+	z = atanhi[id] - ((x*(s1+s2) - atanlo[id]) - x);
+	return sign ? -z : z;
+}
libc/musl/src/math/atanh.c
@@ -0,0 +1,29 @@
+#include "libm.h"
+
+/* atanh(x) = log((1+x)/(1-x))/2 = log1p(2x/(1-x))/2 ~= x + x^3/3 + o(x^5) */
+double atanh(double x)
+{
+	union {double f; uint64_t i;} u = {.f = x};
+	unsigned e = u.i >> 52 & 0x7ff;
+	unsigned s = u.i >> 63;
+	double_t y;
+
+	/* |x| */
+	u.i &= (uint64_t)-1/2;
+	y = u.f;
+
+	if (e < 0x3ff - 1) {
+		if (e < 0x3ff - 32) {
+			/* handle underflow */
+			if (e == 0)
+				FORCE_EVAL((float)y);
+		} else {
+			/* |x| < 0.5, up to 1.7ulp error */
+			y = 0.5*log1p(2*y + 2*y*y/(1-y));
+		}
+	} else {
+		/* avoid overflow */
+		y = 0.5*log1p(2*(y/(1-y)));
+	}
+	return s ? -y : y;
+}
libc/musl/src/math/atanhf.c
@@ -0,0 +1,28 @@
+#include "libm.h"
+
+/* atanh(x) = log((1+x)/(1-x))/2 = log1p(2x/(1-x))/2 ~= x + x^3/3 + o(x^5) */
+float atanhf(float x)
+{
+	union {float f; uint32_t i;} u = {.f = x};
+	unsigned s = u.i >> 31;
+	float_t y;
+
+	/* |x| */
+	u.i &= 0x7fffffff;
+	y = u.f;
+
+	if (u.i < 0x3f800000 - (1<<23)) {
+		if (u.i < 0x3f800000 - (32<<23)) {
+			/* handle underflow */
+			if (u.i < (1<<23))
+				FORCE_EVAL((float)(y*y));
+		} else {
+			/* |x| < 0.5, up to 1.7ulp error */
+			y = 0.5f*log1pf(2*y + 2*y*y/(1-y));
+		}
+	} else {
+		/* avoid overflow */
+		y = 0.5f*log1pf(2*(y/(1-y)));
+	}
+	return s ? -y : y;
+}
libc/musl/src/math/atanhl.c
@@ -0,0 +1,35 @@
+#include "libm.h"
+
+#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024
+long double atanhl(long double x)
+{
+	return atanh(x);
+}
+#elif (LDBL_MANT_DIG == 64 || LDBL_MANT_DIG == 113) && LDBL_MAX_EXP == 16384
+/* atanh(x) = log((1+x)/(1-x))/2 = log1p(2x/(1-x))/2 ~= x + x^3/3 + o(x^5) */
+long double atanhl(long double x)
+{
+	union ldshape u = {x};
+	unsigned e = u.i.se & 0x7fff;
+	unsigned s = u.i.se >> 15;
+
+	/* |x| */
+	u.i.se = e;
+	x = u.f;
+
+	if (e < 0x3ff - 1) {
+		if (e < 0x3ff - LDBL_MANT_DIG/2) {
+			/* handle underflow */
+			if (e == 0)
+				FORCE_EVAL((float)x);
+		} else {
+			/* |x| < 0.5, up to 1.7ulp error */
+			x = 0.5*log1pl(2*x + 2*x*x/(1-x));
+		}
+	} else {
+		/* avoid overflow */
+		x = 0.5*log1pl(2*(x/(1-x)));
+	}
+	return s ? -x : x;
+}
+#endif
libc/musl/src/math/atanl.c
@@ -0,0 +1,184 @@
+/* origin: FreeBSD /usr/src/lib/msun/src/s_atanl.c */
+/*
+ * ====================================================
+ * 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.
+ * ====================================================
+ */
+/*
+ * See comments in atan.c.
+ * Converted to long double by David Schultz <das@FreeBSD.ORG>.
+ */
+
+#include "libm.h"
+
+#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024
+long double atanl(long double x)
+{
+	return atan(x);
+}
+#elif (LDBL_MANT_DIG == 64 || LDBL_MANT_DIG == 113) && LDBL_MAX_EXP == 16384
+
+#if LDBL_MANT_DIG == 64
+#define EXPMAN(u) ((u.i.se & 0x7fff)<<8 | (u.i.m>>55 & 0xff))
+
+static const long double atanhi[] = {
+	 4.63647609000806116202e-01L,
+	 7.85398163397448309628e-01L,
+	 9.82793723247329067960e-01L,
+	 1.57079632679489661926e+00L,
+};
+
+static const long double atanlo[] = {
+	 1.18469937025062860669e-20L,
+	-1.25413940316708300586e-20L,
+	 2.55232234165405176172e-20L,
+	-2.50827880633416601173e-20L,
+};
+
+static const long double aT[] = {
+	 3.33333333333333333017e-01L,
+	-1.99999999999999632011e-01L,
+	 1.42857142857046531280e-01L,
+	-1.11111111100562372733e-01L,
+	 9.09090902935647302252e-02L,
+	-7.69230552476207730353e-02L,
+	 6.66661718042406260546e-02L,
+	-5.88158892835030888692e-02L,
+	 5.25499891539726639379e-02L,
+	-4.70119845393155721494e-02L,
+	 4.03539201366454414072e-02L,
+	-2.91303858419364158725e-02L,
+	 1.24822046299269234080e-02L,
+};
+
+static long double T_even(long double x)
+{
+	return aT[0] + x * (aT[2] + x * (aT[4] + x * (aT[6] +
+		x * (aT[8] + x * (aT[10] + x * aT[12])))));
+}
+
+static long double T_odd(long double x)
+{
+	return aT[1] + x * (aT[3] + x * (aT[5] + x * (aT[7] +
+		x * (aT[9] + x * aT[11]))));
+}
+#elif LDBL_MANT_DIG == 113
+#define EXPMAN(u) ((u.i.se & 0x7fff)<<8 | u.i.top>>8)
+
+const long double atanhi[] = {
+	 4.63647609000806116214256231461214397e-01L,
+	 7.85398163397448309615660845819875699e-01L,
+	 9.82793723247329067985710611014666038e-01L,
+	 1.57079632679489661923132169163975140e+00L,
+};
+
+const long double atanlo[] = {
+	 4.89509642257333492668618435220297706e-36L,
+	 2.16795253253094525619926100651083806e-35L,
+	-2.31288434538183565909319952098066272e-35L,
+	 4.33590506506189051239852201302167613e-35L,
+};
+
+const long double aT[] = {
+	 3.33333333333333333333333333333333125e-01L,
+	-1.99999999999999999999999999999180430e-01L,
+	 1.42857142857142857142857142125269827e-01L,
+	-1.11111111111111111111110834490810169e-01L,
+	 9.09090909090909090908522355708623681e-02L,
+	-7.69230769230769230696553844935357021e-02L,
+	 6.66666666666666660390096773046256096e-02L,
+	-5.88235294117646671706582985209643694e-02L,
+	 5.26315789473666478515847092020327506e-02L,
+	-4.76190476189855517021024424991436144e-02L,
+	 4.34782608678695085948531993458097026e-02L,
+	-3.99999999632663469330634215991142368e-02L,
+	 3.70370363987423702891250829918659723e-02L,
+	-3.44827496515048090726669907612335954e-02L,
+	 3.22579620681420149871973710852268528e-02L,
+	-3.03020767654269261041647570626778067e-02L,
+	 2.85641979882534783223403715930946138e-02L,
+	-2.69824879726738568189929461383741323e-02L,
+	 2.54194698498808542954187110873675769e-02L,
+	-2.35083879708189059926183138130183215e-02L,
+	 2.04832358998165364349957325067131428e-02L,
+	-1.54489555488544397858507248612362957e-02L,
+	 8.64492360989278761493037861575248038e-03L,
+	-2.58521121597609872727919154569765469e-03L,
+};
+
+static long double T_even(long double x)
+{
+	return (aT[0] + x * (aT[2] + x * (aT[4] + x * (aT[6] + x * (aT[8] +
+		x * (aT[10] + x * (aT[12] + x * (aT[14] + x * (aT[16] +
+		x * (aT[18] + x * (aT[20] + x * aT[22])))))))))));
+}
+
+static long double T_odd(long double x)
+{
+	return (aT[1] + x * (aT[3] + x * (aT[5] + x * (aT[7] + x * (aT[9] +
+		x * (aT[11] + x * (aT[13] + x * (aT[15] + x * (aT[17] +
+		x * (aT[19] + x * (aT[21] + x * aT[23])))))))))));
+}
+#endif
+
+long double atanl(long double x)
+{
+	union ldshape u = {x};
+	long double w, s1, s2, z;
+	int id;
+	unsigned e = u.i.se & 0x7fff;
+	unsigned sign = u.i.se >> 15;
+	unsigned expman;
+
+	if (e >= 0x3fff + LDBL_MANT_DIG + 1) { /* if |x| is large, atan(x)~=pi/2 */
+		if (isnan(x))
+			return x;
+		return sign ? -atanhi[3] : atanhi[3];
+	}
+	/* Extract the exponent and the first few bits of the mantissa. */
+	expman = EXPMAN(u);
+	if (expman < ((0x3fff - 2) << 8) + 0xc0) {  /* |x| < 0.4375 */
+		if (e < 0x3fff - (LDBL_MANT_DIG+1)/2) {   /* if |x| is small, atanl(x)~=x */
+			/* raise underflow if subnormal */
+			if (e == 0)
+				FORCE_EVAL((float)x);
+			return x;
+		}
+		id = -1;
+	} else {
+		x = fabsl(x);
+		if (expman < (0x3fff << 8) + 0x30) {  /* |x| < 1.1875 */
+			if (expman < ((0x3fff - 1) << 8) + 0x60) { /*  7/16 <= |x| < 11/16 */
+				id = 0;
+				x = (2.0*x-1.0)/(2.0+x);
+			} else {                                 /* 11/16 <= |x| < 19/16 */
+				id = 1;
+				x = (x-1.0)/(x+1.0);
+			}
+		} else {
+			if (expman < ((0x3fff + 1) << 8) + 0x38) { /* |x| < 2.4375 */
+				id = 2;
+				x = (x-1.5)/(1.0+1.5*x);
+			} else {                                 /* 2.4375 <= |x| */
+				id = 3;
+				x = -1.0/x;
+			}
+		}
+	}
+	/* end of argument reduction */
+	z = x*x;
+	w = z*z;
+	/* break sum aT[i]z**(i+1) into odd and even poly */
+	s1 = z*T_even(w);
+	s2 = w*T_odd(w);
+	if (id < 0)
+		return x - x*(s1+s2);
+	z = atanhi[id] - ((x*(s1+s2) - atanlo[id]) - x);
+	return sign ? -z : z;
+}
+#endif
libc/musl/src/math/cbrt.c
@@ -0,0 +1,103 @@
+/* origin: FreeBSD /usr/src/lib/msun/src/s_cbrt.c */
+/*
+ * ====================================================
+ * 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.
+ * ====================================================
+ *
+ * Optimized by Bruce D. Evans.
+ */
+/* cbrt(x)
+ * Return cube root of x
+ */
+
+#include <math.h>
+#include <stdint.h>
+
+static const uint32_t
+B1 = 715094163, /* B1 = (1023-1023/3-0.03306235651)*2**20 */
+B2 = 696219795; /* B2 = (1023-1023/3-54/3-0.03306235651)*2**20 */
+
+/* |1/cbrt(x) - p(x)| < 2**-23.5 (~[-7.93e-8, 7.929e-8]). */
+static const double
+P0 =  1.87595182427177009643,  /* 0x3ffe03e6, 0x0f61e692 */
+P1 = -1.88497979543377169875,  /* 0xbffe28e0, 0x92f02420 */
+P2 =  1.621429720105354466140, /* 0x3ff9f160, 0x4a49d6c2 */
+P3 = -0.758397934778766047437, /* 0xbfe844cb, 0xbee751d9 */
+P4 =  0.145996192886612446982; /* 0x3fc2b000, 0xd4e4edd7 */
+
+double cbrt(double x)
+{
+	union {double f; uint64_t i;} u = {x};
+	double_t r,s,t,w;
+	uint32_t hx = u.i>>32 & 0x7fffffff;
+
+	if (hx >= 0x7ff00000)  /* cbrt(NaN,INF) is itself */
+		return x+x;
+
+	/*
+	 * Rough cbrt to 5 bits:
+	 *    cbrt(2**e*(1+m) ~= 2**(e/3)*(1+(e%3+m)/3)
+	 * where e is integral and >= 0, m is real and in [0, 1), and "/" and
+	 * "%" are integer division and modulus with rounding towards minus
+	 * infinity.  The RHS is always >= the LHS and has a maximum relative
+	 * error of about 1 in 16.  Adding a bias of -0.03306235651 to the
+	 * (e%3+m)/3 term reduces the error to about 1 in 32. With the IEEE
+	 * floating point representation, for finite positive normal values,
+	 * ordinary integer divison of the value in bits magically gives
+	 * almost exactly the RHS of the above provided we first subtract the
+	 * exponent bias (1023 for doubles) and later add it back.  We do the
+	 * subtraction virtually to keep e >= 0 so that ordinary integer
+	 * division rounds towards minus infinity; this is also efficient.
+	 */
+	if (hx < 0x00100000) { /* zero or subnormal? */
+		u.f = x*0x1p54;
+		hx = u.i>>32 & 0x7fffffff;
+		if (hx == 0)
+			return x;  /* cbrt(0) is itself */
+		hx = hx/3 + B2;
+	} else
+		hx = hx/3 + B1;
+	u.i &= 1ULL<<63;
+	u.i |= (uint64_t)hx << 32;
+	t = u.f;
+
+	/*
+	 * New cbrt to 23 bits:
+	 *    cbrt(x) = t*cbrt(x/t**3) ~= t*P(t**3/x)
+	 * where P(r) is a polynomial of degree 4 that approximates 1/cbrt(r)
+	 * to within 2**-23.5 when |r - 1| < 1/10.  The rough approximation
+	 * has produced t such than |t/cbrt(x) - 1| ~< 1/32, and cubing this
+	 * gives us bounds for r = t**3/x.
+	 *
+	 * Try to optimize for parallel evaluation as in __tanf.c.
+	 */
+	r = (t*t)*(t/x);
+	t = t*((P0+r*(P1+r*P2))+((r*r)*r)*(P3+r*P4));
+
+	/*
+	 * Round t away from zero to 23 bits (sloppily except for ensuring that
+	 * the result is larger in magnitude than cbrt(x) but not much more than
+	 * 2 23-bit ulps larger).  With rounding towards zero, the error bound
+	 * would be ~5/6 instead of ~4/6.  With a maximum error of 2 23-bit ulps
+	 * in the rounded t, the infinite-precision error in the Newton
+	 * approximation barely affects third digit in the final error
+	 * 0.667; the error in the rounded t can be up to about 3 23-bit ulps
+	 * before the final error is larger than 0.667 ulps.
+	 */
+	u.f = t;
+	u.i = (u.i + 0x80000000) & 0xffffffffc0000000ULL;
+	t = u.f;
+
+	/* one step Newton iteration to 53 bits with error < 0.667 ulps */
+	s = t*t;         /* t*t is exact */
+	r = x/s;         /* error <= 0.5 ulps; |r| < |t| */
+	w = t+t;         /* t+t is exact */
+	r = (r-t)/(w+r); /* r-t is exact; w+r ~= 3*t */
+	t = t+t*r;       /* error <= 0.5 + 0.5/3 + epsilon */
+	return t;
+}
libc/musl/src/math/cbrtf.c
@@ -0,0 +1,66 @@
+/* origin: FreeBSD /usr/src/lib/msun/src/s_cbrtf.c */
+/*
+ * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.
+ * Debugged and optimized by Bruce D. Evans.
+ */
+/*
+ * ====================================================
+ * 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.
+ * ====================================================
+ */
+/* cbrtf(x)
+ * Return cube root of x
+ */
+
+#include <math.h>
+#include <stdint.h>
+
+static const unsigned
+B1 = 709958130, /* B1 = (127-127.0/3-0.03306235651)*2**23 */
+B2 = 642849266; /* B2 = (127-127.0/3-24/3-0.03306235651)*2**23 */
+
+float cbrtf(float x)
+{
+	double_t r,T;
+	union {float f; uint32_t i;} u = {x};
+	uint32_t hx = u.i & 0x7fffffff;
+
+	if (hx >= 0x7f800000)  /* cbrt(NaN,INF) is itself */
+		return x + x;
+
+	/* rough cbrt to 5 bits */
+	if (hx < 0x00800000) {  /* zero or subnormal? */
+		if (hx == 0)
+			return x;  /* cbrt(+-0) is itself */
+		u.f = x*0x1p24f;
+		hx = u.i & 0x7fffffff;
+		hx = hx/3 + B2;
+	} else
+		hx = hx/3 + B1;
+	u.i &= 0x80000000;
+	u.i |= hx;
+
+	/*
+	 * First step Newton iteration (solving t*t-x/t == 0) to 16 bits.  In
+	 * double precision so that its terms can be arranged for efficiency
+	 * without causing overflow or underflow.
+	 */
+	T = u.f;
+	r = T*T*T;
+	T = T*((double_t)x+x+r)/(x+r+r);
+
+	/*
+	 * Second step Newton iteration to 47 bits.  In double precision for
+	 * efficiency and accuracy.
+	 */
+	r = T*T*T;
+	T = T*((double_t)x+x+r)/(x+r+r);
+
+	/* rounding to 24 bits is perfect in round-to-nearest mode */
+	return T;
+}
libc/musl/src/math/cbrtl.c
@@ -0,0 +1,124 @@
+/* origin: FreeBSD /usr/src/lib/msun/src/s_cbrtl.c */
+/*-
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ * Copyright (c) 2009-2011, Bruce D. Evans, Steven G. Kargl, David Schultz.
+ *
+ * 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.
+ * ====================================================
+ *
+ * The argument reduction and testing for exceptional cases was
+ * written by Steven G. Kargl with input from Bruce D. Evans
+ * and David A. Schultz.
+ */
+
+#include "libm.h"
+
+#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024
+long double cbrtl(long double x)
+{
+	return cbrt(x);
+}
+#elif (LDBL_MANT_DIG == 64 || LDBL_MANT_DIG == 113) && LDBL_MAX_EXP == 16384
+static const unsigned B1 = 709958130; /* B1 = (127-127.0/3-0.03306235651)*2**23 */
+
+long double cbrtl(long double x)
+{
+	union ldshape u = {x}, v;
+	union {float f; uint32_t i;} uft;
+	long double r, s, t, w;
+	double_t dr, dt, dx;
+	float_t ft;
+	int e = u.i.se & 0x7fff;
+	int sign = u.i.se & 0x8000;
+
+	/*
+	 * If x = +-Inf, then cbrt(x) = +-Inf.
+	 * If x = NaN, then cbrt(x) = NaN.
+	 */
+	if (e == 0x7fff)
+		return x + x;
+	if (e == 0) {
+		/* Adjust subnormal numbers. */
+		u.f *= 0x1p120;
+		e = u.i.se & 0x7fff;
+		/* If x = +-0, then cbrt(x) = +-0. */
+		if (e == 0)
+			return x;
+		e -= 120;
+	}
+	e -= 0x3fff;
+	u.i.se = 0x3fff;
+	x = u.f;
+	switch (e % 3) {
+	case 1:
+	case -2:
+		x *= 2;
+		e--;
+		break;
+	case 2:
+	case -1:
+		x *= 4;
+		e -= 2;
+		break;
+	}
+	v.f = 1.0;
+	v.i.se = sign | (0x3fff + e/3);
+
+	/*
+	 * The following is the guts of s_cbrtf, with the handling of
+	 * special values removed and extra care for accuracy not taken,
+	 * but with most of the extra accuracy not discarded.
+	 */
+
+	/* ~5-bit estimate: */
+	uft.f = x;
+	uft.i = (uft.i & 0x7fffffff)/3 + B1;
+	ft = uft.f;
+
+	/* ~16-bit estimate: */
+	dx = x;
+	dt = ft;
+	dr = dt * dt * dt;
+	dt = dt * (dx + dx + dr) / (dx + dr + dr);
+
+	/* ~47-bit estimate: */
+	dr = dt * dt * dt;
+	dt = dt * (dx + dx + dr) / (dx + dr + dr);
+
+#if LDBL_MANT_DIG == 64
+	/*
+	 * dt is cbrtl(x) to ~47 bits (after x has been reduced to 1 <= x < 8).
+	 * Round it away from zero to 32 bits (32 so that t*t is exact, and
+	 * away from zero for technical reasons).
+	 */
+	t = dt + (0x1.0p32L + 0x1.0p-31L) - 0x1.0p32;
+#elif LDBL_MANT_DIG == 113
+	/*
+	 * Round dt away from zero to 47 bits.  Since we don't trust the 47,
+	 * add 2 47-bit ulps instead of 1 to round up.  Rounding is slow and
+	 * might be avoidable in this case, since on most machines dt will
+	 * have been evaluated in 53-bit precision and the technical reasons
+	 * for rounding up might not apply to either case in cbrtl() since
+	 * dt is much more accurate than needed.
+	 */
+	t = dt + 0x2.0p-46 + 0x1.0p60L - 0x1.0p60;
+#endif
+
+	/*
+	 * Final step Newton iteration to 64 or 113 bits with
+	 * error < 0.667 ulps
+	 */
+	s = t*t;         /* t*t is exact */
+	r = x/s;         /* error <= 0.5 ulps; |r| < |t| */
+	w = t+t;         /* t+t is exact */
+	r = (r-t)/(w+r); /* r-t is exact; w+r ~= 3*t */
+	t = t+t*r;       /* error <= 0.5 + 0.5/3 + epsilon */
+
+	t *= v.f;
+	return t;
+}
+#endif
libc/musl/src/math/ceil.c
@@ -0,0 +1,31 @@
+#include "libm.h"
+
+#if FLT_EVAL_METHOD==0 || FLT_EVAL_METHOD==1
+#define EPS DBL_EPSILON
+#elif FLT_EVAL_METHOD==2
+#define EPS LDBL_EPSILON
+#endif
+static const double_t toint = 1/EPS;
+
+double ceil(double x)
+{
+	union {double f; uint64_t i;} u = {x};
+	int e = u.i >> 52 & 0x7ff;
+	double_t y;
+
+	if (e >= 0x3ff+52 || x == 0)
+		return x;
+	/* y = int(x) - x, where int(x) is an integer neighbor of x */
+	if (u.i >> 63)
+		y = x - toint + toint - x;
+	else
+		y = x + toint - toint - x;
+	/* special case because of non-nearest rounding modes */
+	if (e <= 0x3ff-1) {
+		FORCE_EVAL(y);
+		return u.i >> 63 ? -0.0 : 1;
+	}
+	if (y < 0)
+		return x + y + 1;
+	return x + y;
+}
libc/musl/src/math/ceilf.c
@@ -0,0 +1,27 @@
+#include "libm.h"
+
+float ceilf(float x)
+{
+	union {float f; uint32_t i;} u = {x};
+	int e = (int)(u.i >> 23 & 0xff) - 0x7f;
+	uint32_t m;
+
+	if (e >= 23)
+		return x;
+	if (e >= 0) {
+		m = 0x007fffff >> e;
+		if ((u.i & m) == 0)
+			return x;
+		FORCE_EVAL(x + 0x1p120f);
+		if (u.i >> 31 == 0)
+			u.i += m;
+		u.i &= ~m;
+	} else {
+		FORCE_EVAL(x + 0x1p120f);
+		if (u.i >> 31)
+			u.f = -0.0;
+		else if (u.i << 1)
+			u.f = 1.0;
+	}
+	return u.f;
+}
libc/musl/src/math/ceill.c
@@ -0,0 +1,34 @@
+#include "libm.h"
+
+#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024
+long double ceill(long double x)
+{
+	return ceil(x);
+}
+#elif (LDBL_MANT_DIG == 64 || LDBL_MANT_DIG == 113) && LDBL_MAX_EXP == 16384
+
+static const long double toint = 1/LDBL_EPSILON;
+
+long double ceill(long double x)
+{
+	union ldshape u = {x};
+	int e = u.i.se & 0x7fff;
+	long double y;
+
+	if (e >= 0x3fff+LDBL_MANT_DIG-1 || x == 0)
+		return x;
+	/* y = int(x) - x, where int(x) is an integer neighbor of x */
+	if (u.i.se >> 15)
+		y = x - toint + toint - x;
+	else
+		y = x + toint - toint - x;
+	/* special case because of non-nearest rounding modes */
+	if (e <= 0x3fff-1) {
+		FORCE_EVAL(y);
+		return u.i.se >> 15 ? -0.0 : 1;
+	}
+	if (y < 0)
+		return x + y + 1;
+	return x + y;
+}
+#endif
libc/musl/src/math/copysign.c
@@ -0,0 +1,8 @@
+#include "libm.h"
+
+double copysign(double x, double y) {
+	union {double f; uint64_t i;} ux={x}, uy={y};
+	ux.i &= -1ULL/2;
+	ux.i |= uy.i & 1ULL<<63;
+	return ux.f;
+}
libc/musl/src/math/copysignf.c
@@ -0,0 +1,10 @@
+#include <math.h>
+#include <stdint.h>
+
+float copysignf(float x, float y)
+{
+	union {float f; uint32_t i;} ux={x}, uy={y};
+	ux.i &= 0x7fffffff;
+	ux.i |= uy.i & 0x80000000;
+	return ux.f;
+}
libc/musl/src/math/copysignl.c
@@ -0,0 +1,16 @@
+#include "libm.h"
+
+#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024
+long double copysignl(long double x, long double y)
+{
+	return copysign(x, y);
+}
+#elif (LDBL_MANT_DIG == 64 || LDBL_MANT_DIG == 113) && LDBL_MAX_EXP == 16384
+long double copysignl(long double x, long double y)
+{
+	union ldshape ux = {x}, uy = {y};
+	ux.i.se &= 0x7fff;
+	ux.i.se |= uy.i.se & 0x8000;
+	return ux.f;
+}
+#endif
libc/musl/src/math/cos.c
@@ -0,0 +1,77 @@
+/* origin: FreeBSD /usr/src/lib/msun/src/s_cos.c */
+/*
+ * ====================================================
+ * 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.
+ * ====================================================
+ */
+/* cos(x)
+ * Return cosine function of x.
+ *
+ * kernel function:
+ *      __sin           ... sine function on [-pi/4,pi/4]
+ *      __cos           ... cosine function on [-pi/4,pi/4]
+ *      __rem_pio2      ... 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 "libm.h"
+
+double cos(double x)
+{
+	double y[2];
+	uint32_t ix;
+	unsigned n;
+
+	GET_HIGH_WORD(ix, x);
+	ix &= 0x7fffffff;
+
+	/* |x| ~< pi/4 */
+	if (ix <= 0x3fe921fb) {
+		if (ix < 0x3e46a09e) {  /* |x| < 2**-27 * sqrt(2) */
+			/* raise inexact if x!=0 */
+			FORCE_EVAL(x + 0x1p120f);
+			return 1.0;
+		}
+		return __cos(x, 0);
+	}
+
+	/* cos(Inf or NaN) is NaN */
+	if (ix >= 0x7ff00000)
+		return x-x;
+
+	/* argument reduction */
+	n = __rem_pio2(x, y);
+	switch (n&3) {
+	case 0: return  __cos(y[0], y[1]);
+	case 1: return -__sin(y[0], y[1], 1);
+	case 2: return -__cos(y[0], y[1]);
+	default:
+		return  __sin(y[0], y[1], 1);
+	}
+}
libc/musl/src/math/cosf.c
@@ -0,0 +1,78 @@
+/* origin: FreeBSD /usr/src/lib/msun/src/s_cosf.c */
+/*
+ * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.
+ * Optimized by Bruce D. Evans.
+ */
+/*
+ * ====================================================
+ * 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 "libm.h"
+
+/* Small multiples of pi/2 rounded to double precision. */
+static const double
+c1pio2 = 1*M_PI_2, /* 0x3FF921FB, 0x54442D18 */
+c2pio2 = 2*M_PI_2, /* 0x400921FB, 0x54442D18 */
+c3pio2 = 3*M_PI_2, /* 0x4012D97C, 0x7F3321D2 */
+c4pio2 = 4*M_PI_2; /* 0x401921FB, 0x54442D18 */
+
+float cosf(float x)
+{
+	double y;
+	uint32_t ix;
+	unsigned n, sign;
+
+	GET_FLOAT_WORD(ix, x);
+	sign = ix >> 31;
+	ix &= 0x7fffffff;
+
+	if (ix <= 0x3f490fda) {  /* |x| ~<= pi/4 */
+		if (ix < 0x39800000) {  /* |x| < 2**-12 */
+			/* raise inexact if x != 0 */
+			FORCE_EVAL(x + 0x1p120f);
+			return 1.0f;
+		}
+		return __cosdf(x);
+	}
+	if (ix <= 0x407b53d1) {  /* |x| ~<= 5*pi/4 */
+		if (ix > 0x4016cbe3)  /* |x|  ~> 3*pi/4 */
+			return -__cosdf(sign ? x+c2pio2 : x-c2pio2);
+		else {
+			if (sign)
+				return __sindf(x + c1pio2);
+			else
+				return __sindf(c1pio2 - x);
+		}
+	}
+	if (ix <= 0x40e231d5) {  /* |x| ~<= 9*pi/4 */
+		if (ix > 0x40afeddf)  /* |x| ~> 7*pi/4 */
+			return __cosdf(sign ? x+c4pio2 : x-c4pio2);
+		else {
+			if (sign)
+				return __sindf(-x - c3pio2);
+			else
+				return __sindf(x - c3pio2);
+		}
+	}
+
+	/* cos(Inf or NaN) is NaN */
+	if (ix >= 0x7f800000)
+		return x-x;
+
+	/* general argument reduction needed */
+	n = __rem_pio2f(x,&y);
+	switch (n&3) {
+	case 0: return  __cosdf(y);
+	case 1: return  __sindf(-y);
+	case 2: return -__cosdf(y);
+	default:
+		return  __sindf(y);
+	}
+}
libc/musl/src/math/cosh.c
@@ -0,0 +1,40 @@
+#include "libm.h"
+
+/* cosh(x) = (exp(x) + 1/exp(x))/2
+ *         = 1 + 0.5*(exp(x)-1)*(exp(x)-1)/exp(x)
+ *         = 1 + x*x/2 + o(x^4)
+ */
+double cosh(double x)
+{
+	union {double f; uint64_t i;} u = {.f = x};
+	uint32_t w;
+	double t;
+
+	/* |x| */
+	u.i &= (uint64_t)-1/2;
+	x = u.f;
+	w = u.i >> 32;
+
+	/* |x| < log(2) */
+	if (w < 0x3fe62e42) {
+		if (w < 0x3ff00000 - (26<<20)) {
+			/* raise inexact if x!=0 */
+			FORCE_EVAL(x + 0x1p120f);
+			return 1;
+		}
+		t = expm1(x);
+		return 1 + t*t/(2*(1+t));
+	}
+
+	/* |x| < log(DBL_MAX) */
+	if (w < 0x40862e42) {
+		t = exp(x);
+		/* note: if x>log(0x1p26) then the 1/t is not needed */
+		return 0.5*(t + 1/t);
+	}
+
+	/* |x| > log(DBL_MAX) or nan */
+	/* note: the result is stored to handle overflow */
+	t = __expo2(x);
+	return t;
+}
libc/musl/src/math/coshf.c
@@ -0,0 +1,33 @@
+#include "libm.h"
+
+float coshf(float x)
+{
+	union {float f; uint32_t i;} u = {.f = x};
+	uint32_t w;
+	float t;
+
+	/* |x| */
+	u.i &= 0x7fffffff;
+	x = u.f;
+	w = u.i;
+
+	/* |x| < log(2) */
+	if (w < 0x3f317217) {
+		if (w < 0x3f800000 - (12<<23)) {
+			FORCE_EVAL(x + 0x1p120f);
+			return 1;
+		}
+		t = expm1f(x);
+		return 1 + t*t/(2*(1+t));
+	}
+
+	/* |x| < log(FLT_MAX) */
+	if (w < 0x42b17217) {
+		t = expf(x);
+		return 0.5f*(t + 1/t);
+	}
+
+	/* |x| > log(FLT_MAX) or nan */
+	t = __expo2f(x);
+	return t;
+}
libc/musl/src/math/coshl.c
@@ -0,0 +1,47 @@
+#include "libm.h"
+
+#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024
+long double coshl(long double x)
+{
+	return cosh(x);
+}
+#elif LDBL_MANT_DIG == 64 && LDBL_MAX_EXP == 16384
+long double coshl(long double x)
+{
+	union ldshape u = {x};
+	unsigned ex = u.i.se & 0x7fff;
+	uint32_t w;
+	long double t;
+
+	/* |x| */
+	u.i.se = ex;
+	x = u.f;
+	w = u.i.m >> 32;
+
+	/* |x| < log(2) */
+	if (ex < 0x3fff-1 || (ex == 0x3fff-1 && w < 0xb17217f7)) {
+		if (ex < 0x3fff-32) {
+			FORCE_EVAL(x + 0x1p120f);
+			return 1;
+		}
+		t = expm1l(x);
+		return 1 + t*t/(2*(1+t));
+	}
+
+	/* |x| < log(LDBL_MAX) */
+	if (ex < 0x3fff+13 || (ex == 0x3fff+13 && w < 0xb17217f7)) {
+		t = expl(x);
+		return 0.5*(t + 1/t);
+	}
+
+	/* |x| > log(LDBL_MAX) or nan */
+	t = expl(0.5*x);
+	return 0.5*t*t;
+}
+#elif LDBL_MANT_DIG == 113 && LDBL_MAX_EXP == 16384
+// TODO: broken implementation to make things compile
+long double coshl(long double x)
+{
+	return cosh(x);
+}
+#endif
libc/musl/src/math/cosl.c
@@ -0,0 +1,39 @@
+#include "libm.h"
+
+#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024
+long double cosl(long double x) {
+	return cos(x);
+}
+#elif (LDBL_MANT_DIG == 64 || LDBL_MANT_DIG == 113) && LDBL_MAX_EXP == 16384
+long double cosl(long double x)
+{
+	union ldshape u = {x};
+	unsigned n;
+	long double y[2], hi, lo;
+
+	u.i.se &= 0x7fff;
+	if (u.i.se == 0x7fff)
+		return x - x;
+	x = u.f;
+	if (x < M_PI_4) {
+		if (u.i.se < 0x3fff - LDBL_MANT_DIG)
+			/* raise inexact if x!=0 */
+			return 1.0 + x;
+		return __cosl(x, 0);
+	}
+	n = __rem_pio2l(x, y);
+	hi = y[0];
+	lo = y[1];
+	switch (n & 3) {
+	case 0:
+		return __cosl(hi, lo);
+	case 1:
+		return -__sinl(hi, lo, 1);
+	case 2:
+		return -__cosl(hi, lo);
+	case 3:
+	default:
+		return __sinl(hi, lo, 1);
+	}
+}
+#endif
libc/musl/src/math/erf.c
@@ -0,0 +1,273 @@
+/* origin: FreeBSD /usr/src/lib/msun/src/s_erf.c */
+/*
+ * ====================================================
+ * 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.
+ * ====================================================
+ */
+/* 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 "libm.h"
+
+static const double
+erx  = 8.45062911510467529297e-01, /* 0x3FEB0AC1, 0x60000000 */
+/*
+ * Coefficients for approximation to  erf on [0,0.84375]
+ */
+efx8 =  1.02703333676410069053e+00, /* 0x3FF06EBA, 0x8214DB69 */
+pp0  =  1.28379167095512558561e-01, /* 0x3FC06EBA, 0x8214DB68 */
+pp1  = -3.25042107247001499370e-01, /* 0xBFD4CD7D, 0x691CB913 */
+pp2  = -2.84817495755985104766e-02, /* 0xBF9D2A51, 0xDBD7194F */
+pp3  = -5.77027029648944159157e-03, /* 0xBF77A291, 0x236668E4 */
+pp4  = -2.37630166566501626084e-05, /* 0xBEF8EAD6, 0x120016AC */
+qq1  =  3.97917223959155352819e-01, /* 0x3FD97779, 0xCDDADC09 */
+qq2  =  6.50222499887672944485e-02, /* 0x3FB0A54C, 0x5536CEBA */
+qq3  =  5.08130628187576562776e-03, /* 0x3F74D022, 0xC4D36B0F */
+qq4  =  1.32494738004321644526e-04, /* 0x3F215DC9, 0x221C1A10 */
+qq5  = -3.96022827877536812320e-06, /* 0xBED09C43, 0x42A26120 */
+/*
+ * Coefficients for approximation to  erf  in [0.84375,1.25]
+ */
+pa0  = -2.36211856075265944077e-03, /* 0xBF6359B8, 0xBEF77538 */
+pa1  =  4.14856118683748331666e-01, /* 0x3FDA8D00, 0xAD92B34D */
+pa2  = -3.72207876035701323847e-01, /* 0xBFD7D240, 0xFBB8C3F1 */
+pa3  =  3.18346619901161753674e-01, /* 0x3FD45FCA, 0x805120E4 */
+pa4  = -1.10894694282396677476e-01, /* 0xBFBC6398, 0x3D3E28EC */
+pa5  =  3.54783043256182359371e-02, /* 0x3FA22A36, 0x599795EB */
+pa6  = -2.16637559486879084300e-03, /* 0xBF61BF38, 0x0A96073F */
+qa1  =  1.06420880400844228286e-01, /* 0x3FBB3E66, 0x18EEE323 */
+qa2  =  5.40397917702171048937e-01, /* 0x3FE14AF0, 0x92EB6F33 */
+qa3  =  7.18286544141962662868e-02, /* 0x3FB2635C, 0xD99FE9A7 */
+qa4  =  1.26171219808761642112e-01, /* 0x3FC02660, 0xE763351F */
+qa5  =  1.36370839120290507362e-02, /* 0x3F8BEDC2, 0x6B51DD1C */
+qa6  =  1.19844998467991074170e-02, /* 0x3F888B54, 0x5735151D */
+/*
+ * Coefficients for approximation to  erfc in [1.25,1/0.35]
+ */
+ra0  = -9.86494403484714822705e-03, /* 0xBF843412, 0x600D6435 */
+ra1  = -6.93858572707181764372e-01, /* 0xBFE63416, 0xE4BA7360 */
+ra2  = -1.05586262253232909814e+01, /* 0xC0251E04, 0x41B0E726 */
+ra3  = -6.23753324503260060396e+01, /* 0xC04F300A, 0xE4CBA38D */
+ra4  = -1.62396669462573470355e+02, /* 0xC0644CB1, 0x84282266 */
+ra5  = -1.84605092906711035994e+02, /* 0xC067135C, 0xEBCCABB2 */
+ra6  = -8.12874355063065934246e+01, /* 0xC0545265, 0x57E4D2F2 */
+ra7  = -9.81432934416914548592e+00, /* 0xC023A0EF, 0xC69AC25C */
+sa1  =  1.96512716674392571292e+01, /* 0x4033A6B9, 0xBD707687 */
+sa2  =  1.37657754143519042600e+02, /* 0x4061350C, 0x526AE721 */
+sa3  =  4.34565877475229228821e+02, /* 0x407B290D, 0xD58A1A71 */
+sa4  =  6.45387271733267880336e+02, /* 0x40842B19, 0x21EC2868 */
+sa5  =  4.29008140027567833386e+02, /* 0x407AD021, 0x57700314 */
+sa6  =  1.08635005541779435134e+02, /* 0x405B28A3, 0xEE48AE2C */
+sa7  =  6.57024977031928170135e+00, /* 0x401A47EF, 0x8E484A93 */
+sa8  = -6.04244152148580987438e-02, /* 0xBFAEEFF2, 0xEE749A62 */
+/*
+ * Coefficients for approximation to  erfc in [1/.35,28]
+ */
+rb0  = -9.86494292470009928597e-03, /* 0xBF843412, 0x39E86F4A */
+rb1  = -7.99283237680523006574e-01, /* 0xBFE993BA, 0x70C285DE */
+rb2  = -1.77579549177547519889e+01, /* 0xC031C209, 0x555F995A */
+rb3  = -1.60636384855821916062e+02, /* 0xC064145D, 0x43C5ED98 */
+rb4  = -6.37566443368389627722e+02, /* 0xC083EC88, 0x1375F228 */
+rb5  = -1.02509513161107724954e+03, /* 0xC0900461, 0x6A2E5992 */
+rb6  = -4.83519191608651397019e+02, /* 0xC07E384E, 0x9BDC383F */
+sb1  =  3.03380607434824582924e+01, /* 0x403E568B, 0x261D5190 */
+sb2  =  3.25792512996573918826e+02, /* 0x40745CAE, 0x221B9F0A */
+sb3  =  1.53672958608443695994e+03, /* 0x409802EB, 0x189D5118 */
+sb4  =  3.19985821950859553908e+03, /* 0x40A8FFB7, 0x688C246A */
+sb5  =  2.55305040643316442583e+03, /* 0x40A3F219, 0xCEDF3BE6 */
+sb6  =  4.74528541206955367215e+02, /* 0x407DA874, 0xE79FE763 */
+sb7  = -2.24409524465858183362e+01; /* 0xC03670E2, 0x42712D62 */
+
+static double erfc1(double x)
+{
+	double_t s,P,Q;
+
+	s = fabs(x) - 1;
+	P = pa0+s*(pa1+s*(pa2+s*(pa3+s*(pa4+s*(pa5+s*pa6)))));
+	Q = 1+s*(qa1+s*(qa2+s*(qa3+s*(qa4+s*(qa5+s*qa6)))));
+	return 1 - erx - P/Q;
+}
+
+static double erfc2(uint32_t ix, double x)
+{
+	double_t s,R,S;
+	double z;
+
+	if (ix < 0x3ff40000)  /* |x| < 1.25 */
+		return erfc1(x);
+
+	x = fabs(x);
+	s = 1/(x*x);
+	if (ix < 0x4006db6d) {  /* |x| < 1/.35 ~ 2.85714 */
+		R = ra0+s*(ra1+s*(ra2+s*(ra3+s*(ra4+s*(
+		     ra5+s*(ra6+s*ra7))))));
+		S = 1.0+s*(sa1+s*(sa2+s*(sa3+s*(sa4+s*(
+		     sa5+s*(sa6+s*(sa7+s*sa8)))))));
+	} else {                /* |x| > 1/.35 */
+		R = rb0+s*(rb1+s*(rb2+s*(rb3+s*(rb4+s*(
+		     rb5+s*rb6)))));
+		S = 1.0+s*(sb1+s*(sb2+s*(sb3+s*(sb4+s*(
+		     sb5+s*(sb6+s*sb7))))));
+	}
+	z = x;
+	SET_LOW_WORD(z,0);
+	return exp(-z*z-0.5625)*exp((z-x)*(z+x)+R/S)/x;
+}
+
+double erf(double x)
+{
+	double r,s,z,y;
+	uint32_t ix;
+	int sign;
+
+	GET_HIGH_WORD(ix, x);
+	sign = ix>>31;
+	ix &= 0x7fffffff;
+	if (ix >= 0x7ff00000) {
+		/* erf(nan)=nan, erf(+-inf)=+-1 */
+		return 1-2*sign + 1/x;
+	}
+	if (ix < 0x3feb0000) {  /* |x| < 0.84375 */
+		if (ix < 0x3e300000) {  /* |x| < 2**-28 */
+			/* avoid underflow */
+			return 0.125*(8*x + efx8*x);
+		}
+		z = x*x;
+		r = pp0+z*(pp1+z*(pp2+z*(pp3+z*pp4)));
+		s = 1.0+z*(qq1+z*(qq2+z*(qq3+z*(qq4+z*qq5))));
+		y = r/s;
+		return x + x*y;
+	}
+	if (ix < 0x40180000)  /* 0.84375 <= |x| < 6 */
+		y = 1 - erfc2(ix,x);
+	else
+		y = 1 - 0x1p-1022;
+	return sign ? -y : y;
+}
+
+double erfc(double x)
+{
+	double r,s,z,y;
+	uint32_t ix;
+	int sign;
+
+	GET_HIGH_WORD(ix, x);
+	sign = ix>>31;
+	ix &= 0x7fffffff;
+	if (ix >= 0x7ff00000) {
+		/* erfc(nan)=nan, erfc(+-inf)=0,2 */
+		return 2*sign + 1/x;
+	}
+	if (ix < 0x3feb0000) {  /* |x| < 0.84375 */
+		if (ix < 0x3c700000)  /* |x| < 2**-56 */
+			return 1.0 - x;
+		z = x*x;
+		r = pp0+z*(pp1+z*(pp2+z*(pp3+z*pp4)));
+		s = 1.0+z*(qq1+z*(qq2+z*(qq3+z*(qq4+z*qq5))));
+		y = r/s;
+		if (sign || ix < 0x3fd00000) {  /* x < 1/4 */
+			return 1.0 - (x+x*y);
+		}
+		return 0.5 - (x - 0.5 + x*y);
+	}
+	if (ix < 0x403c0000) {  /* 0.84375 <= |x| < 28 */
+		return sign ? 2 - erfc2(ix,x) : erfc2(ix,x);
+	}
+	return sign ? 2 - 0x1p-1022 : 0x1p-1022*0x1p-1022;
+}
libc/musl/src/math/erff.c
@@ -0,0 +1,183 @@
+/* origin: FreeBSD /usr/src/lib/msun/src/s_erff.c */
+/*
+ * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.
+ */
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunPro, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+
+#include "libm.h"
+
+static const float
+erx  =  8.4506291151e-01, /* 0x3f58560b */
+/*
+ * Coefficients for approximation to  erf on [0,0.84375]
+ */
+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 */
+
+static float erfc1(float x)
+{
+	float_t s,P,Q;
+
+	s = fabsf(x) - 1;
+	P = pa0+s*(pa1+s*(pa2+s*(pa3+s*(pa4+s*(pa5+s*pa6)))));
+	Q = 1+s*(qa1+s*(qa2+s*(qa3+s*(qa4+s*(qa5+s*qa6)))));
+	return 1 - erx - P/Q;
+}
+
+static float erfc2(uint32_t ix, float x)
+{
+	float_t s,R,S;
+	float z;
+
+	if (ix < 0x3fa00000)  /* |x| < 1.25 */
+		return erfc1(x);
+
+	x = fabsf(x);
+	s = 1/(x*x);
+	if (ix < 0x4036db6d) {   /* |x| < 1/0.35 */
+		R = ra0+s*(ra1+s*(ra2+s*(ra3+s*(ra4+s*(
+		     ra5+s*(ra6+s*ra7))))));
+		S = 1.0f+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 = 1.0f+s*(sb1+s*(sb2+s*(sb3+s*(sb4+s*(
+		     sb5+s*(sb6+s*sb7))))));
+	}
+	GET_FLOAT_WORD(ix, x);
+	SET_FLOAT_WORD(z, ix&0xffffe000);
+	return expf(-z*z - 0.5625f) * expf((z-x)*(z+x) + R/S)/x;
+}
+
+float erff(float x)
+{
+	float r,s,z,y;
+	uint32_t ix;
+	int sign;
+
+	GET_FLOAT_WORD(ix, x);
+	sign = ix>>31;
+	ix &= 0x7fffffff;
+	if (ix >= 0x7f800000) {
+		/* erf(nan)=nan, erf(+-inf)=+-1 */
+		return 1-2*sign + 1/x;
+	}
+	if (ix < 0x3f580000) {  /* |x| < 0.84375 */
+		if (ix < 0x31800000) {  /* |x| < 2**-28 */
+			/*avoid underflow */
+			return 0.125f*(8*x + efx8*x);
+		}
+		z = x*x;
+		r = pp0+z*(pp1+z*(pp2+z*(pp3+z*pp4)));
+		s = 1+z*(qq1+z*(qq2+z*(qq3+z*(qq4+z*qq5))));
+		y = r/s;
+		return x + x*y;
+	}
+	if (ix < 0x40c00000)  /* |x| < 6 */
+		y = 1 - erfc2(ix,x);
+	else
+		y = 1 - 0x1p-120f;
+	return sign ? -y : y;
+}
+
+float erfcf(float x)
+{
+	float r,s,z,y;
+	uint32_t ix;
+	int sign;
+
+	GET_FLOAT_WORD(ix, x);
+	sign = ix>>31;
+	ix &= 0x7fffffff;
+	if (ix >= 0x7f800000) {
+		/* erfc(nan)=nan, erfc(+-inf)=0,2 */
+		return 2*sign + 1/x;
+	}
+
+	if (ix < 0x3f580000) {  /* |x| < 0.84375 */
+		if (ix < 0x23800000)  /* |x| < 2**-56 */
+			return 1.0f - x;
+		z = x*x;
+		r = pp0+z*(pp1+z*(pp2+z*(pp3+z*pp4)));
+		s = 1.0f+z*(qq1+z*(qq2+z*(qq3+z*(qq4+z*qq5))));
+		y = r/s;
+		if (sign || ix < 0x3e800000)  /* x < 1/4 */
+			return 1.0f - (x+x*y);
+		return 0.5f - (x - 0.5f + x*y);
+	}
+	if (ix < 0x41e00000) {  /* |x| < 28 */
+		return sign ? 2 - erfc2(ix,x) : erfc2(ix,x);
+	}
+	return sign ? 2 - 0x1p-120f : 0x1p-120f*0x1p-120f;
+}
libc/musl/src/math/erfl.c
@@ -0,0 +1,353 @@
+/* origin: OpenBSD /usr/src/lib/libm/src/ld80/e_erfl.c */
+/*
+ * ====================================================
+ * 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.
+ * ====================================================
+ */
+/*
+ * Copyright (c) 2008 Stephen L. Moshier <steve@moshier.net>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+/* 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 "libm.h"
+
+#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024
+long double erfl(long double x)
+{
+	return erf(x);
+}
+long double erfcl(long double x)
+{
+	return erfc(x);
+}
+#elif LDBL_MANT_DIG == 64 && LDBL_MAX_EXP == 16384
+static const long double
+erx = 0.845062911510467529296875L,
+
+/*
+ * Coefficients for approximation to  erf on [0,0.84375]
+ */
+/* 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 */
+};
+
+static long double erfc1(long double x)
+{
+	long double s,P,Q;
+
+	s = fabsl(x) - 1;
+	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))))));
+	return 1 - erx - P / Q;
+}
+
+static long double erfc2(uint32_t ix, long double x)
+{
+	union ldshape u;
+	long double s,z,R,S;
+
+	if (ix < 0x3fffa000)  /* 0.84375 <= |x| < 1.25 */
+		return erfc1(x);
+
+	x = fabsl(x);
+	s = 1 / (x * x);
+	if (ix < 0x4000b6db) {  /* 1.25 <= |x| < 2.857 ~ 1/.35 */
+		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) {  /* 2.857 <= |x| < 6.6666259765625 */
+		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 { /* 6.666 <= |x| < 107 (erfc only) */
+		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))));
+	}
+	u.f = x;
+	u.i.m &= -1ULL << 40;
+	z = u.f;
+	return expl(-z*z - 0.5625) * expl((z - x) * (z + x) + R / S) / x;
+}
+
+long double erfl(long double x)
+{
+	long double r, s, z, y;
+	union ldshape u = {x};
+	uint32_t ix = (u.i.se & 0x7fffU)<<16 | u.i.m>>48;
+	int sign = u.i.se >> 15;
+
+	if (ix >= 0x7fff0000)
+		/* erf(nan)=nan, erf(+-inf)=+-1 */
+		return 1 - 2*sign + 1/x;
+	if (ix < 0x3ffed800) {  /* |x| < 0.84375 */
+		if (ix < 0x3fde8000) {  /* |x| < 2**-33 */
+			return 0.125 * (8 * x + efx8 * x);  /* avoid underflow */
+		}
+		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 < 0x4001d555)  /* |x| < 6.6666259765625 */
+		y = 1 - erfc2(ix,x);
+	else
+		y = 1 - 0x1p-16382L;
+	return sign ? -y : y;
+}
+
+long double erfcl(long double x)
+{
+	long double r, s, z, y;
+	union ldshape u = {x};
+	uint32_t ix = (u.i.se & 0x7fffU)<<16 | u.i.m>>48;
+	int sign = u.i.se >> 15;
+
+	if (ix >= 0x7fff0000)
+		/* erfc(nan) = nan, erfc(+-inf) = 0,2 */
+		return 2*sign + 1/x;
+	if (ix < 0x3ffed800) {  /* |x| < 0.84375 */
+		if (ix < 0x3fbe0000)  /* |x| < 2**-65 */
+			return 1.0 - 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 1.0 - (x + x * y);
+		return 0.5 - (x - 0.5 + x * y);
+	}
+	if (ix < 0x4005d600)  /* |x| < 107 */
+		return sign ? 2 - erfc2(ix,x) : erfc2(ix,x);
+	y = 0x1p-16382L;
+	return sign ? 2 - y : y*y;
+}
+#elif LDBL_MANT_DIG == 113 && LDBL_MAX_EXP == 16384
+// TODO: broken implementation to make things compile
+long double erfl(long double x)
+{
+	return erf(x);
+}
+long double erfcl(long double x)
+{
+	return erfc(x);
+}
+#endif
libc/musl/src/math/exp.c
@@ -0,0 +1,134 @@
+/* origin: FreeBSD /usr/src/lib/msun/src/e_exp.c */
+/*
+ * ====================================================
+ * Copyright (C) 2004 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+/* exp(x)
+ * Returns the exponential of x.
+ *
+ * Method
+ *   1. Argument reduction:
+ *      Reduce x to an r so that |r| <= 0.5*ln2 ~ 0.34658.
+ *      Given x, find r and integer k such that
+ *
+ *               x = k*ln2 + r,  |r| <= 0.5*ln2.
+ *
+ *      Here r will be represented as r = hi-lo for better
+ *      accuracy.
+ *
+ *   2. Approximation of exp(r) by a special rational function on
+ *      the interval [0,0.34658]:
+ *      Write
+ *          R(r**2) = r*(exp(r)+1)/(exp(r)-1) = 2 + r*r/6 - r**4/360 + ...
+ *      We use a special Remez algorithm on [0,0.34658] to generate
+ *      a polynomial of degree 5 to approximate R. The maximum error
+ *      of this polynomial approximation is bounded by 2**-59. In
+ *      other words,
+ *          R(z) ~ 2.0 + P1*z + P2*z**2 + P3*z**3 + P4*z**4 + P5*z**5
+ *      (where z=r*r, and the values of P1 to P5 are listed below)
+ *      and
+ *          |                  5          |     -59
+ *          | 2.0+P1*z+...+P5*z   -  R(z) | <= 2
+ *          |                             |
+ *      The computation of exp(r) thus becomes
+ *                              2*r
+ *              exp(r) = 1 + ----------
+ *                            R(r) - r
+ *                                 r*c(r)
+ *                     = 1 + r + ----------- (for better accuracy)
+ *                                2 - c(r)
+ *      where
+ *                              2       4             10
+ *              c(r) = r - (P1*r  + P2*r  + ... + P5*r   ).
+ *
+ *   3. Scale back to obtain exp(x):
+ *      From step 1, we have
+ *         exp(x) = 2^k * exp(r)
+ *
+ * Special cases:
+ *      exp(INF) is INF, exp(NaN) is NaN;
+ *      exp(-INF) is 0, and
+ *      for finite argument, only exp(0)=1 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 >  709.782712893383973096 then exp(x) overflows
+ *          if x < -745.133219101941108420 then exp(x) underflows
+ */
+
+#include "libm.h"
+
+static const double
+half[2] = {0.5,-0.5},
+ln2hi = 6.93147180369123816490e-01, /* 0x3fe62e42, 0xfee00000 */
+ln2lo = 1.90821492927058770002e-10, /* 0x3dea39ef, 0x35793c76 */
+invln2 = 1.44269504088896338700e+00, /* 0x3ff71547, 0x652b82fe */
+P1   =  1.66666666666666019037e-01, /* 0x3FC55555, 0x5555553E */
+P2   = -2.77777777770155933842e-03, /* 0xBF66C16C, 0x16BEBD93 */
+P3   =  6.61375632143793436117e-05, /* 0x3F11566A, 0xAF25DE2C */
+P4   = -1.65339022054652515390e-06, /* 0xBEBBBD41, 0xC5D26BF1 */
+P5   =  4.13813679705723846039e-08; /* 0x3E663769, 0x72BEA4D0 */
+
+double exp(double x)
+{
+	double_t hi, lo, c, xx, y;
+	int k, sign;
+	uint32_t hx;
+
+	GET_HIGH_WORD(hx, x);
+	sign = hx>>31;
+	hx &= 0x7fffffff;  /* high word of |x| */
+
+	/* special cases */
+	if (hx >= 0x4086232b) {  /* if |x| >= 708.39... */
+		if (isnan(x))
+			return x;
+		if (x > 709.782712893383973096) {
+			/* overflow if x!=inf */
+			x *= 0x1p1023;
+			return x;
+		}
+		if (x < -708.39641853226410622) {
+			/* underflow if x!=-inf */
+			FORCE_EVAL((float)(-0x1p-149/x));
+			if (x < -745.13321910194110842)
+				return 0;
+		}
+	}
+
+	/* argument reduction */
+	if (hx > 0x3fd62e42) {  /* if |x| > 0.5 ln2 */
+		if (hx >= 0x3ff0a2b2)  /* if |x| >= 1.5 ln2 */
+			k = (int)(invln2*x + half[sign]);
+		else
+			k = 1 - sign - sign;
+		hi = x - k*ln2hi;  /* k*ln2hi is exact here */
+		lo = k*ln2lo;
+		x = hi - lo;
+	} else if (hx > 0x3e300000)  {  /* if |x| > 2**-28 */
+		k = 0;
+		hi = x;
+		lo = 0;
+	} else {
+		/* inexact if x!=0 */
+		FORCE_EVAL(0x1p1023 + x);
+		return 1 + x;
+	}
+
+	/* x is now in primary range */
+	xx = x*x;
+	c = x - xx*(P1+xx*(P2+xx*(P3+xx*(P4+xx*P5))));
+	y = 1 + (x*c/(2-c) - lo + hi);
+	if (k == 0)
+		return y;
+	return scalbn(y, k);
+}
libc/musl/src/math/exp10.c
@@ -0,0 +1,24 @@
+#define _GNU_SOURCE
+#include <math.h>
+#include <stdint.h>
+
+double exp10(double x)
+{
+	static const double p10[] = {
+		1e-15, 1e-14, 1e-13, 1e-12, 1e-11, 1e-10,
+		1e-9, 1e-8, 1e-7, 1e-6, 1e-5, 1e-4, 1e-3, 1e-2, 1e-1,
+		1, 1e1, 1e2, 1e3, 1e4, 1e5, 1e6, 1e7, 1e8, 1e9,
+		1e10, 1e11, 1e12, 1e13, 1e14, 1e15
+	};
+	double n, y = modf(x, &n);
+	union {double f; uint64_t i;} u = {n};
+	/* fabs(n) < 16 without raising invalid on nan */
+	if ((u.i>>52 & 0x7ff) < 0x3ff+4) {
+		if (!y) return p10[(int)n+15];
+		y = exp2(3.32192809488736234787031942948939 * y);
+		return y * p10[(int)n+15];
+	}
+	return pow(10.0, x);
+}
+
+weak_alias(exp10, pow10);
libc/musl/src/math/exp10f.c
@@ -0,0 +1,22 @@
+#define _GNU_SOURCE
+#include <math.h>
+#include <stdint.h>
+
+float exp10f(float x)
+{
+	static const float p10[] = {
+		1e-7f, 1e-6f, 1e-5f, 1e-4f, 1e-3f, 1e-2f, 1e-1f,
+		1, 1e1, 1e2, 1e3, 1e4, 1e5, 1e6, 1e7
+	};
+	float n, y = modff(x, &n);
+	union {float f; uint32_t i;} u = {n};
+	/* fabsf(n) < 8 without raising invalid on nan */
+	if ((u.i>>23 & 0xff) < 0x7f+3) {
+		if (!y) return p10[(int)n+7];
+		y = exp2f(3.32192809488736234787031942948939f * y);
+		return y * p10[(int)n+7];
+	}
+	return exp2(3.32192809488736234787031942948939 * x);
+}
+
+weak_alias(exp10f, pow10f);
libc/musl/src/math/exp10l.c
@@ -0,0 +1,32 @@
+#define _GNU_SOURCE
+#include <float.h>
+#include <math.h>
+#include "libm.h"
+
+#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024
+long double exp10l(long double x)
+{
+	return exp10(x);
+}
+#elif (LDBL_MANT_DIG == 64 || LDBL_MANT_DIG == 113) && LDBL_MAX_EXP == 16384
+long double exp10l(long double x)
+{
+	static const long double p10[] = {
+		1e-15L, 1e-14L, 1e-13L, 1e-12L, 1e-11L, 1e-10L,
+		1e-9L, 1e-8L, 1e-7L, 1e-6L, 1e-5L, 1e-4L, 1e-3L, 1e-2L, 1e-1L,
+		1, 1e1, 1e2, 1e3, 1e4, 1e5, 1e6, 1e7, 1e8, 1e9,
+		1e10, 1e11, 1e12, 1e13, 1e14, 1e15
+	};
+	long double n, y = modfl(x, &n);
+	union ldshape u = {n};
+	/* fabsl(n) < 16 without raising invalid on nan */
+	if ((u.i.se & 0x7fff) < 0x3fff+4) {
+		if (!y) return p10[(int)n+15];
+		y = exp2l(3.32192809488736234787031942948939L * y);
+		return y * p10[(int)n+15];
+	}
+	return powl(10.0, x);
+}
+#endif
+
+weak_alias(exp10l, pow10l);
libc/musl/src/math/exp2.c
@@ -0,0 +1,375 @@
+/* origin: FreeBSD /usr/src/lib/msun/src/s_exp2.c */
+/*-
+ * Copyright (c) 2005 David Schultz <das@FreeBSD.ORG>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include "libm.h"
+
+#define TBLSIZE 256
+
+static const double
+redux = 0x1.8p52 / TBLSIZE,
+P1    = 0x1.62e42fefa39efp-1,
+P2    = 0x1.ebfbdff82c575p-3,
+P3    = 0x1.c6b08d704a0a6p-5,
+P4    = 0x1.3b2ab88f70400p-7,
+P5    = 0x1.5d88003875c74p-10;
+
+static const double tbl[TBLSIZE * 2] = {
+/*  exp2(z + eps)          eps     */
+  0x1.6a09e667f3d5dp-1,  0x1.9880p-44,
+  0x1.6b052fa751744p-1,  0x1.8000p-50,
+  0x1.6c012750bd9fep-1, -0x1.8780p-45,
+  0x1.6cfdcddd476bfp-1,  0x1.ec00p-46,
+  0x1.6dfb23c651a29p-1, -0x1.8000p-50,
+  0x1.6ef9298593ae3p-1, -0x1.c000p-52,
+  0x1.6ff7df9519386p-1, -0x1.fd80p-45,
+  0x1.70f7466f42da3p-1, -0x1.c880p-45,
+  0x1.71f75e8ec5fc3p-1,  0x1.3c00p-46,
+  0x1.72f8286eacf05p-1, -0x1.8300p-44,
+  0x1.73f9a48a58152p-1, -0x1.0c00p-47,
+  0x1.74fbd35d7ccfcp-1,  0x1.f880p-45,
+  0x1.75feb564267f1p-1,  0x1.3e00p-47,
+  0x1.77024b1ab6d48p-1, -0x1.7d00p-45,
+  0x1.780694fde5d38p-1, -0x1.d000p-50,
+  0x1.790b938ac1d00p-1,  0x1.3000p-49,
+  0x1.7a11473eb0178p-1, -0x1.d000p-49,
+  0x1.7b17b0976d060p-1,  0x1.0400p-45,
+  0x1.7c1ed0130c133p-1,  0x1.0000p-53,
+  0x1.7d26a62ff8636p-1, -0x1.6900p-45,
+  0x1.7e2f336cf4e3bp-1, -0x1.2e00p-47,
+  0x1.7f3878491c3e8p-1, -0x1.4580p-45,
+  0x1.80427543e1b4ep-1,  0x1.3000p-44,
+  0x1.814d2add1071ap-1,  0x1.f000p-47,
+  0x1.82589994ccd7ep-1, -0x1.1c00p-45,
+  0x1.8364c1eb942d0p-1,  0x1.9d00p-45,
+  0x1.8471a4623cab5p-1,  0x1.7100p-43,
+  0x1.857f4179f5bbcp-1,  0x1.2600p-45,
+  0x1.868d99b4491afp-1, -0x1.2c40p-44,
+  0x1.879cad931a395p-1, -0x1.3000p-45,
+  0x1.88ac7d98a65b8p-1, -0x1.a800p-45,
+  0x1.89bd0a4785800p-1, -0x1.d000p-49,
+  0x1.8ace5422aa223p-1,  0x1.3280p-44,
+  0x1.8be05bad619fap-1,  0x1.2b40p-43,
+  0x1.8cf3216b54383p-1, -0x1.ed00p-45,
+  0x1.8e06a5e08664cp-1, -0x1.0500p-45,
+  0x1.8f1ae99157807p-1,  0x1.8280p-45,
+  0x1.902fed0282c0ep-1, -0x1.cb00p-46,
+  0x1.9145b0b91ff96p-1, -0x1.5e00p-47,
+  0x1.925c353aa2ff9p-1,  0x1.5400p-48,
+  0x1.93737b0cdc64ap-1,  0x1.7200p-46,
+  0x1.948b82b5f98aep-1, -0x1.9000p-47,
+  0x1.95a44cbc852cbp-1,  0x1.5680p-45,
+  0x1.96bdd9a766f21p-1, -0x1.6d00p-44,
+  0x1.97d829fde4e2ap-1, -0x1.1000p-47,
+  0x1.98f33e47a23a3p-1,  0x1.d000p-45,
+  0x1.9a0f170ca0604p-1, -0x1.8a40p-44,
+  0x1.9b2bb4d53ff89p-1,  0x1.55c0p-44,
+  0x1.9c49182a3f15bp-1,  0x1.6b80p-45,
+  0x1.9d674194bb8c5p-1, -0x1.c000p-49,
+  0x1.9e86319e3238ep-1,  0x1.7d00p-46,
+  0x1.9fa5e8d07f302p-1,  0x1.6400p-46,
+  0x1.a0c667b5de54dp-1, -0x1.5000p-48,
+  0x1.a1e7aed8eb8f6p-1,  0x1.9e00p-47,
+  0x1.a309bec4a2e27p-1,  0x1.ad80p-45,
+  0x1.a42c980460a5dp-1, -0x1.af00p-46,
+  0x1.a5503b23e259bp-1,  0x1.b600p-47,
+  0x1.a674a8af46213p-1,  0x1.8880p-44,
+  0x1.a799e1330b3a7p-1,  0x1.1200p-46,
+  0x1.a8bfe53c12e8dp-1,  0x1.6c00p-47,
+  0x1.a9e6b5579fcd2p-1, -0x1.9b80p-45,
+  0x1.ab0e521356fb8p-1,  0x1.b700p-45,
+  0x1.ac36bbfd3f381p-1,  0x1.9000p-50,
+  0x1.ad5ff3a3c2780p-1,  0x1.4000p-49,
+  0x1.ae89f995ad2a3p-1, -0x1.c900p-45,
+  0x1.afb4ce622f367p-1,  0x1.6500p-46,
+  0x1.b0e07298db790p-1,  0x1.fd40p-45,
+  0x1.b20ce6c9a89a9p-1,  0x1.2700p-46,
+  0x1.b33a2b84f1a4bp-1,  0x1.d470p-43,
+  0x1.b468415b747e7p-1, -0x1.8380p-44,
+  0x1.b59728de5593ap-1,  0x1.8000p-54,
+  0x1.b6c6e29f1c56ap-1,  0x1.ad00p-47,
+  0x1.b7f76f2fb5e50p-1,  0x1.e800p-50,
+  0x1.b928cf22749b2p-1, -0x1.4c00p-47,
+  0x1.ba5b030a10603p-1, -0x1.d700p-47,
+  0x1.bb8e0b79a6f66p-1,  0x1.d900p-47,
+  0x1.bcc1e904bc1ffp-1,  0x1.2a00p-47,
+  0x1.bdf69c3f3a16fp-1, -0x1.f780p-46,
+  0x1.bf2c25bd71db8p-1, -0x1.0a00p-46,
+  0x1.c06286141b2e9p-1, -0x1.1400p-46,
+  0x1.c199bdd8552e0p-1,  0x1.be00p-47,
+  0x1.c2d1cd9fa64eep-1, -0x1.9400p-47,
+  0x1.c40ab5fffd02fp-1, -0x1.ed00p-47,
+  0x1.c544778fafd15p-1,  0x1.9660p-44,
+  0x1.c67f12e57d0cbp-1, -0x1.a100p-46,
+  0x1.c7ba88988c1b6p-1, -0x1.8458p-42,
+  0x1.c8f6d9406e733p-1, -0x1.a480p-46,
+  0x1.ca3405751c4dfp-1,  0x1.b000p-51,
+  0x1.cb720dcef9094p-1,  0x1.1400p-47,
+  0x1.ccb0f2e6d1689p-1,  0x1.0200p-48,
+  0x1.cdf0b555dc412p-1,  0x1.3600p-48,
+  0x1.cf3155b5bab3bp-1, -0x1.6900p-47,
+  0x1.d072d4a0789bcp-1,  0x1.9a00p-47,
+  0x1.d1b532b08c8fap-1, -0x1.5e00p-46,
+  0x1.d2f87080d8a85p-1,  0x1.d280p-46,
+  0x1.d43c8eacaa203p-1,  0x1.1a00p-47,
+  0x1.d5818dcfba491p-1,  0x1.f000p-50,
+  0x1.d6c76e862e6a1p-1, -0x1.3a00p-47,
+  0x1.d80e316c9834ep-1, -0x1.cd80p-47,
+  0x1.d955d71ff6090p-1,  0x1.4c00p-48,
+  0x1.da9e603db32aep-1,  0x1.f900p-48,
+  0x1.dbe7cd63a8325p-1,  0x1.9800p-49,
+  0x1.dd321f301b445p-1, -0x1.5200p-48,
+  0x1.de7d5641c05bfp-1, -0x1.d700p-46,
+  0x1.dfc97337b9aecp-1, -0x1.6140p-46,
+  0x1.e11676b197d5ep-1,  0x1.b480p-47,
+  0x1.e264614f5a3e7p-1,  0x1.0ce0p-43,
+  0x1.e3b333b16ee5cp-1,  0x1.c680p-47,
+  0x1.e502ee78b3fb4p-1, -0x1.9300p-47,
+  0x1.e653924676d68p-1, -0x1.5000p-49,
+  0x1.e7a51fbc74c44p-1, -0x1.7f80p-47,
+  0x1.e8f7977cdb726p-1, -0x1.3700p-48,
+  0x1.ea4afa2a490e8p-1,  0x1.5d00p-49,
+  0x1.eb9f4867ccae4p-1,  0x1.61a0p-46,
+  0x1.ecf482d8e680dp-1,  0x1.5500p-48,
+  0x1.ee4aaa2188514p-1,  0x1.6400p-51,
+  0x1.efa1bee615a13p-1, -0x1.e800p-49,
+  0x1.f0f9c1cb64106p-1, -0x1.a880p-48,
+  0x1.f252b376bb963p-1, -0x1.c900p-45,
+  0x1.f3ac948dd7275p-1,  0x1.a000p-53,
+  0x1.f50765b6e4524p-1, -0x1.4f00p-48,
+  0x1.f6632798844fdp-1,  0x1.a800p-51,
+  0x1.f7bfdad9cbe38p-1,  0x1.abc0p-48,
+  0x1.f91d802243c82p-1, -0x1.4600p-50,
+  0x1.fa7c1819e908ep-1, -0x1.b0c0p-47,
+  0x1.fbdba3692d511p-1, -0x1.0e00p-51,
+  0x1.fd3c22b8f7194p-1, -0x1.0de8p-46,
+  0x1.fe9d96b2a23eep-1,  0x1.e430p-49,
+  0x1.0000000000000p+0,  0x0.0000p+0,
+  0x1.00b1afa5abcbep+0, -0x1.3400p-52,
+  0x1.0163da9fb3303p+0, -0x1.2170p-46,
+  0x1.02168143b0282p+0,  0x1.a400p-52,
+  0x1.02c9a3e77806cp+0,  0x1.f980p-49,
+  0x1.037d42e11bbcap+0, -0x1.7400p-51,
+  0x1.04315e86e7f89p+0,  0x1.8300p-50,
+  0x1.04e5f72f65467p+0, -0x1.a3f0p-46,
+  0x1.059b0d315855ap+0, -0x1.2840p-47,
+  0x1.0650a0e3c1f95p+0,  0x1.1600p-48,
+  0x1.0706b29ddf71ap+0,  0x1.5240p-46,
+  0x1.07bd42b72a82dp+0, -0x1.9a00p-49,
+  0x1.0874518759bd0p+0,  0x1.6400p-49,
+  0x1.092bdf66607c8p+0, -0x1.0780p-47,
+  0x1.09e3ecac6f383p+0, -0x1.8000p-54,
+  0x1.0a9c79b1f3930p+0,  0x1.fa00p-48,
+  0x1.0b5586cf988fcp+0, -0x1.ac80p-48,
+  0x1.0c0f145e46c8ap+0,  0x1.9c00p-50,
+  0x1.0cc922b724816p+0,  0x1.5200p-47,
+  0x1.0d83b23395dd8p+0, -0x1.ad00p-48,
+  0x1.0e3ec32d3d1f3p+0,  0x1.bac0p-46,
+  0x1.0efa55fdfa9a6p+0, -0x1.4e80p-47,
+  0x1.0fb66affed2f0p+0, -0x1.d300p-47,
+  0x1.1073028d7234bp+0,  0x1.1500p-48,
+  0x1.11301d0125b5bp+0,  0x1.c000p-49,
+  0x1.11edbab5e2af9p+0,  0x1.6bc0p-46,
+  0x1.12abdc06c31d5p+0,  0x1.8400p-49,
+  0x1.136a814f2047dp+0, -0x1.ed00p-47,
+  0x1.1429aaea92de9p+0,  0x1.8e00p-49,
+  0x1.14e95934f3138p+0,  0x1.b400p-49,
+  0x1.15a98c8a58e71p+0,  0x1.5300p-47,
+  0x1.166a45471c3dfp+0,  0x1.3380p-47,
+  0x1.172b83c7d5211p+0,  0x1.8d40p-45,
+  0x1.17ed48695bb9fp+0, -0x1.5d00p-47,
+  0x1.18af9388c8d93p+0, -0x1.c880p-46,
+  0x1.1972658375d66p+0,  0x1.1f00p-46,
+  0x1.1a35beb6fcba7p+0,  0x1.0480p-46,
+  0x1.1af99f81387e3p+0, -0x1.7390p-43,
+  0x1.1bbe084045d54p+0,  0x1.4e40p-45,
+  0x1.1c82f95281c43p+0, -0x1.a200p-47,
+  0x1.1d4873168b9b2p+0,  0x1.3800p-49,
+  0x1.1e0e75eb44031p+0,  0x1.ac00p-49,
+  0x1.1ed5022fcd938p+0,  0x1.1900p-47,
+  0x1.1f9c18438cdf7p+0, -0x1.b780p-46,
+  0x1.2063b88628d8fp+0,  0x1.d940p-45,
+  0x1.212be3578a81ep+0,  0x1.8000p-50,
+  0x1.21f49917ddd41p+0,  0x1.b340p-45,
+  0x1.22bdda2791323p+0,  0x1.9f80p-46,
+  0x1.2387a6e7561e7p+0, -0x1.9c80p-46,
+  0x1.2451ffb821427p+0,  0x1.2300p-47,
+  0x1.251ce4fb2a602p+0, -0x1.3480p-46,
+  0x1.25e85711eceb0p+0,  0x1.2700p-46,
+  0x1.26b4565e27d16p+0,  0x1.1d00p-46,
+  0x1.2780e341de00fp+0,  0x1.1ee0p-44,
+  0x1.284dfe1f5633ep+0, -0x1.4c00p-46,
+  0x1.291ba7591bb30p+0, -0x1.3d80p-46,
+  0x1.29e9df51fdf09p+0,  0x1.8b00p-47,
+  0x1.2ab8a66d10e9bp+0, -0x1.27c0p-45,
+  0x1.2b87fd0dada3ap+0,  0x1.a340p-45,
+  0x1.2c57e39771af9p+0, -0x1.0800p-46,
+  0x1.2d285a6e402d9p+0, -0x1.ed00p-47,
+  0x1.2df961f641579p+0, -0x1.4200p-48,
+  0x1.2ecafa93e2ecfp+0, -0x1.4980p-45,
+  0x1.2f9d24abd8822p+0, -0x1.6300p-46,
+  0x1.306fe0a31b625p+0, -0x1.2360p-44,
+  0x1.31432edeea50bp+0, -0x1.0df8p-40,
+  0x1.32170fc4cd7b8p+0, -0x1.2480p-45,
+  0x1.32eb83ba8e9a2p+0, -0x1.5980p-45,
+  0x1.33c08b2641766p+0,  0x1.ed00p-46,
+  0x1.3496266e3fa27p+0, -0x1.c000p-50,
+  0x1.356c55f929f0fp+0, -0x1.0d80p-44,
+  0x1.36431a2de88b9p+0,  0x1.2c80p-45,
+  0x1.371a7373aaa39p+0,  0x1.0600p-45,
+  0x1.37f26231e74fep+0, -0x1.6600p-46,
+  0x1.38cae6d05d838p+0, -0x1.ae00p-47,
+  0x1.39a401b713ec3p+0, -0x1.4720p-43,
+  0x1.3a7db34e5a020p+0,  0x1.8200p-47,
+  0x1.3b57fbfec6e95p+0,  0x1.e800p-44,
+  0x1.3c32dc313a8f2p+0,  0x1.f800p-49,
+  0x1.3d0e544ede122p+0, -0x1.7a00p-46,
+  0x1.3dea64c1234bbp+0,  0x1.6300p-45,
+  0x1.3ec70df1c4eccp+0, -0x1.8a60p-43,
+  0x1.3fa4504ac7e8cp+0, -0x1.cdc0p-44,
+  0x1.40822c367a0bbp+0,  0x1.5b80p-45,
+  0x1.4160a21f72e95p+0,  0x1.ec00p-46,
+  0x1.423fb27094646p+0, -0x1.3600p-46,
+  0x1.431f5d950a920p+0,  0x1.3980p-45,
+  0x1.43ffa3f84b9ebp+0,  0x1.a000p-48,
+  0x1.44e0860618919p+0, -0x1.6c00p-48,
+  0x1.45c2042a7d201p+0, -0x1.bc00p-47,
+  0x1.46a41ed1d0016p+0, -0x1.2800p-46,
+  0x1.4786d668b3326p+0,  0x1.0e00p-44,
+  0x1.486a2b5c13c00p+0, -0x1.d400p-45,
+  0x1.494e1e192af04p+0,  0x1.c200p-47,
+  0x1.4a32af0d7d372p+0, -0x1.e500p-46,
+  0x1.4b17dea6db801p+0,  0x1.7800p-47,
+  0x1.4bfdad53629e1p+0, -0x1.3800p-46,
+  0x1.4ce41b817c132p+0,  0x1.0800p-47,
+  0x1.4dcb299fddddbp+0,  0x1.c700p-45,
+  0x1.4eb2d81d8ab96p+0, -0x1.ce00p-46,
+  0x1.4f9b2769d2d02p+0,  0x1.9200p-46,
+  0x1.508417f4531c1p+0, -0x1.8c00p-47,
+  0x1.516daa2cf662ap+0, -0x1.a000p-48,
+  0x1.5257de83f51eap+0,  0x1.a080p-43,
+  0x1.5342b569d4edap+0, -0x1.6d80p-45,
+  0x1.542e2f4f6ac1ap+0, -0x1.2440p-44,
+  0x1.551a4ca5d94dbp+0,  0x1.83c0p-43,
+  0x1.56070dde9116bp+0,  0x1.4b00p-45,
+  0x1.56f4736b529dep+0,  0x1.15a0p-43,
+  0x1.57e27dbe2c40ep+0, -0x1.9e00p-45,
+  0x1.58d12d497c76fp+0, -0x1.3080p-45,
+  0x1.59c0827ff0b4cp+0,  0x1.dec0p-43,
+  0x1.5ab07dd485427p+0, -0x1.4000p-51,
+  0x1.5ba11fba87af4p+0,  0x1.0080p-44,
+  0x1.5c9268a59460bp+0, -0x1.6c80p-45,
+  0x1.5d84590998e3fp+0,  0x1.69a0p-43,
+  0x1.5e76f15ad20e1p+0, -0x1.b400p-46,
+  0x1.5f6a320dcebcap+0,  0x1.7700p-46,
+  0x1.605e1b976dcb8p+0,  0x1.6f80p-45,
+  0x1.6152ae6cdf715p+0,  0x1.1000p-47,
+  0x1.6247eb03a5531p+0, -0x1.5d00p-46,
+  0x1.633dd1d1929b5p+0, -0x1.2d00p-46,
+  0x1.6434634ccc313p+0, -0x1.a800p-49,
+  0x1.652b9febc8efap+0, -0x1.8600p-45,
+  0x1.6623882553397p+0,  0x1.1fe0p-40,
+  0x1.671c1c708328ep+0, -0x1.7200p-44,
+  0x1.68155d44ca97ep+0,  0x1.6800p-49,
+  0x1.690f4b19e9471p+0, -0x1.9780p-45,
+};
+
+/*
+ * exp2(x): compute the base 2 exponential of x
+ *
+ * Accuracy: Peak error < 0.503 ulp for normalized results.
+ *
+ * Method: (accurate tables)
+ *
+ *   Reduce x:
+ *     x = k + y, for integer k and |y| <= 1/2.
+ *     Thus we have exp2(x) = 2**k * exp2(y).
+ *
+ *   Reduce y:
+ *     y = i/TBLSIZE + z - eps[i] for integer i near y * TBLSIZE.
+ *     Thus we have exp2(y) = exp2(i/TBLSIZE) * exp2(z - eps[i]),
+ *     with |z - eps[i]| <= 2**-9 + 2**-39 for the table used.
+ *
+ *   We compute exp2(i/TBLSIZE) via table lookup and exp2(z - eps[i]) via
+ *   a degree-5 minimax polynomial with maximum error under 1.3 * 2**-61.
+ *   The values in exp2t[] and eps[] are chosen such that
+ *   exp2t[i] = exp2(i/TBLSIZE + eps[i]), and eps[i] is a small offset such
+ *   that exp2t[i] is accurate to 2**-64.
+ *
+ *   Note that the range of i is +-TBLSIZE/2, so we actually index the tables
+ *   by i0 = i + TBLSIZE/2.  For cache efficiency, exp2t[] and eps[] are
+ *   virtual tables, interleaved in the real table tbl[].
+ *
+ *   This method is due to Gal, with many details due to Gal and Bachelis:
+ *
+ *      Gal, S. and Bachelis, B.  An Accurate Elementary Mathematical Library
+ *      for the IEEE Floating Point Standard.  TOMS 17(1), 26-46 (1991).
+ */
+double exp2(double x)
+{
+	double_t r, t, z;
+	uint32_t ix, i0;
+	union {double f; uint64_t i;} u = {x};
+	union {uint32_t u; int32_t i;} k;
+
+	/* Filter out exceptional cases. */
+	ix = u.i>>32 & 0x7fffffff;
+	if (ix >= 0x408ff000) {  /* |x| >= 1022 or nan */
+		if (ix >= 0x40900000 && u.i>>63 == 0) {  /* x >= 1024 or nan */
+			/* overflow */
+			x *= 0x1p1023;
+			return x;
+		}
+		if (ix >= 0x7ff00000)  /* -inf or -nan */
+			return -1/x;
+		if (u.i>>63) {  /* x <= -1022 */
+			/* underflow */
+			if (x <= -1075 || x - 0x1p52 + 0x1p52 != x)
+				FORCE_EVAL((float)(-0x1p-149/x));
+			if (x <= -1075)
+				return 0;
+		}
+	} else if (ix < 0x3c900000) {  /* |x| < 0x1p-54 */
+		return 1.0 + x;
+	}
+
+	/* Reduce x, computing z, i0, and k. */
+	u.f = x + redux;
+	i0 = u.i;
+	i0 += TBLSIZE / 2;
+	k.u = i0 / TBLSIZE * TBLSIZE;
+	k.i /= TBLSIZE;
+	i0 %= TBLSIZE;
+	u.f -= redux;
+	z = x - u.f;
+
+	/* Compute r = exp2(y) = exp2t[i0] * p(z - eps[i]). */
+	t = tbl[2*i0];       /* exp2t[i0] */
+	z -= tbl[2*i0 + 1];  /* eps[i0]   */
+	r = t + t * z * (P1 + z * (P2 + z * (P3 + z * (P4 + z * P5))));
+
+	return scalbn(r, k.i);
+}
libc/musl/src/math/exp2f.c
@@ -0,0 +1,126 @@
+/* origin: FreeBSD /usr/src/lib/msun/src/s_exp2f.c */
+/*-
+ * Copyright (c) 2005 David Schultz <das@FreeBSD.ORG>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include "libm.h"
+
+#define TBLSIZE 16
+
+static const float
+redux = 0x1.8p23f / TBLSIZE,
+P1    = 0x1.62e430p-1f,
+P2    = 0x1.ebfbe0p-3f,
+P3    = 0x1.c6b348p-5f,
+P4    = 0x1.3b2c9cp-7f;
+
+static const double exp2ft[TBLSIZE] = {
+  0x1.6a09e667f3bcdp-1,
+  0x1.7a11473eb0187p-1,
+  0x1.8ace5422aa0dbp-1,
+  0x1.9c49182a3f090p-1,
+  0x1.ae89f995ad3adp-1,
+  0x1.c199bdd85529cp-1,
+  0x1.d5818dcfba487p-1,
+  0x1.ea4afa2a490dap-1,
+  0x1.0000000000000p+0,
+  0x1.0b5586cf9890fp+0,
+  0x1.172b83c7d517bp+0,
+  0x1.2387a6e756238p+0,
+  0x1.306fe0a31b715p+0,
+  0x1.3dea64c123422p+0,
+  0x1.4bfdad5362a27p+0,
+  0x1.5ab07dd485429p+0,
+};
+
+/*
+ * exp2f(x): compute the base 2 exponential of x
+ *
+ * Accuracy: Peak error < 0.501 ulp; location of peak: -0.030110927.
+ *
+ * Method: (equally-spaced tables)
+ *
+ *   Reduce x:
+ *     x = k + y, for integer k and |y| <= 1/2.
+ *     Thus we have exp2f(x) = 2**k * exp2(y).
+ *
+ *   Reduce y:
+ *     y = i/TBLSIZE + z for integer i near y * TBLSIZE.
+ *     Thus we have exp2(y) = exp2(i/TBLSIZE) * exp2(z),
+ *     with |z| <= 2**-(TBLSIZE+1).
+ *
+ *   We compute exp2(i/TBLSIZE) via table lookup and exp2(z) via a
+ *   degree-4 minimax polynomial with maximum error under 1.4 * 2**-33.
+ *   Using double precision for everything except the reduction makes
+ *   roundoff error insignificant and simplifies the scaling step.
+ *
+ *   This method is due to Tang, but I do not use his suggested parameters:
+ *
+ *      Tang, P.  Table-driven Implementation of the Exponential Function
+ *      in IEEE Floating-Point Arithmetic.  TOMS 15(2), 144-157 (1989).
+ */
+float exp2f(float x)
+{
+	double_t t, r, z;
+	union {float f; uint32_t i;} u = {x};
+	union {double f; uint64_t i;} uk;
+	uint32_t ix, i0, k;
+
+	/* Filter out exceptional cases. */
+	ix = u.i & 0x7fffffff;
+	if (ix > 0x42fc0000) {  /* |x| > 126 */
+		if (ix > 0x7f800000) /* NaN */
+			return x;
+		if (u.i >= 0x43000000 && u.i < 0x80000000) {  /* x >= 128 */
+			x *= 0x1p127f;
+			return x;
+		}
+		if (u.i >= 0x80000000) {  /* x < -126 */
+			if (u.i >= 0xc3160000 || (u.i & 0x0000ffff))
+				FORCE_EVAL(-0x1p-149f/x);
+			if (u.i >= 0xc3160000)  /* x <= -150 */
+				return 0;
+		}
+	} else if (ix <= 0x33000000) {  /* |x| <= 0x1p-25 */
+		return 1.0f + x;
+	}
+
+	/* Reduce x, computing z, i0, and k. */
+	u.f = x + redux;
+	i0 = u.i;
+	i0 += TBLSIZE / 2;
+	k = i0 / TBLSIZE;
+	uk.i = (uint64_t)(0x3ff + k)<<52;
+	i0 &= TBLSIZE - 1;
+	u.f -= redux;
+	z = x - u.f;
+	/* Compute r = exp2(y) = exp2ft[i0] * p(z). */
+	r = exp2ft[i0];
+	t = r * z;
+	r = r + t * (P1 + z * P2) + t * (z * z) * (P3 + z * P4);
+
+	/* Scale by 2**k */
+	return r * uk.f;
+}
libc/musl/src/math/exp2l.c
@@ -0,0 +1,619 @@
+/* origin: FreeBSD /usr/src/lib/msun/ld80/s_exp2l.c and /usr/src/lib/msun/ld128/s_exp2l.c */
+/*-
+ * Copyright (c) 2005-2008 David Schultz <das@FreeBSD.ORG>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include "libm.h"
+
+#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024
+long double exp2l(long double x)
+{
+	return exp2(x);
+}
+#elif LDBL_MANT_DIG == 64 && LDBL_MAX_EXP == 16384
+#define TBLBITS 7
+#define TBLSIZE (1 << TBLBITS)
+
+static const double
+redux = 0x1.8p63 / TBLSIZE,
+P1    = 0x1.62e42fefa39efp-1,
+P2    = 0x1.ebfbdff82c58fp-3,
+P3    = 0x1.c6b08d7049fap-5,
+P4    = 0x1.3b2ab6fba4da5p-7,
+P5    = 0x1.5d8804780a736p-10,
+P6    = 0x1.430918835e33dp-13;
+
+static const double tbl[TBLSIZE * 2] = {
+	0x1.6a09e667f3bcdp-1,   -0x1.bdd3413b2648p-55,
+	0x1.6c012750bdabfp-1,   -0x1.2895667ff0cp-57,
+	0x1.6dfb23c651a2fp-1,   -0x1.bbe3a683c88p-58,
+	0x1.6ff7df9519484p-1,   -0x1.83c0f25860fp-56,
+	0x1.71f75e8ec5f74p-1,   -0x1.16e4786887bp-56,
+	0x1.73f9a48a58174p-1,   -0x1.0a8d96c65d5p-55,
+	0x1.75feb564267c9p-1,   -0x1.0245957316ep-55,
+	0x1.780694fde5d3fp-1,    0x1.866b80a0216p-55,
+	0x1.7a11473eb0187p-1,   -0x1.41577ee0499p-56,
+	0x1.7c1ed0130c132p-1,    0x1.f124cd1164ep-55,
+	0x1.7e2f336cf4e62p-1,    0x1.05d02ba157ap-57,
+	0x1.80427543e1a12p-1,   -0x1.27c86626d97p-55,
+	0x1.82589994cce13p-1,   -0x1.d4c1dd41533p-55,
+	0x1.8471a4623c7adp-1,   -0x1.8d684a341cep-56,
+	0x1.868d99b4492edp-1,   -0x1.fc6f89bd4f68p-55,
+	0x1.88ac7d98a6699p-1,    0x1.994c2f37cb5p-55,
+	0x1.8ace5422aa0dbp-1,    0x1.6e9f156864bp-55,
+	0x1.8cf3216b5448cp-1,   -0x1.0d55e32e9e4p-57,
+	0x1.8f1ae99157736p-1,    0x1.5cc13a2e397p-56,
+	0x1.9145b0b91ffc6p-1,   -0x1.dd6792e5825p-55,
+	0x1.93737b0cdc5e5p-1,   -0x1.75fc781b58p-58,
+	0x1.95a44cbc8520fp-1,   -0x1.64b7c96a5fp-57,
+	0x1.97d829fde4e5p-1,    -0x1.d185b7c1b86p-55,
+	0x1.9a0f170ca07bap-1,   -0x1.173bd91cee6p-55,
+	0x1.9c49182a3f09p-1,     0x1.c7c46b071f2p-57,
+	0x1.9e86319e32323p-1,    0x1.824ca78e64cp-57,
+	0x1.a0c667b5de565p-1,   -0x1.359495d1cd5p-55,
+	0x1.a309bec4a2d33p-1,    0x1.6305c7ddc368p-55,
+	0x1.a5503b23e255dp-1,   -0x1.d2f6edb8d42p-55,
+	0x1.a799e1330b358p-1,    0x1.bcb7ecac564p-55,
+	0x1.a9e6b5579fdbfp-1,    0x1.0fac90ef7fdp-55,
+	0x1.ac36bbfd3f37ap-1,   -0x1.f9234cae76dp-56,
+	0x1.ae89f995ad3adp-1,    0x1.7a1cd345dcc8p-55,
+	0x1.b0e07298db666p-1,   -0x1.bdef54c80e4p-55,
+	0x1.b33a2b84f15fbp-1,   -0x1.2805e3084d8p-58,
+	0x1.b59728de5593ap-1,   -0x1.c71dfbbba6ep-55,
+	0x1.b7f76f2fb5e47p-1,   -0x1.5584f7e54acp-57,
+	0x1.ba5b030a1064ap-1,   -0x1.efcd30e5429p-55,
+	0x1.bcc1e904bc1d2p-1,    0x1.23dd07a2d9fp-56,
+	0x1.bf2c25bd71e09p-1,   -0x1.efdca3f6b9c8p-55,
+	0x1.c199bdd85529cp-1,    0x1.11065895049p-56,
+	0x1.c40ab5fffd07ap-1,    0x1.b4537e083c6p-55,
+	0x1.c67f12e57d14bp-1,    0x1.2884dff483c8p-55,
+	0x1.c8f6d9406e7b5p-1,    0x1.1acbc48805cp-57,
+	0x1.cb720dcef9069p-1,    0x1.503cbd1e94ap-57,
+	0x1.cdf0b555dc3fap-1,   -0x1.dd83b53829dp-56,
+	0x1.d072d4a07897cp-1,   -0x1.cbc3743797a8p-55,
+	0x1.d2f87080d89f2p-1,   -0x1.d487b719d858p-55,
+	0x1.d5818dcfba487p-1,    0x1.2ed02d75b37p-56,
+	0x1.d80e316c98398p-1,   -0x1.11ec18bedep-55,
+	0x1.da9e603db3285p-1,    0x1.c2300696db5p-55,
+	0x1.dd321f301b46p-1,     0x1.2da5778f019p-55,
+	0x1.dfc97337b9b5fp-1,   -0x1.1a5cd4f184b8p-55,
+	0x1.e264614f5a129p-1,   -0x1.7b627817a148p-55,
+	0x1.e502ee78b3ff6p-1,    0x1.39e8980a9cdp-56,
+	0x1.e7a51fbc74c83p-1,    0x1.2d522ca0c8ep-55,
+	0x1.ea4afa2a490dap-1,   -0x1.e9c23179c288p-55,
+	0x1.ecf482d8e67f1p-1,   -0x1.c93f3b411ad8p-55,
+	0x1.efa1bee615a27p-1,    0x1.dc7f486a4b68p-55,
+	0x1.f252b376bba97p-1,    0x1.3a1a5bf0d8e8p-55,
+	0x1.f50765b6e454p-1,     0x1.9d3e12dd8a18p-55,
+	0x1.f7bfdad9cbe14p-1,   -0x1.dbb12d00635p-55,
+	0x1.fa7c1819e90d8p-1,    0x1.74853f3a593p-56,
+	0x1.fd3c22b8f71f1p-1,    0x1.2eb74966578p-58,
+	0x1p+0,                  0x0p+0,
+	0x1.0163da9fb3335p+0,    0x1.b61299ab8cd8p-54,
+	0x1.02c9a3e778061p+0,   -0x1.19083535b08p-56,
+	0x1.04315e86e7f85p+0,   -0x1.0a31c1977c98p-54,
+	0x1.059b0d3158574p+0,    0x1.d73e2a475b4p-55,
+	0x1.0706b29ddf6dep+0,   -0x1.c91dfe2b13cp-55,
+	0x1.0874518759bc8p+0,    0x1.186be4bb284p-57,
+	0x1.09e3ecac6f383p+0,    0x1.14878183161p-54,
+	0x1.0b5586cf9890fp+0,    0x1.8a62e4adc61p-54,
+	0x1.0cc922b7247f7p+0,    0x1.01edc16e24f8p-54,
+	0x1.0e3ec32d3d1a2p+0,    0x1.03a1727c58p-59,
+	0x1.0fb66affed31bp+0,   -0x1.b9bedc44ebcp-57,
+	0x1.11301d0125b51p+0,   -0x1.6c51039449bp-54,
+	0x1.12abdc06c31ccp+0,   -0x1.1b514b36ca8p-58,
+	0x1.1429aaea92dep+0,    -0x1.32fbf9af1368p-54,
+	0x1.15a98c8a58e51p+0,    0x1.2406ab9eeabp-55,
+	0x1.172b83c7d517bp+0,   -0x1.19041b9d78ap-55,
+	0x1.18af9388c8deap+0,   -0x1.11023d1970f8p-54,
+	0x1.1a35beb6fcb75p+0,    0x1.e5b4c7b4969p-55,
+	0x1.1bbe084045cd4p+0,   -0x1.95386352ef6p-54,
+	0x1.1d4873168b9aap+0,    0x1.e016e00a264p-54,
+	0x1.1ed5022fcd91dp+0,   -0x1.1df98027bb78p-54,
+	0x1.2063b88628cd6p+0,    0x1.dc775814a85p-55,
+	0x1.21f49917ddc96p+0,    0x1.2a97e9494a6p-55,
+	0x1.2387a6e756238p+0,    0x1.9b07eb6c7058p-54,
+	0x1.251ce4fb2a63fp+0,    0x1.ac155bef4f5p-55,
+	0x1.26b4565e27cddp+0,    0x1.2bd339940eap-55,
+	0x1.284dfe1f56381p+0,   -0x1.a4c3a8c3f0d8p-54,
+	0x1.29e9df51fdee1p+0,    0x1.612e8afad12p-55,
+	0x1.2b87fd0dad99p+0,    -0x1.10adcd6382p-59,
+	0x1.2d285a6e4030bp+0,    0x1.0024754db42p-54,
+	0x1.2ecafa93e2f56p+0,    0x1.1ca0f45d524p-56,
+	0x1.306fe0a31b715p+0,    0x1.6f46ad23183p-55,
+	0x1.32170fc4cd831p+0,    0x1.a9ce78e1804p-55,
+	0x1.33c08b26416ffp+0,    0x1.327218436598p-54,
+	0x1.356c55f929ff1p+0,   -0x1.b5cee5c4e46p-55,
+	0x1.371a7373aa9cbp+0,   -0x1.63aeabf42ebp-54,
+	0x1.38cae6d05d866p+0,   -0x1.e958d3c99048p-54,
+	0x1.3a7db34e59ff7p+0,   -0x1.5e436d661f6p-56,
+	0x1.3c32dc313a8e5p+0,   -0x1.efff8375d2ap-54,
+	0x1.3dea64c123422p+0,    0x1.ada0911f09fp-55,
+	0x1.3fa4504ac801cp+0,   -0x1.7d023f956fap-54,
+	0x1.4160a21f72e2ap+0,   -0x1.ef3691c309p-58,
+	0x1.431f5d950a897p+0,   -0x1.1c7dde35f7ap-55,
+	0x1.44e086061892dp+0,    0x1.89b7a04ef8p-59,
+	0x1.46a41ed1d0057p+0,    0x1.c944bd1648a8p-54,
+	0x1.486a2b5c13cdp+0,     0x1.3c1a3b69062p-56,
+	0x1.4a32af0d7d3dep+0,    0x1.9cb62f3d1be8p-54,
+	0x1.4bfdad5362a27p+0,    0x1.d4397afec42p-56,
+	0x1.4dcb299fddd0dp+0,    0x1.8ecdbbc6a78p-54,
+	0x1.4f9b2769d2ca7p+0,   -0x1.4b309d25958p-54,
+	0x1.516daa2cf6642p+0,   -0x1.f768569bd94p-55,
+	0x1.5342b569d4f82p+0,   -0x1.07abe1db13dp-55,
+	0x1.551a4ca5d920fp+0,   -0x1.d689cefede6p-55,
+	0x1.56f4736b527dap+0,    0x1.9bb2c011d938p-54,
+	0x1.58d12d497c7fdp+0,    0x1.295e15b9a1ep-55,
+	0x1.5ab07dd485429p+0,    0x1.6324c0546478p-54,
+	0x1.5c9268a5946b7p+0,    0x1.c4b1b81698p-60,
+	0x1.5e76f15ad2148p+0,    0x1.ba6f93080e68p-54,
+	0x1.605e1b976dc09p+0,   -0x1.3e2429b56de8p-54,
+	0x1.6247eb03a5585p+0,   -0x1.383c17e40b48p-54,
+	0x1.6434634ccc32p+0,    -0x1.c483c759d89p-55,
+	0x1.6623882552225p+0,   -0x1.bb60987591cp-54,
+	0x1.68155d44ca973p+0,    0x1.038ae44f74p-57,
+};
+
+/*
+ * exp2l(x): compute the base 2 exponential of x
+ *
+ * Accuracy: Peak error < 0.511 ulp.
+ *
+ * Method: (equally-spaced tables)
+ *
+ *   Reduce x:
+ *     x = 2**k + y, for integer k and |y| <= 1/2.
+ *     Thus we have exp2l(x) = 2**k * exp2(y).
+ *
+ *   Reduce y:
+ *     y = i/TBLSIZE + z for integer i near y * TBLSIZE.
+ *     Thus we have exp2(y) = exp2(i/TBLSIZE) * exp2(z),
+ *     with |z| <= 2**-(TBLBITS+1).
+ *
+ *   We compute exp2(i/TBLSIZE) via table lookup and exp2(z) via a
+ *   degree-6 minimax polynomial with maximum error under 2**-69.
+ *   The table entries each have 104 bits of accuracy, encoded as
+ *   a pair of double precision values.
+ */
+long double exp2l(long double x)
+{
+	union ldshape u = {x};
+	int e = u.i.se & 0x7fff;
+	long double r, z;
+	uint32_t i0;
+	union {uint32_t u; int32_t i;} k;
+
+	/* Filter out exceptional cases. */
+	if (e >= 0x3fff + 13) {  /* |x| >= 8192 or x is NaN */
+		if (u.i.se >= 0x3fff + 14 && u.i.se >> 15 == 0)
+			/* overflow */
+			return x * 0x1p16383L;
+		if (e == 0x7fff)  /* -inf or -nan */
+			return -1/x;
+		if (x < -16382) {
+			if (x <= -16446 || x - 0x1p63 + 0x1p63 != x)
+				/* underflow */
+				FORCE_EVAL((float)(-0x1p-149/x));
+			if (x <= -16446)
+				return 0;
+		}
+	} else if (e < 0x3fff - 64) {
+		return 1 + x;
+	}
+
+	/*
+	 * Reduce x, computing z, i0, and k. The low bits of x + redux
+	 * contain the 16-bit integer part of the exponent (k) followed by
+	 * TBLBITS fractional bits (i0). We use bit tricks to extract these
+	 * as integers, then set z to the remainder.
+	 *
+	 * Example: Suppose x is 0xabc.123456p0 and TBLBITS is 8.
+	 * Then the low-order word of x + redux is 0x000abc12,
+	 * We split this into k = 0xabc and i0 = 0x12 (adjusted to
+	 * index into the table), then we compute z = 0x0.003456p0.
+	 */
+	u.f = x + redux;
+	i0 = u.i.m + TBLSIZE / 2;
+	k.u = i0 / TBLSIZE * TBLSIZE;
+	k.i /= TBLSIZE;
+	i0 %= TBLSIZE;
+	u.f -= redux;
+	z = x - u.f;
+
+	/* Compute r = exp2l(y) = exp2lt[i0] * p(z). */
+	long double t_hi = tbl[2*i0];
+	long double t_lo = tbl[2*i0 + 1];
+	/* XXX This gives > 1 ulp errors outside of FE_TONEAREST mode */
+	r = t_lo + (t_hi + t_lo) * z * (P1 + z * (P2 + z * (P3 + z * (P4
+	     + z * (P5 + z * P6))))) + t_hi;
+
+	return scalbnl(r, k.i);
+}
+#elif LDBL_MANT_DIG == 113 && LDBL_MAX_EXP == 16384
+#define TBLBITS 7
+#define TBLSIZE (1 << TBLBITS)
+
+static const long double
+    P1        = 0x1.62e42fefa39ef35793c7673007e6p-1L,
+    P2        = 0x1.ebfbdff82c58ea86f16b06ec9736p-3L,
+    P3        = 0x1.c6b08d704a0bf8b33a762bad3459p-5L,
+    P4        = 0x1.3b2ab6fba4e7729ccbbe0b4f3fc2p-7L,
+    P5        = 0x1.5d87fe78a67311071dee13fd11d9p-10L,
+    P6        = 0x1.430912f86c7876f4b663b23c5fe5p-13L;
+
+static const double
+    P7        = 0x1.ffcbfc588b041p-17,
+    P8        = 0x1.62c0223a5c7c7p-20,
+    P9        = 0x1.b52541ff59713p-24,
+    P10       = 0x1.e4cf56a391e22p-28,
+    redux     = 0x1.8p112 / TBLSIZE;
+
+static const long double tbl[TBLSIZE] = {
+	0x1.6a09e667f3bcc908b2fb1366dfeap-1L,
+	0x1.6c012750bdabeed76a99800f4edep-1L,
+	0x1.6dfb23c651a2ef220e2cbe1bc0d4p-1L,
+	0x1.6ff7df9519483cf87e1b4f3e1e98p-1L,
+	0x1.71f75e8ec5f73dd2370f2ef0b148p-1L,
+	0x1.73f9a48a58173bd5c9a4e68ab074p-1L,
+	0x1.75feb564267c8bf6e9aa33a489a8p-1L,
+	0x1.780694fde5d3f619ae02808592a4p-1L,
+	0x1.7a11473eb0186d7d51023f6ccb1ap-1L,
+	0x1.7c1ed0130c1327c49334459378dep-1L,
+	0x1.7e2f336cf4e62105d02ba1579756p-1L,
+	0x1.80427543e1a11b60de67649a3842p-1L,
+	0x1.82589994cce128acf88afab34928p-1L,
+	0x1.8471a4623c7acce52f6b97c6444cp-1L,
+	0x1.868d99b4492ec80e41d90ac2556ap-1L,
+	0x1.88ac7d98a669966530bcdf2d4cc0p-1L,
+	0x1.8ace5422aa0db5ba7c55a192c648p-1L,
+	0x1.8cf3216b5448bef2aa1cd161c57ap-1L,
+	0x1.8f1ae991577362b982745c72eddap-1L,
+	0x1.9145b0b91ffc588a61b469f6b6a0p-1L,
+	0x1.93737b0cdc5e4f4501c3f2540ae8p-1L,
+	0x1.95a44cbc8520ee9b483695a0e7fep-1L,
+	0x1.97d829fde4e4f8b9e920f91e8eb6p-1L,
+	0x1.9a0f170ca07b9ba3109b8c467844p-1L,
+	0x1.9c49182a3f0901c7c46b071f28dep-1L,
+	0x1.9e86319e323231824ca78e64c462p-1L,
+	0x1.a0c667b5de564b29ada8b8cabbacp-1L,
+	0x1.a309bec4a2d3358c171f770db1f4p-1L,
+	0x1.a5503b23e255c8b424491caf88ccp-1L,
+	0x1.a799e1330b3586f2dfb2b158f31ep-1L,
+	0x1.a9e6b5579fdbf43eb243bdff53a2p-1L,
+	0x1.ac36bbfd3f379c0db966a3126988p-1L,
+	0x1.ae89f995ad3ad5e8734d17731c80p-1L,
+	0x1.b0e07298db66590842acdfc6fb4ep-1L,
+	0x1.b33a2b84f15faf6bfd0e7bd941b0p-1L,
+	0x1.b59728de559398e3881111648738p-1L,
+	0x1.b7f76f2fb5e46eaa7b081ab53ff6p-1L,
+	0x1.ba5b030a10649840cb3c6af5b74cp-1L,
+	0x1.bcc1e904bc1d2247ba0f45b3d06cp-1L,
+	0x1.bf2c25bd71e088408d7025190cd0p-1L,
+	0x1.c199bdd85529c2220cb12a0916bap-1L,
+	0x1.c40ab5fffd07a6d14df820f17deap-1L,
+	0x1.c67f12e57d14b4a2137fd20f2a26p-1L,
+	0x1.c8f6d9406e7b511acbc48805c3f6p-1L,
+	0x1.cb720dcef90691503cbd1e949d0ap-1L,
+	0x1.cdf0b555dc3f9c44f8958fac4f12p-1L,
+	0x1.d072d4a07897b8d0f22f21a13792p-1L,
+	0x1.d2f87080d89f18ade123989ea50ep-1L,
+	0x1.d5818dcfba48725da05aeb66dff8p-1L,
+	0x1.d80e316c98397bb84f9d048807a0p-1L,
+	0x1.da9e603db3285708c01a5b6d480cp-1L,
+	0x1.dd321f301b4604b695de3c0630c0p-1L,
+	0x1.dfc97337b9b5eb968cac39ed284cp-1L,
+	0x1.e264614f5a128a12761fa17adc74p-1L,
+	0x1.e502ee78b3ff6273d130153992d0p-1L,
+	0x1.e7a51fbc74c834b548b2832378a4p-1L,
+	0x1.ea4afa2a490d9858f73a18f5dab4p-1L,
+	0x1.ecf482d8e67f08db0312fb949d50p-1L,
+	0x1.efa1bee615a27771fd21a92dabb6p-1L,
+	0x1.f252b376bba974e8696fc3638f24p-1L,
+	0x1.f50765b6e4540674f84b762861a6p-1L,
+	0x1.f7bfdad9cbe138913b4bfe72bd78p-1L,
+	0x1.fa7c1819e90d82e90a7e74b26360p-1L,
+	0x1.fd3c22b8f71f10975ba4b32bd006p-1L,
+	0x1.0000000000000000000000000000p+0L,
+	0x1.0163da9fb33356d84a66ae336e98p+0L,
+	0x1.02c9a3e778060ee6f7caca4f7a18p+0L,
+	0x1.04315e86e7f84bd738f9a20da442p+0L,
+	0x1.059b0d31585743ae7c548eb68c6ap+0L,
+	0x1.0706b29ddf6ddc6dc403a9d87b1ep+0L,
+	0x1.0874518759bc808c35f25d942856p+0L,
+	0x1.09e3ecac6f3834521e060c584d5cp+0L,
+	0x1.0b5586cf9890f6298b92b7184200p+0L,
+	0x1.0cc922b7247f7407b705b893dbdep+0L,
+	0x1.0e3ec32d3d1a2020742e4f8af794p+0L,
+	0x1.0fb66affed31af232091dd8a169ep+0L,
+	0x1.11301d0125b50a4ebbf1aed9321cp+0L,
+	0x1.12abdc06c31cbfb92bad324d6f84p+0L,
+	0x1.1429aaea92ddfb34101943b2588ep+0L,
+	0x1.15a98c8a58e512480d573dd562aep+0L,
+	0x1.172b83c7d517adcdf7c8c50eb162p+0L,
+	0x1.18af9388c8de9bbbf70b9a3c269cp+0L,
+	0x1.1a35beb6fcb753cb698f692d2038p+0L,
+	0x1.1bbe084045cd39ab1e72b442810ep+0L,
+	0x1.1d4873168b9aa7805b8028990be8p+0L,
+	0x1.1ed5022fcd91cb8819ff61121fbep+0L,
+	0x1.2063b88628cd63b8eeb0295093f6p+0L,
+	0x1.21f49917ddc962552fd29294bc20p+0L,
+	0x1.2387a6e75623866c1fadb1c159c0p+0L,
+	0x1.251ce4fb2a63f3582ab7de9e9562p+0L,
+	0x1.26b4565e27cdd257a673281d3068p+0L,
+	0x1.284dfe1f5638096cf15cf03c9fa0p+0L,
+	0x1.29e9df51fdee12c25d15f5a25022p+0L,
+	0x1.2b87fd0dad98ffddea46538fca24p+0L,
+	0x1.2d285a6e4030b40091d536d0733ep+0L,
+	0x1.2ecafa93e2f5611ca0f45d5239a4p+0L,
+	0x1.306fe0a31b7152de8d5a463063bep+0L,
+	0x1.32170fc4cd8313539cf1c3009330p+0L,
+	0x1.33c08b26416ff4c9c8610d96680ep+0L,
+	0x1.356c55f929ff0c94623476373be4p+0L,
+	0x1.371a7373aa9caa7145502f45452ap+0L,
+	0x1.38cae6d05d86585a9cb0d9bed530p+0L,
+	0x1.3a7db34e59ff6ea1bc9299e0a1fep+0L,
+	0x1.3c32dc313a8e484001f228b58cf0p+0L,
+	0x1.3dea64c12342235b41223e13d7eep+0L,
+	0x1.3fa4504ac801ba0bf701aa417b9cp+0L,
+	0x1.4160a21f72e29f84325b8f3dbacap+0L,
+	0x1.431f5d950a896dc704439410b628p+0L,
+	0x1.44e086061892d03136f409df0724p+0L,
+	0x1.46a41ed1d005772512f459229f0ap+0L,
+	0x1.486a2b5c13cd013c1a3b69062f26p+0L,
+	0x1.4a32af0d7d3de672d8bcf46f99b4p+0L,
+	0x1.4bfdad5362a271d4397afec42e36p+0L,
+	0x1.4dcb299fddd0d63b36ef1a9e19dep+0L,
+	0x1.4f9b2769d2ca6ad33d8b69aa0b8cp+0L,
+	0x1.516daa2cf6641c112f52c84d6066p+0L,
+	0x1.5342b569d4f81df0a83c49d86bf4p+0L,
+	0x1.551a4ca5d920ec52ec620243540cp+0L,
+	0x1.56f4736b527da66ecb004764e61ep+0L,
+	0x1.58d12d497c7fd252bc2b7343d554p+0L,
+	0x1.5ab07dd48542958c93015191e9a8p+0L,
+	0x1.5c9268a5946b701c4b1b81697ed4p+0L,
+	0x1.5e76f15ad21486e9be4c20399d12p+0L,
+	0x1.605e1b976dc08b076f592a487066p+0L,
+	0x1.6247eb03a5584b1f0fa06fd2d9eap+0L,
+	0x1.6434634ccc31fc76f8714c4ee122p+0L,
+	0x1.66238825522249127d9e29b92ea2p+0L,
+	0x1.68155d44ca973081c57227b9f69ep+0L,
+};
+
+static const float eps[TBLSIZE] = {
+	-0x1.5c50p-101,
+	-0x1.5d00p-106,
+	 0x1.8e90p-102,
+	-0x1.5340p-103,
+	 0x1.1bd0p-102,
+	-0x1.4600p-105,
+	-0x1.7a40p-104,
+	 0x1.d590p-102,
+	-0x1.d590p-101,
+	 0x1.b100p-103,
+	-0x1.0d80p-105,
+	 0x1.6b00p-103,
+	-0x1.9f00p-105,
+	 0x1.c400p-103,
+	 0x1.e120p-103,
+	-0x1.c100p-104,
+	-0x1.9d20p-103,
+	 0x1.a800p-108,
+	 0x1.4c00p-106,
+	-0x1.9500p-106,
+	 0x1.6900p-105,
+	-0x1.29d0p-100,
+	 0x1.4c60p-103,
+	 0x1.13a0p-102,
+	-0x1.5b60p-103,
+	-0x1.1c40p-103,
+	 0x1.db80p-102,
+	 0x1.91a0p-102,
+	 0x1.dc00p-105,
+	 0x1.44c0p-104,
+	 0x1.9710p-102,
+	 0x1.8760p-103,
+	-0x1.a720p-103,
+	 0x1.ed20p-103,
+	-0x1.49c0p-102,
+	-0x1.e000p-111,
+	 0x1.86a0p-103,
+	 0x1.2b40p-103,
+	-0x1.b400p-108,
+	 0x1.1280p-99,
+	-0x1.02d8p-102,
+	-0x1.e3d0p-103,
+	-0x1.b080p-105,
+	-0x1.f100p-107,
+	-0x1.16c0p-105,
+	-0x1.1190p-103,
+	-0x1.a7d2p-100,
+	 0x1.3450p-103,
+	-0x1.67c0p-105,
+	 0x1.4b80p-104,
+	-0x1.c4e0p-103,
+	 0x1.6000p-108,
+	-0x1.3f60p-105,
+	 0x1.93f0p-104,
+	 0x1.5fe0p-105,
+	 0x1.6f80p-107,
+	-0x1.7600p-106,
+	 0x1.21e0p-106,
+	-0x1.3a40p-106,
+	-0x1.40c0p-104,
+	-0x1.9860p-105,
+	-0x1.5d40p-108,
+	-0x1.1d70p-106,
+	 0x1.2760p-105,
+	 0x0.0000p+0,
+	 0x1.21e2p-104,
+	-0x1.9520p-108,
+	-0x1.5720p-106,
+	-0x1.4810p-106,
+	-0x1.be00p-109,
+	 0x1.0080p-105,
+	-0x1.5780p-108,
+	-0x1.d460p-105,
+	-0x1.6140p-105,
+	 0x1.4630p-104,
+	 0x1.ad50p-103,
+	 0x1.82e0p-105,
+	 0x1.1d3cp-101,
+	 0x1.6100p-107,
+	 0x1.ec30p-104,
+	 0x1.f200p-108,
+	 0x1.0b40p-103,
+	 0x1.3660p-102,
+	 0x1.d9d0p-103,
+	-0x1.02d0p-102,
+	 0x1.b070p-103,
+	 0x1.b9c0p-104,
+	-0x1.01c0p-103,
+	-0x1.dfe0p-103,
+	 0x1.1b60p-104,
+	-0x1.ae94p-101,
+	-0x1.3340p-104,
+	 0x1.b3d8p-102,
+	-0x1.6e40p-105,
+	-0x1.3670p-103,
+	 0x1.c140p-104,
+	 0x1.1840p-101,
+	 0x1.1ab0p-102,
+	-0x1.a400p-104,
+	 0x1.1f00p-104,
+	-0x1.7180p-103,
+	 0x1.4ce0p-102,
+	 0x1.9200p-107,
+	-0x1.54c0p-103,
+	 0x1.1b80p-105,
+	-0x1.1828p-101,
+	 0x1.5720p-102,
+	-0x1.a060p-100,
+	 0x1.9160p-102,
+	 0x1.a280p-104,
+	 0x1.3400p-107,
+	 0x1.2b20p-102,
+	 0x1.7800p-108,
+	 0x1.cfd0p-101,
+	 0x1.2ef0p-102,
+	-0x1.2760p-99,
+	 0x1.b380p-104,
+	 0x1.0048p-101,
+	-0x1.60b0p-102,
+	 0x1.a1ccp-100,
+	-0x1.a640p-104,
+	-0x1.08a0p-101,
+	 0x1.7e60p-102,
+	 0x1.22c0p-103,
+	-0x1.7200p-106,
+	 0x1.f0f0p-102,
+	 0x1.eb4ep-99,
+	 0x1.c6e0p-103,
+};
+
+/*
+ * exp2l(x): compute the base 2 exponential of x
+ *
+ * Accuracy: Peak error < 0.502 ulp.
+ *
+ * Method: (accurate tables)
+ *
+ *   Reduce x:
+ *     x = 2**k + y, for integer k and |y| <= 1/2.
+ *     Thus we have exp2(x) = 2**k * exp2(y).
+ *
+ *   Reduce y:
+ *     y = i/TBLSIZE + z - eps[i] for integer i near y * TBLSIZE.
+ *     Thus we have exp2(y) = exp2(i/TBLSIZE) * exp2(z - eps[i]),
+ *     with |z - eps[i]| <= 2**-8 + 2**-98 for the table used.
+ *
+ *   We compute exp2(i/TBLSIZE) via table lookup and exp2(z - eps[i]) via
+ *   a degree-10 minimax polynomial with maximum error under 2**-120.
+ *   The values in exp2t[] and eps[] are chosen such that
+ *   exp2t[i] = exp2(i/TBLSIZE + eps[i]), and eps[i] is a small offset such
+ *   that exp2t[i] is accurate to 2**-122.
+ *
+ *   Note that the range of i is +-TBLSIZE/2, so we actually index the tables
+ *   by i0 = i + TBLSIZE/2.
+ *
+ *   This method is due to Gal, with many details due to Gal and Bachelis:
+ *
+ *	Gal, S. and Bachelis, B.  An Accurate Elementary Mathematical Library
+ *	for the IEEE Floating Point Standard.  TOMS 17(1), 26-46 (1991).
+ */
+long double
+exp2l(long double x)
+{
+	union ldshape u = {x};
+	int e = u.i.se & 0x7fff;
+	long double r, z, t;
+	uint32_t i0;
+	union {uint32_t u; int32_t i;} k;
+
+	/* Filter out exceptional cases. */
+	if (e >= 0x3fff + 14) {  /* |x| >= 16384 or x is NaN */
+		if (u.i.se >= 0x3fff + 15 && u.i.se >> 15 == 0)
+			/* overflow */
+			return x * 0x1p16383L;
+		if (e == 0x7fff)  /* -inf or -nan */
+			return -1/x;
+		if (x < -16382) {
+			if (x <= -16495 || x - 0x1p112 + 0x1p112 != x)
+				/* underflow */
+				FORCE_EVAL((float)(-0x1p-149/x));
+			if (x <= -16446)
+				return 0;
+		}
+	} else if (e < 0x3fff - 114) {
+		return 1 + x;
+	}
+
+	/*
+	 * Reduce x, computing z, i0, and k. The low bits of x + redux
+	 * contain the 16-bit integer part of the exponent (k) followed by
+	 * TBLBITS fractional bits (i0). We use bit tricks to extract these
+	 * as integers, then set z to the remainder.
+	 *
+	 * Example: Suppose x is 0xabc.123456p0 and TBLBITS is 8.
+	 * Then the low-order word of x + redux is 0x000abc12,
+	 * We split this into k = 0xabc and i0 = 0x12 (adjusted to
+	 * index into the table), then we compute z = 0x0.003456p0.
+	 */
+	u.f = x + redux;
+	i0 = u.i2.lo + TBLSIZE / 2;
+	k.u = i0 / TBLSIZE * TBLSIZE;
+	k.i /= TBLSIZE;
+	i0 %= TBLSIZE;
+	u.f -= redux;
+	z = x - u.f;
+
+	/* Compute r = exp2(y) = exp2t[i0] * p(z - eps[i]). */
+	t = tbl[i0];
+	z -= eps[i0];
+	r = t + t * z * (P1 + z * (P2 + z * (P3 + z * (P4 + z * (P5 + z * (P6
+	    + z * (P7 + z * (P8 + z * (P9 + z * P10)))))))));
+
+	return scalbnl(r, k.i);
+}
+#endif
libc/musl/src/math/expf.c
@@ -0,0 +1,83 @@
+/* origin: FreeBSD /usr/src/lib/msun/src/e_expf.c */
+/*
+ * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.
+ */
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunPro, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+
+#include "libm.h"
+
+static const float
+half[2] = {0.5,-0.5},
+ln2hi   = 6.9314575195e-1f,  /* 0x3f317200 */
+ln2lo   = 1.4286067653e-6f,  /* 0x35bfbe8e */
+invln2  = 1.4426950216e+0f,  /* 0x3fb8aa3b */
+/*
+ * Domain [-0.34568, 0.34568], range ~[-4.278e-9, 4.447e-9]:
+ * |x*(exp(x)+1)/(exp(x)-1) - p(x)| < 2**-27.74
+ */
+P1 =  1.6666625440e-1f, /*  0xaaaa8f.0p-26 */
+P2 = -2.7667332906e-3f; /* -0xb55215.0p-32 */
+
+float expf(float x)
+{
+	float_t hi, lo, c, xx, y;
+	int k, sign;
+	uint32_t hx;
+
+	GET_FLOAT_WORD(hx, x);
+	sign = hx >> 31;   /* sign bit of x */
+	hx &= 0x7fffffff;  /* high word of |x| */
+
+	/* special cases */
+	if (hx >= 0x42aeac50) {  /* if |x| >= -87.33655f or NaN */
+		if (hx > 0x7f800000) /* NaN */
+			return x;
+		if (hx >= 0x42b17218 && !sign) {  /* x >= 88.722839f */
+			/* overflow */
+			x *= 0x1p127f;
+			return x;
+		}
+		if (sign) {
+			/* underflow */
+			FORCE_EVAL(-0x1p-149f/x);
+			if (hx >= 0x42cff1b5)  /* x <= -103.972084f */
+				return 0;
+		}
+	}
+
+	/* argument reduction */
+	if (hx > 0x3eb17218) {  /* if |x| > 0.5 ln2 */
+		if (hx > 0x3f851592)  /* if |x| > 1.5 ln2 */
+			k = invln2*x + half[sign];
+		else
+			k = 1 - sign - sign;
+		hi = x - k*ln2hi;  /* k*ln2hi is exact here */
+		lo = k*ln2lo;
+		x = hi - lo;
+	} else if (hx > 0x39000000) {  /* |x| > 2**-14 */
+		k = 0;
+		hi = x;
+		lo = 0;
+	} else {
+		/* raise inexact */
+		FORCE_EVAL(0x1p127f + x);
+		return 1 + x;
+	}
+
+	/* x is now in primary range */
+	xx = x*x;
+	c = x - xx*(P1+xx*P2);
+	y = 1 + (x*c/(2-c) - lo + hi);
+	if (k == 0)
+		return y;
+	return scalbnf(y, k);
+}
libc/musl/src/math/expl.c
@@ -0,0 +1,128 @@
+/* origin: OpenBSD /usr/src/lib/libm/src/ld80/e_expl.c */
+/*
+ * Copyright (c) 2008 Stephen L. Moshier <steve@moshier.net>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+/*
+ *      Exponential function, long double precision
+ *
+ *
+ * SYNOPSIS:
+ *
+ * long double x, y, expl();
+ *
+ * y = expl( x );
+ *
+ *
+ * DESCRIPTION:
+ *
+ * Returns e (2.71828...) raised to the x power.
+ *
+ * Range reduction is accomplished by separating the argument
+ * into an integer k and fraction f such that
+ *
+ *     x    k  f
+ *    e  = 2  e.
+ *
+ * A Pade' form of degree 5/6 is used to approximate exp(f) - 1
+ * in the basic range [-0.5 ln 2, 0.5 ln 2].
+ *
+ *
+ * ACCURACY:
+ *
+ *                      Relative error:
+ * arithmetic   domain     # trials      peak         rms
+ *    IEEE      +-10000     50000       1.12e-19    2.81e-20
+ *
+ *
+ * Error amplification in the exponential function can be
+ * a serious matter.  The error propagation involves
+ * exp( X(1+delta) ) = exp(X) ( 1 + X*delta + ... ),
+ * which shows that a 1 lsb error in representing X produces
+ * a relative error of X times 1 lsb in the function.
+ * While the routine gives an accurate result for arguments
+ * that are exactly represented by a long double precision
+ * computer number, the result contains amplified roundoff
+ * error for large arguments not exactly represented.
+ *
+ *
+ * ERROR MESSAGES:
+ *
+ *   message         condition      value returned
+ * exp underflow    x < MINLOG         0.0
+ * exp overflow     x > MAXLOG         MAXNUM
+ *
+ */
+
+#include "libm.h"
+
+#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024
+long double expl(long double x)
+{
+	return exp(x);
+}
+#elif LDBL_MANT_DIG == 64 && LDBL_MAX_EXP == 16384
+
+static const long double P[3] = {
+ 1.2617719307481059087798E-4L,
+ 3.0299440770744196129956E-2L,
+ 9.9999999999999999991025E-1L,
+};
+static const long double Q[4] = {
+ 3.0019850513866445504159E-6L,
+ 2.5244834034968410419224E-3L,
+ 2.2726554820815502876593E-1L,
+ 2.0000000000000000000897E0L,
+};
+static const long double
+LN2HI = 6.9314575195312500000000E-1L,
+LN2LO = 1.4286068203094172321215E-6L,
+LOG2E = 1.4426950408889634073599E0L;
+
+long double expl(long double x)
+{
+	long double px, xx;
+	int k;
+
+	if (isnan(x))
+		return x;
+	if (x > 11356.5234062941439488L) /* x > ln(2^16384 - 0.5) */
+		return x * 0x1p16383L;
+	if (x < -11399.4985314888605581L) /* x < ln(2^-16446) */
+		return -0x1p-16445L/x;
+
+	/* Express e**x = e**f 2**k
+	 *   = e**(f + k ln(2))
+	 */
+	px = floorl(LOG2E * x + 0.5);
+	k = px;
+	x -= px * LN2HI;
+	x -= px * LN2LO;
+
+	/* rational approximation of the fractional part:
+	 * e**x =  1 + 2x P(x**2)/(Q(x**2) - x P(x**2))
+	 */
+	xx = x * x;
+	px = x * __polevll(xx, P, 2);
+	x = px/(__polevll(xx, Q, 3) - px);
+	x = 1.0 + 2.0 * x;
+	return scalbnl(x, k);
+}
+#elif LDBL_MANT_DIG == 113 && LDBL_MAX_EXP == 16384
+// TODO: broken implementation to make things compile
+long double expl(long double x)
+{
+	return exp(x);
+}
+#endif
libc/musl/src/math/expm1.c
@@ -0,0 +1,201 @@
+/* origin: FreeBSD /usr/src/lib/msun/src/s_expm1.c */
+/*
+ * ====================================================
+ * 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.
+ * ====================================================
+ */
+/* 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 Remez 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;
+ *              z   =  r*r,
+ *      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 "libm.h"
+
+static const double
+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 Q's: Qn_here = 2**n * Qn_above, for R(2*z) where z = hxs = x*x/2: */
+Q1 = -3.33333333333331316428e-02, /* BFA11111 111110F4 */
+Q2 =  1.58730158725481460165e-03, /* 3F5A01A0 19FE5585 */
+Q3 = -7.93650757867487942473e-05, /* BF14CE19 9EAADBB7 */
+Q4 =  4.00821782732936239552e-06, /* 3ED0CFCA 86E65239 */
+Q5 = -2.01099218183624371326e-07; /* BE8AFDB7 6E09C32D */
+
+double expm1(double x)
+{
+	double_t y,hi,lo,c,t,e,hxs,hfx,r1,twopk;
+	union {double f; uint64_t i;} u = {x};
+	uint32_t hx = u.i>>32 & 0x7fffffff;
+	int k, sign = u.i>>63;
+
+	/* filter out huge and non-finite argument */
+	if (hx >= 0x4043687A) {  /* if |x|>=56*ln2 */
+		if (isnan(x))
+			return x;
+		if (sign)
+			return -1;
+		if (x > o_threshold) {
+			x *= 0x1p1023;
+			return x;
+		}
+	}
+
+	/* argument reduction */
+	if (hx > 0x3fd62e42) {  /* if  |x| > 0.5 ln2 */
+		if (hx < 0x3FF0A2B2) {  /* and |x| < 1.5 ln2 */
+			if (!sign) {
+				hi = x - ln2_hi;
+				lo = ln2_lo;
+				k =  1;
+			} else {
+				hi = x + ln2_hi;
+				lo = -ln2_lo;
+				k = -1;
+			}
+		} else {
+			k  = invln2*x + (sign ? -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) {  /* |x| < 2**-54, return x */
+		if (hx < 0x00100000)
+			FORCE_EVAL((float)x);
+		return x;
+	} else
+		k = 0;
+
+	/* x is now in primary range */
+	hfx = 0.5*x;
+	hxs = x*hfx;
+	r1 = 1.0+hxs*(Q1+hxs*(Q2+hxs*(Q3+hxs*(Q4+hxs*Q5))));
+	t  = 3.0-r1*hfx;
+	e  = hxs*((r1-t)/(6.0 - x*t));
+	if (k == 0)   /* c is 0 */
+		return x - (x*e-hxs);
+	e  = x*(e-c) - c;
+	e -= hxs;
+	/* exp(x) ~ 2^k (x_reduced - e + 1) */
+	if (k == -1)
+		return 0.5*(x-e) - 0.5;
+	if (k == 1) {
+		if (x < -0.25)
+			return -2.0*(e-(x+0.5));
+		return 1.0+2.0*(x-e);
+	}
+	u.i = (uint64_t)(0x3ff + k)<<52;  /* 2^k */
+	twopk = u.f;
+	if (k < 0 || k > 56) {  /* suffice to return exp(x)-1 */
+		y = x - e + 1.0;
+		if (k == 1024)
+			y = y*2.0*0x1p1023;
+		else
+			y = y*twopk;
+		return y - 1.0;
+	}
+	u.i = (uint64_t)(0x3ff - k)<<52;  /* 2^-k */
+	if (k < 20)
+		y = (x-e+(1-u.f))*twopk;
+	else
+		y = (x-(e+u.f)+1)*twopk;
+	return y;
+}
libc/musl/src/math/expm1f.c
@@ -0,0 +1,111 @@
+/* origin: FreeBSD /usr/src/lib/msun/src/s_expm1f.c */
+/*
+ * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.
+ */
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunPro, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+
+#include "libm.h"
+
+static const float
+o_threshold = 8.8721679688e+01, /* 0x42b17180 */
+ln2_hi      = 6.9313812256e-01, /* 0x3f317180 */
+ln2_lo      = 9.0580006145e-06, /* 0x3717f7d1 */
+invln2      = 1.4426950216e+00, /* 0x3fb8aa3b */
+/*
+ * Domain [-0.34568, 0.34568], range ~[-6.694e-10, 6.696e-10]:
+ * |6 / x * (1 + 2 * (1 / (exp(x) - 1) - 1 / x)) - q(x)| < 2**-30.04
+ * Scaled coefficients: Qn_here = 2**n * Qn_for_q (see s_expm1.c):
+ */
+Q1 = -3.3333212137e-2, /* -0x888868.0p-28 */
+Q2 =  1.5807170421e-3; /*  0xcf3010.0p-33 */
+
+float expm1f(float x)
+{
+	float_t y,hi,lo,c,t,e,hxs,hfx,r1,twopk;
+	union {float f; uint32_t i;} u = {x};
+	uint32_t hx = u.i & 0x7fffffff;
+	int k, sign = u.i >> 31;
+
+	/* filter out huge and non-finite argument */
+	if (hx >= 0x4195b844) {  /* if |x|>=27*ln2 */
+		if (hx > 0x7f800000)  /* NaN */
+			return x;
+		if (sign)
+			return -1;
+		if (x > o_threshold) {
+			x *= 0x1p127f;
+			return x;
+		}
+	}
+
+	/* argument reduction */
+	if (hx > 0x3eb17218) {           /* if  |x| > 0.5 ln2 */
+		if (hx < 0x3F851592) {       /* and |x| < 1.5 ln2 */
+			if (!sign) {
+				hi = x - ln2_hi;
+				lo = ln2_lo;
+				k =  1;
+			} else {
+				hi = x + ln2_hi;
+				lo = -ln2_lo;
+				k = -1;
+			}
+		} else {
+			k  = invln2*x + (sign ? -0.5f : 0.5f);
+			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 */
+		if (hx < 0x00800000)
+			FORCE_EVAL(x*x);
+		return x;
+	} else
+		k = 0;
+
+	/* x is now in primary range */
+	hfx = 0.5f*x;
+	hxs = x*hfx;
+	r1 = 1.0f+hxs*(Q1+hxs*Q2);
+	t  = 3.0f - r1*hfx;
+	e  = hxs*((r1-t)/(6.0f - x*t));
+	if (k == 0)  /* c is 0 */
+		return x - (x*e-hxs);
+	e  = x*(e-c) - c;
+	e -= hxs;
+	/* exp(x) ~ 2^k (x_reduced - e + 1) */
+	if (k == -1)
+		return 0.5f*(x-e) - 0.5f;
+	if (k == 1) {
+		if (x < -0.25f)
+			return -2.0f*(e-(x+0.5f));
+		return 1.0f + 2.0f*(x-e);
+	}
+	u.i = (0x7f+k)<<23;  /* 2^k */
+	twopk = u.f;
+	if (k < 0 || k > 56) {   /* suffice to return exp(x)-1 */
+		y = x - e + 1.0f;
+		if (k == 128)
+			y = y*2.0f*0x1p127f;
+		else
+			y = y*twopk;
+		return y - 1.0f;
+	}
+	u.i = (0x7f-k)<<23;  /* 2^-k */
+	if (k < 23)
+		y = (x-e+(1-u.f))*twopk;
+	else
+		y = (x-(e+u.f)+1)*twopk;
+	return y;
+}
libc/musl/src/math/expm1l.c
@@ -0,0 +1,123 @@
+/* origin: OpenBSD /usr/src/lib/libm/src/ld80/e_expm1l.c */
+/*
+ * Copyright (c) 2008 Stephen L. Moshier <steve@moshier.net>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+/*
+ *      Exponential function, minus 1
+ *      Long double precision
+ *
+ *
+ * SYNOPSIS:
+ *
+ * long double x, y, expm1l();
+ *
+ * y = expm1l( x );
+ *
+ *
+ * DESCRIPTION:
+ *
+ * Returns e (2.71828...) raised to the x power, minus 1.
+ *
+ * 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    -45,+maxarg   200,000     1.2e-19     2.5e-20
+ */
+
+#include "libm.h"
+
+#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024
+long double expm1l(long double x)
+{
+	return expm1(x);
+}
+#elif LDBL_MANT_DIG == 64 && LDBL_MAX_EXP == 16384
+
+/* 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 = 3.4e-22  */
+static const long double
+P0 = -1.586135578666346600772998894928250240826E4L,
+P1 =  2.642771505685952966904660652518429479531E3L,
+P2 = -3.423199068835684263987132888286791620673E2L,
+P3 =  1.800826371455042224581246202420972737840E1L,
+P4 = -5.238523121205561042771939008061958820811E-1L,
+Q0 = -9.516813471998079611319047060563358064497E4L,
+Q1 =  3.964866271411091674556850458227710004570E4L,
+Q2 = -7.207678383830091850230366618190187434796E3L,
+Q3 =  7.206038318724600171970199625081491823079E2L,
+Q4 = -4.002027679107076077238836622982900945173E1L,
+/* Q5 = 1.000000000000000000000000000000000000000E0 */
+/* C1 + C2 = ln 2 */
+C1 = 6.93145751953125E-1L,
+C2 = 1.428606820309417232121458176568075500134E-6L,
+/* ln 2^-65 */
+minarg = -4.5054566736396445112120088E1L,
+/* ln 2^16384 */
+maxarg = 1.1356523406294143949492E4L;
+
+long double expm1l(long double x)
+{
+	long double px, qx, xx;
+	int k;
+
+	if (isnan(x))
+		return x;
+	if (x > maxarg)
+		return x*0x1p16383L; /* overflow, unless x==inf */
+	if (x == 0.0)
+		return x;
+	if (x < minarg)
+		return -1.0;
+
+	xx = C1 + C2;
+	/* Express x = ln 2 (k + remainder), remainder not exceeding 1/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 = (((( P4 * x + P3) * x + P2) * x + P1) * x + P0) * x;
+	qx = (((( 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 = scalbnl(1.0, k);
+	x = px * qx + (px - 1.0);
+	return x;
+}
+#elif LDBL_MANT_DIG == 113 && LDBL_MAX_EXP == 16384
+// TODO: broken implementation to make things compile
+long double expm1l(long double x)
+{
+	return expm1(x);
+}
+#endif
libc/musl/src/math/fabs.c
@@ -0,0 +1,9 @@
+#include <math.h>
+#include <stdint.h>
+
+double fabs(double x)
+{
+	union {double f; uint64_t i;} u = {x};
+	u.i &= -1ULL/2;
+	return u.f;
+}
libc/musl/src/math/fabsf.c
@@ -0,0 +1,9 @@
+#include <math.h>
+#include <stdint.h>
+
+float fabsf(float x)
+{
+	union {float f; uint32_t i;} u = {x};
+	u.i &= 0x7fffffff;
+	return u.f;
+}
libc/musl/src/math/fabsl.c
@@ -0,0 +1,15 @@
+#include "libm.h"
+#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024
+long double fabsl(long double x)
+{
+	return fabs(x);
+}
+#elif (LDBL_MANT_DIG == 64 || LDBL_MANT_DIG == 113) && LDBL_MAX_EXP == 16384
+long double fabsl(long double x)
+{
+	union ldshape u = {x};
+
+	u.i.se &= 0x7fff;
+	return u.f;
+}
+#endif
libc/musl/src/math/fdim.c
@@ -0,0 +1,10 @@
+#include <math.h>
+
+double fdim(double x, double y)
+{
+	if (isnan(x))
+		return x;
+	if (isnan(y))
+		return y;
+	return x > y ? x - y : 0;
+}
libc/musl/src/math/fdimf.c
@@ -0,0 +1,10 @@
+#include <math.h>
+
+float fdimf(float x, float y)
+{
+	if (isnan(x))
+		return x;
+	if (isnan(y))
+		return y;
+	return x > y ? x - y : 0;
+}
libc/musl/src/math/fdiml.c
@@ -0,0 +1,18 @@
+#include <math.h>
+#include <float.h>
+
+#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024
+long double fdiml(long double x, long double y)
+{
+	return fdim(x, y);
+}
+#else
+long double fdiml(long double x, long double y)
+{
+	if (isnan(x))
+		return x;
+	if (isnan(y))
+		return y;
+	return x > y ? x - y : 0;
+}
+#endif
libc/musl/src/math/finite.c
@@ -0,0 +1,7 @@
+#define _GNU_SOURCE
+#include <math.h>
+
+int finite(double x)
+{
+	return isfinite(x);
+}
libc/musl/src/math/finitef.c
@@ -0,0 +1,7 @@
+#define _GNU_SOURCE
+#include <math.h>
+
+int finitef(float x)
+{
+	return isfinite(x);
+}
libc/musl/src/math/floor.c
@@ -0,0 +1,31 @@
+#include "libm.h"
+
+#if FLT_EVAL_METHOD==0 || FLT_EVAL_METHOD==1
+#define EPS DBL_EPSILON
+#elif FLT_EVAL_METHOD==2
+#define EPS LDBL_EPSILON
+#endif
+static const double_t toint = 1/EPS;
+
+double floor(double x)
+{
+	union {double f; uint64_t i;} u = {x};
+	int e = u.i >> 52 & 0x7ff;
+	double_t y;
+
+	if (e >= 0x3ff+52 || x == 0)
+		return x;
+	/* y = int(x) - x, where int(x) is an integer neighbor of x */
+	if (u.i >> 63)
+		y = x - toint + toint - x;
+	else
+		y = x + toint - toint - x;
+	/* special case because of non-nearest rounding modes */
+	if (e <= 0x3ff-1) {
+		FORCE_EVAL(y);
+		return u.i >> 63 ? -1 : 0;
+	}
+	if (y > 0)
+		return x + y - 1;
+	return x + y;
+}
libc/musl/src/math/floorf.c
@@ -0,0 +1,27 @@
+#include "libm.h"
+
+float floorf(float x)
+{
+	union {float f; uint32_t i;} u = {x};
+	int e = (int)(u.i >> 23 & 0xff) - 0x7f;
+	uint32_t m;
+
+	if (e >= 23)
+		return x;
+	if (e >= 0) {
+		m = 0x007fffff >> e;
+		if ((u.i & m) == 0)
+			return x;
+		FORCE_EVAL(x + 0x1p120f);
+		if (u.i >> 31)
+			u.i += m;
+		u.i &= ~m;
+	} else {
+		FORCE_EVAL(x + 0x1p120f);
+		if (u.i >> 31 == 0)
+			u.i = 0;
+		else if (u.i << 1)
+			u.f = -1.0;
+	}
+	return u.f;
+}
libc/musl/src/math/floorl.c
@@ -0,0 +1,34 @@
+#include "libm.h"
+
+#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024
+long double floorl(long double x)
+{
+	return floor(x);
+}
+#elif (LDBL_MANT_DIG == 64 || LDBL_MANT_DIG == 113) && LDBL_MAX_EXP == 16384
+
+static const long double toint = 1/LDBL_EPSILON;
+
+long double floorl(long double x)
+{
+	union ldshape u = {x};
+	int e = u.i.se & 0x7fff;
+	long double y;
+
+	if (e >= 0x3fff+LDBL_MANT_DIG-1 || x == 0)
+		return x;
+	/* y = int(x) - x, where int(x) is an integer neighbor of x */
+	if (u.i.se >> 15)
+		y = x - toint + toint - x;
+	else
+		y = x + toint - toint - x;
+	/* special case because of non-nearest rounding modes */
+	if (e <= 0x3fff-1) {
+		FORCE_EVAL(y);
+		return u.i.se >> 15 ? -1 : 0;
+	}
+	if (y > 0)
+		return x + y - 1;
+	return x + y;
+}
+#endif
libc/musl/src/math/fma.c
@@ -0,0 +1,183 @@
+#include <stdint.h>
+#include <float.h>
+#include <math.h>
+#include "atomic.h"
+
+#define ASUINT64(x) ((union {double f; uint64_t i;}){x}).i
+#define ZEROINFNAN (0x7ff-0x3ff-52-1)
+
+struct num { uint64_t m; int e; int sign; };
+
+static struct num normalize(double x)
+{
+	uint64_t ix = ASUINT64(x);
+	int e = ix>>52;
+	int sign = e & 0x800;
+	e &= 0x7ff;
+	if (!e) {
+		ix = ASUINT64(x*0x1p63);
+		e = ix>>52 & 0x7ff;
+		e = e ? e-63 : 0x800;
+	}
+	ix &= (1ull<<52)-1;
+	ix |= 1ull<<52;
+	ix <<= 1;
+	e -= 0x3ff + 52 + 1;
+	return (struct num){ix,e,sign};
+}
+
+static void mul(uint64_t *hi, uint64_t *lo, uint64_t x, uint64_t y)
+{
+	uint64_t t1,t2,t3;
+	uint64_t xlo = (uint32_t)x, xhi = x>>32;
+	uint64_t ylo = (uint32_t)y, yhi = y>>32;
+
+	t1 = xlo*ylo;
+	t2 = xlo*yhi + xhi*ylo;
+	t3 = xhi*yhi;
+	*lo = t1 + (t2<<32);
+	*hi = t3 + (t2>>32) + (t1 > *lo);
+}
+
+double fma(double x, double y, double z)
+{
+	#pragma STDC FENV_ACCESS ON
+
+	/* normalize so top 10bits and last bit are 0 */
+	struct num nx, ny, nz;
+	nx = normalize(x);
+	ny = normalize(y);
+	nz = normalize(z);
+
+	if (nx.e >= ZEROINFNAN || ny.e >= ZEROINFNAN)
+		return x*y + z;
+	if (nz.e >= ZEROINFNAN) {
+		if (nz.e > ZEROINFNAN) /* z==0 */
+			return x*y + z;
+		return z;
+	}
+
+	/* mul: r = x*y */
+	uint64_t rhi, rlo, zhi, zlo;
+	mul(&rhi, &rlo, nx.m, ny.m);
+	/* either top 20 or 21 bits of rhi and last 2 bits of rlo are 0 */
+
+	/* align exponents */
+	int e = nx.e + ny.e;
+	int d = nz.e - e;
+	/* shift bits z<<=kz, r>>=kr, so kz+kr == d, set e = e+kr (== ez-kz) */
+	if (d > 0) {
+		if (d < 64) {
+			zlo = nz.m<<d;
+			zhi = nz.m>>64-d;
+		} else {
+			zlo = 0;
+			zhi = nz.m;
+			e = nz.e - 64;
+			d -= 64;
+			if (d == 0) {
+			} else if (d < 64) {
+				rlo = rhi<<64-d | rlo>>d | !!(rlo<<64-d);
+				rhi = rhi>>d;
+			} else {
+				rlo = 1;
+				rhi = 0;
+			}
+		}
+	} else {
+		zhi = 0;
+		d = -d;
+		if (d == 0) {
+			zlo = nz.m;
+		} else if (d < 64) {
+			zlo = nz.m>>d | !!(nz.m<<64-d);
+		} else {
+			zlo = 1;
+		}
+	}
+
+	/* add */
+	int sign = nx.sign^ny.sign;
+	int samesign = !(sign^nz.sign);
+	int nonzero = 1;
+	if (samesign) {
+		/* r += z */
+		rlo += zlo;
+		rhi += zhi + (rlo < zlo);
+	} else {
+		/* r -= z */
+		uint64_t t = rlo;
+		rlo -= zlo;
+		rhi = rhi - zhi - (t < rlo);
+		if (rhi>>63) {
+			rlo = -rlo;
+			rhi = -rhi-!!rlo;
+			sign = !sign;
+		}
+		nonzero = !!rhi;
+	}
+
+	/* set rhi to top 63bit of the result (last bit is sticky) */
+	if (nonzero) {
+		e += 64;
+		d = a_clz_64(rhi)-1;
+		/* note: d > 0 */
+		rhi = rhi<<d | rlo>>64-d | !!(rlo<<d);
+	} else if (rlo) {
+		d = a_clz_64(rlo)-1;
+		if (d < 0)
+			rhi = rlo>>1 | (rlo&1);
+		else
+			rhi = rlo<<d;
+	} else {
+		/* exact +-0 */
+		return x*y + z;
+	}
+	e -= d;
+
+	/* convert to double */
+	int64_t i = rhi; /* i is in [1<<62,(1<<63)-1] */
+	if (sign)
+		i = -i;
+	double r = i; /* |r| is in [0x1p62,0x1p63] */
+
+	if (e < -1022-62) {
+		/* result is subnormal before rounding */
+		if (e == -1022-63) {
+			double c = 0x1p63;
+			if (sign)
+				c = -c;
+			if (r == c) {
+				/* min normal after rounding, underflow depends
+				   on arch behaviour which can be imitated by
+				   a double to float conversion */
+				float fltmin = 0x0.ffffff8p-63*FLT_MIN * r;
+				return DBL_MIN/FLT_MIN * fltmin;
+			}
+			/* one bit is lost when scaled, add another top bit to
+			   only round once at conversion if it is inexact */
+			if (rhi << 53) {
+				i = rhi>>1 | (rhi&1) | 1ull<<62;
+				if (sign)
+					i = -i;
+				r = i;
+				r = 2*r - c; /* remove top bit */
+
+				/* raise underflow portably, such that it
+				   cannot be optimized away */
+				{
+					double_t tiny = DBL_MIN/FLT_MIN * r;
+					r += (double)(tiny*tiny) * (r-r);
+				}
+			}
+		} else {
+			/* only round once when scaled */
+			d = 10;
+			i = ( rhi>>d | !!(rhi<<64-d) ) << d;
+			if (sign)
+				i = -i;
+			r = i;
+		}
+	}
+	return scalbn(r, e);
+}
libc/musl/src/math/fmaf.c
@@ -0,0 +1,93 @@
+/* origin: FreeBSD /usr/src/lib/msun/src/s_fmaf.c */
+/*-
+ * Copyright (c) 2005-2011 David Schultz <das@FreeBSD.ORG>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <fenv.h>
+#include <math.h>
+#include <stdint.h>
+
+/*
+ * Fused multiply-add: Compute x * y + z with a single rounding error.
+ *
+ * A double has more than twice as much precision than a float, so
+ * direct double-precision arithmetic suffices, except where double
+ * rounding occurs.
+ */
+float fmaf(float x, float y, float z)
+{
+	#pragma STDC FENV_ACCESS ON
+	double xy, result;
+	union {double f; uint64_t i;} u;
+	int e;
+
+	xy = (double)x * y;
+	result = xy + z;
+	u.f = result;
+	e = u.i>>52 & 0x7ff;
+	/* Common case: The double precision result is fine. */
+	if ((u.i & 0x1fffffff) != 0x10000000 || /* not a halfway case */
+		e == 0x7ff ||                   /* NaN */
+		(result - xy == z && result - z == xy) || /* exact */
+		fegetround() != FE_TONEAREST)       /* not round-to-nearest */
+	{
+		/*
+		underflow may not be raised correctly, example:
+		fmaf(0x1p-120f, 0x1p-120f, 0x1p-149f)
+		*/
+#if defined(FE_INEXACT) && defined(FE_UNDERFLOW)
+		if (e < 0x3ff-126 && e >= 0x3ff-149 && fetestexcept(FE_INEXACT)) {
+			feclearexcept(FE_INEXACT);
+			/* TODO: gcc and clang bug workaround */
+			volatile float vz = z;
+			result = xy + vz;
+			if (fetestexcept(FE_INEXACT))
+				feraiseexcept(FE_UNDERFLOW);
+			else
+				feraiseexcept(FE_INEXACT);
+		}
+#endif
+		z = result;
+		return z;
+	}
+
+	/*
+	 * If result is inexact, and exactly halfway between two float values,
+	 * we need to adjust the low-order bit in the direction of the error.
+	 */
+#ifdef FE_TOWARDZERO
+	fesetround(FE_TOWARDZERO);
+#endif
+	volatile double vxy = xy;  /* XXX work around gcc CSE bug */
+	double adjusted_result = vxy + z;
+	fesetround(FE_TONEAREST);
+	if (result == adjusted_result) {
+		u.f = adjusted_result;
+		u.i++;
+		adjusted_result = u.f;
+	}
+	z = adjusted_result;
+	return z;
+}
libc/musl/src/math/fmal.c
@@ -0,0 +1,293 @@
+/* origin: FreeBSD /usr/src/lib/msun/src/s_fmal.c */
+/*-
+ * Copyright (c) 2005-2011 David Schultz <das@FreeBSD.ORG>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+
+#include "libm.h"
+#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024
+long double fmal(long double x, long double y, long double z)
+{
+	return fma(x, y, z);
+}
+#elif (LDBL_MANT_DIG == 64 || LDBL_MANT_DIG == 113) && LDBL_MAX_EXP == 16384
+#include <fenv.h>
+#if LDBL_MANT_DIG == 64
+#define LASTBIT(u) (u.i.m & 1)
+#define SPLIT (0x1p32L + 1)
+#elif LDBL_MANT_DIG == 113
+#define LASTBIT(u) (u.i.lo & 1)
+#define SPLIT (0x1p57L + 1)
+#endif
+
+/*
+ * A struct dd represents a floating-point number with twice the precision
+ * of a long double.  We maintain the invariant that "hi" stores the high-order
+ * bits of the result.
+ */
+struct dd {
+	long double hi;
+	long double lo;
+};
+
+/*
+ * Compute a+b exactly, returning the exact result in a struct dd.  We assume
+ * that both a and b are finite, but make no assumptions about their relative
+ * magnitudes.
+ */
+static inline struct dd dd_add(long double a, long double b)
+{
+	struct dd ret;
+	long double s;
+
+	ret.hi = a + b;
+	s = ret.hi - a;
+	ret.lo = (a - (ret.hi - s)) + (b - s);
+	return (ret);
+}
+
+/*
+ * Compute a+b, with a small tweak:  The least significant bit of the
+ * result is adjusted into a sticky bit summarizing all the bits that
+ * were lost to rounding.  This adjustment negates the effects of double
+ * rounding when the result is added to another number with a higher
+ * exponent.  For an explanation of round and sticky bits, see any reference
+ * on FPU design, e.g.,
+ *
+ *     J. Coonen.  An Implementation Guide to a Proposed Standard for
+ *     Floating-Point Arithmetic.  Computer, vol. 13, no. 1, Jan 1980.
+ */
+static inline long double add_adjusted(long double a, long double b)
+{
+	struct dd sum;
+	union ldshape u;
+
+	sum = dd_add(a, b);
+	if (sum.lo != 0) {
+		u.f = sum.hi;
+		if (!LASTBIT(u))
+			sum.hi = nextafterl(sum.hi, INFINITY * sum.lo);
+	}
+	return (sum.hi);
+}
+
+/*
+ * Compute ldexp(a+b, scale) with a single rounding error. It is assumed
+ * that the result will be subnormal, and care is taken to ensure that
+ * double rounding does not occur.
+ */
+static inline long double add_and_denormalize(long double a, long double b, int scale)
+{
+	struct dd sum;
+	int bits_lost;
+	union ldshape u;
+
+	sum = dd_add(a, b);
+
+	/*
+	 * If we are losing at least two bits of accuracy to denormalization,
+	 * then the first lost bit becomes a round bit, and we adjust the
+	 * lowest bit of sum.hi to make it a sticky bit summarizing all the
+	 * bits in sum.lo. With the sticky bit adjusted, the hardware will
+	 * break any ties in the correct direction.
+	 *
+	 * If we are losing only one bit to denormalization, however, we must
+	 * break the ties manually.
+	 */
+	if (sum.lo != 0) {
+		u.f = sum.hi;
+		bits_lost = -u.i.se - scale + 1;
+		if ((bits_lost != 1) ^ LASTBIT(u))
+			sum.hi = nextafterl(sum.hi, INFINITY * sum.lo);
+	}
+	return scalbnl(sum.hi, scale);
+}
+
+/*
+ * Compute a*b exactly, returning the exact result in a struct dd.  We assume
+ * that both a and b are normalized, so no underflow or overflow will occur.
+ * The current rounding mode must be round-to-nearest.
+ */
+static inline struct dd dd_mul(long double a, long double b)
+{
+	struct dd ret;
+	long double ha, hb, la, lb, p, q;
+
+	p = a * SPLIT;
+	ha = a - p;
+	ha += p;
+	la = a - ha;
+
+	p = b * SPLIT;
+	hb = b - p;
+	hb += p;
+	lb = b - hb;
+
+	p = ha * hb;
+	q = ha * lb + la * hb;
+
+	ret.hi = p + q;
+	ret.lo = p - ret.hi + q + la * lb;
+	return (ret);
+}
+
+/*
+ * Fused multiply-add: Compute x * y + z with a single rounding error.
+ *
+ * We use scaling to avoid overflow/underflow, along with the
+ * canonical precision-doubling technique adapted from:
+ *
+ *      Dekker, T.  A Floating-Point Technique for Extending the
+ *      Available Precision.  Numer. Math. 18, 224-242 (1971).
+ */
+long double fmal(long double x, long double y, long double z)
+{
+	#pragma STDC FENV_ACCESS ON
+	long double xs, ys, zs, adj;
+	struct dd xy, r;
+	int oround;
+	int ex, ey, ez;
+	int spread;
+
+	/*
+	 * Handle special cases. The order of operations and the particular
+	 * return values here are crucial in handling special cases involving
+	 * infinities, NaNs, overflows, and signed zeroes correctly.
+	 */
+	if (!isfinite(x) || !isfinite(y))
+		return (x * y + z);
+	if (!isfinite(z))
+		return (z);
+	if (x == 0.0 || y == 0.0)
+		return (x * y + z);
+	if (z == 0.0)
+		return (x * y);
+
+	xs = frexpl(x, &ex);
+	ys = frexpl(y, &ey);
+	zs = frexpl(z, &ez);
+	oround = fegetround();
+	spread = ex + ey - ez;
+
+	/*
+	 * If x * y and z are many orders of magnitude apart, the scaling
+	 * will overflow, so we handle these cases specially.  Rounding
+	 * modes other than FE_TONEAREST are painful.
+	 */
+	if (spread < -LDBL_MANT_DIG) {
+#ifdef FE_INEXACT
+		feraiseexcept(FE_INEXACT);
+#endif
+#ifdef FE_UNDERFLOW
+		if (!isnormal(z))
+			feraiseexcept(FE_UNDERFLOW);
+#endif
+		switch (oround) {
+		default: /* FE_TONEAREST */
+			return (z);
+#ifdef FE_TOWARDZERO
+		case FE_TOWARDZERO:
+			if (x > 0.0 ^ y < 0.0 ^ z < 0.0)
+				return (z);
+			else
+				return (nextafterl(z, 0));
+#endif
+#ifdef FE_DOWNWARD
+		case FE_DOWNWARD:
+			if (x > 0.0 ^ y < 0.0)
+				return (z);
+			else
+				return (nextafterl(z, -INFINITY));
+#endif
+#ifdef FE_UPWARD
+		case FE_UPWARD:
+			if (x > 0.0 ^ y < 0.0)
+				return (nextafterl(z, INFINITY));
+			else
+				return (z);
+#endif
+		}
+	}
+	if (spread <= LDBL_MANT_DIG * 2)
+		zs = scalbnl(zs, -spread);
+	else
+		zs = copysignl(LDBL_MIN, zs);
+
+	fesetround(FE_TONEAREST);
+
+	/*
+	 * Basic approach for round-to-nearest:
+	 *
+	 *     (xy.hi, xy.lo) = x * y           (exact)
+	 *     (r.hi, r.lo)   = xy.hi + z       (exact)
+	 *     adj = xy.lo + r.lo               (inexact; low bit is sticky)
+	 *     result = r.hi + adj              (correctly rounded)
+	 */
+	xy = dd_mul(xs, ys);
+	r = dd_add(xy.hi, zs);
+
+	spread = ex + ey;
+
+	if (r.hi == 0.0) {
+		/*
+		 * When the addends cancel to 0, ensure that the result has
+		 * the correct sign.
+		 */
+		fesetround(oround);
+		volatile long double vzs = zs; /* XXX gcc CSE bug workaround */
+		return xy.hi + vzs + scalbnl(xy.lo, spread);
+	}
+
+	if (oround != FE_TONEAREST) {
+		/*
+		 * There is no need to worry about double rounding in directed
+		 * rounding modes.
+		 * But underflow may not be raised correctly, example in downward rounding:
+		 * fmal(0x1.0000000001p-16000L, 0x1.0000000001p-400L, -0x1p-16440L)
+		 */
+		long double ret;
+#if defined(FE_INEXACT) && defined(FE_UNDERFLOW)
+		int e = fetestexcept(FE_INEXACT);
+		feclearexcept(FE_INEXACT);
+#endif
+		fesetround(oround);
+		adj = r.lo + xy.lo;
+		ret = scalbnl(r.hi + adj, spread);
+#if defined(FE_INEXACT) && defined(FE_UNDERFLOW)
+		if (ilogbl(ret) < -16382 && fetestexcept(FE_INEXACT))
+			feraiseexcept(FE_UNDERFLOW);
+		else if (e)
+			feraiseexcept(FE_INEXACT);
+#endif
+		return ret;
+	}
+
+	adj = add_adjusted(r.lo, xy.lo);
+	if (spread + ilogbl(r.hi) > -16383)
+		return scalbnl(r.hi + adj, spread);
+	else
+		return add_and_denormalize(r.hi, adj, spread);
+}
+#endif
libc/musl/src/math/fmax.c
@@ -0,0 +1,13 @@
+#include <math.h>
+
+double fmax(double x, double y)
+{
+	if (isnan(x))
+		return y;
+	if (isnan(y))
+		return x;
+	/* handle signed zeros, see C99 Annex F.9.9.2 */
+	if (signbit(x) != signbit(y))
+		return signbit(x) ? y : x;
+	return x < y ? y : x;
+}
libc/musl/src/math/fmaxf.c
@@ -0,0 +1,13 @@
+#include <math.h>
+
+float fmaxf(float x, float y)
+{
+	if (isnan(x))
+		return y;
+	if (isnan(y))
+		return x;
+	/* handle signed zeroes, see C99 Annex F.9.9.2 */
+	if (signbit(x) != signbit(y))
+		return signbit(x) ? y : x;
+	return x < y ? y : x;
+}
libc/musl/src/math/fmaxl.c
@@ -0,0 +1,21 @@
+#include <math.h>
+#include <float.h>
+
+#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024
+long double fmaxl(long double x, long double y)
+{
+	return fmax(x, y);
+}
+#else
+long double fmaxl(long double x, long double y)
+{
+	if (isnan(x))
+		return y;
+	if (isnan(y))
+		return x;
+	/* handle signed zeros, see C99 Annex F.9.9.2 */
+	if (signbit(x) != signbit(y))
+		return signbit(x) ? y : x;
+	return x < y ? y : x;
+}
+#endif
libc/musl/src/math/fmin.c
@@ -0,0 +1,13 @@
+#include <math.h>
+
+double fmin(double x, double y)
+{
+	if (isnan(x))
+		return y;
+	if (isnan(y))
+		return x;
+	/* handle signed zeros, see C99 Annex F.9.9.2 */
+	if (signbit(x) != signbit(y))
+		return signbit(x) ? x : y;
+	return x < y ? x : y;
+}
libc/musl/src/math/fminf.c
@@ -0,0 +1,13 @@
+#include <math.h>
+
+float fminf(float x, float y)
+{
+	if (isnan(x))
+		return y;
+	if (isnan(y))
+		return x;
+	/* handle signed zeros, see C99 Annex F.9.9.2 */
+	if (signbit(x) != signbit(y))
+		return signbit(x) ? x : y;
+	return x < y ? x : y;
+}
libc/musl/src/math/fminl.c
@@ -0,0 +1,21 @@
+#include <math.h>
+#include <float.h>
+
+#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024
+long double fminl(long double x, long double y)
+{
+	return fmin(x, y);
+}
+#else
+long double fminl(long double x, long double y)
+{
+	if (isnan(x))
+		return y;
+	if (isnan(y))
+		return x;
+	/* handle signed zeros, see C99 Annex F.9.9.2 */
+	if (signbit(x) != signbit(y))
+		return signbit(x) ? x : y;
+	return x < y ? x : y;
+}
+#endif
libc/musl/src/math/fmod.c
@@ -0,0 +1,68 @@
+#include <math.h>
+#include <stdint.h>
+
+double fmod(double x, double y)
+{
+	union {double f; uint64_t i;} ux = {x}, uy = {y};
+	int ex = ux.i>>52 & 0x7ff;
+	int ey = uy.i>>52 & 0x7ff;
+	int sx = ux.i>>63;
+	uint64_t i;
+
+	/* in the followings uxi should be ux.i, but then gcc wrongly adds */
+	/* float load/store to inner loops ruining performance and code size */
+	uint64_t uxi = ux.i;
+
+	if (uy.i<<1 == 0 || isnan(y) || ex == 0x7ff)
+		return (x*y)/(x*y);
+	if (uxi<<1 <= uy.i<<1) {
+		if (uxi<<1 == uy.i<<1)
+			return 0*x;
+		return x;
+	}
+
+	/* normalize x and y */
+	if (!ex) {
+		for (i = uxi<<12; i>>63 == 0; ex--, i <<= 1);
+		uxi <<= -ex + 1;
+	} else {
+		uxi &= -1ULL >> 12;
+		uxi |= 1ULL << 52;
+	}
+	if (!ey) {
+		for (i = uy.i<<12; i>>63 == 0; ey--, i <<= 1);
+		uy.i <<= -ey + 1;
+	} else {
+		uy.i &= -1ULL >> 12;
+		uy.i |= 1ULL << 52;
+	}
+
+	/* x mod y */
+	for (; ex > ey; ex--) {
+		i = uxi - uy.i;
+		if (i >> 63 == 0) {
+			if (i == 0)
+				return 0*x;
+			uxi = i;
+		}
+		uxi <<= 1;
+	}
+	i = uxi - uy.i;
+	if (i >> 63 == 0) {
+		if (i == 0)
+			return 0*x;
+		uxi = i;
+	}
+	for (; uxi>>52 == 0; uxi <<= 1, ex--);
+
+	/* scale result */
+	if (ex > 0) {
+		uxi -= 1ULL << 52;
+		uxi |= (uint64_t)ex << 52;
+	} else {
+		uxi >>= -ex + 1;
+	}
+	uxi |= (uint64_t)sx << 63;
+	ux.i = uxi;
+	return ux.f;
+}
libc/musl/src/math/fmodf.c
@@ -0,0 +1,65 @@
+#include <math.h>
+#include <stdint.h>
+
+float fmodf(float x, float y)
+{
+	union {float f; uint32_t i;} ux = {x}, uy = {y};
+	int ex = ux.i>>23 & 0xff;
+	int ey = uy.i>>23 & 0xff;
+	uint32_t sx = ux.i & 0x80000000;
+	uint32_t i;
+	uint32_t uxi = ux.i;
+
+	if (uy.i<<1 == 0 || isnan(y) || ex == 0xff)
+		return (x*y)/(x*y);
+	if (uxi<<1 <= uy.i<<1) {
+		if (uxi<<1 == uy.i<<1)
+			return 0*x;
+		return x;
+	}
+
+	/* normalize x and y */
+	if (!ex) {
+		for (i = uxi<<9; i>>31 == 0; ex--, i <<= 1);
+		uxi <<= -ex + 1;
+	} else {
+		uxi &= -1U >> 9;
+		uxi |= 1U << 23;
+	}
+	if (!ey) {
+		for (i = uy.i<<9; i>>31 == 0; ey--, i <<= 1);
+		uy.i <<= -ey + 1;
+	} else {
+		uy.i &= -1U >> 9;
+		uy.i |= 1U << 23;
+	}
+
+	/* x mod y */
+	for (; ex > ey; ex--) {
+		i = uxi - uy.i;
+		if (i >> 31 == 0) {
+			if (i == 0)
+				return 0*x;
+			uxi = i;
+		}
+		uxi <<= 1;
+	}
+	i = uxi - uy.i;
+	if (i >> 31 == 0) {
+		if (i == 0)
+			return 0*x;
+		uxi = i;
+	}
+	for (; uxi>>23 == 0; uxi <<= 1, ex--);
+
+	/* scale result up */
+	if (ex > 0) {
+		uxi -= 1U << 23;
+		uxi |= (uint32_t)ex << 23;
+	} else {
+		uxi >>= -ex + 1;
+	}
+	uxi |= sx;
+	ux.i = uxi;
+	return ux.f;
+}
libc/musl/src/math/fmodl.c
@@ -0,0 +1,105 @@
+#include "libm.h"
+
+#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024
+long double fmodl(long double x, long double y)
+{
+	return fmod(x, y);
+}
+#elif (LDBL_MANT_DIG == 64 || LDBL_MANT_DIG == 113) && LDBL_MAX_EXP == 16384
+long double fmodl(long double x, long double y)
+{
+	union ldshape ux = {x}, uy = {y};
+	int ex = ux.i.se & 0x7fff;
+	int ey = uy.i.se & 0x7fff;
+	int sx = ux.i.se & 0x8000;
+
+	if (y == 0 || isnan(y) || ex == 0x7fff)
+		return (x*y)/(x*y);
+	ux.i.se = ex;
+	uy.i.se = ey;
+	if (ux.f <= uy.f) {
+		if (ux.f == uy.f)
+			return 0*x;
+		return x;
+	}
+
+	/* normalize x and y */
+	if (!ex) {
+		ux.f *= 0x1p120f;
+		ex = ux.i.se - 120;
+	}
+	if (!ey) {
+		uy.f *= 0x1p120f;
+		ey = uy.i.se - 120;
+	}
+
+	/* x mod y */
+#if LDBL_MANT_DIG == 64
+	uint64_t i, mx, my;
+	mx = ux.i.m;
+	my = uy.i.m;
+	for (; ex > ey; ex--) {
+		i = mx - my;
+		if (mx >= my) {
+			if (i == 0)
+				return 0*x;
+			mx = 2*i;
+		} else if (2*mx < mx) {
+			mx = 2*mx - my;
+		} else {
+			mx = 2*mx;
+		}
+	}
+	i = mx - my;
+	if (mx >= my) {
+		if (i == 0)
+			return 0*x;
+		mx = i;
+	}
+	for (; mx >> 63 == 0; mx *= 2, ex--);
+	ux.i.m = mx;
+#elif LDBL_MANT_DIG == 113
+	uint64_t hi, lo, xhi, xlo, yhi, ylo;
+	xhi = (ux.i2.hi & -1ULL>>16) | 1ULL<<48;
+	yhi = (uy.i2.hi & -1ULL>>16) | 1ULL<<48;
+	xlo = ux.i2.lo;
+	ylo = uy.i2.lo;
+	for (; ex > ey; ex--) {
+		hi = xhi - yhi;
+		lo = xlo - ylo;
+		if (xlo < ylo)
+			hi -= 1;
+		if (hi >> 63 == 0) {
+			if ((hi|lo) == 0)
+				return 0*x;
+			xhi = 2*hi + (lo>>63);
+			xlo = 2*lo;
+		} else {
+			xhi = 2*xhi + (xlo>>63);
+			xlo = 2*xlo;
+		}
+	}
+	hi = xhi - yhi;
+	lo = xlo - ylo;
+	if (xlo < ylo)
+		hi -= 1;
+	if (hi >> 63 == 0) {
+		if ((hi|lo) == 0)
+			return 0*x;
+		xhi = hi;
+		xlo = lo;
+	}
+	for (; xhi >> 48 == 0; xhi = 2*xhi + (xlo>>63), xlo = 2*xlo, ex--);
+	ux.i2.hi = xhi;
+	ux.i2.lo = xlo;
+#endif
+
+	/* scale result */
+	if (ex <= 0) {
+		ux.i.se = (ex+120)|sx;
+		ux.f *= 0x1p-120f;
+	} else
+		ux.i.se = ex|sx;
+	return ux.f;
+}
+#endif
libc/musl/src/math/frexp.c
@@ -0,0 +1,23 @@
+#include <math.h>
+#include <stdint.h>
+
+double frexp(double x, int *e)
+{
+	union { double d; uint64_t i; } y = { x };
+	int ee = y.i>>52 & 0x7ff;
+
+	if (!ee) {
+		if (x) {
+			x = frexp(x*0x1p64, e);
+			*e -= 64;
+		} else *e = 0;
+		return x;
+	} else if (ee == 0x7ff) {
+		return x;
+	}
+
+	*e = ee - 0x3fe;
+	y.i &= 0x800fffffffffffffull;
+	y.i |= 0x3fe0000000000000ull;
+	return y.d;
+}
libc/musl/src/math/frexpf.c
@@ -0,0 +1,23 @@
+#include <math.h>
+#include <stdint.h>
+
+float frexpf(float x, int *e)
+{
+	union { float f; uint32_t i; } y = { x };
+	int ee = y.i>>23 & 0xff;
+
+	if (!ee) {
+		if (x) {
+			x = frexpf(x*0x1p64, e);
+			*e -= 64;
+		} else *e = 0;
+		return x;
+	} else if (ee == 0xff) {
+		return x;
+	}
+
+	*e = ee - 0x7e;
+	y.i &= 0x807ffffful;
+	y.i |= 0x3f000000ul;
+	return y.f;
+}
libc/musl/src/math/frexpl.c
@@ -0,0 +1,29 @@
+#include "libm.h"
+
+#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024
+long double frexpl(long double x, int *e)
+{
+	return frexp(x, e);
+}
+#elif (LDBL_MANT_DIG == 64 || LDBL_MANT_DIG == 113) && LDBL_MAX_EXP == 16384
+long double frexpl(long double x, int *e)
+{
+	union ldshape u = {x};
+	int ee = u.i.se & 0x7fff;
+
+	if (!ee) {
+		if (x) {
+			x = frexpl(x*0x1p120, e);
+			*e -= 120;
+		} else *e = 0;
+		return x;
+	} else if (ee == 0x7fff) {
+		return x;
+	}
+
+	*e = ee - 0x3ffe;
+	u.i.se &= 0x8000;
+	u.i.se |= 0x3ffe;
+	return u.f;
+}
+#endif
libc/musl/src/math/hypot.c
@@ -0,0 +1,67 @@
+#include <math.h>
+#include <stdint.h>
+#include <float.h>
+
+#if FLT_EVAL_METHOD > 1U && LDBL_MANT_DIG == 64
+#define SPLIT (0x1p32 + 1)
+#else
+#define SPLIT (0x1p27 + 1)
+#endif
+
+static void sq(double_t *hi, double_t *lo, double x)
+{
+	double_t xh, xl, xc;
+
+	xc = (double_t)x*SPLIT;
+	xh = x - xc + xc;
+	xl = x - xh;
+	*hi = (double_t)x*x;
+	*lo = xh*xh - *hi + 2*xh*xl + xl*xl;
+}
+
+double hypot(double x, double y)
+{
+	union {double f; uint64_t i;} ux = {x}, uy = {y}, ut;
+	int ex, ey;
+	double_t hx, lx, hy, ly, z;
+
+	/* arrange |x| >= |y| */
+	ux.i &= -1ULL>>1;
+	uy.i &= -1ULL>>1;
+	if (ux.i < uy.i) {
+		ut = ux;
+		ux = uy;
+		uy = ut;
+	}
+
+	/* special cases */
+	ex = ux.i>>52;
+	ey = uy.i>>52;
+	x = ux.f;
+	y = uy.f;
+	/* note: hypot(inf,nan) == inf */
+	if (ey == 0x7ff)
+		return y;
+	if (ex == 0x7ff || uy.i == 0)
+		return x;
+	/* note: hypot(x,y) ~= x + y*y/x/2 with inexact for small y/x */
+	/* 64 difference is enough for ld80 double_t */
+	if (ex - ey > 64)
+		return x + y;
+
+	/* precise sqrt argument in nearest rounding mode without overflow */
+	/* xh*xh must not overflow and xl*xl must not underflow in sq */
+	z = 1;
+	if (ex > 0x3ff+510) {
+		z = 0x1p700;
+		x *= 0x1p-700;
+		y *= 0x1p-700;
+	} else if (ey < 0x3ff-450) {
+		z = 0x1p-700;
+		x *= 0x1p700;
+		y *= 0x1p700;
+	}
+	sq(&hx, &lx, x);
+	sq(&hy, &ly, y);
+	return z*sqrt(ly+lx+hy+hx);
+}
libc/musl/src/math/hypotf.c
@@ -0,0 +1,35 @@
+#include <math.h>
+#include <stdint.h>
+
+float hypotf(float x, float y)
+{
+	union {float f; uint32_t i;} ux = {x}, uy = {y}, ut;
+	float_t z;
+
+	ux.i &= -1U>>1;
+	uy.i &= -1U>>1;
+	if (ux.i < uy.i) {
+		ut = ux;
+		ux = uy;
+		uy = ut;
+	}
+
+	x = ux.f;
+	y = uy.f;
+	if (uy.i == 0xff<<23)
+		return y;
+	if (ux.i >= 0xff<<23 || uy.i == 0 || ux.i - uy.i >= 25<<23)
+		return x + y;
+
+	z = 1;
+	if (ux.i >= (0x7f+60)<<23) {
+		z = 0x1p90f;
+		x *= 0x1p-90f;
+		y *= 0x1p-90f;
+	} else if (uy.i < (0x7f-60)<<23) {
+		z = 0x1p-90f;
+		x *= 0x1p90f;
+		y *= 0x1p90f;
+	}
+	return z*sqrtf((double)x*x + (double)y*y);
+}
libc/musl/src/math/hypotl.c
@@ -0,0 +1,66 @@
+#include "libm.h"
+
+#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024
+long double hypotl(long double x, long double y)
+{
+	return hypot(x, y);
+}
+#elif (LDBL_MANT_DIG == 64 || LDBL_MANT_DIG == 113) && LDBL_MAX_EXP == 16384
+#if LDBL_MANT_DIG == 64
+#define SPLIT (0x1p32L+1)
+#elif LDBL_MANT_DIG == 113
+#define SPLIT (0x1p57L+1)
+#endif
+
+static void sq(long double *hi, long double *lo, long double x)
+{
+	long double xh, xl, xc;
+	xc = x*SPLIT;
+	xh = x - xc + xc;
+	xl = x - xh;
+	*hi = x*x;
+	*lo = xh*xh - *hi + 2*xh*xl + xl*xl;
+}
+
+long double hypotl(long double x, long double y)
+{
+	union ldshape ux = {x}, uy = {y};
+	int ex, ey;
+	long double hx, lx, hy, ly, z;
+
+	ux.i.se &= 0x7fff;
+	uy.i.se &= 0x7fff;
+	if (ux.i.se < uy.i.se) {
+		ex = uy.i.se;
+		ey = ux.i.se;
+		x = uy.f;
+		y = ux.f;
+	} else {
+		ex = ux.i.se;
+		ey = uy.i.se;
+		x = ux.f;
+		y = uy.f;
+	}
+
+	if (ex == 0x7fff && isinf(y))
+		return y;
+	if (ex == 0x7fff || y == 0)
+		return x;
+	if (ex - ey > LDBL_MANT_DIG)
+		return x + y;
+
+	z = 1;
+	if (ex > 0x3fff+8000) {
+		z = 0x1p10000L;
+		x *= 0x1p-10000L;
+		y *= 0x1p-10000L;
+	} else if (ey < 0x3fff-8000) {
+		z = 0x1p-10000L;
+		x *= 0x1p10000L;
+		y *= 0x1p10000L;
+	}
+	sq(&hx, &lx, x);
+	sq(&hy, &ly, y);
+	return z*sqrtl(ly+lx+hy+hx);
+}
+#endif
libc/musl/src/math/ilogb.c
@@ -0,0 +1,26 @@
+#include <limits.h>
+#include "libm.h"
+
+int ilogb(double x)
+{
+	#pragma STDC FENV_ACCESS ON
+	union {double f; uint64_t i;} u = {x};
+	uint64_t i = u.i;
+	int e = i>>52 & 0x7ff;
+
+	if (!e) {
+		i <<= 12;
+		if (i == 0) {
+			FORCE_EVAL(0/0.0f);
+			return FP_ILOGB0;
+		}
+		/* subnormal x */
+		for (e = -0x3ff; i>>63 == 0; e--, i<<=1);
+		return e;
+	}
+	if (e == 0x7ff) {
+		FORCE_EVAL(0/0.0f);
+		return i<<12 ? FP_ILOGBNAN : INT_MAX;
+	}
+	return e - 0x3ff;
+}
libc/musl/src/math/ilogbf.c
@@ -0,0 +1,26 @@
+#include <limits.h>
+#include "libm.h"
+
+int ilogbf(float x)
+{
+	#pragma STDC FENV_ACCESS ON
+	union {float f; uint32_t i;} u = {x};
+	uint32_t i = u.i;
+	int e = i>>23 & 0xff;
+
+	if (!e) {
+		i <<= 9;
+		if (i == 0) {
+			FORCE_EVAL(0/0.0f);
+			return FP_ILOGB0;
+		}
+		/* subnormal x */
+		for (e = -0x7f; i>>31 == 0; e--, i<<=1);
+		return e;
+	}
+	if (e == 0xff) {
+		FORCE_EVAL(0/0.0f);
+		return i<<9 ? FP_ILOGBNAN : INT_MAX;
+	}
+	return e - 0x7f;
+}
libc/musl/src/math/ilogbl.c
@@ -0,0 +1,55 @@
+#include <limits.h>
+#include "libm.h"
+
+#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024
+int ilogbl(long double x)
+{
+	return ilogb(x);
+}
+#elif LDBL_MANT_DIG == 64 && LDBL_MAX_EXP == 16384
+int ilogbl(long double x)
+{
+	#pragma STDC FENV_ACCESS ON
+	union ldshape u = {x};
+	uint64_t m = u.i.m;
+	int e = u.i.se & 0x7fff;
+
+	if (!e) {
+		if (m == 0) {
+			FORCE_EVAL(0/0.0f);
+			return FP_ILOGB0;
+		}
+		/* subnormal x */
+		for (e = -0x3fff+1; m>>63 == 0; e--, m<<=1);
+		return e;
+	}
+	if (e == 0x7fff) {
+		FORCE_EVAL(0/0.0f);
+		return m<<1 ? FP_ILOGBNAN : INT_MAX;
+	}
+	return e - 0x3fff;
+}
+#elif LDBL_MANT_DIG == 113 && LDBL_MAX_EXP == 16384
+int ilogbl(long double x)
+{
+	#pragma STDC FENV_ACCESS ON
+	union ldshape u = {x};
+	int e = u.i.se & 0x7fff;
+
+	if (!e) {
+		if (x == 0) {
+			FORCE_EVAL(0/0.0f);
+			return FP_ILOGB0;
+		}
+		/* subnormal x */
+		x *= 0x1p120;
+		return ilogbl(x) - 120;
+	}
+	if (e == 0x7fff) {
+		FORCE_EVAL(0/0.0f);
+		u.i.se = 0;
+		return u.f ? FP_ILOGBNAN : INT_MAX;
+	}
+	return e - 0x3fff;
+}
+#endif
libc/musl/src/math/j0.c
@@ -0,0 +1,375 @@
+/* origin: FreeBSD /usr/src/lib/msun/src/e_j0.c */
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunSoft, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+/* j0(x), y0(x)
+ * Bessel function of the first and second kinds of order zero.
+ * Method -- j0(x):
+ *      1. For tiny x, we use j0(x) = 1 - x^2/4 + x^4/64 - ...
+ *      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 "libm.h"
+
+static double pzero(double), qzero(double);
+
+static const double
+invsqrtpi = 5.64189583547756279280e-01, /* 0x3FE20DD7, 0x50429B6D */
+tpi       = 6.36619772367581382433e-01; /* 0x3FE45F30, 0x6DC9C883 */
+
+/* common method when |x|>=2 */
+static double common(uint32_t ix, double x, int y0)
+{
+	double s,c,ss,cc,z;
+
+	/*
+	 * j0(x) = sqrt(2/(pi*x))*(p0(x)*cos(x-pi/4)-q0(x)*sin(x-pi/4))
+	 * y0(x) = sqrt(2/(pi*x))*(p0(x)*sin(x-pi/4)+q0(x)*cos(x-pi/4))
+	 *
+	 * sin(x-pi/4) = (sin(x) - cos(x))/sqrt(2)
+	 * cos(x-pi/4) = (sin(x) + cos(x))/sqrt(2)
+	 * sin(x) +- cos(x) = -cos(2x)/(sin(x) -+ cos(x))
+	 */
+	s = sin(x);
+	c = cos(x);
+	if (y0)
+		c = -c;
+	cc = s+c;
+	/* avoid overflow in 2*x, big ulp error when x>=0x1p1023 */
+	if (ix < 0x7fe00000) {
+		ss = s-c;
+		z = -cos(2*x);
+		if (s*c < 0)
+			cc = z/ss;
+		else
+			ss = z/cc;
+		if (ix < 0x48000000) {
+			if (y0)
+				ss = -ss;
+			cc = pzero(x)*cc-qzero(x)*ss;
+		}
+	}
+	return invsqrtpi*cc/sqrt(x);
+}
+
+/* R0/S0 on [0, 2.00] */
+static const double
+R02 =  1.56249999999999947958e-02, /* 0x3F8FFFFF, 0xFFFFFFFD */
+R03 = -1.89979294238854721751e-04, /* 0xBF28E6A5, 0xB61AC6E9 */
+R04 =  1.82954049532700665670e-06, /* 0x3EBEB1D1, 0x0C503919 */
+R05 = -4.61832688532103189199e-09, /* 0xBE33D5E7, 0x73D63FCE */
+S01 =  1.56191029464890010492e-02, /* 0x3F8FFCE8, 0x82C8C2A4 */
+S02 =  1.16926784663337450260e-04, /* 0x3F1EA6D2, 0xDD57DBF4 */
+S03 =  5.13546550207318111446e-07, /* 0x3EA13B54, 0xCE84D5A9 */
+S04 =  1.16614003333790000205e-09; /* 0x3E1408BC, 0xF4745D8F */
+
+double j0(double x)
+{
+	double z,r,s;
+	uint32_t ix;
+
+	GET_HIGH_WORD(ix, x);
+	ix &= 0x7fffffff;
+
+	/* j0(+-inf)=0, j0(nan)=nan */
+	if (ix >= 0x7ff00000)
+		return 1/(x*x);
+	x = fabs(x);
+
+	if (ix >= 0x40000000) {  /* |x| >= 2 */
+		/* large ulp error near zeros: 2.4, 5.52, 8.6537,.. */
+		return common(ix,x,0);
+	}
+
+	/* 1 - x*x/4 + x*x*R(x^2)/S(x^2) */
+	if (ix >= 0x3f200000) {  /* |x| >= 2**-13 */
+		/* up to 4ulp error close to 2 */
+		z = x*x;
+		r = z*(R02+z*(R03+z*(R04+z*R05)));
+		s = 1+z*(S01+z*(S02+z*(S03+z*S04)));
+		return (1+x/2)*(1-x/2) + z*(r/s);
+	}
+
+	/* 1 - x*x/4 */
+	/* prevent underflow */
+	/* inexact should be raised when x!=0, this is not done correctly */
+	if (ix >= 0x38000000)  /* |x| >= 2**-127 */
+		x = 0.25*x*x;
+	return 1 - x;
+}
+
+static const double
+u00  = -7.38042951086872317523e-02, /* 0xBFB2E4D6, 0x99CBD01F */
+u01  =  1.76666452509181115538e-01, /* 0x3FC69D01, 0x9DE9E3FC */
+u02  = -1.38185671945596898896e-02, /* 0xBF8C4CE8, 0xB16CFA97 */
+u03  =  3.47453432093683650238e-04, /* 0x3F36C54D, 0x20B29B6B */
+u04  = -3.81407053724364161125e-06, /* 0xBECFFEA7, 0x73D25CAD */
+u05  =  1.95590137035022920206e-08, /* 0x3E550057, 0x3B4EABD4 */
+u06  = -3.98205194132103398453e-11, /* 0xBDC5E43D, 0x693FB3C8 */
+v01  =  1.27304834834123699328e-02, /* 0x3F8A1270, 0x91C9C71A */
+v02  =  7.60068627350353253702e-05, /* 0x3F13ECBB, 0xF578C6C1 */
+v03  =  2.59150851840457805467e-07, /* 0x3E91642D, 0x7FF202FD */
+v04  =  4.41110311332675467403e-10; /* 0x3DFE5018, 0x3BD6D9EF */
+
+double y0(double x)
+{
+	double z,u,v;
+	uint32_t ix,lx;
+
+	EXTRACT_WORDS(ix, lx, x);
+
+	/* y0(nan)=nan, y0(<0)=nan, y0(0)=-inf, y0(inf)=0 */
+	if ((ix<<1 | lx) == 0)
+		return -1/0.0;
+	if (ix>>31)
+		return 0/0.0;
+	if (ix >= 0x7ff00000)
+		return 1/x;
+
+	if (ix >= 0x40000000) {  /* x >= 2 */
+		/* large ulp errors near zeros: 3.958, 7.086,.. */
+		return common(ix,x,1);
+	}
+
+	/* U(x^2)/V(x^2) + (2/pi)*j0(x)*log(x) */
+	if (ix >= 0x3e400000) {  /* x >= 2**-27 */
+		/* large ulp error near the first zero, x ~= 0.89 */
+		z = x*x;
+		u = u00+z*(u01+z*(u02+z*(u03+z*(u04+z*(u05+z*u06)))));
+		v = 1.0+z*(v01+z*(v02+z*(v03+z*v04)));
+		return u/v + tpi*(j0(x)*log(x));
+	}
+	return u00 + tpi*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)
+ */
+static const double pR8[6] = { /* for x in [inf, 8]=1/[0,0.125] */
+  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 */
+};
+static const double pS8[5] = {
+  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 */
+};
+
+static const double pR5[6] = { /* for x in [8,4.5454]=1/[0.125,0.22001] */
+ -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 */
+};
+static const double pS5[5] = {
+  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 */
+};
+
+static const double pR3[6] = {/* for x in [4.547,2.8571]=1/[0.2199,0.35001] */
+ -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 */
+};
+static const double pS3[5] = {
+  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 */
+};
+
+static const double pR2[6] = {/* for x in [2.8570,2]=1/[0.3499,0.5] */
+ -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 */
+};
+static const double pS2[5] = {
+  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 */
+};
+
+static double pzero(double x)
+{
+	const double *p,*q;
+	double_t z,r,s;
+	uint32_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 /*ix >= 0x40000000*/ {p = pR2; q = pS2;}
+	z = 1.0/(x*x);
+	r = p[0]+z*(p[1]+z*(p[2]+z*(p[3]+z*(p[4]+z*p[5]))));
+	s = 1.0+z*(q[0]+z*(q[1]+z*(q[2]+z*(q[3]+z*q[4]))));
+	return 1.0 + 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)
+ */
+static const double qR8[6] = { /* for x in [inf, 8]=1/[0,0.125] */
+  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 */
+};
+static const double qS8[6] = {
+  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 */
+};
+
+static const double qR5[6] = { /* for x in [8,4.5454]=1/[0.125,0.22001] */
+  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 */
+};
+static const double qS5[6] = {
+  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 */
+};
+
+static const double qR3[6] = {/* for x in [4.547,2.8571]=1/[0.2199,0.35001] */
+  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 */
+};
+static const double qS3[6] = {
+  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 */
+};
+
+static const double qR2[6] = {/* for x in [2.8570,2]=1/[0.3499,0.5] */
+  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 */
+};
+static const double qS2[6] = {
+  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 */
+};
+
+static double qzero(double x)
+{
+	const double *p,*q;
+	double_t s,r,z;
+	uint32_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 /*ix >= 0x40000000*/ {p = qR2; q = qS2;}
+	z = 1.0/(x*x);
+	r = p[0]+z*(p[1]+z*(p[2]+z*(p[3]+z*(p[4]+z*p[5]))));
+	s = 1.0+z*(q[0]+z*(q[1]+z*(q[2]+z*(q[3]+z*(q[4]+z*q[5])))));
+	return (-.125 + r/s)/x;
+}
libc/musl/src/math/j0f.c
@@ -0,0 +1,314 @@
+/* origin: FreeBSD /usr/src/lib/msun/src/e_j0f.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.
+ * ====================================================
+ */
+
+#define _GNU_SOURCE
+#include "libm.h"
+
+static float pzerof(float), qzerof(float);
+
+static const float
+invsqrtpi = 5.6418961287e-01, /* 0x3f106ebb */
+tpi       = 6.3661974669e-01; /* 0x3f22f983 */
+
+static float common(uint32_t ix, float x, int y0)
+{
+	float z,s,c,ss,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)
+	 */
+	s = sinf(x);
+	c = cosf(x);
+	if (y0)
+		c = -c;
+	cc = s+c;
+	if (ix < 0x7f000000) {
+		ss = s-c;
+		z = -cosf(2*x);
+		if (s*c < 0)
+			cc = z/ss;
+		else
+			ss = z/cc;
+		if (ix < 0x58800000) {
+			if (y0)
+				ss = -ss;
+			cc = pzerof(x)*cc-qzerof(x)*ss;
+		}
+	}
+	return invsqrtpi*cc/sqrtf(x);
+}
+
+/* R0/S0 on [0, 2.00] */
+static const float
+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 */
+
+float j0f(float x)
+{
+	float z,r,s;
+	uint32_t ix;
+
+	GET_FLOAT_WORD(ix, x);
+	ix &= 0x7fffffff;
+	if (ix >= 0x7f800000)
+		return 1/(x*x);
+	x = fabsf(x);
+
+	if (ix >= 0x40000000) {  /* |x| >= 2 */
+		/* large ulp error near zeros */
+		return common(ix, x, 0);
+	}
+	if (ix >= 0x3a000000) {  /* |x| >= 2**-11 */
+		/* up to 4ulp error near 2 */
+		z = x*x;
+		r = z*(R02+z*(R03+z*(R04+z*R05)));
+		s = 1+z*(S01+z*(S02+z*(S03+z*S04)));
+		return (1+x/2)*(1-x/2) + z*(r/s);
+	}
+	if (ix >= 0x21800000)  /* |x| >= 2**-60 */
+		x = 0.25f*x*x;
+	return 1 - x;
+}
+
+static const float
+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 */
+
+float y0f(float x)
+{
+	float z,u,v;
+	uint32_t ix;
+
+	GET_FLOAT_WORD(ix, x);
+	if ((ix & 0x7fffffff) == 0)
+		return -1/0.0f;
+	if (ix>>31)
+		return 0/0.0f;
+	if (ix >= 0x7f800000)
+		return 1/x;
+	if (ix >= 0x40000000) {  /* |x| >= 2.0 */
+		/* large ulp error near zeros */
+		return common(ix,x,1);
+	}
+	if (ix >= 0x39000000) {  /* x >= 2**-13 */
+		/* large ulp error at x ~= 0.89 */
+		z = x*x;
+		u = u00+z*(u01+z*(u02+z*(u03+z*(u04+z*(u05+z*u06)))));
+		v = 1+z*(v01+z*(v02+z*(v03+z*v04)));
+		return u/v + tpi*(j0f(x)*logf(x));
+	}
+	return u00 + tpi*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)
+ */
+static const float pR8[6] = { /* for x in [inf, 8]=1/[0,0.125] */
+  0.0000000000e+00, /* 0x00000000 */
+ -7.0312500000e-02, /* 0xbd900000 */
+ -8.0816707611e+00, /* 0xc1014e86 */
+ -2.5706311035e+02, /* 0xc3808814 */
+ -2.4852163086e+03, /* 0xc51b5376 */
+ -5.2530439453e+03, /* 0xc5a4285a */
+};
+static const float pS8[5] = {
+  1.1653436279e+02, /* 0x42e91198 */
+  3.8337448730e+03, /* 0x456f9beb */
+  4.0597855469e+04, /* 0x471e95db */
+  1.1675296875e+05, /* 0x47e4087c */
+  4.7627726562e+04, /* 0x473a0bba */
+};
+static const float pR5[6] = { /* for x in [8,4.5454]=1/[0.125,0.22001] */
+ -1.1412546255e-11, /* 0xad48c58a */
+ -7.0312492549e-02, /* 0xbd8fffff */
+ -4.1596107483e+00, /* 0xc0851b88 */
+ -6.7674766541e+01, /* 0xc287597b */
+ -3.3123129272e+02, /* 0xc3a59d9b */
+ -3.4643338013e+02, /* 0xc3ad3779 */
+};
+static const float pS5[5] = {
+  6.0753936768e+01, /* 0x42730408 */
+  1.0512523193e+03, /* 0x44836813 */
+  5.9789707031e+03, /* 0x45bad7c4 */
+  9.6254453125e+03, /* 0x461665c8 */
+  2.4060581055e+03, /* 0x451660ee */
+};
+
+static const float pR3[6] = {/* for x in [4.547,2.8571]=1/[0.2199,0.35001] */
+ -2.5470459075e-09, /* 0xb12f081b */
+ -7.0311963558e-02, /* 0xbd8fffb8 */
+ -2.4090321064e+00, /* 0xc01a2d95 */
+ -2.1965976715e+01, /* 0xc1afba52 */
+ -5.8079170227e+01, /* 0xc2685112 */
+ -3.1447946548e+01, /* 0xc1fb9565 */
+};
+static const float pS3[5] = {
+  3.5856033325e+01, /* 0x420f6c94 */
+  3.6151397705e+02, /* 0x43b4c1ca */
+  1.1936077881e+03, /* 0x44953373 */
+  1.1279968262e+03, /* 0x448cffe6 */
+  1.7358093262e+02, /* 0x432d94b8 */
+};
+
+static const float pR2[6] = {/* for x in [2.8570,2]=1/[0.3499,0.5] */
+ -8.8753431271e-08, /* 0xb3be98b7 */
+ -7.0303097367e-02, /* 0xbd8ffb12 */
+ -1.4507384300e+00, /* 0xbfb9b1cc */
+ -7.6356959343e+00, /* 0xc0f4579f */
+ -1.1193166733e+01, /* 0xc1331736 */
+ -3.2336456776e+00, /* 0xc04ef40d */
+};
+static const float pS2[5] = {
+  2.2220300674e+01, /* 0x41b1c32d */
+  1.3620678711e+02, /* 0x430834f0 */
+  2.7047027588e+02, /* 0x43873c32 */
+  1.5387539673e+02, /* 0x4319e01a */
+  1.4657617569e+01, /* 0x416a859a */
+};
+
+static float pzerof(float x)
+{
+	const float *p,*q;
+	float_t z,r,s;
+	uint32_t ix;
+
+	GET_FLOAT_WORD(ix, x);
+	ix &= 0x7fffffff;
+	if      (ix >= 0x41000000){p = pR8; q = pS8;}
+	else if (ix >= 0x409173eb){p = pR5; q = pS5;}
+	else if (ix >= 0x4036d917){p = pR3; q = pS3;}
+	else /*ix >= 0x40000000*/ {p = pR2; q = pS2;}
+	z = 1.0f/(x*x);
+	r = p[0]+z*(p[1]+z*(p[2]+z*(p[3]+z*(p[4]+z*p[5]))));
+	s = 1.0f+z*(q[0]+z*(q[1]+z*(q[2]+z*(q[3]+z*q[4]))));
+	return 1.0f + 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)
+ */
+static const float qR8[6] = { /* for x in [inf, 8]=1/[0,0.125] */
+  0.0000000000e+00, /* 0x00000000 */
+  7.3242187500e-02, /* 0x3d960000 */
+  1.1768206596e+01, /* 0x413c4a93 */
+  5.5767340088e+02, /* 0x440b6b19 */
+  8.8591972656e+03, /* 0x460a6cca */
+  3.7014625000e+04, /* 0x471096a0 */
+};
+static const float qS8[6] = {
+  1.6377603149e+02, /* 0x4323c6aa */
+  8.0983447266e+03, /* 0x45fd12c2 */
+  1.4253829688e+05, /* 0x480b3293 */
+  8.0330925000e+05, /* 0x49441ed4 */
+  8.4050156250e+05, /* 0x494d3359 */
+ -3.4389928125e+05, /* 0xc8a7eb69 */
+};
+
+static const float qR5[6] = { /* for x in [8,4.5454]=1/[0.125,0.22001] */
+  1.8408595828e-11, /* 0x2da1ec79 */
+  7.3242180049e-02, /* 0x3d95ffff */
+  5.8356351852e+00, /* 0x40babd86 */
+  1.3511157227e+02, /* 0x43071c90 */
+  1.0272437744e+03, /* 0x448067cd */
+  1.9899779053e+03, /* 0x44f8bf4b */
+};
+static const float qS5[6] = {
+  8.2776611328e+01, /* 0x42a58da0 */
+  2.0778142090e+03, /* 0x4501dd07 */
+  1.8847289062e+04, /* 0x46933e94 */
+  5.6751113281e+04, /* 0x475daf1d */
+  3.5976753906e+04, /* 0x470c88c1 */
+ -5.3543427734e+03, /* 0xc5a752be */
+};
+
+static const float qR3[6] = {/* for x in [4.547,2.8571]=1/[0.2199,0.35001] */
+  4.3774099900e-09, /* 0x3196681b */
+  7.3241114616e-02, /* 0x3d95ff70 */
+  3.3442313671e+00, /* 0x405607e3 */
+  4.2621845245e+01, /* 0x422a7cc5 */
+  1.7080809021e+02, /* 0x432acedf */
+  1.6673394775e+02, /* 0x4326bbe4 */
+};
+static const float qS3[6] = {
+  4.8758872986e+01, /* 0x42430916 */
+  7.0968920898e+02, /* 0x44316c1c */
+  3.7041481934e+03, /* 0x4567825f */
+  6.4604252930e+03, /* 0x45c9e367 */
+  2.5163337402e+03, /* 0x451d4557 */
+ -1.4924745178e+02, /* 0xc3153f59 */
+};
+
+static const float qR2[6] = {/* for x in [2.8570,2]=1/[0.3499,0.5] */
+  1.5044444979e-07, /* 0x342189db */
+  7.3223426938e-02, /* 0x3d95f62a */
+  1.9981917143e+00, /* 0x3fffc4bf */
+  1.4495602608e+01, /* 0x4167edfd */
+  3.1666231155e+01, /* 0x41fd5471 */
+  1.6252708435e+01, /* 0x4182058c */
+};
+static const float qS2[6] = {
+  3.0365585327e+01, /* 0x41f2ecb8 */
+  2.6934811401e+02, /* 0x4386ac8f */
+  8.4478375244e+02, /* 0x44533229 */
+  8.8293585205e+02, /* 0x445cbbe5 */
+  2.1266638184e+02, /* 0x4354aa98 */
+ -5.3109550476e+00, /* 0xc0a9f358 */
+};
+
+static float qzerof(float x)
+{
+	const float *p,*q;
+	float_t s,r,z;
+	uint32_t ix;
+
+	GET_FLOAT_WORD(ix, x);
+	ix &= 0x7fffffff;
+	if      (ix >= 0x41000000){p = qR8; q = qS8;}
+	else if (ix >= 0x409173eb){p = qR5; q = qS5;}
+	else if (ix >= 0x4036d917){p = qR3; q = qS3;}
+	else /*ix >= 0x40000000*/ {p = qR2; q = qS2;}
+	z = 1.0f/(x*x);
+	r = p[0]+z*(p[1]+z*(p[2]+z*(p[3]+z*(p[4]+z*p[5]))));
+	s = 1.0f+z*(q[0]+z*(q[1]+z*(q[2]+z*(q[3]+z*(q[4]+z*q[5])))));
+	return (-.125f + r/s)/x;
+}
libc/musl/src/math/j1.c
@@ -0,0 +1,362 @@
+/* origin: FreeBSD /usr/src/lib/msun/src/e_j1.c */
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunSoft, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+/* j1(x), y1(x)
+ * Bessel function of the first and second kinds of order zero.
+ * Method -- j1(x):
+ *      1. For tiny x, we use j1(x) = x/2 - x^3/16 + x^5/384 - ...
+ *      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 "libm.h"
+
+static double pone(double), qone(double);
+
+static const double
+invsqrtpi = 5.64189583547756279280e-01, /* 0x3FE20DD7, 0x50429B6D */
+tpi       = 6.36619772367581382433e-01; /* 0x3FE45F30, 0x6DC9C883 */
+
+static double common(uint32_t ix, double x, int y1, int sign)
+{
+	double z,s,c,ss,cc;
+
+	/*
+	 * j1(x) = sqrt(2/(pi*x))*(p1(x)*cos(x-3pi/4)-q1(x)*sin(x-3pi/4))
+	 * y1(x) = sqrt(2/(pi*x))*(p1(x)*sin(x-3pi/4)+q1(x)*cos(x-3pi/4))
+	 *
+	 * sin(x-3pi/4) = -(sin(x) + cos(x))/sqrt(2)
+	 * cos(x-3pi/4) = (sin(x) - cos(x))/sqrt(2)
+	 * sin(x) +- cos(x) = -cos(2x)/(sin(x) -+ cos(x))
+	 */
+	s = sin(x);
+	if (y1)
+		s = -s;
+	c = cos(x);
+	cc = s-c;
+	if (ix < 0x7fe00000) {
+		/* avoid overflow in 2*x */
+		ss = -s-c;
+		z = cos(2*x);
+		if (s*c > 0)
+			cc = z/ss;
+		else
+			ss = z/cc;
+		if (ix < 0x48000000) {
+			if (y1)
+				ss = -ss;
+			cc = pone(x)*cc-qone(x)*ss;
+		}
+	}
+	if (sign)
+		cc = -cc;
+	return invsqrtpi*cc/sqrt(x);
+}
+
+/* R0/S0 on [0,2] */
+static const double
+r00 = -6.25000000000000000000e-02, /* 0xBFB00000, 0x00000000 */
+r01 =  1.40705666955189706048e-03, /* 0x3F570D9F, 0x98472C61 */
+r02 = -1.59955631084035597520e-05, /* 0xBEF0C5C6, 0xBA169668 */
+r03 =  4.96727999609584448412e-08, /* 0x3E6AAAFA, 0x46CA0BD9 */
+s01 =  1.91537599538363460805e-02, /* 0x3F939D0B, 0x12637E53 */
+s02 =  1.85946785588630915560e-04, /* 0x3F285F56, 0xB9CDF664 */
+s03 =  1.17718464042623683263e-06, /* 0x3EB3BFF8, 0x333F8498 */
+s04 =  5.04636257076217042715e-09, /* 0x3E35AC88, 0xC97DFF2C */
+s05 =  1.23542274426137913908e-11; /* 0x3DAB2ACF, 0xCFB97ED8 */
+
+double j1(double x)
+{
+	double z,r,s;
+	uint32_t ix;
+	int sign;
+
+	GET_HIGH_WORD(ix, x);
+	sign = ix>>31;
+	ix &= 0x7fffffff;
+	if (ix >= 0x7ff00000)
+		return 1/(x*x);
+	if (ix >= 0x40000000)  /* |x| >= 2 */
+		return common(ix, fabs(x), 0, sign);
+	if (ix >= 0x38000000) {  /* |x| >= 2**-127 */
+		z = x*x;
+		r = z*(r00+z*(r01+z*(r02+z*r03)));
+		s = 1+z*(s01+z*(s02+z*(s03+z*(s04+z*s05))));
+		z = r/s;
+	} else
+		/* avoid underflow, raise inexact if x!=0 */
+		z = x;
+	return (0.5 + z)*x;
+}
+
+static const double U0[5] = {
+ -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 */
+};
+static const double V0[5] = {
+  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 */
+};
+
+double y1(double x)
+{
+	double z,u,v;
+	uint32_t ix,lx;
+
+	EXTRACT_WORDS(ix, lx, x);
+	/* y1(nan)=nan, y1(<0)=nan, y1(0)=-inf, y1(inf)=0 */
+	if ((ix<<1 | lx) == 0)
+		return -1/0.0;
+	if (ix>>31)
+		return 0/0.0;
+	if (ix >= 0x7ff00000)
+		return 1/x;
+
+	if (ix >= 0x40000000)  /* x >= 2 */
+		return common(ix, x, 1, 0);
+	if (ix < 0x3c900000)  /* 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 = 1+z*(V0[0]+z*(V0[1]+z*(V0[2]+z*(V0[3]+z*V0[4]))));
+	return x*(u/v) + tpi*(j1(x)*log(x)-1/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)
+ */
+
+static const double pr8[6] = { /* for x in [inf, 8]=1/[0,0.125] */
+  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 */
+};
+static const double ps8[5] = {
+  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 */
+};
+
+static const double pr5[6] = { /* for x in [8,4.5454]=1/[0.125,0.22001] */
+  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 */
+};
+static const double ps5[5] = {
+  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 */
+};
+
+static const double pr3[6] = {
+  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 */
+};
+static const double ps3[5] = {
+  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 */
+};
+
+static const double pr2[6] = {/* for x in [2.8570,2]=1/[0.3499,0.5] */
+  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 */
+};
+static const double ps2[5] = {
+  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 */
+};
+
+static double pone(double x)
+{
+	const double *p,*q;
+	double_t z,r,s;
+	uint32_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 /*ix >= 0x40000000*/ {p = pr2; q = ps2;}
+	z = 1.0/(x*x);
+	r = p[0]+z*(p[1]+z*(p[2]+z*(p[3]+z*(p[4]+z*p[5]))));
+	s = 1.0+z*(q[0]+z*(q[1]+z*(q[2]+z*(q[3]+z*q[4]))));
+	return 1.0+ 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)
+ */
+
+static const double qr8[6] = { /* for x in [inf, 8]=1/[0,0.125] */
+  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 */
+};
+static const double qs8[6] = {
+  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 */
+};
+
+static const double qr5[6] = { /* for x in [8,4.5454]=1/[0.125,0.22001] */
+ -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 */
+};
+static const double qs5[6] = {
+  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 */
+};
+
+static const double qr3[6] = {
+ -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 */
+};
+static const double qs3[6] = {
+  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 */
+};
+
+static const double qr2[6] = {/* for x in [2.8570,2]=1/[0.3499,0.5] */
+ -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 */
+};
+static const double qs2[6] = {
+  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 */
+};
+
+static double qone(double x)
+{
+	const double *p,*q;
+	double_t s,r,z;
+	uint32_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 /*ix >= 0x40000000*/ {p = qr2; q = qs2;}
+	z = 1.0/(x*x);
+	r = p[0]+z*(p[1]+z*(p[2]+z*(p[3]+z*(p[4]+z*p[5]))));
+	s = 1.0+z*(q[0]+z*(q[1]+z*(q[2]+z*(q[3]+z*(q[4]+z*q[5])))));
+	return (.375 + r/s)/x;
+}
libc/musl/src/math/j1f.c
@@ -0,0 +1,310 @@
+/* origin: FreeBSD /usr/src/lib/msun/src/e_j1f.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.
+ * ====================================================
+ */
+
+#define _GNU_SOURCE
+#include "libm.h"
+
+static float ponef(float), qonef(float);
+
+static const float
+invsqrtpi = 5.6418961287e-01, /* 0x3f106ebb */
+tpi       = 6.3661974669e-01; /* 0x3f22f983 */
+
+static float common(uint32_t ix, float x, int y1, int sign)
+{
+	double z,s,c,ss,cc;
+
+	s = sinf(x);
+	if (y1)
+		s = -s;
+	c = cosf(x);
+	cc = s-c;
+	if (ix < 0x7f000000) {
+		ss = -s-c;
+		z = cosf(2*x);
+		if (s*c > 0)
+			cc = z/ss;
+		else
+			ss = z/cc;
+		if (ix < 0x58800000) {
+			if (y1)
+				ss = -ss;
+			cc = ponef(x)*cc-qonef(x)*ss;
+		}
+	}
+	if (sign)
+		cc = -cc;
+	return invsqrtpi*cc/sqrtf(x);
+}
+
+/* R0/S0 on [0,2] */
+static const float
+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 */
+
+float j1f(float x)
+{
+	float z,r,s;
+	uint32_t ix;
+	int sign;
+
+	GET_FLOAT_WORD(ix, x);
+	sign = ix>>31;
+	ix &= 0x7fffffff;
+	if (ix >= 0x7f800000)
+		return 1/(x*x);
+	if (ix >= 0x40000000)  /* |x| >= 2 */
+		return common(ix, fabsf(x), 0, sign);
+	if (ix >= 0x39000000) {  /* |x| >= 2**-13 */
+		z = x*x;
+		r = z*(r00+z*(r01+z*(r02+z*r03)));
+		s = 1+z*(s01+z*(s02+z*(s03+z*(s04+z*s05))));
+		z = 0.5f + r/s;
+	} else
+		z = 0.5f;
+	return z*x;
+}
+
+static const float U0[5] = {
+ -1.9605709612e-01, /* 0xbe48c331 */
+  5.0443872809e-02, /* 0x3d4e9e3c */
+ -1.9125689287e-03, /* 0xbafaaf2a */
+  2.3525259166e-05, /* 0x37c5581c */
+ -9.1909917899e-08, /* 0xb3c56003 */
+};
+static const float V0[5] = {
+  1.9916731864e-02, /* 0x3ca3286a */
+  2.0255257550e-04, /* 0x3954644b */
+  1.3560879779e-06, /* 0x35b602d4 */
+  6.2274145840e-09, /* 0x31d5f8eb */
+  1.6655924903e-11, /* 0x2d9281cf */
+};
+
+float y1f(float x)
+{
+	float z,u,v;
+	uint32_t ix;
+
+	GET_FLOAT_WORD(ix, x);
+	if ((ix & 0x7fffffff) == 0)
+		return -1/0.0f;
+	if (ix>>31)
+		return 0/0.0f;
+	if (ix >= 0x7f800000)
+		return 1/x;
+	if (ix >= 0x40000000)  /* |x| >= 2.0 */
+		return common(ix,x,1,0);
+	if (ix < 0x33000000)  /* x < 2**-25 */
+		return -tpi/x;
+	z = x*x;
+	u = U0[0]+z*(U0[1]+z*(U0[2]+z*(U0[3]+z*U0[4])));
+	v = 1.0f+z*(V0[0]+z*(V0[1]+z*(V0[2]+z*(V0[3]+z*V0[4]))));
+	return x*(u/v) + tpi*(j1f(x)*logf(x)-1.0f/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)
+ */
+
+static const float pr8[6] = { /* for x in [inf, 8]=1/[0,0.125] */
+  0.0000000000e+00, /* 0x00000000 */
+  1.1718750000e-01, /* 0x3df00000 */
+  1.3239480972e+01, /* 0x4153d4ea */
+  4.1205184937e+02, /* 0x43ce06a3 */
+  3.8747453613e+03, /* 0x45722bed */
+  7.9144794922e+03, /* 0x45f753d6 */
+};
+static const float ps8[5] = {
+  1.1420736694e+02, /* 0x42e46a2c */
+  3.6509309082e+03, /* 0x45642ee5 */
+  3.6956207031e+04, /* 0x47105c35 */
+  9.7602796875e+04, /* 0x47bea166 */
+  3.0804271484e+04, /* 0x46f0a88b */
+};
+
+static const float pr5[6] = { /* for x in [8,4.5454]=1/[0.125,0.22001] */
+  1.3199052094e-11, /* 0x2d68333f */
+  1.1718749255e-01, /* 0x3defffff */
+  6.8027510643e+00, /* 0x40d9b023 */
+  1.0830818176e+02, /* 0x42d89dca */
+  5.1763616943e+02, /* 0x440168b7 */
+  5.2871520996e+02, /* 0x44042dc6 */
+};
+static const float ps5[5] = {
+  5.9280597687e+01, /* 0x426d1f55 */
+  9.9140142822e+02, /* 0x4477d9b1 */
+  5.3532670898e+03, /* 0x45a74a23 */
+  7.8446904297e+03, /* 0x45f52586 */
+  1.5040468750e+03, /* 0x44bc0180 */
+};
+
+static const float pr3[6] = {
+  3.0250391081e-09, /* 0x314fe10d */
+  1.1718686670e-01, /* 0x3defffab */
+  3.9329774380e+00, /* 0x407bb5e7 */
+  3.5119403839e+01, /* 0x420c7a45 */
+  9.1055007935e+01, /* 0x42b61c2a */
+  4.8559066772e+01, /* 0x42423c7c */
+};
+static const float ps3[5] = {
+  3.4791309357e+01, /* 0x420b2a4d */
+  3.3676245117e+02, /* 0x43a86198 */
+  1.0468714600e+03, /* 0x4482dbe3 */
+  8.9081134033e+02, /* 0x445eb3ed */
+  1.0378793335e+02, /* 0x42cf936c */
+};
+
+static const float pr2[6] = {/* for x in [2.8570,2]=1/[0.3499,0.5] */
+  1.0771083225e-07, /* 0x33e74ea8 */
+  1.1717621982e-01, /* 0x3deffa16 */
+  2.3685150146e+00, /* 0x401795c0 */
+  1.2242610931e+01, /* 0x4143e1bc */
+  1.7693971634e+01, /* 0x418d8d41 */
+  5.0735230446e+00, /* 0x40a25a4d */
+};
+static const float ps2[5] = {
+  2.1436485291e+01, /* 0x41ab7dec */
+  1.2529022980e+02, /* 0x42fa9499 */
+  2.3227647400e+02, /* 0x436846c7 */
+  1.1767937469e+02, /* 0x42eb5bd7 */
+  8.3646392822e+00, /* 0x4105d590 */
+};
+
+static float ponef(float x)
+{
+	const float *p,*q;
+	float_t z,r,s;
+	uint32_t ix;
+
+	GET_FLOAT_WORD(ix, x);
+	ix &= 0x7fffffff;
+	if      (ix >= 0x41000000){p = pr8; q = ps8;}
+	else if (ix >= 0x409173eb){p = pr5; q = ps5;}
+	else if (ix >= 0x4036d917){p = pr3; q = ps3;}
+	else /*ix >= 0x40000000*/ {p = pr2; q = ps2;}
+	z = 1.0f/(x*x);
+	r = p[0]+z*(p[1]+z*(p[2]+z*(p[3]+z*(p[4]+z*p[5]))));
+	s = 1.0f+z*(q[0]+z*(q[1]+z*(q[2]+z*(q[3]+z*q[4]))));
+	return 1.0f + 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)
+ */
+
+static const float qr8[6] = { /* for x in [inf, 8]=1/[0,0.125] */
+  0.0000000000e+00, /* 0x00000000 */
+ -1.0253906250e-01, /* 0xbdd20000 */
+ -1.6271753311e+01, /* 0xc1822c8d */
+ -7.5960174561e+02, /* 0xc43de683 */
+ -1.1849806641e+04, /* 0xc639273a */
+ -4.8438511719e+04, /* 0xc73d3683 */
+};
+static const float qs8[6] = {
+  1.6139537048e+02, /* 0x43216537 */
+  7.8253862305e+03, /* 0x45f48b17 */
+  1.3387534375e+05, /* 0x4802bcd6 */
+  7.1965775000e+05, /* 0x492fb29c */
+  6.6660125000e+05, /* 0x4922be94 */
+ -2.9449025000e+05, /* 0xc88fcb48 */
+};
+
+static const float qr5[6] = { /* for x in [8,4.5454]=1/[0.125,0.22001] */
+ -2.0897993405e-11, /* 0xadb7d219 */
+ -1.0253904760e-01, /* 0xbdd1fffe */
+ -8.0564479828e+00, /* 0xc100e736 */
+ -1.8366960144e+02, /* 0xc337ab6b */
+ -1.3731937256e+03, /* 0xc4aba633 */
+ -2.6124443359e+03, /* 0xc523471c */
+};
+static const float qs5[6] = {
+  8.1276550293e+01, /* 0x42a28d98 */
+  1.9917987061e+03, /* 0x44f8f98f */
+  1.7468484375e+04, /* 0x468878f8 */
+  4.9851425781e+04, /* 0x4742bb6d */
+  2.7948074219e+04, /* 0x46da5826 */
+ -4.7191835938e+03, /* 0xc5937978 */
+};
+
+static const float qr3[6] = {
+ -5.0783124372e-09, /* 0xb1ae7d4f */
+ -1.0253783315e-01, /* 0xbdd1ff5b */
+ -4.6101160049e+00, /* 0xc0938612 */
+ -5.7847221375e+01, /* 0xc267638e */
+ -2.2824453735e+02, /* 0xc3643e9a */
+ -2.1921012878e+02, /* 0xc35b35cb */
+};
+static const float qs3[6] = {
+  4.7665153503e+01, /* 0x423ea91e */
+  6.7386511230e+02, /* 0x4428775e */
+  3.3801528320e+03, /* 0x45534272 */
+  5.5477290039e+03, /* 0x45ad5dd5 */
+  1.9031191406e+03, /* 0x44ede3d0 */
+ -1.3520118713e+02, /* 0xc3073381 */
+};
+
+static const float qr2[6] = {/* for x in [2.8570,2]=1/[0.3499,0.5] */
+ -1.7838172539e-07, /* 0xb43f8932 */
+ -1.0251704603e-01, /* 0xbdd1f475 */
+ -2.7522056103e+00, /* 0xc0302423 */
+ -1.9663616180e+01, /* 0xc19d4f16 */
+ -4.2325313568e+01, /* 0xc2294d1f */
+ -2.1371921539e+01, /* 0xc1aaf9b2 */
+};
+static const float qs2[6] = {
+  2.9533363342e+01, /* 0x41ec4454 */
+  2.5298155212e+02, /* 0x437cfb47 */
+  7.5750280762e+02, /* 0x443d602e */
+  7.3939318848e+02, /* 0x4438d92a */
+  1.5594900513e+02, /* 0x431bf2f2 */
+ -4.9594988823e+00, /* 0xc09eb437 */
+};
+
+static float qonef(float x)
+{
+	const float *p,*q;
+	float_t s,r,z;
+	uint32_t ix;
+
+	GET_FLOAT_WORD(ix, x);
+	ix &= 0x7fffffff;
+	if      (ix >= 0x41000000){p = qr8; q = qs8;}
+	else if (ix >= 0x409173eb){p = qr5; q = qs5;}
+	else if (ix >= 0x4036d917){p = qr3; q = qs3;}
+	else /*ix >= 0x40000000*/ {p = qr2; q = qs2;}
+	z = 1.0f/(x*x);
+	r = p[0]+z*(p[1]+z*(p[2]+z*(p[3]+z*(p[4]+z*p[5]))));
+	s = 1.0f+z*(q[0]+z*(q[1]+z*(q[2]+z*(q[3]+z*(q[4]+z*q[5])))));
+	return (.375f + r/s)/x;
+}
libc/musl/src/math/jn.c
@@ -0,0 +1,280 @@
+/* origin: FreeBSD /usr/src/lib/msun/src/e_jn.c */
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunSoft, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+/*
+ * jn(n, x), 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 is 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 "libm.h"
+
+static const double invsqrtpi = 5.64189583547756279280e-01; /* 0x3FE20DD7, 0x50429B6D */
+
+double jn(int n, double x)
+{
+	uint32_t ix, lx;
+	int nm1, i, sign;
+	double a, b, temp;
+
+	EXTRACT_WORDS(ix, lx, x);
+	sign = ix>>31;
+	ix &= 0x7fffffff;
+
+	if ((ix | (lx|-lx)>>31) > 0x7ff00000) /* nan */
+		return x;
+
+	/* J(-n,x) = (-1)^n * J(n, x), J(n, -x) = (-1)^n * J(n, x)
+	 * Thus, J(-n,x) = J(n,-x)
+	 */
+	/* nm1 = |n|-1 is used instead of |n| to handle n==INT_MIN */
+	if (n == 0)
+		return j0(x);
+	if (n < 0) {
+		nm1 = -(n+1);
+		x = -x;
+		sign ^= 1;
+	} else
+		nm1 = n-1;
+	if (nm1 == 0)
+		return j1(x);
+
+	sign &= n;  /* even n: 0, odd n: signbit(x) */
+	x = fabs(x);
+	if ((ix|lx) == 0 || ix == 0x7ff00000)  /* if x is 0 or inf */
+		b = 0.0;
+	else if (nm1 < 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
+			 */
+			switch(nm1&3) {
+			case 0: temp = -cos(x)+sin(x); break;
+			case 1: temp = -cos(x)-sin(x); break;
+			case 2: temp =  cos(x)-sin(x); break;
+			default:
+			case 3: temp =  cos(x)+sin(x); break;
+			}
+			b = invsqrtpi*temp/sqrt(x);
+		} else {
+			a = j0(x);
+			b = j1(x);
+			for (i=0; i<nm1; ) {
+				i++;
+				temp = b;
+				b = b*(2.0*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 (nm1 > 32)  /* underflow */
+				b = 0.0;
+			else {
+				temp = x*0.5;
+				b = temp;
+				a = 1.0;
+				for (i=2; i<=nm1+1; 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,q0,q1,w,h,z,tmp,nf;
+			int k;
+
+			nf = nm1 + 1.0;
+			w = 2*nf/x;
+			h = 2/x;
+			z = w+h;
+			q0 = w;
+			q1 = w*z - 1.0;
+			k = 1;
+			while (q1 < 1.0e9) {
+				k += 1;
+				z += h;
+				tmp = z*q1 - q0;
+				q0 = q1;
+				q1 = tmp;
+			}
+			for (t=0.0, i=k; i>=0; i--)
+				t = 1/(2*(i+nf)/x - t);
+			a = t;
+			b = 1.0;
+			/*  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 = nf*log(fabs(w));
+			if (tmp < 7.09782712893383973096e+02) {
+				for (i=nm1; i>0; i--) {
+					temp = b;
+					b = b*(2.0*i)/x - a;
+					a = temp;
+				}
+			} else {
+				for (i=nm1; i>0; i--) {
+					temp = b;
+					b = b*(2.0*i)/x - a;
+					a = temp;
+					/* scale b to avoid spurious overflow */
+					if (b > 0x1p500) {
+						a /= b;
+						t /= b;
+						b  = 1.0;
+					}
+				}
+			}
+			z = j0(x);
+			w = j1(x);
+			if (fabs(z) >= fabs(w))
+				b = t*z/b;
+			else
+				b = t*w/a;
+		}
+	}
+	return sign ? -b : b;
+}
+
+
+double yn(int n, double x)
+{
+	uint32_t ix, lx, ib;
+	int nm1, sign, i;
+	double a, b, temp;
+
+	EXTRACT_WORDS(ix, lx, x);
+	sign = ix>>31;
+	ix &= 0x7fffffff;
+
+	if ((ix | (lx|-lx)>>31) > 0x7ff00000) /* nan */
+		return x;
+	if (sign && (ix|lx)!=0) /* x < 0 */
+		return 0/0.0;
+	if (ix == 0x7ff00000)
+		return 0.0;
+
+	if (n == 0)
+		return y0(x);
+	if (n < 0) {
+		nm1 = -(n+1);
+		sign = n&1;
+	} else {
+		nm1 = n-1;
+		sign = 0;
+	}
+	if (nm1 == 0)
+		return sign ? -y1(x) : y1(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
+		 */
+		switch(nm1&3) {
+		case 0: temp = -sin(x)-cos(x); break;
+		case 1: temp = -sin(x)+cos(x); break;
+		case 2: temp =  sin(x)+cos(x); break;
+		default:
+		case 3: temp =  sin(x)-cos(x); break;
+		}
+		b = invsqrtpi*temp/sqrt(x);
+	} else {
+		a = y0(x);
+		b = y1(x);
+		/* quit if b is -inf */
+		GET_HIGH_WORD(ib, b);
+		for (i=0; i<nm1 && ib!=0xfff00000; ){
+			i++;
+			temp = b;
+			b = (2.0*i/x)*b - a;
+			GET_HIGH_WORD(ib, b);
+			a = temp;
+		}
+	}
+	return sign ? -b : b;
+}
libc/musl/src/math/jnf.c
@@ -0,0 +1,202 @@
+/* origin: FreeBSD /usr/src/lib/msun/src/e_jnf.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.
+ * ====================================================
+ */
+
+#define _GNU_SOURCE
+#include "libm.h"
+
+float jnf(int n, float x)
+{
+	uint32_t ix;
+	int nm1, sign, i;
+	float a, b, temp;
+
+	GET_FLOAT_WORD(ix, x);
+	sign = ix>>31;
+	ix &= 0x7fffffff;
+	if (ix > 0x7f800000) /* nan */
+		return x;
+
+	/* J(-n,x) = J(n,-x), use |n|-1 to avoid overflow in -n */
+	if (n == 0)
+		return j0f(x);
+	if (n < 0) {
+		nm1 = -(n+1);
+		x = -x;
+		sign ^= 1;
+	} else
+		nm1 = n-1;
+	if (nm1 == 0)
+		return j1f(x);
+
+	sign &= n;  /* even n: 0, odd n: signbit(x) */
+	x = fabsf(x);
+	if (ix == 0 || ix == 0x7f800000)  /* if x is 0 or inf */
+		b = 0.0f;
+	else if (nm1 < x) {
+		/* Safe to use J(n+1,x)=2n/x *J(n,x)-J(n-1,x) */
+		a = j0f(x);
+		b = j1f(x);
+		for (i=0; i<nm1; ){
+			i++;
+			temp = b;
+			b = b*(2.0f*i/x) - a;
+			a = temp;
+		}
+	} else {
+		if (ix < 0x35800000) { /* x < 2**-20 */
+			/* x is tiny, return the first Taylor expansion of J(n,x)
+			 * J(n,x) = 1/n!*(x/2)^n  - ...
+			 */
+			if (nm1 > 8)  /* underflow */
+				nm1 = 8;
+			temp = 0.5f * x;
+			b = temp;
+			a = 1.0f;
+			for (i=2; i<=nm1+1; 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,q0,q1,w,h,z,tmp,nf;
+			int k;
+
+			nf = nm1+1.0f;
+			w = 2*nf/x;
+			h = 2/x;
+			z = w+h;
+			q0 = w;
+			q1 = w*z - 1.0f;
+			k = 1;
+			while (q1 < 1.0e4f) {
+				k += 1;
+				z += h;
+				tmp = z*q1 - q0;
+				q0 = q1;
+				q1 = tmp;
+			}
+			for (t=0.0f, i=k; i>=0; i--)
+				t = 1.0f/(2*(i+nf)/x-t);
+			a = t;
+			b = 1.0f;
+			/*  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 = nf*logf(fabsf(w));
+			if (tmp < 88.721679688f) {
+				for (i=nm1; i>0; i--) {
+					temp = b;
+					b = 2.0f*i*b/x - a;
+					a = temp;
+				}
+			} else {
+				for (i=nm1; i>0; i--){
+					temp = b;
+					b = 2.0f*i*b/x - a;
+					a = temp;
+					/* scale b to avoid spurious overflow */
+					if (b > 0x1p60f) {
+						a /= b;
+						t /= b;
+						b = 1.0f;
+					}
+				}
+			}
+			z = j0f(x);
+			w = j1f(x);
+			if (fabsf(z) >= fabsf(w))
+				b = t*z/b;
+			else
+				b = t*w/a;
+		}
+	}
+	return sign ? -b : b;
+}
+
+float ynf(int n, float x)
+{
+	uint32_t ix, ib;
+	int nm1, sign, i;
+	float a, b, temp;
+
+	GET_FLOAT_WORD(ix, x);
+	sign = ix>>31;
+	ix &= 0x7fffffff;
+	if (ix > 0x7f800000) /* nan */
+		return x;
+	if (sign && ix != 0) /* x < 0 */
+		return 0/0.0f;
+	if (ix == 0x7f800000)
+		return 0.0f;
+
+	if (n == 0)
+		return y0f(x);
+	if (n < 0) {
+		nm1 = -(n+1);
+		sign = n&1;
+	} else {
+		nm1 = n-1;
+		sign = 0;
+	}
+	if (nm1 == 0)
+		return sign ? -y1f(x) : y1f(x);
+
+	a = y0f(x);
+	b = y1f(x);
+	/* quit if b is -inf */
+	GET_FLOAT_WORD(ib,b);
+	for (i = 0; i < nm1 && ib != 0xff800000; ) {
+		i++;
+		temp = b;
+		b = (2.0f*i/x)*b - a;
+		GET_FLOAT_WORD(ib, b);
+		a = temp;
+	}
+	return sign ? -b : b;
+}
libc/musl/src/math/ldexp.c
@@ -0,0 +1,6 @@
+#include <math.h>
+
+double ldexp(double x, int n)
+{
+	return scalbn(x, n);
+}
libc/musl/src/math/ldexpf.c
@@ -0,0 +1,6 @@
+#include <math.h>
+
+float ldexpf(float x, int n)
+{
+	return scalbnf(x, n);
+}
libc/musl/src/math/ldexpl.c
@@ -0,0 +1,6 @@
+#include <math.h>
+
+long double ldexpl(long double x, int n)
+{
+	return scalbnl(x, n);
+}
libc/musl/src/math/lgamma.c
@@ -0,0 +1,7 @@
+#include <math.h>
+#include "libm.h"
+
+double lgamma(double x)
+{
+	return __lgamma_r(x, &__signgam);
+}
libc/musl/src/math/lgamma_r.c
@@ -0,0 +1,283 @@
+/* origin: FreeBSD /usr/src/lib/msun/src/e_lgamma_r.c */
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunSoft, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ *
+ */
+/* 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(neg.integer) = inf and raise divide-by-zero
+ *              lgamma(inf) = inf
+ *              lgamma(-inf) = inf (bug for bug compatible with C99!?)
+ *
+ */
+
+#include "libm.h"
+
+static const double
+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 */
+
+/* sin(pi*x) assuming x > 2^-100, if sin(pi*x)==0 the sign is arbitrary */
+static double sin_pi(double x)
+{
+	int n;
+
+	/* spurious inexact if odd int */
+	x = 2.0*(x*0.5 - floor(x*0.5));  /* x mod 2.0 */
+
+	n = (int)(x*4.0);
+	n = (n+1)/2;
+	x -= n*0.5f;
+	x *= pi;
+
+	switch (n) {
+	default: /* case 4: */
+	case 0: return __sin(x, 0.0, 0);
+	case 1: return __cos(x, 0.0);
+	case 2: return __sin(-x, 0.0, 0);
+	case 3: return -__cos(x, 0.0);
+	}
+}
+
+double __lgamma_r(double x, int *signgamp)
+{
+	union {double f; uint64_t i;} u = {x};
+	double_t t,y,z,nadj,p,p1,p2,p3,q,r,w;
+	uint32_t ix;
+	int sign,i;
+
+	/* purge off +-inf, NaN, +-0, tiny and negative arguments */
+	*signgamp = 1;
+	sign = u.i>>63;
+	ix = u.i>>32 & 0x7fffffff;
+	if (ix >= 0x7ff00000)
+		return x*x;
+	if (ix < (0x3ff-70)<<20) {  /* |x|<2**-70, return -log(|x|) */
+		if(sign) {
+			x = -x;
+			*signgamp = -1;
+		}
+		return -log(x);
+	}
+	if (sign) {
+		x = -x;
+		t = sin_pi(x);
+		if (t == 0.0) /* -integer */
+			return 1.0/(x-x);
+		if (t > 0.0)
+			*signgamp = -1;
+		else
+			t = -t;
+		nadj = log(pi/(t*x));
+	}
+
+	/* purge off 1 and 2 */
+	if ((ix == 0x3ff00000 || ix == 0x40000000) && (uint32_t)u.i == 0)
+		r = 0;
+	/* for x < 2.0 */
+	else if (ix < 0x40000000) {
+		if (ix <= 0x3feccccc) {   /* lgamma(x) = lgamma(x+1)-log(x) */
+			r = -log(x);
+			if (ix >= 0x3FE76944) {
+				y = 1.0 - x;
+				i = 0;
+			} else if (ix >= 0x3FCDA661) {
+				y = x - (tc-1.0);
+				i = 1;
+			} else {
+				y = x;
+				i = 2;
+			}
+		} else {
+			r = 0.0;
+			if (ix >= 0x3FFBB4C3) {  /* [1.7316,2] */
+				y = 2.0 - x;
+				i = 0;
+			} else if(ix >= 0x3FF3B4C4) {  /* [1.23,1.73] */
+				y = x - tc;
+				i = 1;
+			} else {
+				y = x - 1.0;
+				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 = 1.0+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;
+		y = x - (double)i;
+		p = y*(s0+y*(s1+y*(s2+y*(s3+y*(s4+y*(s5+y*s6))))));
+		q = 1.0+y*(r1+y*(r2+y*(r3+y*(r4+y*(r5+y*r6)))));
+		r = 0.5*y+p/q;
+		z = 1.0;    /* 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 += log(z);
+			break;
+		}
+	} else if (ix < 0x43900000) {  /* 8.0 <= x < 2**58 */
+		t = log(x);
+		z = 1.0/x;
+		y = z*z;
+		w = w0+z*(w1+y*(w2+y*(w3+y*(w4+y*(w5+y*w6)))));
+		r = (x-0.5)*(t-1.0)+w;
+	} else                         /* 2**58 <= x <= inf */
+		r =  x*(log(x)-1.0);
+	if (sign)
+		r = nadj - r;
+	return r;
+}
+
+weak_alias(__lgamma_r, lgamma_r);
libc/musl/src/math/lgammaf.c
@@ -0,0 +1,7 @@
+#include <math.h>
+#include "libm.h"
+
+float lgammaf(float x)
+{
+	return __lgammaf_r(x, &__signgam);
+}
libc/musl/src/math/lgammaf_r.c
@@ -0,0 +1,218 @@
+/* origin: FreeBSD /usr/src/lib/msun/src/e_lgammaf_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.
+ * ====================================================
+ */
+
+#include "libm.h"
+
+static const float
+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 */
+
+/* sin(pi*x) assuming x > 2^-100, if sin(pi*x)==0 the sign is arbitrary */
+static float sin_pi(float x)
+{
+	double_t y;
+	int n;
+
+	/* spurious inexact if odd int */
+	x = 2*(x*0.5f - floorf(x*0.5f));  /* x mod 2.0 */
+
+	n = (int)(x*4);
+	n = (n+1)/2;
+	y = x - n*0.5f;
+	y *= 3.14159265358979323846;
+	switch (n) {
+	default: /* case 4: */
+	case 0: return __sindf(y);
+	case 1: return __cosdf(y);
+	case 2: return __sindf(-y);
+	case 3: return -__cosdf(y);
+	}
+}
+
+float __lgammaf_r(float x, int *signgamp)
+{
+	union {float f; uint32_t i;} u = {x};
+	float t,y,z,nadj,p,p1,p2,p3,q,r,w;
+	uint32_t ix;
+	int i,sign;
+
+	/* purge off +-inf, NaN, +-0, tiny and negative arguments */
+	*signgamp = 1;
+	sign = u.i>>31;
+	ix = u.i & 0x7fffffff;
+	if (ix >= 0x7f800000)
+		return x*x;
+	if (ix < 0x35000000) {  /* |x| < 2**-21, return -log(|x|) */
+		if (sign) {
+			*signgamp = -1;
+			x = -x;
+		}
+		return -logf(x);
+	}
+	if (sign) {
+		x = -x;
+		t = sin_pi(x);
+		if (t == 0.0f) /* -integer */
+			return 1.0f/(x-x);
+		if (t > 0.0f)
+			*signgamp = -1;
+		else
+			t = -t;
+		nadj = logf(pi/(t*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 = -logf(x);
+			if (ix >= 0x3f3b4a20) {
+				y = 1.0f - x;
+				i = 0;
+			} else if (ix >= 0x3e6d3308) {
+				y = x - (tc-1.0f);
+				i = 1;
+			} else {
+				y = x;
+				i = 2;
+			}
+		} else {
+			r = 0.0f;
+			if (ix >= 0x3fdda618) {  /* [1.7316,2] */
+				y = 2.0f - x;
+				i = 0;
+			} else if (ix >= 0x3F9da620) {  /* [1.23,1.73] */
+				y = x - tc;
+				i = 1;
+			} else {
+				y = x - 1.0f;
+				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.5f*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 = 1.0f+y*(v1+y*(v2+y*(v3+y*(v4+y*v5))));
+			r += -0.5f*y + p1/p2;
+		}
+	} else if (ix < 0x41000000) {  /* x < 8.0 */
+		i = (int)x;
+		y = x - (float)i;
+		p = y*(s0+y*(s1+y*(s2+y*(s3+y*(s4+y*(s5+y*s6))))));
+		q = 1.0f+y*(r1+y*(r2+y*(r3+y*(r4+y*(r5+y*r6)))));
+		r = 0.5f*y+p/q;
+		z = 1.0f;    /* lgamma(1+s) = log(s) + lgamma(s) */
+		switch (i) {
+		case 7: z *= y + 6.0f;  /* FALLTHRU */
+		case 6: z *= y + 5.0f;  /* FALLTHRU */
+		case 5: z *= y + 4.0f;  /* FALLTHRU */
+		case 4: z *= y + 3.0f;  /* FALLTHRU */
+		case 3: z *= y + 2.0f;  /* FALLTHRU */
+			r += logf(z);
+			break;
+		}
+	} else if (ix < 0x5c800000) {  /* 8.0 <= x < 2**58 */
+		t = logf(x);
+		z = 1.0f/x;
+		y = z*z;
+		w = w0+z*(w1+y*(w2+y*(w3+y*(w4+y*(w5+y*w6)))));
+		r = (x-0.5f)*(t-1.0f)+w;
+	} else                         /* 2**58 <= x <= inf */
+		r =  x*(logf(x)-1.0f);
+	if (sign)
+		r = nadj - r;
+	return r;
+}
+
+weak_alias(__lgammaf_r, lgammaf_r);
libc/musl/src/math/lgammal.c
@@ -0,0 +1,353 @@
+/* origin: OpenBSD /usr/src/lib/libm/src/ld80/e_lgammal.c */
+/*
+ * ====================================================
+ * 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.
+ * ====================================================
+ */
+/*
+ * Copyright (c) 2008 Stephen L. Moshier <steve@moshier.net>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+/* lgammal(x)
+ * 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
+ *
+ */
+
+#define _GNU_SOURCE
+#include "libm.h"
+
+#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024
+long double __lgammal_r(long double x, int *sg)
+{
+	return __lgamma_r(x, sg);
+}
+#elif LDBL_MANT_DIG == 64 && LDBL_MAX_EXP == 16384
+static const long double
+pi = 3.14159265358979323846264L,
+
+/* 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;
+
+/* sin(pi*x) assuming x > 2^-1000, if sin(pi*x)==0 the sign is arbitrary */
+static long double sin_pi(long double x)
+{
+	int n;
+
+	/* spurious inexact if odd int */
+	x *= 0.5;
+	x = 2.0*(x - floorl(x));  /* x mod 2.0 */
+
+	n = (int)(x*4.0);
+	n = (n+1)/2;
+	x -= n*0.5f;
+	x *= pi;
+
+	switch (n) {
+	default: /* case 4: */
+	case 0: return __sinl(x, 0.0, 0);
+	case 1: return __cosl(x, 0.0);
+	case 2: return __sinl(-x, 0.0, 0);
+	case 3: return -__cosl(x, 0.0);
+	}
+}
+
+long double __lgammal_r(long double x, int *sg) {
+	long double t, y, z, nadj, p, p1, p2, q, r, w;
+	union ldshape u = {x};
+	uint32_t ix = (u.i.se & 0x7fffU)<<16 | u.i.m>>48;
+	int sign = u.i.se >> 15;
+	int i;
+
+	*sg = 1;
+
+	/* purge off +-inf, NaN, +-0, tiny and negative arguments */
+	if (ix >= 0x7fff0000)
+		return x * x;
+	if (ix < 0x3fc08000) {  /* |x|<2**-63, return -log(|x|) */
+		if (sign) {
+			*sg = -1;
+			x = -x;
+		}
+		return -logl(x);
+	}
+	if (sign) {
+		x = -x;
+		t = sin_pi(x);
+		if (t == 0.0)
+			return 1.0 / (x-x); /* -integer */
+		if (t > 0.0)
+			*sg = -1;
+		else
+			t = -t;
+		nadj = logl(pi / (t * x));
+	}
+
+	/* purge off 1 and 2 (so the sign is ok with downward rounding) */
+	if ((ix == 0x3fff8000 || ix == 0x40008000) && u.i.m == 0) {
+		r = 0;
+	} else if (ix < 0x40008000) {  /* x < 2.0 */
+		if (ix <= 0x3ffee666) {  /* 8.99993896484375e-1 */
+			/* lgamma(x) = lgamma(x+1) - log(x) */
+			r = -logl(x);
+			if (ix >= 0x3ffebb4a) {  /* 7.31597900390625e-1 */
+				y = x - 1.0;
+				i = 0;
+			} else if (ix >= 0x3ffced33) {  /* 2.31639862060546875e-1 */
+				y = x - (tc - 1.0);
+				i = 1;
+			} else { /* x < 0.23 */
+				y = x;
+				i = 2;
+			}
+		} else {
+			r = 0.0;
+			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 - 1.0;
+				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 += 0.5 * 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 += (-0.5 * y + p1 / p2);
+		}
+	} else if (ix < 0x40028000) {  /* 8.0 */
+		/* x < 8.0 */
+		i = (int)x;
+		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 = 0.5 * y + p / q;
+		z = 1.0;
+		/* 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 += logl(z);
+			break;
+		}
+	} else if (ix < 0x40418000) {  /* 2^66 */
+		/* 8.0 <= x < 2**66 */
+		t = logl(x);
+		z = 1.0 / x;
+		y = z * z;
+		w = w0 + z * (w1 + y * (w2 + y * (w3 + y * (w4 + y * (w5 + y * (w6 + y * w7))))));
+		r = (x - 0.5) * (t - 1.0) + w;
+	} else /* 2**66 <= x <= inf */
+		r = x * (logl(x) - 1.0);
+	if (sign)
+		r = nadj - r;
+	return r;
+}
+#elif LDBL_MANT_DIG == 113 && LDBL_MAX_EXP == 16384
+// TODO: broken implementation to make things compile
+long double __lgammal_r(long double x, int *sg)
+{
+	return __lgamma_r(x, sg);
+}
+#endif
+
+long double lgammal(long double x)
+{
+	return __lgammal_r(x, &__signgam);
+}
+
+weak_alias(__lgammal_r, lgammal_r);
libc/musl/src/math/llrint.c
@@ -0,0 +1,8 @@
+#include <math.h>
+
+/* uses LLONG_MAX > 2^53, see comments in lrint.c */
+
+long long llrint(double x)
+{
+	return rint(x);
+}
libc/musl/src/math/llrintf.c
@@ -0,0 +1,8 @@
+#include <math.h>
+
+/* uses LLONG_MAX > 2^24, see comments in lrint.c */
+
+long long llrintf(float x)
+{
+	return rintf(x);
+}
libc/musl/src/math/llrintl.c
@@ -0,0 +1,36 @@
+#include <limits.h>
+#include <fenv.h>
+#include "libm.h"
+
+
+#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024
+long long llrintl(long double x)
+{
+	return llrint(x);
+}
+#elif defined(FE_INEXACT)
+/*
+see comments in lrint.c
+
+Note that if LLONG_MAX == 0x7fffffffffffffff && LDBL_MANT_DIG == 64
+then x == 2**63 - 0.5 is the only input that overflows and
+raises inexact (with tonearest or upward rounding mode)
+*/
+long long llrintl(long double x)
+{
+	#pragma STDC FENV_ACCESS ON
+	int e;
+
+	e = fetestexcept(FE_INEXACT);
+	x = rintl(x);
+	if (!e && (x > LLONG_MAX || x < LLONG_MIN))
+		feclearexcept(FE_INEXACT);
+	/* conversion */
+	return x;
+}
+#else
+long long llrintl(long double x)
+{
+	return rintl(x);
+}
+#endif
libc/musl/src/math/llround.c
@@ -0,0 +1,6 @@
+#include <math.h>
+
+long long llround(double x)
+{
+	return round(x);
+}
libc/musl/src/math/llroundf.c
@@ -0,0 +1,6 @@
+#include <math.h>
+
+long long llroundf(float x)
+{
+	return roundf(x);
+}
libc/musl/src/math/llroundl.c
@@ -0,0 +1,6 @@
+#include <math.h>
+
+long long llroundl(long double x)
+{
+	return roundl(x);
+}
libc/musl/src/math/log.c
@@ -0,0 +1,118 @@
+/* origin: FreeBSD /usr/src/lib/msun/src/e_log.c */
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunSoft, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+/* log(x)
+ * Return the logarithm 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 Remez 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*ln2 + log(1+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:
+ *      log(x) is NaN with signal if x < 0 (including -INF) ;
+ *      log(+INF) is +INF; log(0) is -INF with signal;
+ *      log(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.
+ */
+
+#include <math.h>
+#include <stdint.h>
+
+static const double
+ln2_hi = 6.93147180369123816490e-01,  /* 3fe62e42 fee00000 */
+ln2_lo = 1.90821492927058770002e-10,  /* 3dea39ef 35793c76 */
+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 */
+
+double log(double x)
+{
+	union {double f; uint64_t i;} u = {x};
+	double_t hfsq,f,s,z,R,w,t1,t2,dk;
+	uint32_t hx;
+	int k;
+
+	hx = u.i>>32;
+	k = 0;
+	if (hx < 0x00100000 || hx>>31) {
+		if (u.i<<1 == 0)
+			return -1/(x*x);  /* log(+-0)=-inf */
+		if (hx>>31)
+			return (x-x)/0.0; /* log(-#) = NaN */
+		/* subnormal number, scale x up */
+		k -= 54;
+		x *= 0x1p54;
+		u.f = x;
+		hx = u.i>>32;
+	} else if (hx >= 0x7ff00000) {
+		return x;
+	} else if (hx == 0x3ff00000 && u.i<<32 == 0)
+		return 0;
+
+	/* reduce x into [sqrt(2)/2, sqrt(2)] */
+	hx += 0x3ff00000 - 0x3fe6a09e;
+	k += (int)(hx>>20) - 0x3ff;
+	hx = (hx&0x000fffff) + 0x3fe6a09e;
+	u.i = (uint64_t)hx<<32 | (u.i&0xffffffff);
+	x = u.f;
+
+	f = x - 1.0;
+	hfsq = 0.5*f*f;
+	s = f/(2.0+f);
+	z = s*s;
+	w = z*z;
+	t1 = w*(Lg2+w*(Lg4+w*Lg6));
+	t2 = z*(Lg1+w*(Lg3+w*(Lg5+w*Lg7)));
+	R = t2 + t1;
+	dk = k;
+	return s*(hfsq+R) + dk*ln2_lo - hfsq + f + dk*ln2_hi;
+}
libc/musl/src/math/log10.c
@@ -0,0 +1,101 @@
+/* origin: FreeBSD /usr/src/lib/msun/src/e_log10.c */
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunSoft, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+/*
+ * Return the base 10 logarithm of x.  See log.c for most comments.
+ *
+ * Reduce x to 2^k (1+f) and calculate r = log(1+f) - f + f*f/2
+ * as in log.c, then combine and scale in extra precision:
+ *    log10(x) = (f - f*f/2 + r)/log(10) + k*log10(2)
+ */
+
+#include <math.h>
+#include <stdint.h>
+
+static const double
+ivln10hi  = 4.34294481878168880939e-01, /* 0x3fdbcb7b, 0x15200000 */
+ivln10lo  = 2.50829467116452752298e-11, /* 0x3dbb9438, 0xca9aadd5 */
+log10_2hi = 3.01029995663611771306e-01, /* 0x3FD34413, 0x509F6000 */
+log10_2lo = 3.69423907715893078616e-13, /* 0x3D59FEF3, 0x11F12B36 */
+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 */
+
+double log10(double x)
+{
+	union {double f; uint64_t i;} u = {x};
+	double_t hfsq,f,s,z,R,w,t1,t2,dk,y,hi,lo,val_hi,val_lo;
+	uint32_t hx;
+	int k;
+
+	hx = u.i>>32;
+	k = 0;
+	if (hx < 0x00100000 || hx>>31) {
+		if (u.i<<1 == 0)
+			return -1/(x*x);  /* log(+-0)=-inf */
+		if (hx>>31)
+			return (x-x)/0.0; /* log(-#) = NaN */
+		/* subnormal number, scale x up */
+		k -= 54;
+		x *= 0x1p54;
+		u.f = x;
+		hx = u.i>>32;
+	} else if (hx >= 0x7ff00000) {
+		return x;
+	} else if (hx == 0x3ff00000 && u.i<<32 == 0)
+		return 0;
+
+	/* reduce x into [sqrt(2)/2, sqrt(2)] */
+	hx += 0x3ff00000 - 0x3fe6a09e;
+	k += (int)(hx>>20) - 0x3ff;
+	hx = (hx&0x000fffff) + 0x3fe6a09e;
+	u.i = (uint64_t)hx<<32 | (u.i&0xffffffff);
+	x = u.f;
+
+	f = x - 1.0;
+	hfsq = 0.5*f*f;
+	s = f/(2.0+f);
+	z = s*s;
+	w = z*z;
+	t1 = w*(Lg2+w*(Lg4+w*Lg6));
+	t2 = z*(Lg1+w*(Lg3+w*(Lg5+w*Lg7)));
+	R = t2 + t1;
+
+	/* See log2.c for details. */
+	/* hi+lo = f - hfsq + s*(hfsq+R) ~ log(1+f) */
+	hi = f - hfsq;
+	u.f = hi;
+	u.i &= (uint64_t)-1<<32;
+	hi = u.f;
+	lo = f - hi - hfsq + s*(hfsq+R);
+
+	/* val_hi+val_lo ~ log10(1+f) + k*log10(2) */
+	val_hi = hi*ivln10hi;
+	dk = k;
+	y = dk*log10_2hi;
+	val_lo = dk*log10_2lo + (lo+hi)*ivln10lo + lo*ivln10hi;
+
+	/*
+	 * Extra precision in for adding y is not strictly needed
+	 * since there is no very large cancellation near x = sqrt(2) or
+	 * x = 1/sqrt(2), but we do it anyway since it costs little on CPUs
+	 * with some parallelism and it reduces the error for many args.
+	 */
+	w = y + val_hi;
+	val_lo += (y - w) + val_hi;
+	val_hi = w;
+
+	return val_lo + val_hi;
+}
libc/musl/src/math/log10f.c
@@ -0,0 +1,77 @@
+/* origin: FreeBSD /usr/src/lib/msun/src/e_log10f.c */
+/*
+ * ====================================================
+ * 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.
+ * ====================================================
+ */
+/*
+ * See comments in log10.c.
+ */
+
+#include <math.h>
+#include <stdint.h>
+
+static const float
+ivln10hi  =  4.3432617188e-01, /* 0x3ede6000 */
+ivln10lo  = -3.1689971365e-05, /* 0xb804ead9 */
+log10_2hi =  3.0102920532e-01, /* 0x3e9a2080 */
+log10_2lo =  7.9034151668e-07, /* 0x355427db */
+/* |(log(1+s)-log(1-s))/s - Lg(s)| < 2**-34.24 (~[-4.95e-11, 4.97e-11]). */
+Lg1 = 0xaaaaaa.0p-24, /* 0.66666662693 */
+Lg2 = 0xccce13.0p-25, /* 0.40000972152 */
+Lg3 = 0x91e9ee.0p-25, /* 0.28498786688 */
+Lg4 = 0xf89e26.0p-26; /* 0.24279078841 */
+
+float log10f(float x)
+{
+	union {float f; uint32_t i;} u = {x};
+	float_t hfsq,f,s,z,R,w,t1,t2,dk,hi,lo;
+	uint32_t ix;
+	int k;
+
+	ix = u.i;
+	k = 0;
+	if (ix < 0x00800000 || ix>>31) {  /* x < 2**-126  */
+		if (ix<<1 == 0)
+			return -1/(x*x);  /* log(+-0)=-inf */
+		if (ix>>31)
+			return (x-x)/0.0f; /* log(-#) = NaN */
+		/* subnormal number, scale up x */
+		k -= 25;
+		x *= 0x1p25f;
+		u.f = x;
+		ix = u.i;
+	} else if (ix >= 0x7f800000) {
+		return x;
+	} else if (ix == 0x3f800000)
+		return 0;
+
+	/* reduce x into [sqrt(2)/2, sqrt(2)] */
+	ix += 0x3f800000 - 0x3f3504f3;
+	k += (int)(ix>>23) - 0x7f;
+	ix = (ix&0x007fffff) + 0x3f3504f3;
+	u.i = ix;
+	x = u.f;
+
+	f = x - 1.0f;
+	s = f/(2.0f + f);
+	z = s*s;
+	w = z*z;
+	t1= w*(Lg2+w*Lg4);
+	t2= z*(Lg1+w*Lg3);
+	R = t2 + t1;
+	hfsq = 0.5f*f*f;
+
+	hi = f - hfsq;
+	u.f = hi;
+	u.i &= 0xfffff000;
+	hi = u.f;
+	lo = f - hi - hfsq + s*(hfsq+R);
+	dk = k;
+	return dk*log10_2lo + (lo+hi)*ivln10lo + lo*ivln10hi + hi*ivln10hi + dk*log10_2hi;
+}
libc/musl/src/math/log10l.c
@@ -0,0 +1,191 @@
+/* origin: OpenBSD /usr/src/lib/libm/src/ld80/e_log10l.c */
+/*
+ * Copyright (c) 2008 Stephen L. Moshier <steve@moshier.net>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+/*
+ *      Common logarithm, 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      9.0e-20     2.6e-20
+ *    IEEE     exp(+-10000)  30000      6.0e-20     2.3e-20
+ *
+ * In the tests over the interval exp(+-10000), the logarithms
+ * of the random arguments were uniformly distributed over
+ * [-10000, +10000].
+ *
+ * ERROR MESSAGES:
+ *
+ * log singularity:  x = 0; returns MINLOG
+ * log domain:       x < 0; returns MINLOG
+ */
+
+#include "libm.h"
+
+#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024
+long double log10l(long double x)
+{
+	return log10(x);
+}
+#elif LDBL_MANT_DIG == 64 && LDBL_MAX_EXP == 16384
+/* Coefficients for log(1+x) = x - x**2/2 + x**3 P(x)/Q(x)
+ * 1/sqrt(2) <= x < sqrt(2)
+ * Theoretical peak relative error = 6.2e-22
+ */
+static const long double P[] = {
+ 4.9962495940332550844739E-1L,
+ 1.0767376367209449010438E1L,
+ 7.7671073698359539859595E1L,
+ 2.5620629828144409632571E2L,
+ 4.2401812743503691187826E2L,
+ 3.4258224542413922935104E2L,
+ 1.0747524399916215149070E2L,
+};
+static const long double Q[] = {
+/* 1.0000000000000000000000E0,*/
+ 2.3479774160285863271658E1L,
+ 1.9444210022760132894510E2L,
+ 7.7952888181207260646090E2L,
+ 1.6911722418503949084863E3L,
+ 2.0307734695595183428202E3L,
+ 1.2695660352705325274404E3L,
+ 3.2242573199748645407652E2L,
+};
+
+/* 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 = 6.16e-22
+ */
+static const long double R[4] = {
+ 1.9757429581415468984296E-3L,
+-7.1990767473014147232598E-1L,
+ 1.0777257190312272158094E1L,
+-3.5717684488096787370998E1L,
+};
+static const long double S[4] = {
+/* 1.00000000000000000000E0L,*/
+-2.6201045551331104417768E1L,
+ 1.9361891836232102174846E2L,
+-4.2861221385716144629696E2L,
+};
+/* log10(2) */
+#define L102A 0.3125L
+#define L102B -1.1470004336018804786261e-2L
+/* log10(e) */
+#define L10EA 0.5L
+#define L10EB -6.5705518096748172348871e-2L
+
+#define SQRTH 0.70710678118654752440L
+
+long double log10l(long double x)
+{
+	long double y, z;
+	int e;
+
+	if (isnan(x))
+		return x;
+	if(x <= 0.0) {
+		if(x == 0.0)
+			return -1.0 / (x*x);
+		return (x - x) / 0.0;
+	}
+	if (x == INFINITY)
+		return INFINITY;
+	/* 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.5;
+			y = 0.5 * z + 0.5;
+		} else {  /*  2 (x-1)/(x+1)   */
+			z = x - 0.5;
+			z -= 0.5;
+			y = 0.5 * x  + 0.5;
+		}
+		x = z / y;
+		z = x*x;
+		y = x * (z * __polevll(z, R, 3) / __p1evll(z, S, 3));
+		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.0;
+	} else {
+		x = x - 1.0;
+	}
+	z = x*x;
+	y = x * (z * __polevll(x, P, 6) / __p1evll(x, Q, 7));
+	y = y - 0.5*z;
+
+done:
+	/* Multiply log of fraction by log10(e)
+	 * and base 2 exponent by log10(2).
+	 *
+	 * ***CAUTION***
+	 *
+	 * This sequence of operations is critical and it may
+	 * be horribly defeated by some compiler optimizers.
+	 */
+	z = y * (L10EB);
+	z += x * (L10EB);
+	z += e * (L102B);
+	z += y * (L10EA);
+	z += x * (L10EA);
+	z += e * (L102A);
+	return z;
+}
+#elif LDBL_MANT_DIG == 113 && LDBL_MAX_EXP == 16384
+// TODO: broken implementation to make things compile
+long double log10l(long double x)
+{
+	return log10(x);
+}
+#endif
libc/musl/src/math/log1p.c
@@ -0,0 +1,122 @@
+/* origin: FreeBSD /usr/src/lib/msun/src/s_log1p.c */
+/*
+ * ====================================================
+ * 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.
+ * ====================================================
+ */
+/* double log1p(double x)
+ * Return the natural logarithm of 1+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 log(1+f): See log.c
+ *
+ *   3. Finally, log1p(x) = k*ln2 + log(1+f) + c/u. See log.c
+ *
+ * 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 "libm.h"
+
+static const double
+ln2_hi = 6.93147180369123816490e-01,  /* 3fe62e42 fee00000 */
+ln2_lo = 1.90821492927058770002e-10,  /* 3dea39ef 35793c76 */
+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 */
+
+double log1p(double x)
+{
+	union {double f; uint64_t i;} u = {x};
+	double_t hfsq,f,c,s,z,R,w,t1,t2,dk;
+	uint32_t hx,hu;
+	int k;
+
+	hx = u.i>>32;
+	k = 1;
+	if (hx < 0x3fda827a || hx>>31) {  /* 1+x < sqrt(2)+ */
+		if (hx >= 0xbff00000) {  /* x <= -1.0 */
+			if (x == -1)
+				return x/0.0; /* log1p(-1) = -inf */
+			return (x-x)/0.0;     /* log1p(x<-1) = NaN */
+		}
+		if (hx<<1 < 0x3ca00000<<1) {  /* |x| < 2**-53 */
+			/* underflow if subnormal */
+			if ((hx&0x7ff00000) == 0)
+				FORCE_EVAL((float)x);
+			return x;
+		}
+		if (hx <= 0xbfd2bec4) {  /* sqrt(2)/2- <= 1+x < sqrt(2)+ */
+			k = 0;
+			c = 0;
+			f = x;
+		}
+	} else if (hx >= 0x7ff00000)
+		return x;
+	if (k) {
+		u.f = 1 + x;
+		hu = u.i>>32;
+		hu += 0x3ff00000 - 0x3fe6a09e;
+		k = (int)(hu>>20) - 0x3ff;
+		/* correction term ~ log(1+x)-log(u), avoid underflow in c/u */
+		if (k < 54) {
+			c = k >= 2 ? 1-(u.f-x) : x-(u.f-1);
+			c /= u.f;
+		} else
+			c = 0;
+		/* reduce u into [sqrt(2)/2, sqrt(2)] */
+		hu = (hu&0x000fffff) + 0x3fe6a09e;
+		u.i = (uint64_t)hu<<32 | (u.i&0xffffffff);
+		f = u.f - 1;
+	}
+	hfsq = 0.5*f*f;
+	s = f/(2.0+f);
+	z = s*s;
+	w = z*z;
+	t1 = w*(Lg2+w*(Lg4+w*Lg6));
+	t2 = z*(Lg1+w*(Lg3+w*(Lg5+w*Lg7)));
+	R = t2 + t1;
+	dk = k;
+	return s*(hfsq+R) + (dk*ln2_lo+c) - hfsq + f + dk*ln2_hi;
+}
libc/musl/src/math/log1pf.c
@@ -0,0 +1,77 @@
+/* origin: FreeBSD /usr/src/lib/msun/src/s_log1pf.c */
+/*
+ * ====================================================
+ * 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 "libm.h"
+
+static const float
+ln2_hi = 6.9313812256e-01, /* 0x3f317180 */
+ln2_lo = 9.0580006145e-06, /* 0x3717f7d1 */
+/* |(log(1+s)-log(1-s))/s - Lg(s)| < 2**-34.24 (~[-4.95e-11, 4.97e-11]). */
+Lg1 = 0xaaaaaa.0p-24, /* 0.66666662693 */
+Lg2 = 0xccce13.0p-25, /* 0.40000972152 */
+Lg3 = 0x91e9ee.0p-25, /* 0.28498786688 */
+Lg4 = 0xf89e26.0p-26; /* 0.24279078841 */
+
+float log1pf(float x)
+{
+	union {float f; uint32_t i;} u = {x};
+	float_t hfsq,f,c,s,z,R,w,t1,t2,dk;
+	uint32_t ix,iu;
+	int k;
+
+	ix = u.i;
+	k = 1;
+	if (ix < 0x3ed413d0 || ix>>31) {  /* 1+x < sqrt(2)+  */
+		if (ix >= 0xbf800000) {  /* x <= -1.0 */
+			if (x == -1)
+				return x/0.0f; /* log1p(-1)=+inf */
+			return (x-x)/0.0f;     /* log1p(x<-1)=NaN */
+		}
+		if (ix<<1 < 0x33800000<<1) {   /* |x| < 2**-24 */
+			/* underflow if subnormal */
+			if ((ix&0x7f800000) == 0)
+				FORCE_EVAL(x*x);
+			return x;
+		}
+		if (ix <= 0xbe95f619) { /* sqrt(2)/2- <= 1+x < sqrt(2)+ */
+			k = 0;
+			c = 0;
+			f = x;
+		}
+	} else if (ix >= 0x7f800000)
+		return x;
+	if (k) {
+		u.f = 1 + x;
+		iu = u.i;
+		iu += 0x3f800000 - 0x3f3504f3;
+		k = (int)(iu>>23) - 0x7f;
+		/* correction term ~ log(1+x)-log(u), avoid underflow in c/u */
+		if (k < 25) {
+			c = k >= 2 ? 1-(u.f-x) : x-(u.f-1);
+			c /= u.f;
+		} else
+			c = 0;
+		/* reduce u into [sqrt(2)/2, sqrt(2)] */
+		iu = (iu&0x007fffff) + 0x3f3504f3;
+		u.i = iu;
+		f = u.f - 1;
+	}
+	s = f/(2.0f + f);
+	z = s*s;
+	w = z*z;
+	t1= w*(Lg2+w*Lg4);
+	t2= z*(Lg1+w*Lg3);
+	R = t2 + t1;
+	hfsq = 0.5f*f*f;
+	dk = k;
+	return s*(hfsq+R) + (dk*ln2_lo+c) - hfsq + f + dk*ln2_hi;
+}
libc/musl/src/math/log1pl.c
@@ -0,0 +1,177 @@
+/* origin: OpenBSD /usr/src/lib/libm/src/ld80/s_log1pl.c */
+/*
+ * Copyright (c) 2008 Stephen L. Moshier <steve@moshier.net>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+/*
+ *      Relative error logarithm
+ *      Natural logarithm of 1+x, 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(x-1)/x+1),
+ *
+ *     log(x) = z + z^3 P(z)/Q(z).
+ *
+ *
+ * ACCURACY:
+ *
+ *                      Relative error:
+ * arithmetic   domain     # trials      peak         rms
+ *    IEEE     -1.0, 9.0    100000      8.2e-20    2.5e-20
+ */
+
+#include "libm.h"
+
+#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024
+long double log1pl(long double x)
+{
+	return log1p(x);
+}
+#elif LDBL_MANT_DIG == 64 && LDBL_MAX_EXP == 16384
+/* Coefficients for log(1+x) = x - x^2 / 2 + x^3 P(x)/Q(x)
+ * 1/sqrt(2) <= x < sqrt(2)
+ * Theoretical peak relative error = 2.32e-20
+ */
+static const long double P[] = {
+ 4.5270000862445199635215E-5L,
+ 4.9854102823193375972212E-1L,
+ 6.5787325942061044846969E0L,
+ 2.9911919328553073277375E1L,
+ 6.0949667980987787057556E1L,
+ 5.7112963590585538103336E1L,
+ 2.0039553499201281259648E1L,
+};
+static const long double Q[] = {
+/* 1.0000000000000000000000E0,*/
+ 1.5062909083469192043167E1L,
+ 8.3047565967967209469434E1L,
+ 2.2176239823732856465394E2L,
+ 3.0909872225312059774938E2L,
+ 2.1642788614495947685003E2L,
+ 6.0118660497603843919306E1L,
+};
+
+/* 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 = 6.16e-22
+ */
+static const long double R[4] = {
+ 1.9757429581415468984296E-3L,
+-7.1990767473014147232598E-1L,
+ 1.0777257190312272158094E1L,
+-3.5717684488096787370998E1L,
+};
+static const long double S[4] = {
+/* 1.00000000000000000000E0L,*/
+-2.6201045551331104417768E1L,
+ 1.9361891836232102174846E2L,
+-4.2861221385716144629696E2L,
+};
+static const long double C1 = 6.9314575195312500000000E-1L;
+static const long double C2 = 1.4286068203094172321215E-6L;
+
+#define SQRTH 0.70710678118654752440L
+
+long double log1pl(long double xm1)
+{
+	long double x, y, z;
+	int e;
+
+	if (isnan(xm1))
+		return xm1;
+	if (xm1 == INFINITY)
+		return xm1;
+	if (xm1 == 0.0)
+		return xm1;
+
+	x = xm1 + 1.0;
+
+	/* Test for domain errors.  */
+	if (x <= 0.0) {
+		if (x == 0.0)
+			return -1/(x*x); /* -inf with divbyzero */
+		return 0/0.0f; /* nan with invalid */
+	}
+
+	/* Separate mantissa from exponent.
+	   Use frexp 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.5;
+			y = 0.5 * z + 0.5;
+		} else { /*  2 (x-1)/(x+1)   */
+			z = x - 0.5;
+			z -= 0.5;
+			y = 0.5 * x  + 0.5;
+		}
+		x = z / y;
+		z = x*x;
+		z = x * (z * __polevll(z, R, 3) / __p1evll(z, S, 3));
+		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.0 * x - 1.0;
+		else
+			x = xm1;
+	} else {
+		if (e != 0)
+			x = x - 1.0;
+		else
+			x = xm1;
+	}
+	z = x*x;
+	y = x * (z * __polevll(x, P, 6) / __p1evll(x, Q, 6));
+	y = y + e * C2;
+	z = y - 0.5 * z;
+	z = z + x;
+	z = z + e * C1;
+	return z;
+}
+#elif LDBL_MANT_DIG == 113 && LDBL_MAX_EXP == 16384
+// TODO: broken implementation to make things compile
+long double log1pl(long double x)
+{
+	return log1p(x);
+}
+#endif
libc/musl/src/math/log2.c
@@ -0,0 +1,122 @@
+/* origin: FreeBSD /usr/src/lib/msun/src/e_log2.c */
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunSoft, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+/*
+ * Return the base 2 logarithm of x.  See log.c for most comments.
+ *
+ * Reduce x to 2^k (1+f) and calculate r = log(1+f) - f + f*f/2
+ * as in log.c, then combine and scale in extra precision:
+ *    log2(x) = (f - f*f/2 + r)/log(2) + k
+ */
+
+#include <math.h>
+#include <stdint.h>
+
+static const double
+ivln2hi = 1.44269504072144627571e+00, /* 0x3ff71547, 0x65200000 */
+ivln2lo = 1.67517131648865118353e-10, /* 0x3de705fc, 0x2eefa200 */
+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 */
+
+double log2(double x)
+{
+	union {double f; uint64_t i;} u = {x};
+	double_t hfsq,f,s,z,R,w,t1,t2,y,hi,lo,val_hi,val_lo;
+	uint32_t hx;
+	int k;
+
+	hx = u.i>>32;
+	k = 0;
+	if (hx < 0x00100000 || hx>>31) {
+		if (u.i<<1 == 0)
+			return -1/(x*x);  /* log(+-0)=-inf */
+		if (hx>>31)
+			return (x-x)/0.0; /* log(-#) = NaN */
+		/* subnormal number, scale x up */
+		k -= 54;
+		x *= 0x1p54;
+		u.f = x;
+		hx = u.i>>32;
+	} else if (hx >= 0x7ff00000) {
+		return x;
+	} else if (hx == 0x3ff00000 && u.i<<32 == 0)
+		return 0;
+
+	/* reduce x into [sqrt(2)/2, sqrt(2)] */
+	hx += 0x3ff00000 - 0x3fe6a09e;
+	k += (int)(hx>>20) - 0x3ff;
+	hx = (hx&0x000fffff) + 0x3fe6a09e;
+	u.i = (uint64_t)hx<<32 | (u.i&0xffffffff);
+	x = u.f;
+
+	f = x - 1.0;
+	hfsq = 0.5*f*f;
+	s = f/(2.0+f);
+	z = s*s;
+	w = z*z;
+	t1 = w*(Lg2+w*(Lg4+w*Lg6));
+	t2 = z*(Lg1+w*(Lg3+w*(Lg5+w*Lg7)));
+	R = t2 + t1;
+
+	/*
+	 * f-hfsq must (for args near 1) be evaluated in extra precision
+	 * to avoid a large cancellation when x is near sqrt(2) or 1/sqrt(2).
+	 * This is fairly efficient since f-hfsq only depends on f, so can
+	 * be evaluated in parallel with R.  Not combining hfsq with R also
+	 * keeps R small (though not as small as a true `lo' term would be),
+	 * so that extra precision is not needed for terms involving R.
+	 *
+	 * Compiler bugs involving extra precision used to break Dekker's
+	 * theorem for spitting f-hfsq as hi+lo, unless double_t was used
+	 * or the multi-precision calculations were avoided when double_t
+	 * has extra precision.  These problems are now automatically
+	 * avoided as a side effect of the optimization of combining the
+	 * Dekker splitting step with the clear-low-bits step.
+	 *
+	 * y must (for args near sqrt(2) and 1/sqrt(2)) be added in extra
+	 * precision to avoid a very large cancellation when x is very near
+	 * these values.  Unlike the above cancellations, this problem is
+	 * specific to base 2.  It is strange that adding +-1 is so much
+	 * harder than adding +-ln2 or +-log10_2.
+	 *
+	 * This uses Dekker's theorem to normalize y+val_hi, so the
+	 * compiler bugs are back in some configurations, sigh.  And I
+	 * don't want to used double_t to avoid them, since that gives a
+	 * pessimization and the support for avoiding the pessimization
+	 * is not yet available.
+	 *
+	 * The multi-precision calculations for the multiplications are
+	 * routine.
+	 */
+
+	/* hi+lo = f - hfsq + s*(hfsq+R) ~ log(1+f) */
+	hi = f - hfsq;
+	u.f = hi;
+	u.i &= (uint64_t)-1<<32;
+	hi = u.f;
+	lo = f - hi - hfsq + s*(hfsq+R);
+
+	val_hi = hi*ivln2hi;
+	val_lo = (lo+hi)*ivln2lo + lo*ivln2hi;
+
+	/* spadd(val_hi, val_lo, y), except for not using double_t: */
+	y = k;
+	w = y + val_hi;
+	val_lo += (y - w) + val_hi;
+	val_hi = w;
+
+	return val_lo + val_hi;
+}
libc/musl/src/math/log2f.c
@@ -0,0 +1,74 @@
+/* origin: FreeBSD /usr/src/lib/msun/src/e_log2f.c */
+/*
+ * ====================================================
+ * 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.
+ * ====================================================
+ */
+/*
+ * See comments in log2.c.
+ */
+
+#include <math.h>
+#include <stdint.h>
+
+static const float
+ivln2hi =  1.4428710938e+00, /* 0x3fb8b000 */
+ivln2lo = -1.7605285393e-04, /* 0xb9389ad4 */
+/* |(log(1+s)-log(1-s))/s - Lg(s)| < 2**-34.24 (~[-4.95e-11, 4.97e-11]). */
+Lg1 = 0xaaaaaa.0p-24, /* 0.66666662693 */
+Lg2 = 0xccce13.0p-25, /* 0.40000972152 */
+Lg3 = 0x91e9ee.0p-25, /* 0.28498786688 */
+Lg4 = 0xf89e26.0p-26; /* 0.24279078841 */
+
+float log2f(float x)
+{
+	union {float f; uint32_t i;} u = {x};
+	float_t hfsq,f,s,z,R,w,t1,t2,hi,lo;
+	uint32_t ix;
+	int k;
+
+	ix = u.i;
+	k = 0;
+	if (ix < 0x00800000 || ix>>31) {  /* x < 2**-126  */
+		if (ix<<1 == 0)
+			return -1/(x*x);  /* log(+-0)=-inf */
+		if (ix>>31)
+			return (x-x)/0.0f; /* log(-#) = NaN */
+		/* subnormal number, scale up x */
+		k -= 25;
+		x *= 0x1p25f;
+		u.f = x;
+		ix = u.i;
+	} else if (ix >= 0x7f800000) {
+		return x;
+	} else if (ix == 0x3f800000)
+		return 0;
+
+	/* reduce x into [sqrt(2)/2, sqrt(2)] */
+	ix += 0x3f800000 - 0x3f3504f3;
+	k += (int)(ix>>23) - 0x7f;
+	ix = (ix&0x007fffff) + 0x3f3504f3;
+	u.i = ix;
+	x = u.f;
+
+	f = x - 1.0f;
+	s = f/(2.0f + f);
+	z = s*s;
+	w = z*z;
+	t1= w*(Lg2+w*Lg4);
+	t2= z*(Lg1+w*Lg3);
+	R = t2 + t1;
+	hfsq = 0.5f*f*f;
+
+	hi = f - hfsq;
+	u.f = hi;
+	u.i &= 0xfffff000;
+	hi = u.f;
+	lo = f - hi - hfsq + s*(hfsq+R);
+	return (lo+hi)*ivln2lo + lo*ivln2hi + hi*ivln2hi + k;
+}
libc/musl/src/math/log2l.c
@@ -0,0 +1,182 @@
+/* origin: OpenBSD /usr/src/lib/libm/src/ld80/e_log2l.c */
+/*
+ * Copyright (c) 2008 Stephen L. Moshier <steve@moshier.net>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+/*
+ *      Base 2 logarithm, 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     30000      9.8e-20     2.7e-20
+ *    IEEE     exp(+-10000)  70000      5.4e-20     2.3e-20
+ *
+ * In the tests over the interval exp(+-10000), the logarithms
+ * of the random arguments were uniformly distributed over
+ * [-10000, +10000].
+ */
+
+#include "libm.h"
+
+#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024
+long double log2l(long double x)
+{
+	return log2(x);
+}
+#elif LDBL_MANT_DIG == 64 && LDBL_MAX_EXP == 16384
+/* 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 = 6.2e-22
+ */
+static const long double P[] = {
+ 4.9962495940332550844739E-1L,
+ 1.0767376367209449010438E1L,
+ 7.7671073698359539859595E1L,
+ 2.5620629828144409632571E2L,
+ 4.2401812743503691187826E2L,
+ 3.4258224542413922935104E2L,
+ 1.0747524399916215149070E2L,
+};
+static const long double Q[] = {
+/* 1.0000000000000000000000E0,*/
+ 2.3479774160285863271658E1L,
+ 1.9444210022760132894510E2L,
+ 7.7952888181207260646090E2L,
+ 1.6911722418503949084863E3L,
+ 2.0307734695595183428202E3L,
+ 1.2695660352705325274404E3L,
+ 3.2242573199748645407652E2L,
+};
+
+/* 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 = 6.16e-22
+ */
+static const long double R[4] = {
+ 1.9757429581415468984296E-3L,
+-7.1990767473014147232598E-1L,
+ 1.0777257190312272158094E1L,
+-3.5717684488096787370998E1L,
+};
+static const long double S[4] = {
+/* 1.00000000000000000000E0L,*/
+-2.6201045551331104417768E1L,
+ 1.9361891836232102174846E2L,
+-4.2861221385716144629696E2L,
+};
+/* log2(e) - 1 */
+#define LOG2EA 4.4269504088896340735992e-1L
+
+#define SQRTH 0.70710678118654752440L
+
+long double log2l(long double x)
+{
+	long double y, z;
+	int e;
+
+	if (isnan(x))
+		return x;
+	if (x == INFINITY)
+		return x;
+	if (x <= 0.0) {
+		if (x == 0.0)
+			return -1/(x*x); /* -inf with divbyzero */
+		return 0/0.0f; /* nan with invalid */
+	}
+
+	/* 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.5;
+			y = 0.5 * z + 0.5;
+		} else {  /*  2 (x-1)/(x+1)   */
+			z = x - 0.5;
+			z -= 0.5;
+			y = 0.5 * x + 0.5;
+		}
+		x = z / y;
+		z = x*x;
+		y = x * (z * __polevll(z, R, 3) / __p1evll(z, S, 3));
+		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.0;
+	} else {
+		x = x - 1.0;
+	}
+	z = x*x;
+	y = x * (z * __polevll(x, P, 6) / __p1evll(x, Q, 7));
+	y = y - 0.5*z;
+
+done:
+	/* Multiply log of fraction by log2(e)
+	 * and base 2 exponent by 1
+	 *
+	 * ***CAUTION***
+	 *
+	 * This sequence of operations is critical and it may
+	 * be horribly defeated by some compiler optimizers.
+	 */
+	z = y * LOG2EA;
+	z += x * LOG2EA;
+	z += y;
+	z += x;
+	z += e;
+	return z;
+}
+#elif LDBL_MANT_DIG == 113 && LDBL_MAX_EXP == 16384
+// TODO: broken implementation to make things compile
+long double log2l(long double x)
+{
+	return log2(x);
+}
+#endif
libc/musl/src/math/logb.c
@@ -0,0 +1,17 @@
+#include <math.h>
+
+/*
+special cases:
+	logb(+-0) = -inf, and raise divbyzero
+	logb(+-inf) = +inf
+	logb(nan) = nan
+*/
+
+double logb(double x)
+{
+	if (!isfinite(x))
+		return x * x;
+	if (x == 0)
+		return -1/(x*x);
+	return ilogb(x);
+}
libc/musl/src/math/logbf.c
@@ -0,0 +1,10 @@
+#include <math.h>
+
+float logbf(float x)
+{
+	if (!isfinite(x))
+		return x * x;
+	if (x == 0)
+		return -1/(x*x);
+	return ilogbf(x);
+}
libc/musl/src/math/logbl.c
@@ -0,0 +1,16 @@
+#include <math.h>
+#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024
+long double logbl(long double x)
+{
+	return logb(x);
+}
+#else
+long double logbl(long double x)
+{
+	if (!isfinite(x))
+		return x * x;
+	if (x == 0)
+		return -1/(x*x);
+	return ilogbl(x);
+}
+#endif
libc/musl/src/math/logf.c
@@ -0,0 +1,69 @@
+/* origin: FreeBSD /usr/src/lib/msun/src/e_logf.c */
+/*
+ * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.
+ */
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunPro, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+
+#include <math.h>
+#include <stdint.h>
+
+static const float
+ln2_hi = 6.9313812256e-01, /* 0x3f317180 */
+ln2_lo = 9.0580006145e-06, /* 0x3717f7d1 */
+/* |(log(1+s)-log(1-s))/s - Lg(s)| < 2**-34.24 (~[-4.95e-11, 4.97e-11]). */
+Lg1 = 0xaaaaaa.0p-24, /* 0.66666662693 */
+Lg2 = 0xccce13.0p-25, /* 0.40000972152 */
+Lg3 = 0x91e9ee.0p-25, /* 0.28498786688 */
+Lg4 = 0xf89e26.0p-26; /* 0.24279078841 */
+
+float logf(float x)
+{
+	union {float f; uint32_t i;} u = {x};
+	float_t hfsq,f,s,z,R,w,t1,t2,dk;
+	uint32_t ix;
+	int k;
+
+	ix = u.i;
+	k = 0;
+	if (ix < 0x00800000 || ix>>31) {  /* x < 2**-126  */
+		if (ix<<1 == 0)
+			return -1/(x*x);  /* log(+-0)=-inf */
+		if (ix>>31)
+			return (x-x)/0.0f; /* log(-#) = NaN */
+		/* subnormal number, scale up x */
+		k -= 25;
+		x *= 0x1p25f;
+		u.f = x;
+		ix = u.i;
+	} else if (ix >= 0x7f800000) {
+		return x;
+	} else if (ix == 0x3f800000)
+		return 0;
+
+	/* reduce x into [sqrt(2)/2, sqrt(2)] */
+	ix += 0x3f800000 - 0x3f3504f3;
+	k += (int)(ix>>23) - 0x7f;
+	ix = (ix&0x007fffff) + 0x3f3504f3;
+	u.i = ix;
+	x = u.f;
+
+	f = x - 1.0f;
+	s = f/(2.0f + f);
+	z = s*s;
+	w = z*z;
+	t1= w*(Lg2+w*Lg4);
+	t2= z*(Lg1+w*Lg3);
+	R = t2 + t1;
+	hfsq = 0.5f*f*f;
+	dk = k;
+	return s*(hfsq+R) + dk*ln2_lo - hfsq + f + dk*ln2_hi;
+}
libc/musl/src/math/logl.c
@@ -0,0 +1,175 @@
+/* origin: OpenBSD /usr/src/lib/libm/src/ld80/e_logl.c */
+/*
+ * Copyright (c) 2008 Stephen L. Moshier <steve@moshier.net>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+/*
+ *      Natural logarithm, 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.  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) = log(1+z/2) - log(1-z/2) = z + z**3 P(z)/Q(z).
+ *
+ *
+ * ACCURACY:
+ *
+ *                      Relative error:
+ * arithmetic   domain     # trials      peak         rms
+ *    IEEE      0.5, 2.0    150000      8.71e-20    2.75e-20
+ *    IEEE     exp(+-10000) 100000      5.39e-20    2.34e-20
+ *
+ * In the tests over the interval exp(+-10000), the logarithms
+ * of the random arguments were uniformly distributed over
+ * [-10000, +10000].
+ */
+
+#include "libm.h"
+
+#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024
+long double logl(long double x)
+{
+	return log(x);
+}
+#elif LDBL_MANT_DIG == 64 && LDBL_MAX_EXP == 16384
+/* Coefficients for log(1+x) = x - x**2/2 + x**3 P(x)/Q(x)
+ * 1/sqrt(2) <= x < sqrt(2)
+ * Theoretical peak relative error = 2.32e-20
+ */
+static const long double P[] = {
+ 4.5270000862445199635215E-5L,
+ 4.9854102823193375972212E-1L,
+ 6.5787325942061044846969E0L,
+ 2.9911919328553073277375E1L,
+ 6.0949667980987787057556E1L,
+ 5.7112963590585538103336E1L,
+ 2.0039553499201281259648E1L,
+};
+static const long double Q[] = {
+/* 1.0000000000000000000000E0,*/
+ 1.5062909083469192043167E1L,
+ 8.3047565967967209469434E1L,
+ 2.2176239823732856465394E2L,
+ 3.0909872225312059774938E2L,
+ 2.1642788614495947685003E2L,
+ 6.0118660497603843919306E1L,
+};
+
+/* 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 = 6.16e-22
+ */
+static const long double R[4] = {
+ 1.9757429581415468984296E-3L,
+-7.1990767473014147232598E-1L,
+ 1.0777257190312272158094E1L,
+-3.5717684488096787370998E1L,
+};
+static const long double S[4] = {
+/* 1.00000000000000000000E0L,*/
+-2.6201045551331104417768E1L,
+ 1.9361891836232102174846E2L,
+-4.2861221385716144629696E2L,
+};
+static const long double C1 = 6.9314575195312500000000E-1L;
+static const long double C2 = 1.4286068203094172321215E-6L;
+
+#define SQRTH 0.70710678118654752440L
+
+long double logl(long double x)
+{
+	long double y, z;
+	int e;
+
+	if (isnan(x))
+		return x;
+	if (x == INFINITY)
+		return x;
+	if (x <= 0.0) {
+		if (x == 0.0)
+			return -1/(x*x); /* -inf with divbyzero */
+		return 0/0.0f; /* nan with invalid */
+	}
+
+	/* 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.5;
+			y = 0.5 * z + 0.5;
+		} else {  /*  2 (x-1)/(x+1)   */
+			z = x - 0.5;
+			z -= 0.5;
+			y = 0.5 * x  + 0.5;
+		}
+		x = z / y;
+		z = x*x;
+		z = x * (z * __polevll(z, R, 3) / __p1evll(z, S, 3));
+		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;
+		x = 2.0*x - 1.0;
+	} else {
+		x = x - 1.0;
+	}
+	z = x*x;
+	y = x * (z * __polevll(x, P, 6) / __p1evll(x, Q, 6));
+	y = y + e * C2;
+	z = y - 0.5*z;
+	/* Note, the sum of above terms does not exceed x/4,
+	 * so it contributes at most about 1/4 lsb to the error.
+	 */
+	z = z + x;
+	z = z + e * C1; /* This sum has an error of 1/2 lsb. */
+	return z;
+}
+#elif LDBL_MANT_DIG == 113 && LDBL_MAX_EXP == 16384
+// TODO: broken implementation to make things compile
+long double logl(long double x)
+{
+	return log(x);
+}
+#endif
libc/musl/src/math/lrint.c
@@ -0,0 +1,46 @@
+#include <limits.h>
+#include <fenv.h>
+#include "libm.h"
+
+/*
+If the result cannot be represented (overflow, nan), then
+lrint raises the invalid exception.
+
+Otherwise if the input was not an integer then the inexact
+exception is raised.
+
+C99 is a bit vague about whether inexact exception is
+allowed to be raised when invalid is raised.
+(F.9 explicitly allows spurious inexact exceptions, F.9.6.5
+does not make it clear if that rule applies to lrint, but
+IEEE 754r 7.8 seems to forbid spurious inexact exception in
+the ineger conversion functions)
+
+So we try to make sure that no spurious inexact exception is
+raised in case of an overflow.
+
+If the bit size of long > precision of double, then there
+cannot be inexact rounding in case the result overflows,
+otherwise LONG_MAX and LONG_MIN can be represented exactly
+as a double.
+*/
+
+#if LONG_MAX < 1U<<53 && defined(FE_INEXACT)
+long lrint(double x)
+{
+	#pragma STDC FENV_ACCESS ON
+	int e;
+
+	e = fetestexcept(FE_INEXACT);
+	x = rint(x);
+	if (!e && (x > LONG_MAX || x < LONG_MIN))
+		feclearexcept(FE_INEXACT);
+	/* conversion */
+	return x;
+}
+#else
+long lrint(double x)
+{
+	return rint(x);
+}
+#endif
libc/musl/src/math/lrintf.c
@@ -0,0 +1,8 @@
+#include <math.h>
+
+/* uses LONG_MAX > 2^24, see comments in lrint.c */
+
+long lrintf(float x)
+{
+	return rintf(x);
+}
libc/musl/src/math/lrintl.c
@@ -0,0 +1,36 @@
+#include <limits.h>
+#include <fenv.h>
+#include "libm.h"
+
+
+#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024
+long lrintl(long double x)
+{
+	return lrint(x);
+}
+#elif defined(FE_INEXACT)
+/*
+see comments in lrint.c
+
+Note that if LONG_MAX == 0x7fffffffffffffff && LDBL_MANT_DIG == 64
+then x == 2**63 - 0.5 is the only input that overflows and
+raises inexact (with tonearest or upward rounding mode)
+*/
+long lrintl(long double x)
+{
+	#pragma STDC FENV_ACCESS ON
+	int e;
+
+	e = fetestexcept(FE_INEXACT);
+	x = rintl(x);
+	if (!e && (x > LONG_MAX || x < LONG_MIN))
+		feclearexcept(FE_INEXACT);
+	/* conversion */
+	return x;
+}
+#else
+long lrintl(long double x)
+{
+	return rintl(x);
+}
+#endif
libc/musl/src/math/lround.c
@@ -0,0 +1,6 @@
+#include <math.h>
+
+long lround(double x)
+{
+	return round(x);
+}
libc/musl/src/math/lroundf.c
@@ -0,0 +1,6 @@
+#include <math.h>
+
+long lroundf(float x)
+{
+	return roundf(x);
+}
libc/musl/src/math/lroundl.c
@@ -0,0 +1,6 @@
+#include <math.h>
+
+long lroundl(long double x)
+{
+	return roundl(x);
+}
libc/musl/src/math/modf.c
@@ -0,0 +1,34 @@
+#include "libm.h"
+
+double modf(double x, double *iptr)
+{
+	union {double f; uint64_t i;} u = {x};
+	uint64_t mask;
+	int e = (int)(u.i>>52 & 0x7ff) - 0x3ff;
+
+	/* no fractional part */
+	if (e >= 52) {
+		*iptr = x;
+		if (e == 0x400 && u.i<<12 != 0) /* nan */
+			return x;
+		u.i &= 1ULL<<63;
+		return u.f;
+	}
+
+	/* no integral part*/
+	if (e < 0) {
+		u.i &= 1ULL<<63;
+		*iptr = u.f;
+		return x;
+	}
+
+	mask = -1ULL>>12>>e;
+	if ((u.i & mask) == 0) {
+		*iptr = x;
+		u.i &= 1ULL<<63;
+		return u.f;
+	}
+	u.i &= ~mask;
+	*iptr = u.f;
+	return x - u.f;
+}
libc/musl/src/math/modff.c
@@ -0,0 +1,34 @@
+#include "libm.h"
+
+float modff(float x, float *iptr)
+{
+	union {float f; uint32_t i;} u = {x};
+	uint32_t mask;
+	int e = (int)(u.i>>23 & 0xff) - 0x7f;
+
+	/* no fractional part */
+	if (e >= 23) {
+		*iptr = x;
+		if (e == 0x80 && u.i<<9 != 0) { /* nan */
+			return x;
+		}
+		u.i &= 0x80000000;
+		return u.f;
+	}
+	/* no integral part */
+	if (e < 0) {
+		u.i &= 0x80000000;
+		*iptr = u.f;
+		return x;
+	}
+
+	mask = 0x007fffff>>e;
+	if ((u.i & mask) == 0) {
+		*iptr = x;
+		u.i &= 0x80000000;
+		return u.f;
+	}
+	u.i &= ~mask;
+	*iptr = u.f;
+	return x - u.f;
+}
libc/musl/src/math/modfl.c
@@ -0,0 +1,53 @@
+#include "libm.h"
+
+#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024
+long double modfl(long double x, long double *iptr)
+{
+	double d;
+	long double r;
+
+	r = modf(x, &d);
+	*iptr = d;
+	return r;
+}
+#elif (LDBL_MANT_DIG == 64 || LDBL_MANT_DIG == 113) && LDBL_MAX_EXP == 16384
+
+static const long double toint = 1/LDBL_EPSILON;
+
+long double modfl(long double x, long double *iptr)
+{
+	union ldshape u = {x};
+	int e = (u.i.se & 0x7fff) - 0x3fff;
+	int s = u.i.se >> 15;
+	long double absx;
+	long double y;
+
+	/* no fractional part */
+	if (e >= LDBL_MANT_DIG-1) {
+		*iptr = x;
+		if (isnan(x))
+			return x;
+		return s ? -0.0 : 0.0;
+	}
+
+	/* no integral part*/
+	if (e < 0) {
+		*iptr = s ? -0.0 : 0.0;
+		return x;
+	}
+
+	/* raises spurious inexact */
+	absx = s ? -x : x;
+	y = absx + toint - toint - absx;
+	if (y == 0) {
+		*iptr = x;
+		return s ? -0.0 : 0.0;
+	}
+	if (y > 0)
+		y -= 1;
+	if (s)
+		y = -y;
+	*iptr = x + y;
+	return -y;
+}
+#endif
libc/musl/src/math/nan.c
@@ -0,0 +1,6 @@
+#include <math.h>
+
+double nan(const char *s)
+{
+	return NAN;
+}
libc/musl/src/math/nanf.c
@@ -0,0 +1,6 @@
+#include <math.h>
+
+float nanf(const char *s)
+{
+	return NAN;
+}
libc/musl/src/math/nanl.c
@@ -0,0 +1,6 @@
+#include <math.h>
+
+long double nanl(const char *s)
+{
+	return NAN;
+}
libc/musl/src/math/nearbyint.c
@@ -0,0 +1,20 @@
+#include <fenv.h>
+#include <math.h>
+
+/* nearbyint is the same as rint, but it must not raise the inexact exception */
+
+double nearbyint(double x)
+{
+#ifdef FE_INEXACT
+	#pragma STDC FENV_ACCESS ON
+	int e;
+
+	e = fetestexcept(FE_INEXACT);
+#endif
+	x = rint(x);
+#ifdef FE_INEXACT
+	if (!e)
+		feclearexcept(FE_INEXACT);
+#endif
+	return x;
+}
libc/musl/src/math/nearbyintf.c
@@ -0,0 +1,18 @@
+#include <fenv.h>
+#include <math.h>
+
+float nearbyintf(float x)
+{
+#ifdef FE_INEXACT
+	#pragma STDC FENV_ACCESS ON
+	int e;
+
+	e = fetestexcept(FE_INEXACT);
+#endif
+	x = rintf(x);
+#ifdef FE_INEXACT
+	if (!e)
+		feclearexcept(FE_INEXACT);
+#endif
+	return x;
+}
libc/musl/src/math/nearbyintl.c
@@ -0,0 +1,26 @@
+#include <math.h>
+#include <float.h>
+
+#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024
+long double nearbyintl(long double x)
+{
+	return nearbyint(x);
+}
+#else
+#include <fenv.h>
+long double nearbyintl(long double x)
+{
+#ifdef FE_INEXACT
+	#pragma STDC FENV_ACCESS ON
+	int e;
+
+	e = fetestexcept(FE_INEXACT);
+#endif
+	x = rintl(x);
+#ifdef FE_INEXACT
+	if (!e)
+		feclearexcept(FE_INEXACT);
+#endif
+	return x;
+}
+#endif
libc/musl/src/math/nextafter.c
@@ -0,0 +1,31 @@
+#include "libm.h"
+
+double nextafter(double x, double y)
+{
+	union {double f; uint64_t i;} ux={x}, uy={y};
+	uint64_t ax, ay;
+	int e;
+
+	if (isnan(x) || isnan(y))
+		return x + y;
+	if (ux.i == uy.i)
+		return y;
+	ax = ux.i & -1ULL/2;
+	ay = uy.i & -1ULL/2;
+	if (ax == 0) {
+		if (ay == 0)
+			return y;
+		ux.i = (uy.i & 1ULL<<63) | 1;
+	} else if (ax > ay || ((ux.i ^ uy.i) & 1ULL<<63))
+		ux.i--;
+	else
+		ux.i++;
+	e = ux.i >> 52 & 0x7ff;
+	/* raise overflow if ux.f is infinite and x is finite */
+	if (e == 0x7ff)
+		FORCE_EVAL(x+x);
+	/* raise underflow if ux.f is subnormal or zero */
+	if (e == 0)
+		FORCE_EVAL(x*x + ux.f*ux.f);
+	return ux.f;
+}
libc/musl/src/math/nextafterf.c
@@ -0,0 +1,30 @@
+#include "libm.h"
+
+float nextafterf(float x, float y)
+{
+	union {float f; uint32_t i;} ux={x}, uy={y};
+	uint32_t ax, ay, e;
+
+	if (isnan(x) || isnan(y))
+		return x + y;
+	if (ux.i == uy.i)
+		return y;
+	ax = ux.i & 0x7fffffff;
+	ay = uy.i & 0x7fffffff;
+	if (ax == 0) {
+		if (ay == 0)
+			return y;
+		ux.i = (uy.i & 0x80000000) | 1;
+	} else if (ax > ay || ((ux.i ^ uy.i) & 0x80000000))
+		ux.i--;
+	else
+		ux.i++;
+	e = ux.i & 0x7f800000;
+	/* raise overflow if ux.f is infinite and x is finite */
+	if (e == 0x7f800000)
+		FORCE_EVAL(x+x);
+	/* raise underflow if ux.f is subnormal or zero */
+	if (e == 0)
+		FORCE_EVAL(x*x + ux.f*ux.f);
+	return ux.f;
+}
libc/musl/src/math/nextafterl.c
@@ -0,0 +1,75 @@
+#include "libm.h"
+
+#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024
+long double nextafterl(long double x, long double y)
+{
+	return nextafter(x, y);
+}
+#elif LDBL_MANT_DIG == 64 && LDBL_MAX_EXP == 16384
+long double nextafterl(long double x, long double y)
+{
+	union ldshape ux, uy;
+
+	if (isnan(x) || isnan(y))
+		return x + y;
+	if (x == y)
+		return y;
+	ux.f = x;
+	if (x == 0) {
+		uy.f = y;
+		ux.i.m = 1;
+		ux.i.se = uy.i.se & 0x8000;
+	} else if ((x < y) == !(ux.i.se & 0x8000)) {
+		ux.i.m++;
+		if (ux.i.m << 1 == 0) {
+			ux.i.m = 1ULL << 63;
+			ux.i.se++;
+		}
+	} else {
+		if (ux.i.m << 1 == 0) {
+			ux.i.se--;
+			if (ux.i.se)
+				ux.i.m = 0;
+		}
+		ux.i.m--;
+	}
+	/* raise overflow if ux is infinite and x is finite */
+	if ((ux.i.se & 0x7fff) == 0x7fff)
+		return x + x;
+	/* raise underflow if ux is subnormal or zero */
+	if ((ux.i.se & 0x7fff) == 0)
+		FORCE_EVAL(x*x + ux.f*ux.f);
+	return ux.f;
+}
+#elif LDBL_MANT_DIG == 113 && LDBL_MAX_EXP == 16384
+long double nextafterl(long double x, long double y)
+{
+	union ldshape ux, uy;
+
+	if (isnan(x) || isnan(y))
+		return x + y;
+	if (x == y)
+		return y;
+	ux.f = x;
+	if (x == 0) {
+		uy.f = y;
+		ux.i.lo = 1;
+		ux.i.se = uy.i.se & 0x8000;
+	} else if ((x < y) == !(ux.i.se & 0x8000)) {
+		ux.i2.lo++;
+		if (ux.i2.lo == 0)
+			ux.i2.hi++;
+	} else {
+		if (ux.i2.lo == 0)
+			ux.i2.hi--;
+		ux.i2.lo--;
+	}
+	/* raise overflow if ux is infinite and x is finite */
+	if ((ux.i.se & 0x7fff) == 0x7fff)
+		return x + x;
+	/* raise underflow if ux is subnormal or zero */
+	if ((ux.i.se & 0x7fff) == 0)
+		FORCE_EVAL(x*x + ux.f*ux.f);
+	return ux.f;
+}
+#endif
libc/musl/src/math/nexttoward.c
@@ -0,0 +1,42 @@
+#include "libm.h"
+
+#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024
+double nexttoward(double x, long double y)
+{
+	return nextafter(x, y);
+}
+#else
+double nexttoward(double x, long double y)
+{
+	union {double f; uint64_t i;} ux = {x};
+	int e;
+
+	if (isnan(x) || isnan(y))
+		return x + y;
+	if (x == y)
+		return y;
+	if (x == 0) {
+		ux.i = 1;
+		if (signbit(y))
+			ux.i |= 1ULL<<63;
+	} else if (x < y) {
+		if (signbit(x))
+			ux.i--;
+		else
+			ux.i++;
+	} else {
+		if (signbit(x))
+			ux.i++;
+		else
+			ux.i--;
+	}
+	e = ux.i>>52 & 0x7ff;
+	/* raise overflow if ux.f is infinite and x is finite */
+	if (e == 0x7ff)
+		FORCE_EVAL(x+x);
+	/* raise underflow if ux.f is subnormal or zero */
+	if (e == 0)
+		FORCE_EVAL(x*x + ux.f*ux.f);
+	return ux.f;
+}
+#endif
libc/musl/src/math/nexttowardf.c
@@ -0,0 +1,35 @@
+#include "libm.h"
+
+float nexttowardf(float x, long double y)
+{
+	union {float f; uint32_t i;} ux = {x};
+	uint32_t e;
+
+	if (isnan(x) || isnan(y))
+		return x + y;
+	if (x == y)
+		return y;
+	if (x == 0) {
+		ux.i = 1;
+		if (signbit(y))
+			ux.i |= 0x80000000;
+	} else if (x < y) {
+		if (signbit(x))
+			ux.i--;
+		else
+			ux.i++;
+	} else {
+		if (signbit(x))
+			ux.i++;
+		else
+			ux.i--;
+	}
+	e = ux.i & 0x7f800000;
+	/* raise overflow if ux.f is infinite and x is finite */
+	if (e == 0x7f800000)
+		FORCE_EVAL(x+x);
+	/* raise underflow if ux.f is subnormal or zero */
+	if (e == 0)
+		FORCE_EVAL(x*x + ux.f*ux.f);
+	return ux.f;
+}
libc/musl/src/math/nexttowardl.c
@@ -0,0 +1,6 @@
+#include <math.h>
+
+long double nexttowardl(long double x, long double y)
+{
+	return nextafterl(x, y);
+}
libc/musl/src/math/pow.c
@@ -0,0 +1,328 @@
+/* origin: FreeBSD /usr/src/lib/msun/src/e_pow.c */
+/*
+ * ====================================================
+ * Copyright (C) 2004 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+/* pow(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 53-24 = 29 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.  1 ** (anything)  is 1
+ *      3.  (anything except 1) ** 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 1
+ *      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, raise divbyzero
+ *      13. -0 ** (-anything except 0, NAN, odd integer)  is +INF, raise divbyzero
+ *      14. -0 ** (+odd integer) is -0
+ *      15. -0 ** (-odd integer) is -INF, raise divbyzero
+ *      16. +INF ** (+anything except 0,NAN) is +INF
+ *      17. +INF ** (-anything except 0,NAN) is +0
+ *      18. -INF ** (+odd integer) is -INF
+ *      19. -INF ** (anything) = -0 ** (-anything), (anything except odd integer)
+ *      20. (anything) ** 1 is (anything)
+ *      21. (anything) ** -1 is 1/(anything)
+ *      22. (-anything) ** (integer) is (-1)**(integer)*(+anything**integer)
+ *      23. (-anything except 0 and inf) ** (non-integer) is NAN
+ *
+ * Accuracy:
+ *      pow(x,y) returns x**y nearly rounded. In particular
+ *                      pow(integer,integer)
+ *      always returns the correct integer provided it is
+ *      representable.
+ *
+ * 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 "libm.h"
+
+static const double
+bp[]   = {1.0, 1.5,},
+dp_h[] = { 0.0, 5.84962487220764160156e-01,}, /* 0x3FE2B803, 0x40000000 */
+dp_l[] = { 0.0, 1.35003920212974897128e-08,}, /* 0x3E4CFDEB, 0x43CFD006 */
+two53  =  9007199254740992.0, /* 0x43400000, 0x00000000 */
+huge   =  1.0e300,
+tiny   =  1.0e-300,
+/* poly coefs for (3/2)*(log(x)-2s-2/3*s**3 */
+L1 =  5.99999999999994648725e-01, /* 0x3FE33333, 0x33333303 */
+L2 =  4.28571428578550184252e-01, /* 0x3FDB6DB6, 0xDB6FABFF */
+L3 =  3.33333329818377432918e-01, /* 0x3FD55555, 0x518F264D */
+L4 =  2.72728123808534006489e-01, /* 0x3FD17460, 0xA91D4101 */
+L5 =  2.30660745775561754067e-01, /* 0x3FCD864A, 0x93C9DB65 */
+L6 =  2.06975017800338417784e-01, /* 0x3FCA7E28, 0x4A454EEF */
+P1 =  1.66666666666666019037e-01, /* 0x3FC55555, 0x5555553E */
+P2 = -2.77777777770155933842e-03, /* 0xBF66C16C, 0x16BEBD93 */
+P3 =  6.61375632143793436117e-05, /* 0x3F11566A, 0xAF25DE2C */
+P4 = -1.65339022054652515390e-06, /* 0xBEBBBD41, 0xC5D26BF1 */
+P5 =  4.13813679705723846039e-08, /* 0x3E663769, 0x72BEA4D0 */
+lg2     =  6.93147180559945286227e-01, /* 0x3FE62E42, 0xFEFA39EF */
+lg2_h   =  6.93147182464599609375e-01, /* 0x3FE62E43, 0x00000000 */
+lg2_l   = -1.90465429995776804525e-09, /* 0xBE205C61, 0x0CA86C39 */
+ovt     =  8.0085662595372944372e-017, /* -(1024-log2(ovfl+.5ulp)) */
+cp      =  9.61796693925975554329e-01, /* 0x3FEEC709, 0xDC3A03FD =2/(3ln2) */
+cp_h    =  9.61796700954437255859e-01, /* 0x3FEEC709, 0xE0000000 =(float)cp */
+cp_l    = -7.02846165095275826516e-09, /* 0xBE3E2FE0, 0x145B01F5 =tail of cp_h*/
+ivln2   =  1.44269504088896338700e+00, /* 0x3FF71547, 0x652B82FE =1/ln2 */
+ivln2_h =  1.44269502162933349609e+00, /* 0x3FF71547, 0x60000000 =24b 1/ln2*/
+ivln2_l =  1.92596299112661746887e-08; /* 0x3E54AE0B, 0xF85DDF44 =1/ln2 tail*/
+
+double pow(double x, double y)
+{
+	double z,ax,z_h,z_l,p_h,p_l;
+	double y1,t1,t2,r,s,t,u,v,w;
+	int32_t i,j,k,yisint,n;
+	int32_t hx,hy,ix,iy;
+	uint32_t lx,ly;
+
+	EXTRACT_WORDS(hx, lx, x);
+	EXTRACT_WORDS(hy, ly, y);
+	ix = hx & 0x7fffffff;
+	iy = hy & 0x7fffffff;
+
+	/* x**0 = 1, even if x is NaN */
+	if ((iy|ly) == 0)
+		return 1.0;
+	/* 1**y = 1, even if y is NaN */
+	if (hx == 0x3ff00000 && lx == 0)
+		return 1.0;
+	/* NaN if either arg is NaN */
+	if (ix > 0x7ff00000 || (ix == 0x7ff00000 && lx != 0) ||
+	    iy > 0x7ff00000 || (iy == 0x7ff00000 && ly != 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 >= 0x43400000)
+			yisint = 2; /* even integer y */
+		else if (iy >= 0x3ff00000) {
+			k = (iy>>20) - 0x3ff;  /* exponent */
+			if (k > 20) {
+				uint32_t j = ly>>(52-k);
+				if ((j<<(52-k)) == ly)
+					yisint = 2 - (j&1);
+			} else if (ly == 0) {
+				uint32_t j = iy>>(20-k);
+				if ((j<<(20-k)) == iy)
+					yisint = 2 - (j&1);
+			}
+		}
+	}
+
+	/* special value of y */
+	if (ly == 0) {
+		if (iy == 0x7ff00000) {  /* y is +-inf */
+			if (((ix-0x3ff00000)|lx) == 0)  /* (-1)**+-inf is 1 */
+				return 1.0;
+			else if (ix >= 0x3ff00000) /* (|x|>1)**+-inf = inf,0 */
+				return hy >= 0 ? y : 0.0;
+			else                       /* (|x|<1)**+-inf = 0,inf */
+				return hy >= 0 ? 0.0 : -y;
+		}
+		if (iy == 0x3ff00000) {    /* y is +-1 */
+			if (hy >= 0)
+				return x;
+			y = 1/x;
+#if FLT_EVAL_METHOD!=0
+			{
+				union {double f; uint64_t i;} u = {y};
+				uint64_t i = u.i & -1ULL/2;
+				if (i>>52 == 0 && (i&(i-1)))
+					FORCE_EVAL((float)y);
+			}
+#endif
+			return y;
+		}
+		if (hy == 0x40000000)    /* y is 2 */
+			return x*x;
+		if (hy == 0x3fe00000) {  /* y is 0.5 */
+			if (hx >= 0)     /* x >= +0 */
+				return sqrt(x);
+		}
+	}
+
+	ax = fabs(x);
+	/* special value of x */
+	if (lx == 0) {
+		if (ix == 0x7ff00000 || ix == 0 || ix == 0x3ff00000) { /* x is +-0,+-inf,+-1 */
+			z = ax;
+			if (hy < 0)   /* z = (1/|x|) */
+				z = 1.0/z;
+			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;
+		}
+	}
+
+	s = 1.0; /* sign of result */
+	if (hx < 0) {
+		if (yisint == 0) /* (x<0)**(non-int) is NaN */
+			return (x-x)/(x-x);
+		if (yisint == 1) /* (x<0)**(odd int) */
+			s = -1.0;
+	}
+
+	/* |y| is huge */
+	if (iy > 0x41e00000) { /* if |y| > 2**31 */
+		if (iy > 0x43f00000) {  /* if |y| > 2**64, must o/uflow */
+			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 ? s*huge*huge : s*tiny*tiny;
+		if (ix > 0x3ff00000)
+			return hy > 0 ? s*huge*huge : s*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 = ax - 1.0;       /* t has 20 trailing zeros */
+		w = (t*t)*(0.5 - t*(0.3333333333333333333333-t*0.25));
+		u = ivln2_h*t;      /* ivln2_h has 21 sig. bits */
+		v = t*ivln2_l - w*ivln2;
+		t1 = u + v;
+		SET_LOW_WORD(t1, 0);
+		t2 = v - (t1-u);
+	} else {
+		double ss,s2,s_h,s_l,t_h,t_l;
+		n = 0;
+		/* take care subnormal number */
+		if (ix < 0x00100000) {
+			ax *= two53;
+			n -= 53;
+			GET_HIGH_WORD(ix,ax);
+		}
+		n += ((ix)>>20) - 0x3ff;
+		j = ix & 0x000fffff;
+		/* determine interval */
+		ix = j | 0x3ff00000;   /* normalize ix */
+		if (j <= 0x3988E)      /* |x|<sqrt(3/2) */
+			k = 0;
+		else if (j < 0xBB67A)  /* |x|<sqrt(3)   */
+			k = 1;
+		else {
+			k = 0;
+			n += 1;
+			ix -= 0x00100000;
+		}
+		SET_HIGH_WORD(ax, ix);
+
+		/* compute ss = 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 = 1.0/(ax+bp[k]);
+		ss = u*v;
+		s_h = ss;
+		SET_LOW_WORD(s_h, 0);
+		/* t_h=ax+bp[k] High */
+		t_h = 0.0;
+		SET_HIGH_WORD(t_h, ((ix>>1)|0x20000000) + 0x00080000 + (k<<18));
+		t_l = ax - (t_h-bp[k]);
+		s_l = v*((u-s_h*t_h)-s_h*t_l);
+		/* compute log(ax) */
+		s2 = ss*ss;
+		r = s2*s2*(L1+s2*(L2+s2*(L3+s2*(L4+s2*(L5+s2*L6)))));
+		r += s_l*(s_h+ss);
+		s2 = s_h*s_h;
+		t_h = 3.0 + s2 + r;
+		SET_LOW_WORD(t_h, 0);
+		t_l = r - ((t_h-3.0)-s2);
+		/* u+v = ss*(1+...) */
+		u = s_h*t_h;
+		v = s_l*t_h + t_l*ss;
+		/* 2/(3log2)*(ss+...) */
+		p_h = u + v;
+		SET_LOW_WORD(p_h, 0);
+		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) = (ss+..)*2/(3*log2) = n + dp_h + z_h + z_l */
+		t = (double)n;
+		t1 = ((z_h + z_l) + dp_h[k]) + t;
+		SET_LOW_WORD(t1, 0);
+		t2 = z_l - (((t1 - t) - dp_h[k]) - z_h);
+	}
+
+	/* split up y into y1+y2 and compute (y1+y2)*(t1+t2) */
+	y1 = y;
+	SET_LOW_WORD(y1, 0);
+	p_l = (y-y1)*t1 + y*t2;
+	p_h = y1*t1;
+	z = p_l + p_h;
+	EXTRACT_WORDS(j, i, z);
+	if (j >= 0x40900000) {                      /* z >= 1024 */
+		if (((j-0x40900000)|i) != 0)        /* if z > 1024 */
+			return s*huge*huge;         /* overflow */
+		if (p_l + ovt > z - p_h)
+			return s*huge*huge;         /* overflow */
+	} else if ((j&0x7fffffff) >= 0x4090cc00) {  /* z <= -1075 */  // FIXME: instead of abs(j) use unsigned j
+		if (((j-0xc090cc00)|i) != 0)        /* z < -1075 */
+			return s*tiny*tiny;         /* underflow */
+		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 = j + (0x00100000>>(k+1));
+		k = ((n&0x7fffffff)>>20) - 0x3ff;  /* new k for n */
+		t = 0.0;
+		SET_HIGH_WORD(t, n & ~(0x000fffff>>k));
+		n = ((n&0x000fffff)|0x00100000)>>(20-k);
+		if (j < 0)
+			n = -n;
+		p_h -= t;
+	}
+	t = p_l + p_h;
+	SET_LOW_WORD(t, 0);
+	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-2.0) - (w + z*w);
+	z = 1.0 - (r-z);
+	GET_HIGH_WORD(j, z);
+	j += n<<20;
+	if ((j>>20) <= 0)  /* subnormal output */
+		z = scalbn(z,n);
+	else
+		SET_HIGH_WORD(z, j);
+	return s*z;
+}
libc/musl/src/math/powf.c
@@ -0,0 +1,259 @@
+/* origin: FreeBSD /usr/src/lib/msun/src/e_powf.c */
+/*
+ * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.
+ */
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunPro, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+
+#include "libm.h"
+
+static const float
+bp[]   = {1.0, 1.5,},
+dp_h[] = { 0.0, 5.84960938e-01,}, /* 0x3f15c000 */
+dp_l[] = { 0.0, 1.56322085e-06,}, /* 0x35d1cfdc */
+two24  =  16777216.0,  /* 0x4b800000 */
+huge   =  1.0e30,
+tiny   =  1.0e-30,
+/* 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.6191406250e-01, /* 0x3f764000 =12b cp */
+cp_l    = -1.1736857402e-04, /* 0xb8f623c6 =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*/
+
+float powf(float x, float y)
+{
+	float z,ax,z_h,z_l,p_h,p_l;
+	float y1,t1,t2,r,s,sn,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;
+
+	/* x**0 = 1, even if x is NaN */
+	if (iy == 0)
+		return 1.0f;
+	/* 1**y = 1, even if y is NaN */
+	if (hx == 0x3f800000)
+		return 1.0f;
+	/* NaN if either arg is NaN */
+	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)      /* (-1)**+-inf is 1 */
+			return 1.0f;
+		else if (ix > 0x3f800000)  /* (|x|>1)**+-inf = inf,0 */
+			return hy >= 0 ? y : 0.0f;
+		else                       /* (|x|<1)**+-inf = 0,inf */
+			return hy >= 0 ? 0.0f: -y;
+	}
+	if (iy == 0x3f800000)    /* y is +-1 */
+		return hy >= 0 ? x : 1.0f/x;
+	if (hy == 0x40000000)    /* y is 2 */
+		return x*x;
+	if (hy == 0x3f000000) {  /* y is  0.5 */
+		if (hx >= 0)     /* x >= +0 */
+			return sqrtf(x);
+	}
+
+	ax = fabsf(x);
+	/* special value of x */
+	if (ix == 0x7f800000 || ix == 0 || ix == 0x3f800000) { /* x is +-0,+-inf,+-1 */
+		z = ax;
+		if (hy < 0)  /* z = (1/|x|) */
+			z = 1.0f/z;
+		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;
+	}
+
+	sn = 1.0f; /* sign of result */
+	if (hx < 0) {
+		if (yisint == 0) /* (x<0)**(non-int) is NaN */
+			return (x-x)/(x-x);
+		if (yisint == 1) /* (x<0)**(odd int) */
+			sn = -1.0f;
+	}
+
+	/* |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 ? sn*huge*huge : sn*tiny*tiny;
+		if (ix > 0x3f800007)
+			return hy > 0 ? sn*huge*huge : sn*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 = ax - 1;     /* t has 20 trailing zeros */
+		w = (t*t)*(0.5f - t*(0.333333333333f - t*0.25f));
+		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)       /* |x|<sqrt(3/2) */
+			k = 0;
+		else if (j < 0x5db3d7)   /* |x|<sqrt(3)   */
+			k = 1;
+		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 = 1.0f/(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 */
+		is = ((ix>>1) & 0xfffff000) | 0x20000000;
+		SET_FLOAT_WORD(t_h, is + 0x00400000 + (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 = 3.0f + s2 + r;
+		GET_FLOAT_WORD(is, t_h);
+		SET_FLOAT_WORD(t_h, is & 0xfffff000);
+		t_l = r - ((t_h - 3.0f) - 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);
+	}
+
+	/* 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 sn*huge*huge;  /* overflow */
+	else if (j == 0x43000000) {  /* if z == 128 */
+		if (p_l + ovt > z - p_h)
+			return sn*huge*huge;  /* overflow */
+	} else if ((j&0x7fffffff) > 0x43160000)  /* z < -150 */ // FIXME: check should be  (uint32_t)j > 0xc3160000
+		return sn*tiny*tiny;  /* underflow */
+	else if (j == 0xc3160000) {  /* z == -150 */
+		if (p_l <= z-p_h)
+			return sn*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 & 0xffff8000);
+	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-2.0f) - (w+z*w);
+	z = 1.0f - (r - z);
+	GET_FLOAT_WORD(j, z);
+	j += n<<23;
+	if ((j>>23) <= 0)  /* subnormal output */
+		z = scalbnf(z, n);
+	else
+		SET_FLOAT_WORD(z, j);
+	return sn*z;
+}
libc/musl/src/math/powl.c
@@ -0,0 +1,522 @@
+/* origin: OpenBSD /usr/src/lib/libm/src/ld80/e_powl.c */
+/*
+ * Copyright (c) 2008 Stephen L. Moshier <steve@moshier.net>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+/*                                                      powl.c
+ *
+ *      Power function, long double precision
+ *
+ *
+ * SYNOPSIS:
+ *
+ * long double x, y, z, powl();
+ *
+ * z = powl( x, y );
+ *
+ *
+ * DESCRIPTION:
+ *
+ * Computes x raised to the yth power.  Analytically,
+ *
+ *      x**y  =  exp( y log(x) ).
+ *
+ * Following Cody and Waite, this program uses a lookup table
+ * of 2**-i/32 and pseudo extended precision arithmetic to
+ * obtain several extra bits of accuracy in both the logarithm
+ * and the exponential.
+ *
+ *
+ * ACCURACY:
+ *
+ * The relative error of pow(x,y) can be estimated
+ * by   y dl ln(2),   where dl is the absolute error of
+ * the internally computed base 2 logarithm.  At the ends
+ * of the approximation interval the logarithm equal 1/32
+ * and its relative error is about 1 lsb = 1.1e-19.  Hence
+ * the predicted relative error in the result is 2.3e-21 y .
+ *
+ *                      Relative error:
+ * arithmetic   domain     # trials      peak         rms
+ *
+ *    IEEE     +-1000       40000      2.8e-18      3.7e-19
+ * .001 < x < 1000, with log(x) uniformly distributed.
+ * -1000 < y < 1000, y uniformly distributed.
+ *
+ *    IEEE     0,8700       60000      6.5e-18      1.0e-18
+ * 0.99 < x < 1.01, 0 < y < 8700, uniformly distributed.
+ *
+ *
+ * ERROR MESSAGES:
+ *
+ *   message         condition      value returned
+ * pow overflow     x**y > MAXNUM      INFINITY
+ * pow underflow   x**y < 1/MAXNUM       0.0
+ * pow domain      x<0 and y noninteger  0.0
+ *
+ */
+
+#include "libm.h"
+
+#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024
+long double powl(long double x, long double y)
+{
+	return pow(x, y);
+}
+#elif LDBL_MANT_DIG == 64 && LDBL_MAX_EXP == 16384
+
+/* Table size */
+#define NXT 32
+
+/* log(1+x) =  x - .5x^2 + x^3 *  P(z)/Q(z)
+ * on the domain  2^(-1/32) - 1  <=  x  <=  2^(1/32) - 1
+ */
+static const long double P[] = {
+ 8.3319510773868690346226E-4L,
+ 4.9000050881978028599627E-1L,
+ 1.7500123722550302671919E0L,
+ 1.4000100839971580279335E0L,
+};
+static const long double Q[] = {
+/* 1.0000000000000000000000E0L,*/
+ 5.2500282295834889175431E0L,
+ 8.4000598057587009834666E0L,
+ 4.2000302519914740834728E0L,
+};
+/* A[i] = 2^(-i/32), rounded to IEEE long double precision.
+ * If i is even, A[i] + B[i/2] gives additional accuracy.
+ */
+static const long double A[33] = {
+ 1.0000000000000000000000E0L,
+ 9.7857206208770013448287E-1L,
+ 9.5760328069857364691013E-1L,
+ 9.3708381705514995065011E-1L,
+ 9.1700404320467123175367E-1L,
+ 8.9735453750155359320742E-1L,
+ 8.7812608018664974155474E-1L,
+ 8.5930964906123895780165E-1L,
+ 8.4089641525371454301892E-1L,
+ 8.2287773907698242225554E-1L,
+ 8.0524516597462715409607E-1L,
+ 7.8799042255394324325455E-1L,
+ 7.7110541270397041179298E-1L,
+ 7.5458221379671136985669E-1L,
+ 7.3841307296974965571198E-1L,
+ 7.2259040348852331001267E-1L,
+ 7.0710678118654752438189E-1L,
+ 6.9195494098191597746178E-1L,
+ 6.7712777346844636413344E-1L,
+ 6.6261832157987064729696E-1L,
+ 6.4841977732550483296079E-1L,
+ 6.3452547859586661129850E-1L,
+ 6.2092890603674202431705E-1L,
+ 6.0762367999023443907803E-1L,
+ 5.9460355750136053334378E-1L,
+ 5.8186242938878875689693E-1L,
+ 5.6939431737834582684856E-1L,
+ 5.5719337129794626814472E-1L,
+ 5.4525386633262882960438E-1L,
+ 5.3357020033841180906486E-1L,
+ 5.2213689121370692017331E-1L,
+ 5.1094857432705833910408E-1L,
+ 5.0000000000000000000000E-1L,
+};
+static const long double B[17] = {
+ 0.0000000000000000000000E0L,
+ 2.6176170809902549338711E-20L,
+-1.0126791927256478897086E-20L,
+ 1.3438228172316276937655E-21L,
+ 1.2207982955417546912101E-20L,
+-6.3084814358060867200133E-21L,
+ 1.3164426894366316434230E-20L,
+-1.8527916071632873716786E-20L,
+ 1.8950325588932570796551E-20L,
+ 1.5564775779538780478155E-20L,
+ 6.0859793637556860974380E-21L,
+-2.0208749253662532228949E-20L,
+ 1.4966292219224761844552E-20L,
+ 3.3540909728056476875639E-21L,
+-8.6987564101742849540743E-22L,
+-1.2327176863327626135542E-20L,
+ 0.0000000000000000000000E0L,
+};
+
+/* 2^x = 1 + x P(x),
+ * on the interval -1/32 <= x <= 0
+ */
+static const long double R[] = {
+ 1.5089970579127659901157E-5L,
+ 1.5402715328927013076125E-4L,
+ 1.3333556028915671091390E-3L,
+ 9.6181291046036762031786E-3L,
+ 5.5504108664798463044015E-2L,
+ 2.4022650695910062854352E-1L,
+ 6.9314718055994530931447E-1L,
+};
+
+#define MEXP (NXT*16384.0L)
+/* The following if denormal numbers are supported, else -MEXP: */
+#define MNEXP (-NXT*(16384.0L+64.0L))
+/* log2(e) - 1 */
+#define LOG2EA 0.44269504088896340735992L
+
+#define F W
+#define Fa Wa
+#define Fb Wb
+#define G W
+#define Ga Wa
+#define Gb u
+#define H W
+#define Ha Wb
+#define Hb Wb
+
+static const long double MAXLOGL = 1.1356523406294143949492E4L;
+static const long double MINLOGL = -1.13994985314888605586758E4L;
+static const long double LOGE2L = 6.9314718055994530941723E-1L;
+static const long double huge = 0x1p10000L;
+/* XXX Prevent gcc from erroneously constant folding this. */
+static const volatile long double twom10000 = 0x1p-10000L;
+
+static long double reducl(long double);
+static long double powil(long double, int);
+
+long double powl(long double x, long double y)
+{
+	/* double F, Fa, Fb, G, Ga, Gb, H, Ha, Hb */
+	int i, nflg, iyflg, yoddint;
+	long e;
+	volatile long double z=0;
+	long double w=0, W=0, Wa=0, Wb=0, ya=0, yb=0, u=0;
+
+	/* make sure no invalid exception is raised by nan comparision */
+	if (isnan(x)) {
+		if (!isnan(y) && y == 0.0)
+			return 1.0;
+		return x;
+	}
+	if (isnan(y)) {
+		if (x == 1.0)
+			return 1.0;
+		return y;
+	}
+	if (x == 1.0)
+		return 1.0; /* 1**y = 1, even if y is nan */
+	if (x == -1.0 && !isfinite(y))
+		return 1.0; /* -1**inf = 1 */
+	if (y == 0.0)
+		return 1.0; /* x**0 = 1, even if x is nan */
+	if (y == 1.0)
+		return x;
+	if (y >= LDBL_MAX) {
+		if (x > 1.0 || x < -1.0)
+			return INFINITY;
+		if (x != 0.0)
+			return 0.0;
+	}
+	if (y <= -LDBL_MAX) {
+		if (x > 1.0 || x < -1.0)
+			return 0.0;
+		if (x != 0.0 || y == -INFINITY)
+			return INFINITY;
+	}
+	if (x >= LDBL_MAX) {
+		if (y > 0.0)
+			return INFINITY;
+		return 0.0;
+	}
+
+	w = floorl(y);
+
+	/* Set iyflg to 1 if y is an integer. */
+	iyflg = 0;
+	if (w == y)
+		iyflg = 1;
+
+	/* Test for odd integer y. */
+	yoddint = 0;
+	if (iyflg) {
+		ya = fabsl(y);
+		ya = floorl(0.5 * ya);
+		yb = 0.5 * fabsl(w);
+		if( ya != yb )
+			yoddint = 1;
+	}
+
+	if (x <= -LDBL_MAX) {
+		if (y > 0.0) {
+			if (yoddint)
+				return -INFINITY;
+			return INFINITY;
+		}
+		if (y < 0.0) {
+			if (yoddint)
+				return -0.0;
+			return 0.0;
+		}
+	}
+	nflg = 0; /* (x<0)**(odd int) */
+	if (x <= 0.0) {
+		if (x == 0.0) {
+			if (y < 0.0) {
+				if (signbit(x) && yoddint)
+					/* (-0.0)**(-odd int) = -inf, divbyzero */
+					return -1.0/0.0;
+				/* (+-0.0)**(negative) = inf, divbyzero */
+				return 1.0/0.0;
+			}
+			if (signbit(x) && yoddint)
+				return -0.0;
+			return 0.0;
+		}
+		if (iyflg == 0)
+			return (x - x) / (x - x); /* (x<0)**(non-int) is NaN */
+		/* (x<0)**(integer) */
+		if (yoddint)
+			nflg = 1; /* negate result */
+		x = -x;
+	}
+	/* (+integer)**(integer)  */
+	if (iyflg && floorl(x) == x && fabsl(y) < 32768.0) {
+		w = powil(x, (int)y);
+		return nflg ? -w : w;
+	}
+
+	/* separate significand from exponent */
+	x = frexpl(x, &i);
+	e = i;
+
+	/* find significand in antilog table A[] */
+	i = 1;
+	if (x <= A[17])
+		i = 17;
+	if (x <= A[i+8])
+		i += 8;
+	if (x <= A[i+4])
+		i += 4;
+	if (x <= A[i+2])
+		i += 2;
+	if (x >= A[1])
+		i = -1;
+	i += 1;
+
+	/* Find (x - A[i])/A[i]
+	 * in order to compute log(x/A[i]):
+	 *
+	 * log(x) = log( a x/a ) = log(a) + log(x/a)
+	 *
+	 * log(x/a) = log(1+v),  v = x/a - 1 = (x-a)/a
+	 */
+	x -= A[i];
+	x -= B[i/2];
+	x /= A[i];
+
+	/* rational approximation for log(1+v):
+	 *
+	 * log(1+v)  =  v  -  v**2/2  +  v**3 P(v) / Q(v)
+	 */
+	z = x*x;
+	w = x * (z * __polevll(x, P, 3) / __p1evll(x, Q, 3));
+	w = w - 0.5*z;
+
+	/* Convert to base 2 logarithm:
+	 * multiply by log2(e) = 1 + LOG2EA
+	 */
+	z = LOG2EA * w;
+	z += w;
+	z += LOG2EA * x;
+	z += x;
+
+	/* Compute exponent term of the base 2 logarithm. */
+	w = -i;
+	w /= NXT;
+	w += e;
+	/* Now base 2 log of x is w + z. */
+
+	/* Multiply base 2 log by y, in extended precision. */
+
+	/* separate y into large part ya
+	 * and small part yb less than 1/NXT
+	 */
+	ya = reducl(y);
+	yb = y - ya;
+
+	/* (w+z)(ya+yb)
+	 * = w*ya + w*yb + z*y
+	 */
+	F = z * y  +  w * yb;
+	Fa = reducl(F);
+	Fb = F - Fa;
+
+	G = Fa + w * ya;
+	Ga = reducl(G);
+	Gb = G - Ga;
+
+	H = Fb + Gb;
+	Ha = reducl(H);
+	w = (Ga + Ha) * NXT;
+
+	/* Test the power of 2 for overflow */
+	if (w > MEXP)
+		return huge * huge;  /* overflow */
+	if (w < MNEXP)
+		return twom10000 * twom10000;  /* underflow */
+
+	e = w;
+	Hb = H - Ha;
+
+	if (Hb > 0.0) {
+		e += 1;
+		Hb -= 1.0/NXT;  /*0.0625L;*/
+	}
+
+	/* Now the product y * log2(x)  =  Hb + e/NXT.
+	 *
+	 * Compute base 2 exponential of Hb,
+	 * where -0.0625 <= Hb <= 0.
+	 */
+	z = Hb * __polevll(Hb, R, 6);  /*  z = 2**Hb - 1  */
+
+	/* Express e/NXT as an integer plus a negative number of (1/NXT)ths.
+	 * Find lookup table entry for the fractional power of 2.
+	 */
+	if (e < 0)
+		i = 0;
+	else
+		i = 1;
+	i = e/NXT + i;
+	e = NXT*i - e;
+	w = A[e];
+	z = w * z;  /*  2**-e * ( 1 + (2**Hb-1) )  */
+	z = z + w;
+	z = scalbnl(z, i);  /* multiply by integer power of 2 */
+
+	if (nflg)
+		z = -z;
+	return z;
+}
+
+
+/* Find a multiple of 1/NXT that is within 1/NXT of x. */
+static long double reducl(long double x)
+{
+	long double t;
+
+	t = x * NXT;
+	t = floorl(t);
+	t = t / NXT;
+	return t;
+}
+
+/*
+ *      Positive real raised to integer power, long double precision
+ *
+ *
+ * SYNOPSIS:
+ *
+ * long double x, y, powil();
+ * int n;
+ *
+ * y = powil( x, n );
+ *
+ *
+ * DESCRIPTION:
+ *
+ * Returns argument x>0 raised to the nth power.
+ * The routine efficiently decomposes n as a sum of powers of
+ * two. The desired power is a product of two-to-the-kth
+ * powers of x.  Thus to compute the 32767 power of x requires
+ * 28 multiplications instead of 32767 multiplications.
+ *
+ *
+ * ACCURACY:
+ *
+ *                      Relative error:
+ * arithmetic   x domain   n domain  # trials      peak         rms
+ *    IEEE     .001,1000  -1022,1023  50000       4.3e-17     7.8e-18
+ *    IEEE        1,2     -1022,1023  20000       3.9e-17     7.6e-18
+ *    IEEE     .99,1.01     0,8700    10000       3.6e-16     7.2e-17
+ *
+ * Returns MAXNUM on overflow, zero on underflow.
+ */
+
+static long double powil(long double x, int nn)
+{
+	long double ww, y;
+	long double s;
+	int n, e, sign, lx;
+
+	if (nn == 0)
+		return 1.0;
+
+	if (nn < 0) {
+		sign = -1;
+		n = -nn;
+	} else {
+		sign = 1;
+		n = nn;
+	}
+
+	/* Overflow detection */
+
+	/* Calculate approximate logarithm of answer */
+	s = x;
+	s = frexpl( s, &lx);
+	e = (lx - 1)*n;
+	if ((e == 0) || (e > 64) || (e < -64)) {
+		s = (s - 7.0710678118654752e-1L) / (s +  7.0710678118654752e-1L);
+		s = (2.9142135623730950L * s - 0.5 + lx) * nn * LOGE2L;
+	} else {
+		s = LOGE2L * e;
+	}
+
+	if (s > MAXLOGL)
+		return huge * huge;  /* overflow */
+
+	if (s < MINLOGL)
+		return twom10000 * twom10000;  /* underflow */
+	/* Handle tiny denormal answer, but with less accuracy
+	 * since roundoff error in 1.0/x will be amplified.
+	 * The precise demarcation should be the gradual underflow threshold.
+	 */
+	if (s < -MAXLOGL+2.0) {
+		x = 1.0/x;
+		sign = -sign;
+	}
+
+	/* First bit of the power */
+	if (n & 1)
+		y = x;
+	else
+		y = 1.0;
+
+	ww = x;
+	n >>= 1;
+	while (n) {
+		ww = ww * ww;   /* arg to the 2-to-the-kth power */
+		if (n & 1)     /* if that bit is set, then include in product */
+			y *= ww;
+		n >>= 1;
+	}
+
+	if (sign < 0)
+		y = 1.0/y;
+	return y;
+}
+#elif LDBL_MANT_DIG == 113 && LDBL_MAX_EXP == 16384
+// TODO: broken implementation to make things compile
+long double powl(long double x, long double y)
+{
+	return pow(x, y);
+}
+#endif
libc/musl/src/math/remainder.c
@@ -0,0 +1,9 @@
+#include <math.h>
+
+double remainder(double x, double y)
+{
+	int q;
+	return remquo(x, y, &q);
+}
+
+weak_alias(remainder, drem);
libc/musl/src/math/remainderf.c
@@ -0,0 +1,9 @@
+#include <math.h>
+
+float remainderf(float x, float y)
+{
+	int q;
+	return remquof(x, y, &q);
+}
+
+weak_alias(remainderf, dremf);
libc/musl/src/math/remainderl.c
@@ -0,0 +1,15 @@
+#include <math.h>
+#include <float.h>
+
+#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024
+long double remainderl(long double x, long double y)
+{
+	return remainder(x, y);
+}
+#else
+long double remainderl(long double x, long double y)
+{
+	int q;
+	return remquol(x, y, &q);
+}
+#endif
libc/musl/src/math/remquo.c
@@ -0,0 +1,82 @@
+#include <math.h>
+#include <stdint.h>
+
+double remquo(double x, double y, int *quo)
+{
+	union {double f; uint64_t i;} ux = {x}, uy = {y};
+	int ex = ux.i>>52 & 0x7ff;
+	int ey = uy.i>>52 & 0x7ff;
+	int sx = ux.i>>63;
+	int sy = uy.i>>63;
+	uint32_t q;
+	uint64_t i;
+	uint64_t uxi = ux.i;
+
+	*quo = 0;
+	if (uy.i<<1 == 0 || isnan(y) || ex == 0x7ff)
+		return (x*y)/(x*y);
+	if (ux.i<<1 == 0)
+		return x;
+
+	/* normalize x and y */
+	if (!ex) {
+		for (i = uxi<<12; i>>63 == 0; ex--, i <<= 1);
+		uxi <<= -ex + 1;
+	} else {
+		uxi &= -1ULL >> 12;
+		uxi |= 1ULL << 52;
+	}
+	if (!ey) {
+		for (i = uy.i<<12; i>>63 == 0; ey--, i <<= 1);
+		uy.i <<= -ey + 1;
+	} else {
+		uy.i &= -1ULL >> 12;
+		uy.i |= 1ULL << 52;
+	}
+
+	q = 0;
+	if (ex < ey) {
+		if (ex+1 == ey)
+			goto end;
+		return x;
+	}
+
+	/* x mod y */
+	for (; ex > ey; ex--) {
+		i = uxi - uy.i;
+		if (i >> 63 == 0) {
+			uxi = i;
+			q++;
+		}
+		uxi <<= 1;
+		q <<= 1;
+	}
+	i = uxi - uy.i;
+	if (i >> 63 == 0) {
+		uxi = i;
+		q++;
+	}
+	if (uxi == 0)
+		ex = -60;
+	else
+		for (; uxi>>52 == 0; uxi <<= 1, ex--);
+end:
+	/* scale result and decide between |x| and |x|-|y| */
+	if (ex > 0) {
+		uxi -= 1ULL << 52;
+		uxi |= (uint64_t)ex << 52;
+	} else {
+		uxi >>= -ex + 1;
+	}
+	ux.i = uxi;
+	x = ux.f;
+	if (sy)
+		y = -y;
+	if (ex == ey || (ex+1 == ey && (2*x > y || (2*x == y && q%2)))) {
+		x -= y;
+		q++;
+	}
+	q &= 0x7fffffff;
+	*quo = sx^sy ? -(int)q : (int)q;
+	return sx ? -x : x;
+}
libc/musl/src/math/remquof.c
@@ -0,0 +1,82 @@
+#include <math.h>
+#include <stdint.h>
+
+float remquof(float x, float y, int *quo)
+{
+	union {float f; uint32_t i;} ux = {x}, uy = {y};
+	int ex = ux.i>>23 & 0xff;
+	int ey = uy.i>>23 & 0xff;
+	int sx = ux.i>>31;
+	int sy = uy.i>>31;
+	uint32_t q;
+	uint32_t i;
+	uint32_t uxi = ux.i;
+
+	*quo = 0;
+	if (uy.i<<1 == 0 || isnan(y) || ex == 0xff)
+		return (x*y)/(x*y);
+	if (ux.i<<1 == 0)
+		return x;
+
+	/* normalize x and y */
+	if (!ex) {
+		for (i = uxi<<9; i>>31 == 0; ex--, i <<= 1);
+		uxi <<= -ex + 1;
+	} else {
+		uxi &= -1U >> 9;
+		uxi |= 1U << 23;
+	}
+	if (!ey) {
+		for (i = uy.i<<9; i>>31 == 0; ey--, i <<= 1);
+		uy.i <<= -ey + 1;
+	} else {
+		uy.i &= -1U >> 9;
+		uy.i |= 1U << 23;
+	}
+
+	q = 0;
+	if (ex < ey) {
+		if (ex+1 == ey)
+			goto end;
+		return x;
+	}
+
+	/* x mod y */
+	for (; ex > ey; ex--) {
+		i = uxi - uy.i;
+		if (i >> 31 == 0) {
+			uxi = i;
+			q++;
+		}
+		uxi <<= 1;
+		q <<= 1;
+	}
+	i = uxi - uy.i;
+	if (i >> 31 == 0) {
+		uxi = i;
+		q++;
+	}
+	if (uxi == 0)
+		ex = -30;
+	else
+		for (; uxi>>23 == 0; uxi <<= 1, ex--);
+end:
+	/* scale result and decide between |x| and |x|-|y| */
+	if (ex > 0) {
+		uxi -= 1U << 23;
+		uxi |= (uint32_t)ex << 23;
+	} else {
+		uxi >>= -ex + 1;
+	}
+	ux.i = uxi;
+	x = ux.f;
+	if (sy)
+		y = -y;
+	if (ex == ey || (ex+1 == ey && (2*x > y || (2*x == y && q%2)))) {
+		x -= y;
+		q++;
+	}
+	q &= 0x7fffffff;
+	*quo = sx^sy ? -(int)q : (int)q;
+	return sx ? -x : x;
+}
libc/musl/src/math/remquol.c
@@ -0,0 +1,124 @@
+#include "libm.h"
+
+#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024
+long double remquol(long double x, long double y, int *quo)
+{
+	return remquo(x, y, quo);
+}
+#elif (LDBL_MANT_DIG == 64 || LDBL_MANT_DIG == 113) && LDBL_MAX_EXP == 16384
+long double remquol(long double x, long double y, int *quo)
+{
+	union ldshape ux = {x}, uy = {y};
+	int ex = ux.i.se & 0x7fff;
+	int ey = uy.i.se & 0x7fff;
+	int sx = ux.i.se >> 15;
+	int sy = uy.i.se >> 15;
+	uint32_t q;
+
+	*quo = 0;
+	if (y == 0 || isnan(y) || ex == 0x7fff)
+		return (x*y)/(x*y);
+	if (x == 0)
+		return x;
+
+	/* normalize x and y */
+	if (!ex) {
+		ux.i.se = ex;
+		ux.f *= 0x1p120f;
+		ex = ux.i.se - 120;
+	}
+	if (!ey) {
+		uy.i.se = ey;
+		uy.f *= 0x1p120f;
+		ey = uy.i.se - 120;
+	}
+
+	q = 0;
+	if (ex >= ey) {
+		/* x mod y */
+#if LDBL_MANT_DIG == 64
+		uint64_t i, mx, my;
+		mx = ux.i.m;
+		my = uy.i.m;
+		for (; ex > ey; ex--) {
+			i = mx - my;
+			if (mx >= my) {
+				mx = 2*i;
+				q++;
+				q <<= 1;
+			} else if (2*mx < mx) {
+				mx = 2*mx - my;
+				q <<= 1;
+				q++;
+			} else {
+				mx = 2*mx;
+				q <<= 1;
+			}
+		}
+		i = mx - my;
+		if (mx >= my) {
+			mx = i;
+			q++;
+		}
+		if (mx == 0)
+			ex = -120;
+		else
+			for (; mx >> 63 == 0; mx *= 2, ex--);
+		ux.i.m = mx;
+#elif LDBL_MANT_DIG == 113
+		uint64_t hi, lo, xhi, xlo, yhi, ylo;
+		xhi = (ux.i2.hi & -1ULL>>16) | 1ULL<<48;
+		yhi = (uy.i2.hi & -1ULL>>16) | 1ULL<<48;
+		xlo = ux.i2.lo;
+		ylo = ux.i2.lo;
+		for (; ex > ey; ex--) {
+			hi = xhi - yhi;
+			lo = xlo - ylo;
+			if (xlo < ylo)
+				hi -= 1;
+			if (hi >> 63 == 0) {
+				xhi = 2*hi + (lo>>63);
+				xlo = 2*lo;
+				q++;
+			} else {
+				xhi = 2*xhi + (xlo>>63);
+				xlo = 2*xlo;
+			}
+			q <<= 1;
+		}
+		hi = xhi - yhi;
+		lo = xlo - ylo;
+		if (xlo < ylo)
+			hi -= 1;
+		if (hi >> 63 == 0) {
+			xhi = hi;
+			xlo = lo;
+			q++;
+		}
+		if ((xhi|xlo) == 0)
+			ex = -120;
+		else
+			for (; xhi >> 48 == 0; xhi = 2*xhi + (xlo>>63), xlo = 2*xlo, ex--);
+		ux.i2.hi = xhi;
+		ux.i2.lo = xlo;
+#endif
+	}
+
+	/* scale result and decide between |x| and |x|-|y| */
+	if (ex <= 0) {
+		ux.i.se = ex + 120;
+		ux.f *= 0x1p-120f;
+	} else
+		ux.i.se = ex;
+	x = ux.f;
+	if (sy)
+		y = -y;
+	if (ex == ey || (ex+1 == ey && (2*x > y || (2*x == y && q%2)))) {
+		x -= y;
+		q++;
+	}
+	q &= 0x7fffffff;
+	*quo = sx^sy ? -(int)q : (int)q;
+	return sx ? -x : x;
+}
+#endif
libc/musl/src/math/rint.c
@@ -0,0 +1,28 @@
+#include <float.h>
+#include <math.h>
+#include <stdint.h>
+
+#if FLT_EVAL_METHOD==0 || FLT_EVAL_METHOD==1
+#define EPS DBL_EPSILON
+#elif FLT_EVAL_METHOD==2
+#define EPS LDBL_EPSILON
+#endif
+static const double_t toint = 1/EPS;
+
+double rint(double x)
+{
+	union {double f; uint64_t i;} u = {x};
+	int e = u.i>>52 & 0x7ff;
+	int s = u.i>>63;
+	double_t y;
+
+	if (e >= 0x3ff+52)
+		return x;
+	if (s)
+		y = x - toint + toint;
+	else
+		y = x + toint - toint;
+	if (y == 0)
+		return s ? -0.0 : 0;
+	return y;
+}
libc/musl/src/math/rintf.c
@@ -0,0 +1,30 @@
+#include <float.h>
+#include <math.h>
+#include <stdint.h>
+
+#if FLT_EVAL_METHOD==0
+#define EPS FLT_EPSILON
+#elif FLT_EVAL_METHOD==1
+#define EPS DBL_EPSILON
+#elif FLT_EVAL_METHOD==2
+#define EPS LDBL_EPSILON
+#endif
+static const float_t toint = 1/EPS;
+
+float rintf(float x)
+{
+	union {float f; uint32_t i;} u = {x};
+	int e = u.i>>23 & 0xff;
+	int s = u.i>>31;
+	float_t y;
+
+	if (e >= 0x7f+23)
+		return x;
+	if (s)
+		y = x - toint + toint;
+	else
+		y = x + toint - toint;
+	if (y == 0)
+		return s ? -0.0f : 0.0f;
+	return y;
+}
libc/musl/src/math/rintl.c
@@ -0,0 +1,29 @@
+#include "libm.h"
+
+#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024
+long double rintl(long double x)
+{
+	return rint(x);
+}
+#elif (LDBL_MANT_DIG == 64 || LDBL_MANT_DIG == 113) && LDBL_MAX_EXP == 16384
+
+static const long double toint = 1/LDBL_EPSILON;
+
+long double rintl(long double x)
+{
+	union ldshape u = {x};
+	int e = u.i.se & 0x7fff;
+	int s = u.i.se >> 15;
+	long double y;
+
+	if (e >= 0x3fff+LDBL_MANT_DIG-1)
+		return x;
+	if (s)
+		y = x - toint + toint;
+	else
+		y = x + toint - toint;
+	if (y == 0)
+		return 0*x;
+	return y;
+}
+#endif
libc/musl/src/math/round.c
@@ -0,0 +1,35 @@
+#include "libm.h"
+
+#if FLT_EVAL_METHOD==0 || FLT_EVAL_METHOD==1
+#define EPS DBL_EPSILON
+#elif FLT_EVAL_METHOD==2
+#define EPS LDBL_EPSILON
+#endif
+static const double_t toint = 1/EPS;
+
+double round(double x)
+{
+	union {double f; uint64_t i;} u = {x};
+	int e = u.i >> 52 & 0x7ff;
+	double_t y;
+
+	if (e >= 0x3ff+52)
+		return x;
+	if (u.i >> 63)
+		x = -x;
+	if (e < 0x3ff-1) {
+		/* raise inexact if x!=0 */
+		FORCE_EVAL(x + toint);
+		return 0*u.f;
+	}
+	y = x + toint - toint - x;
+	if (y > 0.5)
+		y = y + x - 1;
+	else if (y <= -0.5)
+		y = y + x + 1;
+	else
+		y = y + x;
+	if (u.i >> 63)
+		y = -y;
+	return y;
+}
libc/musl/src/math/roundf.c
@@ -0,0 +1,36 @@
+#include "libm.h"
+
+#if FLT_EVAL_METHOD==0
+#define EPS FLT_EPSILON
+#elif FLT_EVAL_METHOD==1
+#define EPS DBL_EPSILON
+#elif FLT_EVAL_METHOD==2
+#define EPS LDBL_EPSILON
+#endif
+static const float_t toint = 1/EPS;
+
+float roundf(float x)
+{
+	union {float f; uint32_t i;} u = {x};
+	int e = u.i >> 23 & 0xff;
+	float_t y;
+
+	if (e >= 0x7f+23)
+		return x;
+	if (u.i >> 31)
+		x = -x;
+	if (e < 0x7f-1) {
+		FORCE_EVAL(x + toint);
+		return 0*u.f;
+	}
+	y = x + toint - toint - x;
+	if (y > 0.5f)
+		y = y + x - 1;
+	else if (y <= -0.5f)
+		y = y + x + 1;
+	else
+		y = y + x;
+	if (u.i >> 31)
+		y = -y;
+	return y;
+}
libc/musl/src/math/roundl.c
@@ -0,0 +1,37 @@
+#include "libm.h"
+
+#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024
+long double roundl(long double x)
+{
+	return round(x);
+}
+#elif (LDBL_MANT_DIG == 64 || LDBL_MANT_DIG == 113) && LDBL_MAX_EXP == 16384
+
+static const long double toint = 1/LDBL_EPSILON;
+
+long double roundl(long double x)
+{
+	union ldshape u = {x};
+	int e = u.i.se & 0x7fff;
+	long double y;
+
+	if (e >= 0x3fff+LDBL_MANT_DIG-1)
+		return x;
+	if (u.i.se >> 15)
+		x = -x;
+	if (e < 0x3fff-1) {
+		FORCE_EVAL(x + toint);
+		return 0*u.f;
+	}
+	y = x + toint - toint - x;
+	if (y > 0.5)
+		y = y + x - 1;
+	else if (y <= -0.5)
+		y = y + x + 1;
+	else
+		y = y + x;
+	if (u.i.se >> 15)
+		y = -y;
+	return y;
+}
+#endif
libc/musl/src/math/scalb.c
@@ -0,0 +1,35 @@
+/* origin: FreeBSD /usr/src/lib/msun/src/e_scalb.c */
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunSoft, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+/*
+ * scalb(x, fn) is provide for
+ * passing various standard test suite. One
+ * should use scalbn() instead.
+ */
+
+#define _GNU_SOURCE
+#include <math.h>
+
+double scalb(double x, double fn)
+{
+	if (isnan(x) || isnan(fn))
+		return x*fn;
+	if (!isfinite(fn)) {
+		if (fn > 0.0)
+			return x*fn;
+		else
+			return x/(-fn);
+	}
+	if (rint(fn) != fn) return (fn-fn)/(fn-fn);
+	if ( fn > 65000.0) return scalbn(x, 65000);
+	if (-fn > 65000.0) return scalbn(x,-65000);
+	return scalbn(x,(int)fn);
+}
libc/musl/src/math/scalbf.c
@@ -0,0 +1,32 @@
+/* origin: FreeBSD /usr/src/lib/msun/src/e_scalbf.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.
+ * ====================================================
+ */
+
+#define _GNU_SOURCE
+#include <math.h>
+
+float scalbf(float x, float fn)
+{
+	if (isnan(x) || isnan(fn)) return x*fn;
+	if (!isfinite(fn)) {
+		if (fn > 0.0f)
+			return x*fn;
+		else
+			return x/(-fn);
+	}
+	if (rintf(fn) != fn) return (fn-fn)/(fn-fn);
+	if ( fn > 65000.0f) return scalbnf(x, 65000);
+	if (-fn > 65000.0f) return scalbnf(x,-65000);
+	return scalbnf(x,(int)fn);
+}
libc/musl/src/math/scalbln.c
@@ -0,0 +1,11 @@
+#include <limits.h>
+#include <math.h>
+
+double scalbln(double x, long n)
+{
+	if (n > INT_MAX)
+		n = INT_MAX;
+	else if (n < INT_MIN)
+		n = INT_MIN;
+	return scalbn(x, n);
+}
libc/musl/src/math/scalblnf.c
@@ -0,0 +1,11 @@
+#include <limits.h>
+#include <math.h>
+
+float scalblnf(float x, long n)
+{
+	if (n > INT_MAX)
+		n = INT_MAX;
+	else if (n < INT_MIN)
+		n = INT_MIN;
+	return scalbnf(x, n);
+}
libc/musl/src/math/scalblnl.c
@@ -0,0 +1,19 @@
+#include <limits.h>
+#include <math.h>
+#include <float.h>
+
+#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024
+long double scalblnl(long double x, long n)
+{
+	return scalbln(x, n);
+}
+#else
+long double scalblnl(long double x, long n)
+{
+	if (n > INT_MAX)
+		n = INT_MAX;
+	else if (n < INT_MIN)
+		n = INT_MIN;
+	return scalbnl(x, n);
+}
+#endif
libc/musl/src/math/scalbn.c
@@ -0,0 +1,33 @@
+#include <math.h>
+#include <stdint.h>
+
+double scalbn(double x, int n)
+{
+	union {double f; uint64_t i;} u;
+	double_t y = x;
+
+	if (n > 1023) {
+		y *= 0x1p1023;
+		n -= 1023;
+		if (n > 1023) {
+			y *= 0x1p1023;
+			n -= 1023;
+			if (n > 1023)
+				n = 1023;
+		}
+	} else if (n < -1022) {
+		/* make sure final n < -53 to avoid double
+		   rounding in the subnormal range */
+		y *= 0x1p-1022 * 0x1p53;
+		n += 1022 - 53;
+		if (n < -1022) {
+			y *= 0x1p-1022 * 0x1p53;
+			n += 1022 - 53;
+			if (n < -1022)
+				n = -1022;
+		}
+	}
+	u.i = (uint64_t)(0x3ff+n)<<52;
+	x = y * u.f;
+	return x;
+}
libc/musl/src/math/scalbnf.c
@@ -0,0 +1,31 @@
+#include <math.h>
+#include <stdint.h>
+
+float scalbnf(float x, int n)
+{
+	union {float f; uint32_t i;} u;
+	float_t y = x;
+
+	if (n > 127) {
+		y *= 0x1p127f;
+		n -= 127;
+		if (n > 127) {
+			y *= 0x1p127f;
+			n -= 127;
+			if (n > 127)
+				n = 127;
+		}
+	} else if (n < -126) {
+		y *= 0x1p-126f * 0x1p24f;
+		n += 126 - 24;
+		if (n < -126) {
+			y *= 0x1p-126f * 0x1p24f;
+			n += 126 - 24;
+			if (n < -126)
+				n = -126;
+		}
+	}
+	u.i = (uint32_t)(0x7f+n)<<23;
+	x = y * u.f;
+	return x;
+}
libc/musl/src/math/scalbnl.c
@@ -0,0 +1,36 @@
+#include "libm.h"
+
+#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024
+long double scalbnl(long double x, int n)
+{
+	return scalbn(x, n);
+}
+#elif (LDBL_MANT_DIG == 64 || LDBL_MANT_DIG == 113) && LDBL_MAX_EXP == 16384
+long double scalbnl(long double x, int n)
+{
+	union ldshape u;
+
+	if (n > 16383) {
+		x *= 0x1p16383L;
+		n -= 16383;
+		if (n > 16383) {
+			x *= 0x1p16383L;
+			n -= 16383;
+			if (n > 16383)
+				n = 16383;
+		}
+	} else if (n < -16382) {
+		x *= 0x1p-16382L * 0x1p113L;
+		n += 16382 - 113;
+		if (n < -16382) {
+			x *= 0x1p-16382L * 0x1p113L;
+			n += 16382 - 113;
+			if (n < -16382)
+				n = -16382;
+		}
+	}
+	u.f = 1.0;
+	u.i.se = 0x3fff + n;
+	return x * u.f;
+}
+#endif
libc/musl/src/math/signgam.c
@@ -0,0 +1,6 @@
+#include <math.h>
+#include "libm.h"
+
+int __signgam = 0;
+
+weak_alias(__signgam, signgam);
libc/musl/src/math/significand.c
@@ -0,0 +1,7 @@
+#define _GNU_SOURCE
+#include <math.h>
+
+double significand(double x)
+{
+	return scalbn(x, -ilogb(x));
+}
libc/musl/src/math/significandf.c
@@ -0,0 +1,7 @@
+#define _GNU_SOURCE
+#include <math.h>
+
+float significandf(float x)
+{
+	return scalbnf(x, -ilogbf(x));
+}
libc/musl/src/math/sin.c
@@ -0,0 +1,78 @@
+/* origin: FreeBSD /usr/src/lib/msun/src/s_sin.c */
+/*
+ * ====================================================
+ * 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.
+ * ====================================================
+ */
+/* sin(x)
+ * Return sine function of x.
+ *
+ * kernel function:
+ *      __sin            ... sine function on [-pi/4,pi/4]
+ *      __cos            ... cose function on [-pi/4,pi/4]
+ *      __rem_pio2       ... 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 "libm.h"
+
+double sin(double x)
+{
+	double y[2];
+	uint32_t ix;
+	unsigned n;
+
+	/* High word of x. */
+	GET_HIGH_WORD(ix, x);
+	ix &= 0x7fffffff;
+
+	/* |x| ~< pi/4 */
+	if (ix <= 0x3fe921fb) {
+		if (ix < 0x3e500000) {  /* |x| < 2**-26 */
+			/* raise inexact if x != 0 and underflow if subnormal*/
+			FORCE_EVAL(ix < 0x00100000 ? x/0x1p120f : x+0x1p120f);
+			return x;
+		}
+		return __sin(x, 0.0, 0);
+	}
+
+	/* sin(Inf or NaN) is NaN */
+	if (ix >= 0x7ff00000)
+		return x - x;
+
+	/* argument reduction needed */
+	n = __rem_pio2(x, y);
+	switch (n&3) {
+	case 0: return  __sin(y[0], y[1], 1);
+	case 1: return  __cos(y[0], y[1]);
+	case 2: return -__sin(y[0], y[1], 1);
+	default:
+		return -__cos(y[0], y[1]);
+	}
+}
libc/musl/src/math/sincos.c
@@ -0,0 +1,69 @@
+/* origin: FreeBSD /usr/src/lib/msun/src/s_sin.c */
+/*
+ * ====================================================
+ * 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.
+ * ====================================================
+ */
+
+#define _GNU_SOURCE
+#include "libm.h"
+
+void sincos(double x, double *sin, double *cos)
+{
+	double y[2], s, c;
+	uint32_t ix;
+	unsigned n;
+
+	GET_HIGH_WORD(ix, x);
+	ix &= 0x7fffffff;
+
+	/* |x| ~< pi/4 */
+	if (ix <= 0x3fe921fb) {
+		/* if |x| < 2**-27 * sqrt(2) */
+		if (ix < 0x3e46a09e) {
+			/* raise inexact if x!=0 and underflow if subnormal */
+			FORCE_EVAL(ix < 0x00100000 ? x/0x1p120f : x+0x1p120f);
+			*sin = x;
+			*cos = 1.0;
+			return;
+		}
+		*sin = __sin(x, 0.0, 0);
+		*cos = __cos(x, 0.0);
+		return;
+	}
+
+	/* sincos(Inf or NaN) is NaN */
+	if (ix >= 0x7ff00000) {
+		*sin = *cos = x - x;
+		return;
+	}
+
+	/* argument reduction needed */
+	n = __rem_pio2(x, y);
+	s = __sin(y[0], y[1], 1);
+	c = __cos(y[0], y[1]);
+	switch (n&3) {
+	case 0:
+		*sin = s;
+		*cos = c;
+		break;
+	case 1:
+		*sin = c;
+		*cos = -s;
+		break;
+	case 2:
+		*sin = -s;
+		*cos = -c;
+		break;
+	case 3:
+	default:
+		*sin = -c;
+		*cos = s;
+		break;
+	}
+}
libc/musl/src/math/sincosf.c
@@ -0,0 +1,117 @@
+/* origin: FreeBSD /usr/src/lib/msun/src/s_sinf.c */
+/*
+ * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.
+ * Optimized by Bruce D. Evans.
+ */
+/*
+ * ====================================================
+ * 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.
+ * ====================================================
+ */
+
+#define _GNU_SOURCE
+#include "libm.h"
+
+/* Small multiples of pi/2 rounded to double precision. */
+static const double
+s1pio2 = 1*M_PI_2, /* 0x3FF921FB, 0x54442D18 */
+s2pio2 = 2*M_PI_2, /* 0x400921FB, 0x54442D18 */
+s3pio2 = 3*M_PI_2, /* 0x4012D97C, 0x7F3321D2 */
+s4pio2 = 4*M_PI_2; /* 0x401921FB, 0x54442D18 */
+
+void sincosf(float x, float *sin, float *cos)
+{
+	double y;
+	float_t s, c;
+	uint32_t ix;
+	unsigned n, sign;
+
+	GET_FLOAT_WORD(ix, x);
+	sign = ix >> 31;
+	ix &= 0x7fffffff;
+
+	/* |x| ~<= pi/4 */
+	if (ix <= 0x3f490fda) {
+		/* |x| < 2**-12 */
+		if (ix < 0x39800000) {
+			/* raise inexact if x!=0 and underflow if subnormal */
+			FORCE_EVAL(ix < 0x00100000 ? x/0x1p120f : x+0x1p120f);
+			*sin = x;
+			*cos = 1.0f;
+			return;
+		}
+		*sin = __sindf(x);
+		*cos = __cosdf(x);
+		return;
+	}
+
+	/* |x| ~<= 5*pi/4 */
+	if (ix <= 0x407b53d1) {
+		if (ix <= 0x4016cbe3) {  /* |x| ~<= 3pi/4 */
+			if (sign) {
+				*sin = -__cosdf(x + s1pio2);
+				*cos = __sindf(x + s1pio2);
+			} else {
+				*sin = __cosdf(s1pio2 - x);
+				*cos = __sindf(s1pio2 - x);
+			}
+			return;
+		}
+		/* -sin(x+c) is not correct if x+c could be 0: -0 vs +0 */
+		*sin = -__sindf(sign ? x + s2pio2 : x - s2pio2);
+		*cos = -__cosdf(sign ? x + s2pio2 : x - s2pio2);
+		return;
+	}
+
+	/* |x| ~<= 9*pi/4 */
+	if (ix <= 0x40e231d5) {
+		if (ix <= 0x40afeddf) {  /* |x| ~<= 7*pi/4 */
+			if (sign) {
+				*sin = __cosdf(x + s3pio2);
+				*cos = -__sindf(x + s3pio2);
+			} else {
+				*sin = -__cosdf(x - s3pio2);
+				*cos = __sindf(x - s3pio2);
+			}
+			return;
+		}
+		*sin = __sindf(sign ? x + s4pio2 : x - s4pio2);
+		*cos = __cosdf(sign ? x + s4pio2 : x - s4pio2);
+		return;
+	}
+
+	/* sin(Inf or NaN) is NaN */
+	if (ix >= 0x7f800000) {
+		*sin = *cos = x - x;
+		return;
+	}
+
+	/* general argument reduction needed */
+	n = __rem_pio2f(x, &y);
+	s = __sindf(y);
+	c = __cosdf(y);
+	switch (n&3) {
+	case 0:
+		*sin = s;
+		*cos = c;
+		break;
+	case 1:
+		*sin = c;
+		*cos = -s;
+		break;
+	case 2:
+		*sin = -s;
+		*cos = -c;
+		break;
+	case 3:
+	default:
+		*sin = -c;
+		*cos = s;
+		break;
+	}
+}
libc/musl/src/math/sincosl.c
@@ -0,0 +1,60 @@
+#define _GNU_SOURCE
+#include "libm.h"
+
+#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024
+void sincosl(long double x, long double *sin, long double *cos)
+{
+	double sind, cosd;
+	sincos(x, &sind, &cosd);
+	*sin = sind;
+	*cos = cosd;
+}
+#elif (LDBL_MANT_DIG == 64 || LDBL_MANT_DIG == 113) && LDBL_MAX_EXP == 16384
+void sincosl(long double x, long double *sin, long double *cos)
+{
+	union ldshape u = {x};
+	unsigned n;
+	long double y[2], s, c;
+
+	u.i.se &= 0x7fff;
+	if (u.i.se == 0x7fff) {
+		*sin = *cos = x - x;
+		return;
+	}
+	if (u.f < M_PI_4) {
+		if (u.i.se < 0x3fff - LDBL_MANT_DIG) {
+			/* raise underflow if subnormal */
+			if (u.i.se == 0) FORCE_EVAL(x*0x1p-120f);
+			*sin = x;
+			/* raise inexact if x!=0 */
+			*cos = 1.0 + x;
+			return;
+		}
+		*sin = __sinl(x, 0, 0);
+		*cos = __cosl(x, 0);
+		return;
+	}
+	n = __rem_pio2l(x, y);
+	s = __sinl(y[0], y[1], 1);
+	c = __cosl(y[0], y[1]);
+	switch (n & 3) {
+	case 0:
+		*sin = s;
+		*cos = c;
+		break;
+	case 1:
+		*sin = c;
+		*cos = -s;
+		break;
+	case 2:
+		*sin = -s;
+		*cos = -c;
+		break;
+	case 3:
+	default:
+		*sin = -c;
+		*cos = s;
+		break;
+	}
+}
+#endif
libc/musl/src/math/sinf.c
@@ -0,0 +1,76 @@
+/* origin: FreeBSD /usr/src/lib/msun/src/s_sinf.c */
+/*
+ * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.
+ * Optimized by Bruce D. Evans.
+ */
+/*
+ * ====================================================
+ * 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 "libm.h"
+
+/* Small multiples of pi/2 rounded to double precision. */
+static const double
+s1pio2 = 1*M_PI_2, /* 0x3FF921FB, 0x54442D18 */
+s2pio2 = 2*M_PI_2, /* 0x400921FB, 0x54442D18 */
+s3pio2 = 3*M_PI_2, /* 0x4012D97C, 0x7F3321D2 */
+s4pio2 = 4*M_PI_2; /* 0x401921FB, 0x54442D18 */
+
+float sinf(float x)
+{
+	double y;
+	uint32_t ix;
+	int n, sign;
+
+	GET_FLOAT_WORD(ix, x);
+	sign = ix >> 31;
+	ix &= 0x7fffffff;
+
+	if (ix <= 0x3f490fda) {  /* |x| ~<= pi/4 */
+		if (ix < 0x39800000) {  /* |x| < 2**-12 */
+			/* raise inexact if x!=0 and underflow if subnormal */
+			FORCE_EVAL(ix < 0x00800000 ? x/0x1p120f : x+0x1p120f);
+			return x;
+		}
+		return __sindf(x);
+	}
+	if (ix <= 0x407b53d1) {  /* |x| ~<= 5*pi/4 */
+		if (ix <= 0x4016cbe3) {  /* |x| ~<= 3pi/4 */
+			if (sign)
+				return -__cosdf(x + s1pio2);
+			else
+				return __cosdf(x - s1pio2);
+		}
+		return __sindf(sign ? -(x + s2pio2) : -(x - s2pio2));
+	}
+	if (ix <= 0x40e231d5) {  /* |x| ~<= 9*pi/4 */
+		if (ix <= 0x40afeddf) {  /* |x| ~<= 7*pi/4 */
+			if (sign)
+				return __cosdf(x + s3pio2);
+			else
+				return -__cosdf(x - s3pio2);
+		}
+		return __sindf(sign ? x + s4pio2 : x - s4pio2);
+	}
+
+	/* sin(Inf or NaN) is NaN */
+	if (ix >= 0x7f800000)
+		return x - x;
+
+	/* general argument reduction needed */
+	n = __rem_pio2f(x, &y);
+	switch (n&3) {
+	case 0: return  __sindf(y);
+	case 1: return  __cosdf(y);
+	case 2: return  __sindf(-y);
+	default:
+		return -__cosdf(y);
+	}
+}
libc/musl/src/math/sinh.c
@@ -0,0 +1,39 @@
+#include "libm.h"
+
+/* sinh(x) = (exp(x) - 1/exp(x))/2
+ *         = (exp(x)-1 + (exp(x)-1)/exp(x))/2
+ *         = x + x^3/6 + o(x^5)
+ */
+double sinh(double x)
+{
+	union {double f; uint64_t i;} u = {.f = x};
+	uint32_t w;
+	double t, h, absx;
+
+	h = 0.5;
+	if (u.i >> 63)
+		h = -h;
+	/* |x| */
+	u.i &= (uint64_t)-1/2;
+	absx = u.f;
+	w = u.i >> 32;
+
+	/* |x| < log(DBL_MAX) */
+	if (w < 0x40862e42) {
+		t = expm1(absx);
+		if (w < 0x3ff00000) {
+			if (w < 0x3ff00000 - (26<<20))
+				/* note: inexact and underflow are raised by expm1 */
+				/* note: this branch avoids spurious underflow */
+				return x;
+			return h*(2*t - t*t/(t+1));
+		}
+		/* note: |x|>log(0x1p26)+eps could be just h*exp(x) */
+		return h*(t + t/(t+1));
+	}
+
+	/* |x| > log(DBL_MAX) or nan */
+	/* note: the result is stored to handle overflow */
+	t = 2*h*__expo2(absx);
+	return t;
+}
libc/musl/src/math/sinhf.c
@@ -0,0 +1,31 @@
+#include "libm.h"
+
+float sinhf(float x)
+{
+	union {float f; uint32_t i;} u = {.f = x};
+	uint32_t w;
+	float t, h, absx;
+
+	h = 0.5;
+	if (u.i >> 31)
+		h = -h;
+	/* |x| */
+	u.i &= 0x7fffffff;
+	absx = u.f;
+	w = u.i;
+
+	/* |x| < log(FLT_MAX) */
+	if (w < 0x42b17217) {
+		t = expm1f(absx);
+		if (w < 0x3f800000) {
+			if (w < 0x3f800000 - (12<<23))
+				return x;
+			return h*(2*t - t*t/(t+1));
+		}
+		return h*(t + t/(t+1));
+	}
+
+	/* |x| > logf(FLT_MAX) or nan */
+	t = 2*h*__expo2f(absx);
+	return t;
+}
libc/musl/src/math/sinhl.c
@@ -0,0 +1,43 @@
+#include "libm.h"
+
+#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024
+long double sinhl(long double x)
+{
+	return sinh(x);
+}
+#elif LDBL_MANT_DIG == 64 && LDBL_MAX_EXP == 16384
+long double sinhl(long double x)
+{
+	union ldshape u = {x};
+	unsigned ex = u.i.se & 0x7fff;
+	long double h, t, absx;
+
+	h = 0.5;
+	if (u.i.se & 0x8000)
+		h = -h;
+	/* |x| */
+	u.i.se = ex;
+	absx = u.f;
+
+	/* |x| < log(LDBL_MAX) */
+	if (ex < 0x3fff+13 || (ex == 0x3fff+13 && u.i.m>>32 < 0xb17217f7)) {
+		t = expm1l(absx);
+		if (ex < 0x3fff) {
+			if (ex < 0x3fff-32)
+				return x;
+			return h*(2*t - t*t/(1+t));
+		}
+		return h*(t + t/(t+1));
+	}
+
+	/* |x| > log(LDBL_MAX) or nan */
+	t = expl(0.5*absx);
+	return h*t*t;
+}
+#elif LDBL_MANT_DIG == 113 && LDBL_MAX_EXP == 16384
+// TODO: broken implementation to make things compile
+long double sinhl(long double x)
+{
+	return sinh(x);
+}
+#endif
libc/musl/src/math/sinl.c
@@ -0,0 +1,41 @@
+#include "libm.h"
+
+#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024
+long double sinl(long double x)
+{
+	return sin(x);
+}
+#elif (LDBL_MANT_DIG == 64 || LDBL_MANT_DIG == 113) && LDBL_MAX_EXP == 16384
+long double sinl(long double x)
+{
+	union ldshape u = {x};
+	unsigned n;
+	long double y[2], hi, lo;
+
+	u.i.se &= 0x7fff;
+	if (u.i.se == 0x7fff)
+		return x - x;
+	if (u.f < M_PI_4) {
+		if (u.i.se < 0x3fff - LDBL_MANT_DIG/2) {
+			/* raise inexact if x!=0 and underflow if subnormal */
+			FORCE_EVAL(u.i.se == 0 ? x*0x1p-120f : x+0x1p120f);
+			return x;
+		}
+		return __sinl(x, 0.0, 0);
+	}
+	n = __rem_pio2l(x, y);
+	hi = y[0];
+	lo = y[1];
+	switch (n & 3) {
+	case 0:
+		return __sinl(hi, lo, 1);
+	case 1:
+		return __cosl(hi, lo);
+	case 2:
+		return -__sinl(hi, lo, 1);
+	case 3:
+	default:
+		return -__cosl(hi, lo);
+	}
+}
+#endif
libc/musl/src/math/sqrt.c
@@ -0,0 +1,185 @@
+/* origin: FreeBSD /usr/src/lib/msun/src/e_sqrt.c */
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunSoft, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+/* sqrt(x)
+ * Return correctly rounded sqrt.
+ *           ------------------------------------------
+ *           |  Use the hardware sqrt if you have one |
+ *           ------------------------------------------
+ * Method:
+ *   Bit by bit method using integer arithmetic. (Slow, but portable)
+ *   1. Normalization
+ *      Scale x to y in [1,4) with even powers of 2:
+ *      find an integer k such that  1 <= (y=x*2^(2k)) < 4, then
+ *              sqrt(x) = 2^k * sqrt(y)
+ *   2. Bit by bit computation
+ *      Let q  = sqrt(y) truncated to i bit after binary point (q = 1),
+ *           i                                                   0
+ *                                     i+1         2
+ *          s  = 2*q , and      y  =  2   * ( y - q  ).         (1)
+ *           i      i            i                 i
+ *
+ *      To compute q    from q , one checks whether
+ *                  i+1       i
+ *
+ *                            -(i+1) 2
+ *                      (q + 2      ) <= y.                     (2)
+ *                        i
+ *                                                            -(i+1)
+ *      If (2) is false, then q   = q ; otherwise q   = q  + 2      .
+ *                             i+1   i             i+1   i
+ *
+ *      With some algebric manipulation, it is not difficult to see
+ *      that (2) is equivalent to
+ *                             -(i+1)
+ *                      s  +  2       <= y                      (3)
+ *                       i                i
+ *
+ *      The advantage of (3) is that s  and y  can be computed by
+ *                                    i      i
+ *      the following recurrence formula:
+ *          if (3) is false
+ *
+ *          s     =  s  ,       y    = y   ;                    (4)
+ *           i+1      i          i+1    i
+ *
+ *          otherwise,
+ *                         -i                     -(i+1)
+ *          s     =  s  + 2  ,  y    = y  -  s  - 2             (5)
+ *           i+1      i          i+1    i     i
+ *
+ *      One may easily use induction to prove (4) and (5).
+ *      Note. Since the left hand side of (3) contain only i+2 bits,
+ *            it does not necessary to do a full (53-bit) comparison
+ *            in (3).
+ *   3. Final rounding
+ *      After generating the 53 bits result, we compute one more bit.
+ *      Together with the remainder, we can decide whether the
+ *      result is exact, bigger than 1/2ulp, or less than 1/2ulp
+ *      (it will never equal to 1/2ulp).
+ *      The rounding mode can be detected by checking whether
+ *      huge + tiny is equal to huge, and whether huge - tiny is
+ *      equal to huge for some floating point number "huge" and "tiny".
+ *
+ * Special cases:
+ *      sqrt(+-0) = +-0         ... exact
+ *      sqrt(inf) = inf
+ *      sqrt(-ve) = NaN         ... with invalid signal
+ *      sqrt(NaN) = NaN         ... with invalid signal for signaling NaN
+ */
+
+#include "libm.h"
+
+static const double tiny = 1.0e-300;
+
+double sqrt(double x)
+{
+	double z;
+	int32_t sign = (int)0x80000000;
+	int32_t ix0,s0,q,m,t,i;
+	uint32_t r,t1,s1,ix1,q1;
+
+	EXTRACT_WORDS(ix0, ix1, x);
+
+	/* take care of Inf and NaN */
+	if ((ix0&0x7ff00000) == 0x7ff00000) {
+		return x*x + x;  /* sqrt(NaN)=NaN, sqrt(+inf)=+inf, sqrt(-inf)=sNaN */
+	}
+	/* take care of zero */
+	if (ix0 <= 0) {
+		if (((ix0&~sign)|ix1) == 0)
+			return x;  /* sqrt(+-0) = +-0 */
+		if (ix0 < 0)
+			return (x-x)/(x-x);  /* sqrt(-ve) = sNaN */
+	}
+	/* normalize x */
+	m = ix0>>20;
+	if (m == 0) {  /* subnormal x */
+		while (ix0 == 0) {
+			m -= 21;
+			ix0 |= (ix1>>11);
+			ix1 <<= 21;
+		}
+		for (i=0; (ix0&0x00100000) == 0; i++)
+			ix0<<=1;
+		m -= i - 1;
+		ix0 |= ix1>>(32-i);
+		ix1 <<= i;
+	}
+	m -= 1023;    /* unbias exponent */
+	ix0 = (ix0&0x000fffff)|0x00100000;
+	if (m & 1) {  /* odd m, double x to make it even */
+		ix0 += ix0 + ((ix1&sign)>>31);
+		ix1 += ix1;
+	}
+	m >>= 1;      /* m = [m/2] */
+
+	/* generate sqrt(x) bit by bit */
+	ix0 += ix0 + ((ix1&sign)>>31);
+	ix1 += ix1;
+	q = q1 = s0 = s1 = 0;  /* [q,q1] = sqrt(x) */
+	r = 0x00200000;        /* r = moving bit from right to left */
+
+	while (r != 0) {
+		t = s0 + r;
+		if (t <= ix0) {
+			s0   = t + r;
+			ix0 -= t;
+			q   += r;
+		}
+		ix0 += ix0 + ((ix1&sign)>>31);
+		ix1 += ix1;
+		r >>= 1;
+	}
+
+	r = sign;
+	while (r != 0) {
+		t1 = s1 + r;
+		t  = s0;
+		if (t < ix0 || (t == ix0 && t1 <= ix1)) {
+			s1 = t1 + r;
+			if ((t1&sign) == sign && (s1&sign) == 0)
+				s0++;
+			ix0 -= t;
+			if (ix1 < t1)
+				ix0--;
+			ix1 -= t1;
+			q1 += r;
+		}
+		ix0 += ix0 + ((ix1&sign)>>31);
+		ix1 += ix1;
+		r >>= 1;
+	}
+
+	/* use floating add to find out rounding direction */
+	if ((ix0|ix1) != 0) {
+		z = 1.0 - tiny; /* raise inexact flag */
+		if (z >= 1.0) {
+			z = 1.0 + tiny;
+			if (q1 == (uint32_t)0xffffffff) {
+				q1 = 0;
+				q++;
+			} else if (z > 1.0) {
+				if (q1 == (uint32_t)0xfffffffe)
+					q++;
+				q1 += 2;
+			} else
+				q1 += q1 & 1;
+		}
+	}
+	ix0 = (q>>1) + 0x3fe00000;
+	ix1 = q1>>1;
+	if (q&1)
+		ix1 |= sign;
+	ix0 += m << 20;
+	INSERT_WORDS(z, ix0, ix1);
+	return z;
+}
libc/musl/src/math/sqrtf.c
@@ -0,0 +1,84 @@
+/* origin: FreeBSD /usr/src/lib/msun/src/e_sqrtf.c */
+/*
+ * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.
+ */
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunPro, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+
+#include "libm.h"
+
+static const float tiny = 1.0e-30;
+
+float sqrtf(float x)
+{
+	float z;
+	int32_t sign = (int)0x80000000;
+	int32_t ix,s,q,m,t,i;
+	uint32_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 */
+		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 = 1.0f - tiny; /* raise inexact flag */
+		if (z >= 1.0f) {
+			z = 1.0f + tiny;
+			if (z > 1.0f)
+				q += 2;
+			else
+				q += q & 1;
+		}
+	}
+	ix = (q>>1) + 0x3f000000;
+	ix += m << 23;
+	SET_FLOAT_WORD(z, ix);
+	return z;
+}
libc/musl/src/math/sqrtl.c
@@ -0,0 +1,7 @@
+#include <math.h>
+
+long double sqrtl(long double x)
+{
+	/* FIXME: implement in C, this is for LDBL_MANT_DIG == 64 only */
+	return sqrt(x);
+}
libc/musl/src/math/tan.c
@@ -0,0 +1,70 @@
+/* origin: FreeBSD /usr/src/lib/msun/src/s_tan.c */
+/*
+ * ====================================================
+ * 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.
+ * ====================================================
+ */
+/* tan(x)
+ * Return tangent function of x.
+ *
+ * kernel function:
+ *      __tan           ... tangent function on [-pi/4,pi/4]
+ *      __rem_pio2      ... 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 "libm.h"
+
+double tan(double x)
+{
+	double y[2];
+	uint32_t ix;
+	unsigned n;
+
+	GET_HIGH_WORD(ix, x);
+	ix &= 0x7fffffff;
+
+	/* |x| ~< pi/4 */
+	if (ix <= 0x3fe921fb) {
+		if (ix < 0x3e400000) { /* |x| < 2**-27 */
+			/* raise inexact if x!=0 and underflow if subnormal */
+			FORCE_EVAL(ix < 0x00100000 ? x/0x1p120f : x+0x1p120f);
+			return x;
+		}
+		return __tan(x, 0.0, 0);
+	}
+
+	/* tan(Inf or NaN) is NaN */
+	if (ix >= 0x7ff00000)
+		return x - x;
+
+	/* argument reduction */
+	n = __rem_pio2(x, y);
+	return __tan(y[0], y[1], n&1);
+}
libc/musl/src/math/tanf.c
@@ -0,0 +1,64 @@
+/* origin: FreeBSD /usr/src/lib/msun/src/s_tanf.c */
+/*
+ * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.
+ * Optimized by Bruce D. Evans.
+ */
+/*
+ * ====================================================
+ * 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 "libm.h"
+
+/* Small multiples of pi/2 rounded to double precision. */
+static const double
+t1pio2 = 1*M_PI_2, /* 0x3FF921FB, 0x54442D18 */
+t2pio2 = 2*M_PI_2, /* 0x400921FB, 0x54442D18 */
+t3pio2 = 3*M_PI_2, /* 0x4012D97C, 0x7F3321D2 */
+t4pio2 = 4*M_PI_2; /* 0x401921FB, 0x54442D18 */
+
+float tanf(float x)
+{
+	double y;
+	uint32_t ix;
+	unsigned n, sign;
+
+	GET_FLOAT_WORD(ix, x);
+	sign = ix >> 31;
+	ix &= 0x7fffffff;
+
+	if (ix <= 0x3f490fda) {  /* |x| ~<= pi/4 */
+		if (ix < 0x39800000) {  /* |x| < 2**-12 */
+			/* raise inexact if x!=0 and underflow if subnormal */
+			FORCE_EVAL(ix < 0x00800000 ? x/0x1p120f : x+0x1p120f);
+			return x;
+		}
+		return __tandf(x, 0);
+	}
+	if (ix <= 0x407b53d1) {  /* |x| ~<= 5*pi/4 */
+		if (ix <= 0x4016cbe3)  /* |x| ~<= 3pi/4 */
+			return __tandf((sign ? x+t1pio2 : x-t1pio2), 1);
+		else
+			return __tandf((sign ? x+t2pio2 : x-t2pio2), 0);
+	}
+	if (ix <= 0x40e231d5) {  /* |x| ~<= 9*pi/4 */
+		if (ix <= 0x40afeddf)  /* |x| ~<= 7*pi/4 */
+			return __tandf((sign ? x+t3pio2 : x-t3pio2), 1);
+		else
+			return __tandf((sign ? x+t4pio2 : x-t4pio2), 0);
+	}
+
+	/* tan(Inf or NaN) is NaN */
+	if (ix >= 0x7f800000)
+		return x - x;
+
+	/* argument reduction */
+	n = __rem_pio2f(x, &y);
+	return __tandf(y, n&1);
+}
libc/musl/src/math/tanh.c
@@ -0,0 +1,45 @@
+#include "libm.h"
+
+/* tanh(x) = (exp(x) - exp(-x))/(exp(x) + exp(-x))
+ *         = (exp(2*x) - 1)/(exp(2*x) - 1 + 2)
+ *         = (1 - exp(-2*x))/(exp(-2*x) - 1 + 2)
+ */
+double tanh(double x)
+{
+	union {double f; uint64_t i;} u = {.f = x};
+	uint32_t w;
+	int sign;
+	double_t t;
+
+	/* x = |x| */
+	sign = u.i >> 63;
+	u.i &= (uint64_t)-1/2;
+	x = u.f;
+	w = u.i >> 32;
+
+	if (w > 0x3fe193ea) {
+		/* |x| > log(3)/2 ~= 0.5493 or nan */
+		if (w > 0x40340000) {
+			/* |x| > 20 or nan */
+			/* note: this branch avoids raising overflow */
+			t = 1 - 0/x;
+		} else {
+			t = expm1(2*x);
+			t = 1 - 2/(t+2);
+		}
+	} else if (w > 0x3fd058ae) {
+		/* |x| > log(5/3)/2 ~= 0.2554 */
+		t = expm1(2*x);
+		t = t/(t+2);
+	} else if (w >= 0x00100000) {
+		/* |x| >= 0x1p-1022, up to 2ulp error in [0.1,0.2554] */
+		t = expm1(-2*x);
+		t = -t/(t+2);
+	} else {
+		/* |x| is subnormal */
+		/* note: the branch above would not raise underflow in [0x1p-1023,0x1p-1022) */
+		FORCE_EVAL((float)x);
+		t = x;
+	}
+	return sign ? -t : t;
+}
libc/musl/src/math/tanhf.c
@@ -0,0 +1,39 @@
+#include "libm.h"
+
+float tanhf(float x)
+{
+	union {float f; uint32_t i;} u = {.f = x};
+	uint32_t w;
+	int sign;
+	float t;
+
+	/* x = |x| */
+	sign = u.i >> 31;
+	u.i &= 0x7fffffff;
+	x = u.f;
+	w = u.i;
+
+	if (w > 0x3f0c9f54) {
+		/* |x| > log(3)/2 ~= 0.5493 or nan */
+		if (w > 0x41200000) {
+			/* |x| > 10 */
+			t = 1 + 0/x;
+		} else {
+			t = expm1f(2*x);
+			t = 1 - 2/(t+2);
+		}
+	} else if (w > 0x3e82c578) {
+		/* |x| > log(5/3)/2 ~= 0.2554 */
+		t = expm1f(2*x);
+		t = t/(t+2);
+	} else if (w >= 0x00800000) {
+		/* |x| >= 0x1p-126 */
+		t = expm1f(-2*x);
+		t = -t/(t+2);
+	} else {
+		/* |x| is subnormal */
+		FORCE_EVAL(x*x);
+		t = x;
+	}
+	return sign ? -t : t;
+}
libc/musl/src/math/tanhl.c
@@ -0,0 +1,48 @@
+#include "libm.h"
+
+#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024
+long double tanhl(long double x)
+{
+	return tanh(x);
+}
+#elif LDBL_MANT_DIG == 64 && LDBL_MAX_EXP == 16384
+long double tanhl(long double x)
+{
+	union ldshape u = {x};
+	unsigned ex = u.i.se & 0x7fff;
+	unsigned sign = u.i.se & 0x8000;
+	uint32_t w;
+	long double t;
+
+	/* x = |x| */
+	u.i.se = ex;
+	x = u.f;
+	w = u.i.m >> 32;
+
+	if (ex > 0x3ffe || (ex == 0x3ffe && w > 0x8c9f53d5)) {
+		/* |x| > log(3)/2 ~= 0.5493 or nan */
+		if (ex >= 0x3fff+5) {
+			/* |x| >= 32 */
+			t = 1 + 0/(x + 0x1p-120f);
+		} else {
+			t = expm1l(2*x);
+			t = 1 - 2/(t+2);
+		}
+	} else if (ex > 0x3ffd || (ex == 0x3ffd && w > 0x82c577d4)) {
+		/* |x| > log(5/3)/2 ~= 0.2554 */
+		t = expm1l(2*x);
+		t = t/(t+2);
+	} else {
+		/* |x| is small */
+		t = expm1l(-2*x);
+		t = -t/(t+2);
+	}
+	return sign ? -t : t;
+}
+#elif LDBL_MANT_DIG == 113 && LDBL_MAX_EXP == 16384
+// TODO: broken implementation to make things compile
+long double tanhl(long double x)
+{
+	return tanh(x);
+}
+#endif
libc/musl/src/math/tanl.c
@@ -0,0 +1,29 @@
+#include "libm.h"
+
+#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024
+long double tanl(long double x)
+{
+	return tan(x);
+}
+#elif (LDBL_MANT_DIG == 64 || LDBL_MANT_DIG == 113) && LDBL_MAX_EXP == 16384
+long double tanl(long double x)
+{
+	union ldshape u = {x};
+	long double y[2];
+	unsigned n;
+
+	u.i.se &= 0x7fff;
+	if (u.i.se == 0x7fff)
+		return x - x;
+	if (u.f < M_PI_4) {
+		if (u.i.se < 0x3fff - LDBL_MANT_DIG/2) {
+			/* raise inexact if x!=0 and underflow if subnormal */
+			FORCE_EVAL(u.i.se == 0 ? x*0x1p-120f : x+0x1p120f);
+			return x;
+		}
+		return __tanl(x, 0, 0);
+	}
+	n = __rem_pio2l(x, y);
+	return __tanl(y[0], y[1], n&1);
+}
+#endif
libc/musl/src/math/tgamma.c
@@ -0,0 +1,222 @@
+/*
+"A Precision Approximation of the Gamma Function" - Cornelius Lanczos (1964)
+"Lanczos Implementation of the Gamma Function" - Paul Godfrey (2001)
+"An Analysis of the Lanczos Gamma Approximation" - Glendon Ralph Pugh (2004)
+
+approximation method:
+
+                        (x - 0.5)         S(x)
+Gamma(x) = (x + g - 0.5)         *  ----------------
+                                    exp(x + g - 0.5)
+
+with
+                 a1      a2      a3            aN
+S(x) ~= [ a0 + ----- + ----- + ----- + ... + ----- ]
+               x + 1   x + 2   x + 3         x + N
+
+with a0, a1, a2, a3,.. aN constants which depend on g.
+
+for x < 0 the following reflection formula is used:
+
+Gamma(x)*Gamma(-x) = -pi/(x sin(pi x))
+
+most ideas and constants are from boost and python
+*/
+#include "libm.h"
+
+static const double pi = 3.141592653589793238462643383279502884;
+
+/* sin(pi x) with x > 0x1p-100, if sin(pi*x)==0 the sign is arbitrary */
+static double sinpi(double x)
+{
+	int n;
+
+	/* argument reduction: x = |x| mod 2 */
+	/* spurious inexact when x is odd int */
+	x = x * 0.5;
+	x = 2 * (x - floor(x));
+
+	/* reduce x into [-.25,.25] */
+	n = 4 * x;
+	n = (n+1)/2;
+	x -= n * 0.5;
+
+	x *= pi;
+	switch (n) {
+	default: /* case 4 */
+	case 0:
+		return __sin(x, 0, 0);
+	case 1:
+		return __cos(x, 0);
+	case 2:
+		return __sin(-x, 0, 0);
+	case 3:
+		return -__cos(x, 0);
+	}
+}
+
+#define N 12
+//static const double g = 6.024680040776729583740234375;
+static const double gmhalf = 5.524680040776729583740234375;
+static const double Snum[N+1] = {
+	23531376880.410759688572007674451636754734846804940,
+	42919803642.649098768957899047001988850926355848959,
+	35711959237.355668049440185451547166705960488635843,
+	17921034426.037209699919755754458931112671403265390,
+	6039542586.3520280050642916443072979210699388420708,
+	1439720407.3117216736632230727949123939715485786772,
+	248874557.86205415651146038641322942321632125127801,
+	31426415.585400194380614231628318205362874684987640,
+	2876370.6289353724412254090516208496135991145378768,
+	186056.26539522349504029498971604569928220784236328,
+	8071.6720023658162106380029022722506138218516325024,
+	210.82427775157934587250973392071336271166969580291,
+	2.5066282746310002701649081771338373386264310793408,
+};
+static const double Sden[N+1] = {
+	0, 39916800, 120543840, 150917976, 105258076, 45995730, 13339535,
+	2637558, 357423, 32670, 1925, 66, 1,
+};
+/* n! for small integer n */
+static const double fact[] = {
+	1, 1, 2, 6, 24, 120, 720, 5040.0, 40320.0, 362880.0, 3628800.0, 39916800.0,
+	479001600.0, 6227020800.0, 87178291200.0, 1307674368000.0, 20922789888000.0,
+	355687428096000.0, 6402373705728000.0, 121645100408832000.0,
+	2432902008176640000.0, 51090942171709440000.0, 1124000727777607680000.0,
+};
+
+/* S(x) rational function for positive x */
+static double S(double x)
+{
+	double_t num = 0, den = 0;
+	int i;
+
+	/* to avoid overflow handle large x differently */
+	if (x < 8)
+		for (i = N; i >= 0; i--) {
+			num = num * x + Snum[i];
+			den = den * x + Sden[i];
+		}
+	else
+		for (i = 0; i <= N; i++) {
+			num = num / x + Snum[i];
+			den = den / x + Sden[i];
+		}
+	return num/den;
+}
+
+double tgamma(double x)
+{
+	union {double f; uint64_t i;} u = {x};
+	double absx, y;
+	double_t dy, z, r;
+	uint32_t ix = u.i>>32 & 0x7fffffff;
+	int sign = u.i>>63;
+
+	/* special cases */
+	if (ix >= 0x7ff00000)
+		/* tgamma(nan)=nan, tgamma(inf)=inf, tgamma(-inf)=nan with invalid */
+		return x + INFINITY;
+	if (ix < (0x3ff-54)<<20)
+		/* |x| < 2^-54: tgamma(x) ~ 1/x, +-0 raises div-by-zero */
+		return 1/x;
+
+	/* integer arguments */
+	/* raise inexact when non-integer */
+	if (x == floor(x)) {
+		if (sign)
+			return 0/0.0;
+		if (x <= sizeof fact/sizeof *fact)
+			return fact[(int)x - 1];
+	}
+
+	/* x >= 172: tgamma(x)=inf with overflow */
+	/* x =< -184: tgamma(x)=+-0 with underflow */
+	if (ix >= 0x40670000) { /* |x| >= 184 */
+		if (sign) {
+			FORCE_EVAL((float)(0x1p-126/x));
+			if (floor(x) * 0.5 == floor(x * 0.5))
+				return 0;
+			return -0.0;
+		}
+		x *= 0x1p1023;
+		return x;
+	}
+
+	absx = sign ? -x : x;
+
+	/* handle the error of x + g - 0.5 */
+	y = absx + gmhalf;
+	if (absx > gmhalf) {
+		dy = y - absx;
+		dy -= gmhalf;
+	} else {
+		dy = y - gmhalf;
+		dy -= absx;
+	}
+
+	z = absx - 0.5;
+	r = S(absx) * exp(-y);
+	if (x < 0) {
+		/* reflection formula for negative x */
+		/* sinpi(absx) is not 0, integers are already handled */
+		r = -pi / (sinpi(absx) * absx * r);
+		dy = -dy;
+		z = -z;
+	}
+	r += dy * (gmhalf+0.5) * r / y;
+	z = pow(y, 0.5*z);
+	y = r * z * z;
+	return y;
+}
+
+#if 0
+double __lgamma_r(double x, int *sign)
+{
+	double r, absx;
+
+	*sign = 1;
+
+	/* special cases */
+	if (!isfinite(x))
+		/* lgamma(nan)=nan, lgamma(+-inf)=inf */
+		return x*x;
+
+	/* integer arguments */
+	if (x == floor(x) && x <= 2) {
+		/* n <= 0: lgamma(n)=inf with divbyzero */
+		/* n == 1,2: lgamma(n)=0 */
+		if (x <= 0)
+			return 1/0.0;
+		return 0;
+	}
+
+	absx = fabs(x);
+
+	/* lgamma(x) ~ -log(|x|) for tiny |x| */
+	if (absx < 0x1p-54) {
+		*sign = 1 - 2*!!signbit(x);
+		return -log(absx);
+	}
+
+	/* use tgamma for smaller |x| */
+	if (absx < 128) {
+		x = tgamma(x);
+		*sign = 1 - 2*!!signbit(x);
+		return log(fabs(x));
+	}
+
+	/* second term (log(S)-g) could be more precise here.. */
+	/* or with stirling: (|x|-0.5)*(log(|x|)-1) + poly(1/|x|) */
+	r = (absx-0.5)*(log(absx+gmhalf)-1) + (log(S(absx)) - (gmhalf+0.5));
+	if (x < 0) {
+		/* reflection formula for negative x */
+		x = sinpi(absx);
+		*sign = 2*!!signbit(x) - 1;
+		r = log(pi/(fabs(x)*absx)) - r;
+	}
+	return r;
+}
+
+weak_alias(__lgamma_r, lgamma_r);
+#endif
libc/musl/src/math/tgammaf.c
@@ -0,0 +1,6 @@
+#include <math.h>
+
+float tgammaf(float x)
+{
+	return tgamma(x);
+}
libc/musl/src/math/tgammal.c
@@ -0,0 +1,281 @@
+/* origin: OpenBSD /usr/src/lib/libm/src/ld80/e_tgammal.c */
+/*
+ * Copyright (c) 2008 Stephen L. Moshier <steve@moshier.net>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+/*
+ *      Gamma function
+ *
+ *
+ * SYNOPSIS:
+ *
+ * long double x, y, tgammal();
+ *
+ * y = tgammal( x );
+ *
+ *
+ * DESCRIPTION:
+ *
+ * Returns gamma function of the argument.  The result is
+ * correctly signed.
+ *
+ * Arguments |x| <= 13 are reduced by recurrence and the function
+ * approximated by a rational function of degree 7/8 in the
+ * interval (2,3).  Large arguments are handled by Stirling's
+ * formula. Large negative arguments are made positive using
+ * a reflection formula.
+ *
+ *
+ * ACCURACY:
+ *
+ *                      Relative error:
+ * arithmetic   domain     # trials      peak         rms
+ *    IEEE     -40,+40      10000       3.6e-19     7.9e-20
+ *    IEEE    -1755,+1755   10000       4.8e-18     6.5e-19
+ *
+ * Accuracy for large arguments is dominated by error in powl().
+ *
+ */
+
+#include "libm.h"
+
+#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024
+long double tgammal(long double x)
+{
+	return tgamma(x);
+}
+#elif LDBL_MANT_DIG == 64 && LDBL_MAX_EXP == 16384
+/*
+tgamma(x+2) = tgamma(x+2) P(x)/Q(x)
+0 <= x <= 1
+Relative error
+n=7, d=8
+Peak error =  1.83e-20
+Relative error spread =  8.4e-23
+*/
+static const long double P[8] = {
+ 4.212760487471622013093E-5L,
+ 4.542931960608009155600E-4L,
+ 4.092666828394035500949E-3L,
+ 2.385363243461108252554E-2L,
+ 1.113062816019361559013E-1L,
+ 3.629515436640239168939E-1L,
+ 8.378004301573126728826E-1L,
+ 1.000000000000000000009E0L,
+};
+static const long double Q[9] = {
+-1.397148517476170440917E-5L,
+ 2.346584059160635244282E-4L,
+-1.237799246653152231188E-3L,
+-7.955933682494738320586E-4L,
+ 2.773706565840072979165E-2L,
+-4.633887671244534213831E-2L,
+-2.243510905670329164562E-1L,
+ 4.150160950588455434583E-1L,
+ 9.999999999999999999908E-1L,
+};
+
+/*
+static const long double P[] = {
+-3.01525602666895735709e0L,
+-3.25157411956062339893e1L,
+-2.92929976820724030353e2L,
+-1.70730828800510297666e3L,
+-7.96667499622741999770e3L,
+-2.59780216007146401957e4L,
+-5.99650230220855581642e4L,
+-7.15743521530849602425e4L
+};
+static const long double Q[] = {
+ 1.00000000000000000000e0L,
+-1.67955233807178858919e1L,
+ 8.85946791747759881659e1L,
+ 5.69440799097468430177e1L,
+-1.98526250512761318471e3L,
+ 3.31667508019495079814e3L,
+ 1.60577839621734713377e4L,
+-2.97045081369399940529e4L,
+-7.15743521530849602412e4L
+};
+*/
+#define MAXGAML 1755.455L
+/*static const long double LOGPI = 1.14472988584940017414L;*/
+
+/* Stirling's formula for the gamma function
+tgamma(x) = sqrt(2 pi) x^(x-.5) exp(-x) (1 + 1/x P(1/x))
+z(x) = x
+13 <= x <= 1024
+Relative error
+n=8, d=0
+Peak error =  9.44e-21
+Relative error spread =  8.8e-4
+*/
+static const long double STIR[9] = {
+ 7.147391378143610789273E-4L,
+-2.363848809501759061727E-5L,
+-5.950237554056330156018E-4L,
+ 6.989332260623193171870E-5L,
+ 7.840334842744753003862E-4L,
+-2.294719747873185405699E-4L,
+-2.681327161876304418288E-3L,
+ 3.472222222230075327854E-3L,
+ 8.333333333333331800504E-2L,
+};
+
+#define MAXSTIR 1024.0L
+static const long double SQTPI = 2.50662827463100050242E0L;
+
+/* 1/tgamma(x) = z P(z)
+ * z(x) = 1/x
+ * 0 < x < 0.03125
+ * Peak relative error 4.2e-23
+ */
+static const long double S[9] = {
+-1.193945051381510095614E-3L,
+ 7.220599478036909672331E-3L,
+-9.622023360406271645744E-3L,
+-4.219773360705915470089E-2L,
+ 1.665386113720805206758E-1L,
+-4.200263503403344054473E-2L,
+-6.558780715202540684668E-1L,
+ 5.772156649015328608253E-1L,
+ 1.000000000000000000000E0L,
+};
+
+/* 1/tgamma(-x) = z P(z)
+ * z(x) = 1/x
+ * 0 < x < 0.03125
+ * Peak relative error 5.16e-23
+ * Relative error spread =  2.5e-24
+ */
+static const long double SN[9] = {
+ 1.133374167243894382010E-3L,
+ 7.220837261893170325704E-3L,
+ 9.621911155035976733706E-3L,
+-4.219773343731191721664E-2L,
+-1.665386113944413519335E-1L,
+-4.200263503402112910504E-2L,
+ 6.558780715202536547116E-1L,
+ 5.772156649015328608727E-1L,
+-1.000000000000000000000E0L,
+};
+
+static const long double PIL = 3.1415926535897932384626L;
+
+/* Gamma function computed by Stirling's formula.
+ */
+static long double stirf(long double x)
+{
+	long double y, w, v;
+
+	w = 1.0/x;
+	/* For large x, use rational coefficients from the analytical expansion.  */
+	if (x > 1024.0)
+		w = (((((6.97281375836585777429E-5L * w
+		 + 7.84039221720066627474E-4L) * w
+		 - 2.29472093621399176955E-4L) * w
+		 - 2.68132716049382716049E-3L) * w
+		 + 3.47222222222222222222E-3L) * w
+		 + 8.33333333333333333333E-2L) * w
+		 + 1.0;
+	else
+		w = 1.0 + w * __polevll(w, STIR, 8);
+	y = expl(x);
+	if (x > MAXSTIR) { /* Avoid overflow in pow() */
+		v = powl(x, 0.5L * x - 0.25L);
+		y = v * (v / y);
+	} else {
+		y = powl(x, x - 0.5L) / y;
+	}
+	y = SQTPI * y * w;
+	return y;
+}
+
+long double tgammal(long double x)
+{
+	long double p, q, z;
+
+	if (!isfinite(x))
+		return x + INFINITY;
+
+	q = fabsl(x);
+	if (q > 13.0) {
+		if (x < 0.0) {
+			p = floorl(q);
+			z = q - p;
+			if (z == 0)
+				return 0 / z;
+			if (q > MAXGAML) {
+				z = 0;
+			} else {
+				if (z > 0.5) {
+					p += 1.0;
+					z = q - p;
+				}
+				z = q * sinl(PIL * z);
+				z = fabsl(z) * stirf(q);
+				z = PIL/z;
+			}
+			if (0.5 * p == floorl(q * 0.5))
+				z = -z;
+		} else if (x > MAXGAML) {
+			z = x * 0x1p16383L;
+		} else {
+			z = stirf(x);
+		}
+		return z;
+	}
+
+	z = 1.0;
+	while (x >= 3.0) {
+		x -= 1.0;
+		z *= x;
+	}
+	while (x < -0.03125L) {
+		z /= x;
+		x += 1.0;
+	}
+	if (x <= 0.03125L)
+		goto small;
+	while (x < 2.0) {
+		z /= x;
+		x += 1.0;
+	}
+	if (x == 2.0)
+		return z;
+
+	x -= 2.0;
+	p = __polevll(x, P, 7);
+	q = __polevll(x, Q, 8);
+	z = z * p / q;
+	return z;
+
+small:
+	/* z==1 if x was originally +-0 */
+	if (x == 0 && z != 1)
+		return x / x;
+	if (x < 0.0) {
+		x = -x;
+		q = z / (x * __polevll(x, SN, 8));
+	} else
+		q = z / (x * __polevll(x, S, 8));
+	return q;
+}
+#elif LDBL_MANT_DIG == 113 && LDBL_MAX_EXP == 16384
+// TODO: broken implementation to make things compile
+long double tgammal(long double x)
+{
+	return tgamma(x);
+}
+#endif
libc/musl/src/math/trunc.c
@@ -0,0 +1,19 @@
+#include "libm.h"
+
+double trunc(double x)
+{
+	union {double f; uint64_t i;} u = {x};
+	int e = (int)(u.i >> 52 & 0x7ff) - 0x3ff + 12;
+	uint64_t m;
+
+	if (e >= 52 + 12)
+		return x;
+	if (e < 12)
+		e = 1;
+	m = -1ULL >> e;
+	if ((u.i & m) == 0)
+		return x;
+	FORCE_EVAL(x + 0x1p120f);
+	u.i &= ~m;
+	return u.f;
+}
libc/musl/src/math/truncf.c
@@ -0,0 +1,19 @@
+#include "libm.h"
+
+float truncf(float x)
+{
+	union {float f; uint32_t i;} u = {x};
+	int e = (int)(u.i >> 23 & 0xff) - 0x7f + 9;
+	uint32_t m;
+
+	if (e >= 23 + 9)
+		return x;
+	if (e < 9)
+		e = 1;
+	m = -1U >> e;
+	if ((u.i & m) == 0)
+		return x;
+	FORCE_EVAL(x + 0x1p120f);
+	u.i &= ~m;
+	return u.f;
+}
libc/musl/src/math/truncl.c
@@ -0,0 +1,34 @@
+#include "libm.h"
+
+#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024
+long double truncl(long double x)
+{
+	return trunc(x);
+}
+#elif (LDBL_MANT_DIG == 64 || LDBL_MANT_DIG == 113) && LDBL_MAX_EXP == 16384
+
+static const long double toint = 1/LDBL_EPSILON;
+
+long double truncl(long double x)
+{
+	union ldshape u = {x};
+	int e = u.i.se & 0x7fff;
+	int s = u.i.se >> 15;
+	long double y;
+
+	if (e >= 0x3fff+LDBL_MANT_DIG-1)
+		return x;
+	if (e <= 0x3fff-1) {
+		FORCE_EVAL(x + 0x1p120f);
+		return x*0;
+	}
+	/* y = int(|x|) - |x|, where int(|x|) is an integer neighbor of |x| */
+	if (s)
+		x = -x;
+	y = x + toint - toint - x;
+	if (y > 0)
+		y -= 1;
+	x += y;
+	return s ? -x : x;
+}
+#endif
libc/musl/src/misc/a64l.c
@@ -0,0 +1,29 @@
+#include <stdlib.h>
+#include <string.h>
+#include <stdint.h>
+
+static const char digits[] =
+	"./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
+
+long a64l(const char *s)
+{
+	int e;
+	uint32_t x = 0;
+	for (e=0; e<36 && *s; e+=6, s++) {
+		const char *d = strchr(digits, *s);
+		if (!d) break;
+		x |= (uint32_t)(d-digits)<<e;
+	}
+	return (int32_t)x;
+}
+
+char *l64a(long x0)
+{
+	static char s[7];
+	char *p;
+	uint32_t x = x0;
+	for (p=s; x; p++, x>>=6)
+		*p = digits[x&63];
+	*p = 0;
+	return s;
+}
libc/musl/src/misc/basename.c
@@ -0,0 +1,14 @@
+#include <string.h>
+#include <libgen.h>
+
+char *basename(char *s)
+{
+	size_t i;
+	if (!s || !*s) return ".";
+	i = strlen(s)-1;
+	for (; i&&s[i]=='/'; i--) s[i] = 0;
+	for (; i&&s[i-1]!='/'; i--);
+	return s+i;
+}
+
+weak_alias(basename, __xpg_basename);
libc/musl/src/misc/dirname.c
@@ -0,0 +1,14 @@
+#include <string.h>
+#include <libgen.h>
+
+char *dirname(char *s)
+{
+	size_t i;
+	if (!s || !*s) return ".";
+	i = strlen(s)-1;
+	for (; s[i]=='/'; i--) if (!i) return "/";
+	for (; s[i]!='/'; i--) if (!i) return ".";
+	for (; s[i]=='/'; i--) if (!i) return "/";
+	s[i+1] = 0;
+	return s;
+}
libc/musl/src/misc/ffs.c
@@ -0,0 +1,7 @@
+#include <strings.h>
+#include "atomic.h"
+
+int ffs(int i)
+{
+	return i ? a_ctz_l(i)+1 : 0;
+}
libc/musl/src/misc/ffsl.c
@@ -0,0 +1,7 @@
+#include <strings.h>
+#include "atomic.h"
+
+int ffsl(long i)
+{
+	return i ? a_ctz_l(i)+1 : 0;
+}
libc/musl/src/misc/ffsll.c
@@ -0,0 +1,7 @@
+#include <strings.h>
+#include "atomic.h"
+
+int ffsll(long long i)
+{
+	return i ? a_ctz_64(i)+1 : 0;
+}
libc/musl/src/misc/fmtmsg.c
@@ -0,0 +1,90 @@
+/* Public domain fmtmsg()
+ * Written by Isaac Dunham, 2014
+ */
+#include <fmtmsg.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <pthread.h>
+
+/*
+ * If lstr is the first part of bstr, check that the next char in bstr
+ * is either \0 or :
+ */
+static int _strcolcmp(const char *lstr, const char *bstr)
+{
+	size_t i = 0;
+	while (lstr[i] && bstr[i] && (bstr[i] == lstr[i])) i++;
+	if ( lstr[i] || (bstr[i] && bstr[i] != ':')) return 1;
+	return 0;
+}
+
+int fmtmsg(long classification, const char *label, int severity,
+           const char *text, const char *action, const char *tag)
+{
+	int ret = 0, i, consolefd, verb = 0;
+	char *errstring = MM_NULLSEV, *cmsg = getenv("MSGVERB");
+	char *const msgs[] = {
+		"label", "severity", "text", "action", "tag", NULL
+	};
+	int cs;
+
+	pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cs);
+
+	if (severity == MM_HALT) errstring = "HALT: ";
+	else if (severity == MM_ERROR) errstring = "ERROR: ";
+	else if (severity == MM_WARNING) errstring = "WARNING: ";
+	else if (severity == MM_INFO) errstring = "INFO: ";
+
+	if (classification & MM_CONSOLE) {
+		consolefd = open("/dev/console", O_WRONLY);
+		if (consolefd < 0) {
+			ret = MM_NOCON;
+		} else {
+			if (dprintf(consolefd, "%s%s%s%s%s%s%s%s\n",
+			            label?label:"", label?": ":"",
+			            severity?errstring:"", text?text:"",
+			            action?"\nTO FIX: ":"",
+			            action?action:"", action?" ":"",
+			            tag?tag:"" )<1)
+				ret = MM_NOCON;
+			close(consolefd);
+		}
+	}
+
+	if (classification & MM_PRINT) {
+		while (cmsg && cmsg[0]) {
+			for(i=0; msgs[i]; i++) {
+				if (!_strcolcmp(msgs[i], cmsg)) break;
+			}
+			if (msgs[i] == NULL) {
+				//ignore MSGVERB-unrecognized component
+				verb = 0xFF;
+				break;
+			} else {
+				verb |= (1 << i);
+				cmsg = strchr(cmsg, ':');
+				if (cmsg) cmsg++;
+			}
+		}
+		if (!verb) verb = 0xFF;
+		if (dprintf(2, "%s%s%s%s%s%s%s%s\n",
+		            (verb&1 && label) ? label : "",
+		            (verb&1 && label) ? ": " : "",
+		            (verb&2 && severity) ? errstring : "",
+		            (verb&4 && text) ? text : "",
+		            (verb&8 && action) ? "\nTO FIX: " : "",
+		            (verb&8 && action) ? action : "",
+		            (verb&8 && action) ? " " : "",
+		            (verb&16 && tag) ? tag : "" ) < 1)
+			ret |= MM_NOMSG;
+	}
+	if ((ret & (MM_NOCON|MM_NOMSG)) == (MM_NOCON|MM_NOMSG))
+		ret = MM_NOTOK;
+
+	pthread_setcancelstate(cs, 0);
+
+	return ret;
+}
libc/musl/src/misc/forkpty.c
@@ -0,0 +1,57 @@
+#include <pty.h>
+#include <utmp.h>
+#include <unistd.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <sys/wait.h>
+#include <pthread.h>
+
+int forkpty(int *pm, char *name, const struct termios *tio, const struct winsize *ws)
+{
+	int m, s, ec=0, p[2], cs;
+	pid_t pid=-1;
+	sigset_t set, oldset;
+
+	if (openpty(&m, &s, name, tio, ws) < 0) return -1;
+
+	sigfillset(&set);
+	pthread_sigmask(SIG_BLOCK, &set, &oldset);
+	pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cs);
+
+	if (pipe2(p, O_CLOEXEC)) {
+		close(s);
+		goto out;
+	}
+
+	pid = fork();
+	if (!pid) {
+		close(m);
+		close(p[0]);
+		if (login_tty(s)) {
+			write(p[1], &errno, sizeof errno);
+			_exit(127);
+		}
+		close(p[1]);
+		pthread_setcancelstate(cs, 0);
+		pthread_sigmask(SIG_SETMASK, &oldset, 0);
+		return 0;
+	}
+	close(s);
+	close(p[1]);
+	if (read(p[0], &ec, sizeof ec) > 0) {
+		int status;
+		waitpid(pid, &status, 0);
+		pid = -1;
+		errno = ec;
+	}
+	close(p[0]);
+
+out:
+	if (pid > 0) *pm = m;
+	else close(m);
+
+	pthread_setcancelstate(cs, 0);
+	pthread_sigmask(SIG_SETMASK, &oldset, 0);
+
+	return pid;
+}
libc/musl/src/misc/get_current_dir_name.c
@@ -0,0 +1,15 @@
+#define _GNU_SOURCE
+#include <stdlib.h>
+#include <string.h>
+#include <limits.h>
+#include <unistd.h>
+#include <sys/stat.h>
+
+char *get_current_dir_name(void) {
+	struct stat a, b;
+	char *res = getenv("PWD");
+	if (res && *res && !stat(res, &a) && !stat(".", &b)
+	    && (a.st_dev == b.st_dev) && (a.st_ino == b.st_ino))
+		return strdup(res);
+	return getcwd(0, 0);
+}
libc/musl/src/misc/getauxval.c
@@ -0,0 +1,15 @@
+#include <sys/auxv.h>
+#include <errno.h>
+#include "libc.h"
+
+unsigned long __getauxval(unsigned long item)
+{
+	size_t *auxv = libc.auxv;
+	if (item == AT_SECURE) return libc.secure;
+	for (; *auxv; auxv+=2)
+		if (*auxv==item) return auxv[1];
+	errno = ENOENT;
+	return 0;
+}
+
+weak_alias(__getauxval, getauxval);
libc/musl/src/misc/getdomainname.c
@@ -0,0 +1,17 @@
+#define _GNU_SOURCE
+#include <unistd.h>
+#include <sys/utsname.h>
+#include <string.h>
+#include <errno.h>
+
+int getdomainname(char *name, size_t len)
+{
+	struct utsname temp;
+	uname(&temp);
+	if (!len || strlen(temp.domainname) >= len) {
+		errno = EINVAL;
+		return -1;
+	}
+	strcpy(name, temp.domainname);
+	return 0;
+}
libc/musl/src/misc/getentropy.c
@@ -0,0 +1,33 @@
+#define _BSD_SOURCE
+#include <unistd.h>
+#include <sys/random.h>
+#include <pthread.h>
+#include <errno.h>
+
+int getentropy(void *buffer, size_t len)
+{
+	int cs, ret;
+	char *pos = buffer;
+
+	if (len > 256) {
+		errno = EIO;
+		return -1;
+	}
+
+	pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cs);
+
+	while (len) {
+		ret = getrandom(pos, len, 0);
+		if (ret < 0) {
+			if (errno == EINTR) continue;
+			else break;
+		}
+		pos += ret;
+		len -= ret;
+		ret = 0;
+	}
+
+	pthread_setcancelstate(cs, 0);
+
+	return ret;
+}
libc/musl/src/misc/gethostid.c
@@ -0,0 +1,6 @@
+#include <unistd.h>
+
+long gethostid()
+{
+	return 0;
+}
libc/musl/src/misc/getopt.c
@@ -0,0 +1,104 @@
+#include <unistd.h>
+#include <wchar.h>
+#include <string.h>
+#include <limits.h>
+#include <stdlib.h>
+#include "locale_impl.h"
+#include "stdio_impl.h"
+
+char *optarg;
+int optind=1, opterr=1, optopt, __optpos, __optreset=0;
+
+#define optpos __optpos
+weak_alias(__optreset, optreset);
+
+void __getopt_msg(const char *a, const char *b, const char *c, size_t l)
+{
+	FILE *f = stderr;
+	b = __lctrans_cur(b);
+	FLOCK(f);
+	fputs(a, f)>=0
+	&& fwrite(b, strlen(b), 1, f)
+	&& fwrite(c, 1, l, f)==l
+	&& putc('\n', f);
+	FUNLOCK(f);
+}
+
+int getopt(int argc, char * const argv[], const char *optstring)
+{
+	int i;
+	wchar_t c, d;
+	int k, l;
+	char *optchar;
+
+	if (!optind || __optreset) {
+		__optreset = 0;
+		__optpos = 0;
+		optind = 1;
+	}
+
+	if (optind >= argc || !argv[optind])
+		return -1;
+
+	if (argv[optind][0] != '-') {
+		if (optstring[0] == '-') {
+			optarg = argv[optind++];
+			return 1;
+		}
+		return -1;
+	}
+
+	if (!argv[optind][1])
+		return -1;
+
+	if (argv[optind][1] == '-' && !argv[optind][2])
+		return optind++, -1;
+
+	if (!optpos) optpos++;
+	if ((k = mbtowc(&c, argv[optind]+optpos, MB_LEN_MAX)) < 0) {
+		k = 1;
+		c = 0xfffd; /* replacement char */
+	}
+	optchar = argv[optind]+optpos;
+	optpos += k;
+
+	if (!argv[optind][optpos]) {
+		optind++;
+		optpos = 0;
+	}
+
+	if (optstring[0] == '-' || optstring[0] == '+')
+		optstring++;
+
+	i = 0;
+	d = 0;
+	do {
+		l = mbtowc(&d, optstring+i, MB_LEN_MAX);
+		if (l>0) i+=l; else i++;
+	} while (l && d != c);
+
+	if (d != c || c == ':') {
+		optopt = c;
+		if (optstring[0] != ':' && opterr)
+			__getopt_msg(argv[0], ": unrecognized option: ", optchar, k);
+		return '?';
+	}
+	if (optstring[i] == ':') {
+		optarg = 0;
+		if (optstring[i+1] != ':' || optpos) {
+			optarg = argv[optind++] + optpos;
+			optpos = 0;
+		}
+		if (optind > argc) {
+			optopt = c;
+			if (optstring[0] == ':') return ':';
+			if (opterr) __getopt_msg(argv[0],
+				": option requires an argument: ",
+				optchar, k);
+			return '?';
+		}
+	}
+	return c;
+}
+
+weak_alias(getopt, __posix_getopt);
libc/musl/src/misc/getopt_long.c
@@ -0,0 +1,148 @@
+#define _GNU_SOURCE
+#include <stddef.h>
+#include <stdlib.h>
+#include <limits.h>
+#include <getopt.h>
+#include <stdio.h>
+#include <string.h>
+#include "stdio_impl.h"
+
+extern int __optpos, __optreset;
+
+static void permute(char *const *argv, int dest, int src)
+{
+	char **av = (char **)argv;
+	char *tmp = av[src];
+	int i;
+	for (i=src; i>dest; i--)
+		av[i] = av[i-1];
+	av[dest] = tmp;
+}
+
+static int __getopt_long_core(int argc, char *const *argv, const char *optstring, const struct option *longopts, int *idx, int longonly);
+
+static int __getopt_long(int argc, char *const *argv, const char *optstring, const struct option *longopts, int *idx, int longonly)
+{
+	int ret, skipped, resumed;
+	if (!optind || __optreset) {
+		__optreset = 0;
+		__optpos = 0;
+		optind = 1;
+	}
+	if (optind >= argc || !argv[optind]) return -1;
+	skipped = optind;
+	if (optstring[0] != '+' && optstring[0] != '-') {
+		int i;
+		for (i=optind; ; i++) {
+			if (i >= argc || !argv[i]) return -1;
+			if (argv[i][0] == '-' && argv[i][1]) break;
+		}
+		optind = i;
+	}
+	resumed = optind;
+	ret = __getopt_long_core(argc, argv, optstring, longopts, idx, longonly);
+	if (resumed > skipped) {
+		int i, cnt = optind-resumed;
+		for (i=0; i<cnt; i++)
+			permute(argv, skipped, optind-1);
+		optind = skipped + cnt;
+	}
+	return ret;
+}
+
+static int __getopt_long_core(int argc, char *const *argv, const char *optstring, const struct option *longopts, int *idx, int longonly)
+{
+	optarg = 0;
+	if (longopts && argv[optind][0] == '-' &&
+		((longonly && argv[optind][1] && argv[optind][1] != '-') ||
+		 (argv[optind][1] == '-' && argv[optind][2])))
+	{
+		int colon = optstring[optstring[0]=='+'||optstring[0]=='-']==':';
+		int i, cnt, match;
+		char *arg, *opt, *start = argv[optind]+1;
+		for (cnt=i=0; longopts[i].name; i++) {
+			const char *name = longopts[i].name;
+			opt = start;
+			if (*opt == '-') opt++;
+			while (*opt && *opt != '=' && *opt == *name)
+				name++, opt++;
+			if (*opt && *opt != '=') continue;
+			arg = opt;
+			match = i;
+			if (!*name) {
+				cnt = 1;
+				break;
+			}
+			cnt++;
+		}
+		if (cnt==1 && longonly && arg-start == mblen(start, MB_LEN_MAX)) {
+			int l = arg-start;
+			for (i=0; optstring[i]; i++) {
+				int j;
+				for (j=0; j<l && start[j]==optstring[i+j]; j++);
+				if (j==l) {
+					cnt++;
+					break;
+				}
+			}
+		}
+		if (cnt==1) {
+			i = match;
+			opt = arg;
+			optind++;
+			if (*opt == '=') {
+				if (!longopts[i].has_arg) {
+					optopt = longopts[i].val;
+					if (colon || !opterr)
+						return '?';
+					__getopt_msg(argv[0],
+						": option does not take an argument: ",
+						longopts[i].name,
+						strlen(longopts[i].name));
+					return '?';
+				}
+				optarg = opt+1;
+			} else if (longopts[i].has_arg == required_argument) {
+				if (!(optarg = argv[optind])) {
+					optopt = longopts[i].val;
+					if (colon) return ':';
+					if (!opterr) return '?';
+					__getopt_msg(argv[0],
+						": option requires an argument: ",
+						longopts[i].name,
+						strlen(longopts[i].name));
+					return '?';
+				}
+				optind++;
+			}
+			if (idx) *idx = i;
+			if (longopts[i].flag) {
+				*longopts[i].flag = longopts[i].val;
+				return 0;
+			}
+			return longopts[i].val;
+		}
+		if (argv[optind][1] == '-') {
+			optopt = 0;
+			if (!colon && opterr)
+				__getopt_msg(argv[0], cnt ?
+					": option is ambiguous: " :
+					": unrecognized option: ",
+					argv[optind]+2,
+					strlen(argv[optind]+2));
+			optind++;
+			return '?';
+		}
+	}
+	return getopt(argc, argv, optstring);
+}
+
+int getopt_long(int argc, char *const *argv, const char *optstring, const struct option *longopts, int *idx)
+{
+	return __getopt_long(argc, argv, optstring, longopts, idx, 0);
+}
+
+int getopt_long_only(int argc, char *const *argv, const char *optstring, const struct option *longopts, int *idx)
+{
+	return __getopt_long(argc, argv, optstring, longopts, idx, 1);
+}
libc/musl/src/misc/getpriority.c
@@ -0,0 +1,9 @@
+#include <sys/resource.h>
+#include "syscall.h"
+
+int getpriority(int which, id_t who)
+{
+	int ret = syscall(SYS_getpriority, which, who);
+	if (ret < 0) return ret;
+	return 20-ret;
+}
libc/musl/src/misc/getresgid.c
@@ -0,0 +1,8 @@
+#define _GNU_SOURCE
+#include <unistd.h>
+#include "syscall.h"
+
+int getresgid(gid_t *rgid, gid_t *egid, gid_t *sgid)
+{
+	return syscall(SYS_getresgid, rgid, egid, sgid);
+}
libc/musl/src/misc/getresuid.c
@@ -0,0 +1,8 @@
+#define _GNU_SOURCE
+#include <unistd.h>
+#include "syscall.h"
+
+int getresuid(uid_t *ruid, uid_t *euid, uid_t *suid)
+{
+	return syscall(SYS_getresuid, ruid, euid, suid);
+}
libc/musl/src/misc/getrlimit.c
@@ -0,0 +1,26 @@
+#include <sys/resource.h>
+#include <errno.h>
+#include "syscall.h"
+
+#define FIX(x) do{ if ((x)>=SYSCALL_RLIM_INFINITY) (x)=RLIM_INFINITY; }while(0)
+
+int getrlimit(int resource, struct rlimit *rlim)
+{
+	unsigned long k_rlim[2];
+	int ret = syscall(SYS_prlimit64, 0, resource, 0, rlim);
+	if (!ret) {
+		FIX(rlim->rlim_cur);
+		FIX(rlim->rlim_max);
+	}
+	if (!ret || errno != ENOSYS)
+		return ret;
+	if (syscall(SYS_getrlimit, resource, k_rlim) < 0)
+		return -1;
+	rlim->rlim_cur = k_rlim[0] == -1UL ? RLIM_INFINITY : k_rlim[0];
+	rlim->rlim_max = k_rlim[1] == -1UL ? RLIM_INFINITY : k_rlim[1];
+	FIX(rlim->rlim_cur);
+	FIX(rlim->rlim_max);
+	return 0;
+}
+
+weak_alias(getrlimit, getrlimit64);
libc/musl/src/misc/getrusage.c
@@ -0,0 +1,7 @@
+#include <sys/resource.h>
+#include "syscall.h"
+
+int getrusage(int who, struct rusage *ru)
+{
+	return syscall(SYS_getrusage, who, ru);
+}
libc/musl/src/misc/getsubopt.c
@@ -0,0 +1,23 @@
+#include <stdlib.h>
+#include <string.h>
+
+int getsubopt(char **opt, char *const *keys, char **val)
+{
+	char *s = *opt;
+	int i;
+
+	*val = NULL;
+	*opt = strchr(s, ',');
+	if (*opt) *(*opt)++ = 0;
+	else *opt = s + strlen(s);
+
+	for (i=0; keys[i]; i++) {
+		size_t l = strlen(keys[i]);
+		if (strncmp(keys[i], s, l)) continue;
+		if (s[l] == '=')
+			*val = s + l + 1;
+		else if (s[l]) continue;
+		return i;
+	}
+	return -1;
+}
libc/musl/src/misc/initgroups.c
@@ -0,0 +1,11 @@
+#define _GNU_SOURCE
+#include <grp.h>
+#include <limits.h>
+
+int initgroups(const char *user, gid_t gid)
+{
+	gid_t groups[NGROUPS_MAX];
+	int count = NGROUPS_MAX;
+	if (getgrouplist(user, gid, groups, &count) < 0) return -1;
+	return setgroups(count, groups);
+}
libc/musl/src/misc/ioctl.c
@@ -0,0 +1,13 @@
+#include <sys/ioctl.h>
+#include <stdarg.h>
+#include "syscall.h"
+
+int ioctl(int fd, int req, ...)
+{
+	void *arg;
+	va_list ap;
+	va_start(ap, req);
+	arg = va_arg(ap, void *);
+	va_end(ap);
+	return syscall(SYS_ioctl, fd, req, arg);
+}
libc/musl/src/misc/issetugid.c
@@ -0,0 +1,8 @@
+#define _BSD_SOURCE
+#include <unistd.h>
+#include "libc.h"
+
+int issetugid(void)
+{
+	return libc.secure;
+}
libc/musl/src/misc/lockf.c
@@ -0,0 +1,32 @@
+#include <unistd.h>
+#include <fcntl.h>
+#include <errno.h>
+
+int lockf(int fd, int op, off_t size)
+{
+	struct flock l = {
+		.l_type = F_WRLCK,
+		.l_whence = SEEK_CUR,
+		.l_len = size,
+	};
+	switch (op) {
+	case F_TEST:
+		l.l_type = F_RDLCK;
+		if (fcntl(fd, F_GETLK, &l) < 0)
+			return -1;
+		if (l.l_type == F_UNLCK || l.l_pid == getpid())
+			return 0;
+		errno = EACCES;
+		return -1;
+	case F_ULOCK:
+		l.l_type = F_UNLCK;
+	case F_TLOCK:
+		return fcntl(fd, F_SETLK, &l);
+	case F_LOCK:
+		return fcntl(fd, F_SETLKW, &l);
+	}
+	errno = EINVAL;
+	return -1;
+}
+
+weak_alias(lockf, lockf64);
libc/musl/src/misc/login_tty.c
@@ -0,0 +1,14 @@
+#include <utmp.h>
+#include <sys/ioctl.h>
+#include <unistd.h>
+
+int login_tty(int fd)
+{
+	setsid();
+	if (ioctl(fd, TIOCSCTTY, (char *)0)) return -1;
+	dup2(fd, 0);
+	dup2(fd, 1);
+	dup2(fd, 2);
+	if (fd>2) close(fd);
+	return 0;
+}
libc/musl/src/misc/mntent.c
@@ -0,0 +1,77 @@
+#include <stdio.h>
+#include <string.h>
+#include <mntent.h>
+#include <errno.h>
+
+static char *internal_buf;
+static size_t internal_bufsize;
+
+#define SENTINEL (char *)&internal_buf
+
+FILE *setmntent(const char *name, const char *mode)
+{
+	return fopen(name, mode);
+}
+
+int endmntent(FILE *f)
+{
+	if (f) fclose(f);
+	return 1;
+}
+
+struct mntent *getmntent_r(FILE *f, struct mntent *mnt, char *linebuf, int buflen)
+{
+	int cnt, n[8], use_internal = (linebuf == SENTINEL);
+
+	mnt->mnt_freq = 0;
+	mnt->mnt_passno = 0;
+
+	do {
+		if (use_internal) {
+			getline(&internal_buf, &internal_bufsize, f);
+			linebuf = internal_buf;
+		} else {
+			fgets(linebuf, buflen, f);
+		}
+		if (feof(f) || ferror(f)) return 0;
+		if (!strchr(linebuf, '\n')) {
+			fscanf(f, "%*[^\n]%*[\n]");
+			errno = ERANGE;
+			return 0;
+		}
+		cnt = sscanf(linebuf, " %n%*s%n %n%*s%n %n%*s%n %n%*s%n %d %d",
+			n, n+1, n+2, n+3, n+4, n+5, n+6, n+7,
+			&mnt->mnt_freq, &mnt->mnt_passno);
+	} while (cnt < 2 || linebuf[n[0]] == '#');
+
+	linebuf[n[1]] = 0;
+	linebuf[n[3]] = 0;
+	linebuf[n[5]] = 0;
+	linebuf[n[7]] = 0;
+
+	mnt->mnt_fsname = linebuf+n[0];
+	mnt->mnt_dir = linebuf+n[2];
+	mnt->mnt_type = linebuf+n[4];
+	mnt->mnt_opts = linebuf+n[6];
+
+	return mnt;
+}
+
+struct mntent *getmntent(FILE *f)
+{
+	static struct mntent mnt;
+	return getmntent_r(f, &mnt, SENTINEL, 0);
+}
+
+int addmntent(FILE *f, const struct mntent *mnt)
+{
+	if (fseek(f, 0, SEEK_END)) return 1;
+	return fprintf(f, "%s\t%s\t%s\t%s\t%d\t%d\n",
+		mnt->mnt_fsname, mnt->mnt_dir, mnt->mnt_type, mnt->mnt_opts,
+		mnt->mnt_freq, mnt->mnt_passno) < 0;
+}
+
+char *hasmntopt(const struct mntent *mnt, const char *opt)
+{
+	return strstr(mnt->mnt_opts, opt);
+}
libc/musl/src/misc/nftw.c
@@ -0,0 +1,128 @@
+#include <ftw.h>
+#include <dirent.h>
+#include <sys/stat.h>
+#include <errno.h>
+#include <unistd.h>
+#include <string.h>
+#include <limits.h>
+#include <pthread.h>
+
+struct history
+{
+	struct history *chain;
+	dev_t dev;
+	ino_t ino;
+	int level;
+	int base;
+};
+
+#undef dirfd
+#define dirfd(d) (*(int *)d)
+
+static int do_nftw(char *path, int (*fn)(const char *, const struct stat *, int, struct FTW *), int fd_limit, int flags, struct history *h)
+{
+	size_t l = strlen(path), j = l && path[l-1]=='/' ? l-1 : l;
+	struct stat st;
+	struct history new;
+	int type;
+	int r;
+	struct FTW lev;
+
+	if ((flags & FTW_PHYS) ? lstat(path, &st) : stat(path, &st) < 0) {
+		if (!(flags & FTW_PHYS) && errno==ENOENT && !lstat(path, &st))
+			type = FTW_SLN;
+		else if (errno != EACCES) return -1;
+		else type = FTW_NS;
+	} else if (S_ISDIR(st.st_mode)) {
+		if (access(path, R_OK) < 0) type = FTW_DNR;
+		else if (flags & FTW_DEPTH) type = FTW_DP;
+		else type = FTW_D;
+	} else if (S_ISLNK(st.st_mode)) {
+		if (flags & FTW_PHYS) type = FTW_SL;
+		else type = FTW_SLN;
+	} else {
+		type = FTW_F;
+	}
+
+	if ((flags & FTW_MOUNT) && h && st.st_dev != h->dev)
+		return 0;
+	
+	new.chain = h;
+	new.dev = st.st_dev;
+	new.ino = st.st_ino;
+	new.level = h ? h->level+1 : 0;
+	new.base = j+1;
+	
+	lev.level = new.level;
+	if (h) {
+		lev.base = h->base;
+	} else {
+		size_t k;
+		for (k=j; k && path[k]=='/'; k--);
+		for (; k && path[k-1]!='/'; k--);
+		lev.base = k;
+	}
+
+	if (!(flags & FTW_DEPTH) && (r=fn(path, &st, type, &lev)))
+		return r;
+
+	for (; h; h = h->chain)
+		if (h->dev == st.st_dev && h->ino == st.st_ino)
+			return 0;
+
+	if ((type == FTW_D || type == FTW_DP) && fd_limit) {
+		DIR *d = opendir(path);
+		if (d) {
+			struct dirent *de;
+			while ((de = readdir(d))) {
+				if (de->d_name[0] == '.'
+				 && (!de->d_name[1]
+				  || (de->d_name[1]=='.'
+				   && !de->d_name[2]))) continue;
+				if (strlen(de->d_name) >= PATH_MAX-l) {
+					errno = ENAMETOOLONG;
+					closedir(d);
+					return -1;
+				}
+				path[j]='/';
+				strcpy(path+j+1, de->d_name);
+				if ((r=do_nftw(path, fn, fd_limit-1, flags, &new))) {
+					closedir(d);
+					return r;
+				}
+			}
+			closedir(d);
+		} else if (errno != EACCES) {
+			return -1;
+		}
+	}
+
+	path[l] = 0;
+	if ((flags & FTW_DEPTH) && (r=fn(path, &st, type, &lev)))
+		return r;
+
+	return 0;
+}
+
+int nftw(const char *path, int (*fn)(const char *, const struct stat *, int, struct FTW *), int fd_limit, int flags)
+{
+	int r, cs;
+	size_t l;
+	char pathbuf[PATH_MAX+1];
+
+	if (fd_limit <= 0) return 0;
+
+	l = strlen(path);
+	if (l > PATH_MAX) {
+		errno = ENAMETOOLONG;
+		return -1;
+	}
+	memcpy(pathbuf, path, l+1);
+	
+	pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cs);
+	r = do_nftw(pathbuf, fn, fd_limit, flags, NULL);
+	pthread_setcancelstate(cs, 0);
+	return r;
+}
+
+weak_alias(nftw, nftw64);
libc/musl/src/misc/openpty.c
@@ -0,0 +1,40 @@
+#include <stdlib.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <pty.h>
+#include <stdio.h>
+#include <pthread.h>
+
+/* Nonstandard, but vastly superior to the standard functions */
+
+int openpty(int *pm, int *ps, char *name, const struct termios *tio, const struct winsize *ws)
+{
+	int m, s, n=0, cs;
+	char buf[20];
+
+	m = open("/dev/ptmx", O_RDWR|O_NOCTTY);
+	if (m < 0) return -1;
+
+	pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cs);
+
+	if (ioctl(m, TIOCSPTLCK, &n) || ioctl (m, TIOCGPTN, &n))
+		goto fail;
+
+	if (!name) name = buf;
+	snprintf(name, sizeof buf, "/dev/pts/%d", n);
+	if ((s = open(name, O_RDWR|O_NOCTTY)) < 0)
+		goto fail;
+
+	if (tio) tcsetattr(s, TCSANOW, tio);
+	if (ws) ioctl(s, TIOCSWINSZ, ws);
+
+	*pm = m;
+	*ps = s;
+
+	pthread_setcancelstate(cs, 0);
+	return 0;
+fail:
+	close(m);
+	pthread_setcancelstate(cs, 0);
+	return -1;
+}
libc/musl/src/misc/ptsname.c
@@ -0,0 +1,13 @@
+#include <stdlib.h>
+#include <errno.h>
+
+char *ptsname(int fd)
+{
+	static char buf[9 + sizeof(int)*3 + 1];
+	int err = __ptsname_r(fd, buf, sizeof buf);
+	if (err) {
+		errno = err;
+		return 0;
+	}
+	return buf;
+}
libc/musl/src/misc/pty.c
@@ -0,0 +1,33 @@
+#include <stdlib.h>
+#include <sys/ioctl.h>
+#include <stdio.h>
+#include <fcntl.h>
+#include <errno.h>
+#include "syscall.h"
+
+int posix_openpt(int flags)
+{
+	return open("/dev/ptmx", flags);
+}
+
+int grantpt(int fd)
+{
+	return 0;
+}
+
+int unlockpt(int fd)
+{
+	int unlock = 0;
+	return ioctl(fd, TIOCSPTLCK, &unlock);
+}
+
+int __ptsname_r(int fd, char *buf, size_t len)
+{
+	int pty, err;
+	if (!buf) len = 0;
+	if ((err = __syscall(SYS_ioctl, fd, TIOCGPTN, &pty))) return -err;
+	if (snprintf(buf, len, "/dev/pts/%d", pty) >= len) return ERANGE;
+	return 0;
+}
+
+weak_alias(__ptsname_r, ptsname_r);
libc/musl/src/misc/realpath.c
@@ -0,0 +1,43 @@
+#include <stdlib.h>
+#include <limits.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <unistd.h>
+#include <string.h>
+#include "syscall.h"
+
+char *realpath(const char *restrict filename, char *restrict resolved)
+{
+	int fd;
+	ssize_t r;
+	struct stat st1, st2;
+	char buf[15+3*sizeof(int)];
+	char tmp[PATH_MAX];
+
+	if (!filename) {
+		errno = EINVAL;
+		return 0;
+	}
+
+	fd = sys_open(filename, O_PATH|O_NONBLOCK|O_CLOEXEC);
+	if (fd < 0) return 0;
+	__procfdname(buf, fd);
+
+	r = readlink(buf, tmp, sizeof tmp - 1);
+	if (r < 0) goto err;
+	tmp[r] = 0;
+
+	fstat(fd, &st1);
+	r = stat(tmp, &st2);
+	if (r<0 || st1.st_dev != st2.st_dev || st1.st_ino != st2.st_ino) {
+		if (!r) errno = ELOOP;
+		goto err;
+	}
+
+	__syscall(SYS_close, fd);
+	return resolved ? strcpy(resolved, tmp) : strdup(tmp);
+err:
+	__syscall(SYS_close, fd);
+	return 0;
+}
libc/musl/src/misc/setdomainname.c
@@ -0,0 +1,8 @@
+#define _GNU_SOURCE
+#include <unistd.h>
+#include "syscall.h"
+
+int setdomainname(const char *name, size_t len)
+{
+	return syscall(SYS_setdomainname, name, len);
+}
libc/musl/src/misc/setpriority.c
@@ -0,0 +1,7 @@
+#include <sys/resource.h>
+#include "syscall.h"
+
+int setpriority(int which, id_t who, int prio)
+{
+	return syscall(SYS_setpriority, which, who, prio);
+}
libc/musl/src/misc/setrlimit.c
@@ -0,0 +1,50 @@
+#include <sys/resource.h>
+#include <errno.h>
+#include "syscall.h"
+#include "libc.h"
+
+#define MIN(a, b) ((a)<(b) ? (a) : (b))
+#define FIX(x) do{ if ((x)>=SYSCALL_RLIM_INFINITY) (x)=RLIM_INFINITY; }while(0)
+
+static int __setrlimit(int resource, const struct rlimit *rlim)
+{
+	unsigned long k_rlim[2];
+	struct rlimit tmp;
+	if (SYSCALL_RLIM_INFINITY != RLIM_INFINITY) {
+		tmp = *rlim;
+		FIX(tmp.rlim_cur);
+		FIX(tmp.rlim_max);
+		rlim = &tmp;
+	}
+	int ret = __syscall(SYS_prlimit64, 0, resource, rlim, 0);
+	if (ret != -ENOSYS) return ret;
+	k_rlim[0] = MIN(rlim->rlim_cur, MIN(-1UL, SYSCALL_RLIM_INFINITY));
+	k_rlim[1] = MIN(rlim->rlim_max, MIN(-1UL, SYSCALL_RLIM_INFINITY));
+	return __syscall(SYS_setrlimit, resource, k_rlim);
+}
+
+struct ctx {
+	const struct rlimit *rlim;
+	int res;
+	int err;
+};
+
+static void do_setrlimit(void *p)
+{
+	struct ctx *c = p;
+	if (c->err>0) return;
+	c->err = -__setrlimit(c->res, c->rlim);
+}
+
+int setrlimit(int resource, const struct rlimit *rlim)
+{
+	struct ctx c = { .res = resource, .rlim = rlim, .err = -1 };
+	__synccall(do_setrlimit, &c);
+	if (c.err) {
+		if (c.err>0) errno = c.err;
+		return -1;
+	}
+	return 0;
+}
+
+weak_alias(setrlimit, setrlimit64);
libc/musl/src/misc/syscall.c
@@ -0,0 +1,21 @@
+#define _BSD_SOURCE
+#include <unistd.h>
+#include "syscall.h"
+#include <stdarg.h>
+
+#undef syscall
+
+long syscall(long n, ...)
+{
+	va_list ap;
+	syscall_arg_t a,b,c,d,e,f;
+	va_start(ap, n);
+	a=va_arg(ap, syscall_arg_t);
+	b=va_arg(ap, syscall_arg_t);
+	c=va_arg(ap, syscall_arg_t);
+	d=va_arg(ap, syscall_arg_t);
+	e=va_arg(ap, syscall_arg_t);
+	f=va_arg(ap, syscall_arg_t);
+	va_end(ap);
+	return __syscall_ret(__syscall(n,a,b,c,d,e,f));
+}
libc/musl/src/misc/syslog.c
@@ -0,0 +1,144 @@
+#include <stdarg.h>
+#include <sys/socket.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <syslog.h>
+#include <time.h>
+#include <signal.h>
+#include <string.h>
+#include <pthread.h>
+#include <errno.h>
+#include <fcntl.h>
+#include "lock.h"
+
+static volatile int lock[1];
+static char log_ident[32];
+static int log_opt;
+static int log_facility = LOG_USER;
+static int log_mask = 0xff;
+static int log_fd = -1;
+
+int setlogmask(int maskpri)
+{
+	LOCK(lock);
+	int ret = log_mask;
+	if (maskpri) log_mask = maskpri;
+	UNLOCK(lock);
+	return ret;
+}
+
+static const struct {
+	short sun_family;
+	char sun_path[9];
+} log_addr = {
+	AF_UNIX,
+	"/dev/log"
+};
+
+void closelog(void)
+{
+	int cs;
+	pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cs);
+	LOCK(lock);
+	close(log_fd);
+	log_fd = -1;
+	UNLOCK(lock);
+	pthread_setcancelstate(cs, 0);
+}
+
+static void __openlog()
+{
+	log_fd = socket(AF_UNIX, SOCK_DGRAM|SOCK_CLOEXEC, 0);
+	if (log_fd >= 0) connect(log_fd, (void *)&log_addr, sizeof log_addr);
+}
+
+void openlog(const char *ident, int opt, int facility)
+{
+	int cs;
+	pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cs);
+	LOCK(lock);
+
+	if (ident) {
+		size_t n = strnlen(ident, sizeof log_ident - 1);
+		memcpy(log_ident, ident, n);
+		log_ident[n] = 0;
+	} else {
+		log_ident[0] = 0;
+	}
+	log_opt = opt;
+	log_facility = facility;
+
+	if ((opt & LOG_NDELAY) && log_fd<0) __openlog();
+
+	UNLOCK(lock);
+	pthread_setcancelstate(cs, 0);
+}
+
+static int is_lost_conn(int e)
+{
+	return e==ECONNREFUSED || e==ECONNRESET || e==ENOTCONN || e==EPIPE;
+}
+
+static void _vsyslog(int priority, const char *message, va_list ap)
+{
+	char timebuf[16];
+	time_t now;
+	struct tm tm;
+	char buf[1024];
+	int errno_save = errno;
+	int pid;
+	int l, l2;
+	int hlen;
+	int fd;
+
+	if (log_fd < 0) __openlog();
+
+	if (!(priority & LOG_FACMASK)) priority |= log_facility;
+
+	now = time(NULL);
+	gmtime_r(&now, &tm);
+	strftime(timebuf, sizeof timebuf, "%b %e %T", &tm);
+
+	pid = (log_opt & LOG_PID) ? getpid() : 0;
+	l = snprintf(buf, sizeof buf, "<%d>%s %n%s%s%.0d%s: ",
+		priority, timebuf, &hlen, log_ident, "["+!pid, pid, "]"+!pid);
+	errno = errno_save;
+	l2 = vsnprintf(buf+l, sizeof buf - l, message, ap);
+	if (l2 >= 0) {
+		if (l2 >= sizeof buf - l) l = sizeof buf - 1;
+		else l += l2;
+		if (buf[l-1] != '\n') buf[l++] = '\n';
+		if (send(log_fd, buf, l, 0) < 0 && (!is_lost_conn(errno)
+		    || connect(log_fd, (void *)&log_addr, sizeof log_addr) < 0
+		    || send(log_fd, buf, l, 0) < 0)
+		    && (log_opt & LOG_CONS)) {
+			fd = open("/dev/console", O_WRONLY|O_NOCTTY|O_CLOEXEC);
+			if (fd >= 0) {
+				dprintf(fd, "%.*s", l-hlen, buf+hlen);
+				close(fd);
+			}
+		}
+		if (log_opt & LOG_PERROR) dprintf(2, "%.*s", l-hlen, buf+hlen);
+	}
+}
+
+static void __vsyslog(int priority, const char *message, va_list ap)
+{
+	int cs;
+	if (!(log_mask & LOG_MASK(priority&7)) || (priority&~0x3ff)) return;
+	pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cs);
+	LOCK(lock);
+	_vsyslog(priority, message, ap);
+	UNLOCK(lock);
+	pthread_setcancelstate(cs, 0);
+}
+
+void syslog(int priority, const char *message, ...)
+{
+	va_list ap;
+	va_start(ap, message);
+	__vsyslog(priority, message, ap);
+	va_end(ap);
+}
+
+weak_alias(__vsyslog, vsyslog);
libc/musl/src/misc/uname.c
@@ -0,0 +1,7 @@
+#include <sys/utsname.h>
+#include "syscall.h"
+
+int uname(struct utsname *uts)
+{
+	return syscall(SYS_uname, uts);
+}
libc/musl/src/misc/wordexp.c
@@ -0,0 +1,187 @@
+#include <wordexp.h>
+#include <unistd.h>
+#include <stdio.h>
+#include <string.h>
+#include <limits.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <sys/wait.h>
+#include <signal.h>
+#include <errno.h>
+#include <fcntl.h>
+#include "pthread_impl.h"
+
+static void reap(pid_t pid)
+{
+	int status;
+	while (waitpid(pid, &status, 0) < 0 && errno == EINTR);
+}
+
+static char *getword(FILE *f)
+{
+	char *s = 0;
+	return getdelim(&s, (size_t [1]){0}, 0, f) < 0 ? 0 : s;
+}
+
+static int do_wordexp(const char *s, wordexp_t *we, int flags)
+{
+	size_t i, l;
+	int sq=0, dq=0;
+	size_t np=0;
+	char *w, **tmp;
+	char *redir = (flags & WRDE_SHOWERR) ? "" : "2>/dev/null";
+	int err = 0;
+	FILE *f;
+	size_t wc = 0;
+	char **wv = 0;
+	int p[2];
+	pid_t pid;
+	sigset_t set;
+
+	if (flags & WRDE_REUSE) wordfree(we);
+
+	if (flags & WRDE_NOCMD) for (i=0; s[i]; i++) switch (s[i]) {
+	case '\\':
+		if (!sq && !s[++i]) return WRDE_SYNTAX;
+		break;
+	case '\'':
+		if (!dq) sq^=1;
+		break;
+	case '"':
+		if (!sq) dq^=1;
+		break;
+	case '(':
+		if (np) {
+			np++;
+			break;
+		}
+	case ')':
+		if (np) {
+			np--;
+			break;
+		}
+	case '\n':
+	case '|':
+	case '&':
+	case ';':
+	case '<':
+	case '>':
+	case '{':
+	case '}':
+		if (!(sq|dq|np)) return WRDE_BADCHAR;
+		break;
+	case '$':
+		if (sq) break;
+		if (s[i+1]=='(' && s[i+2]=='(') {
+			i += 2;
+			np += 2;
+			break;
+		} else if (s[i+1] != '(') break;
+	case '`':
+		if (sq) break;
+		return WRDE_CMDSUB;
+	}
+
+	if (flags & WRDE_APPEND) {
+		wc = we->we_wordc;
+		wv = we->we_wordv;
+	}
+
+	i = wc;
+	if (flags & WRDE_DOOFFS) {
+		if (we->we_offs > SIZE_MAX/sizeof(void *)/4)
+			goto nospace;
+		i += we->we_offs;
+	} else {
+		we->we_offs = 0;
+	}
+
+	if (pipe2(p, O_CLOEXEC) < 0) goto nospace;
+	__block_all_sigs(&set);
+	pid = fork();
+	__restore_sigs(&set);
+	if (pid < 0) {
+		close(p[0]);
+		close(p[1]);
+		goto nospace;
+	}
+	if (!pid) {
+		if (p[1] == 1) fcntl(1, F_SETFD, 0);
+		else dup2(p[1], 1);
+		execl("/bin/sh", "sh", "-c",
+			"eval \"printf %s\\\\\\\\0 x $1 $2\"",
+			"sh", s, redir, (char *)0);
+		_exit(1);
+	}
+	close(p[1]);
+	
+	f = fdopen(p[0], "r");
+	if (!f) {
+		close(p[0]);
+		kill(pid, SIGKILL);
+		reap(pid);
+		goto nospace;
+	}
+
+	l = wv ? i+1 : 0;
+
+	free(getword(f));
+	if (feof(f)) {
+		fclose(f);
+		reap(pid);
+		return WRDE_SYNTAX;
+	}
+
+	while ((w = getword(f))) {
+		if (i+1 >= l) {
+			l += l/2+10;
+			tmp = realloc(wv, l*sizeof(char *));
+			if (!tmp) break;
+			wv = tmp;
+		}
+		wv[i++] = w;
+		wv[i] = 0;
+	}
+	if (!feof(f)) err = WRDE_NOSPACE;
+
+	fclose(f);
+	reap(pid);
+
+	if (!wv) wv = calloc(i+1, sizeof *wv);
+
+	we->we_wordv = wv;
+	we->we_wordc = i;
+
+	if (flags & WRDE_DOOFFS) {
+		if (wv) for (i=we->we_offs; i; i--)
+			we->we_wordv[i-1] = 0;
+		we->we_wordc -= we->we_offs;
+	}
+	return err;
+
+nospace:
+	if (!(flags & WRDE_APPEND)) {
+		we->we_wordc = 0;
+		we->we_wordv = 0;
+	}
+	return WRDE_NOSPACE;
+}
+
+int wordexp(const char *restrict s, wordexp_t *restrict we, int flags)
+{
+	int r, cs;
+	pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cs);
+	r = do_wordexp(s, we, flags);
+	pthread_setcancelstate(cs, 0);
+	return r;
+}
+
+void wordfree(wordexp_t *we)
+{
+	size_t i;
+	if (!we->we_wordv) return;
+	for (i=0; i<we->we_wordc; i++) free(we->we_wordv[we->we_offs+i]);
+	free(we->we_wordv);
+	we->we_wordv = 0;
+	we->we_wordc = 0;
+}
libc/musl/src/mman/madvise.c
@@ -0,0 +1,9 @@
+#include <sys/mman.h>
+#include "syscall.h"
+
+int __madvise(void *addr, size_t len, int advice)
+{
+	return syscall(SYS_madvise, addr, len, advice);
+}
+
+weak_alias(__madvise, madvise);
libc/musl/src/mman/mincore.c
@@ -0,0 +1,8 @@
+#define _GNU_SOURCE
+#include <sys/mman.h>
+#include "syscall.h"
+
+int mincore (void *addr, size_t len, unsigned char *vec)
+{
+	return syscall(SYS_mincore, addr, len, vec);
+}
libc/musl/src/mman/mlock.c
@@ -0,0 +1,7 @@
+#include <sys/mman.h>
+#include "syscall.h"
+
+int mlock(const void *addr, size_t len)
+{
+	return syscall(SYS_mlock, addr, len);
+}
libc/musl/src/mman/mlockall.c
@@ -0,0 +1,7 @@
+#include <sys/mman.h>
+#include "syscall.h"
+
+int mlockall(int flags)
+{
+	return syscall(SYS_mlockall, flags);
+}
libc/musl/src/mman/mmap.c
@@ -0,0 +1,41 @@
+#include <unistd.h>
+#include <sys/mman.h>
+#include <errno.h>
+#include <stdint.h>
+#include <limits.h>
+#include "syscall.h"
+
+static void dummy(void) { }
+weak_alias(dummy, __vm_wait);
+
+#define UNIT SYSCALL_MMAP2_UNIT
+#define OFF_MASK ((-0x2000ULL << (8*sizeof(syscall_arg_t)-1)) | (UNIT-1))
+
+void *__mmap(void *start, size_t len, int prot, int flags, int fd, off_t off)
+{
+	long ret;
+	if (off & OFF_MASK) {
+		errno = EINVAL;
+		return MAP_FAILED;
+	}
+	if (len >= PTRDIFF_MAX) {
+		errno = ENOMEM;
+		return MAP_FAILED;
+	}
+	if (flags & MAP_FIXED) {
+		__vm_wait();
+	}
+#ifdef SYS_mmap2
+	ret = __syscall(SYS_mmap2, start, len, prot, flags, fd, off/UNIT);
+#else
+	ret = __syscall(SYS_mmap, start, len, prot, flags, fd, off);
+#endif
+	/* Fixup incorrect EPERM from kernel. */
+	if (ret == -EPERM && !start && (flags&MAP_ANON) && !(flags&MAP_FIXED))
+		ret = -ENOMEM;
+	return (void *)__syscall_ret(ret);
+}
+
+weak_alias(__mmap, mmap);
+
+weak_alias(mmap, mmap64);
libc/musl/src/mman/mprotect.c
@@ -0,0 +1,13 @@
+#include <sys/mman.h>
+#include "libc.h"
+#include "syscall.h"
+
+int __mprotect(void *addr, size_t len, int prot)
+{
+	size_t start, end;
+	start = (size_t)addr & -PAGE_SIZE;
+	end = (size_t)((char *)addr + len + PAGE_SIZE-1) & -PAGE_SIZE;
+	return syscall(SYS_mprotect, start, end-start, prot);
+}
+
+weak_alias(__mprotect, mprotect);
libc/musl/src/mman/mremap.c
@@ -0,0 +1,32 @@
+#define _GNU_SOURCE
+#include <unistd.h>
+#include <sys/mman.h>
+#include <errno.h>
+#include <stdint.h>
+#include <stdarg.h>
+#include "syscall.h"
+
+static void dummy(void) { }
+weak_alias(dummy, __vm_wait);
+
+void *__mremap(void *old_addr, size_t old_len, size_t new_len, int flags, ...)
+{
+	va_list ap;
+	void *new_addr = 0;
+
+	if (new_len >= PTRDIFF_MAX) {
+		errno = ENOMEM;
+		return MAP_FAILED;
+	}
+
+	if (flags & MREMAP_FIXED) {
+		__vm_wait();
+		va_start(ap, flags);
+		new_addr = va_arg(ap, void *);
+		va_end(ap);
+	}
+
+	return (void *)syscall(SYS_mremap, old_addr, old_len, new_len, flags, new_addr);
+}
+
+weak_alias(__mremap, mremap);
libc/musl/src/mman/msync.c
@@ -0,0 +1,7 @@
+#include <sys/mman.h>
+#include "syscall.h"
+
+int msync(void *start, size_t len, int flags)
+{
+	return syscall_cp(SYS_msync, start, len, flags);
+}
libc/musl/src/mman/munlock.c
@@ -0,0 +1,7 @@
+#include <sys/mman.h>
+#include "syscall.h"
+
+int munlock(const void *addr, size_t len)
+{
+	return syscall(SYS_munlock, addr, len);
+}
libc/musl/src/mman/munlockall.c
@@ -0,0 +1,7 @@
+#include <sys/mman.h>
+#include "syscall.h"
+
+int munlockall(void)
+{
+	return syscall(SYS_munlockall);
+}
libc/musl/src/mman/munmap.c
@@ -0,0 +1,13 @@
+#include <sys/mman.h>
+#include "syscall.h"
+
+static void dummy(void) { }
+weak_alias(dummy, __vm_wait);
+
+int __munmap(void *start, size_t len)
+{
+	__vm_wait();
+	return syscall(SYS_munmap, start, len);
+}
+
+weak_alias(__munmap, munmap);
libc/musl/src/mman/posix_madvise.c
@@ -0,0 +1,9 @@
+#define _GNU_SOURCE
+#include <sys/mman.h>
+#include "syscall.h"
+
+int posix_madvise(void *addr, size_t len, int advice)
+{
+	if (advice == MADV_DONTNEED) return 0;
+	return -__syscall(SYS_madvise, addr, len, advice);
+}
libc/musl/src/mman/shm_open.c
@@ -0,0 +1,43 @@
+#include <sys/mman.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <string.h>
+#include <limits.h>
+#include <pthread.h>
+
+char *__shm_mapname(const char *name, char *buf)
+{
+	char *p;
+	while (*name == '/') name++;
+	if (*(p = __strchrnul(name, '/')) || p==name ||
+	    (p-name <= 2 && name[0]=='.' && p[-1]=='.')) {
+		errno = EINVAL;
+		return 0;
+	}
+	if (p-name > NAME_MAX) {
+		errno = ENAMETOOLONG;
+		return 0;
+	}
+	memcpy(buf, "/dev/shm/", 9);
+	memcpy(buf+9, name, p-name+1);
+	return buf;
+}
+
+int shm_open(const char *name, int flag, mode_t mode)
+{
+	int cs;
+	char buf[NAME_MAX+10];
+	if (!(name = __shm_mapname(name, buf))) return -1;
+	pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cs);
+	int fd = open(name, flag|O_NOFOLLOW|O_CLOEXEC|O_NONBLOCK, mode);
+	pthread_setcancelstate(cs, 0);
+	return fd;
+}
+
+int shm_unlink(const char *name)
+{
+	char buf[NAME_MAX+10];
+	if (!(name = __shm_mapname(name, buf))) return -1;
+	return unlink(name);
+}
libc/musl/src/mq/mq_close.c
@@ -0,0 +1,7 @@
+#include <mqueue.h>
+#include "syscall.h"
+
+int mq_close(mqd_t mqd)
+{
+	return syscall(SYS_close, mqd);
+}
libc/musl/src/mq/mq_getattr.c
@@ -0,0 +1,7 @@
+#include <mqueue.h>
+#include "syscall.h"
+
+int mq_getattr(mqd_t mqd, struct mq_attr *attr)
+{
+	return mq_setattr(mqd, 0, attr);
+}
libc/musl/src/mq/mq_notify.c
@@ -0,0 +1,73 @@
+#include <mqueue.h>
+#include <pthread.h>
+#include <errno.h>
+#include <sys/socket.h>
+#include <signal.h>
+#include <unistd.h>
+#include "syscall.h"
+
+struct args {
+	pthread_barrier_t barrier;
+	int sock;
+	const struct sigevent *sev;
+};
+
+static void *start(void *p)
+{
+	struct args *args = p;
+	char buf[32];
+	ssize_t n;
+	int s = args->sock;
+	void (*func)(union sigval) = args->sev->sigev_notify_function;
+	union sigval val = args->sev->sigev_value;
+
+	pthread_barrier_wait(&args->barrier);
+	n = recv(s, buf, sizeof(buf), MSG_NOSIGNAL|MSG_WAITALL);
+	close(s);
+	if (n==sizeof buf && buf[sizeof buf - 1] == 1)
+		func(val);
+	return 0;
+}
+
+int mq_notify(mqd_t mqd, const struct sigevent *sev)
+{
+	struct args args = { .sev = sev };
+	pthread_attr_t attr;
+	pthread_t td;
+	int s;
+	struct sigevent sev2;
+	static const char zeros[32];
+
+	if (!sev || sev->sigev_notify != SIGEV_THREAD)
+		return syscall(SYS_mq_notify, mqd, sev);
+
+	s = socket(AF_NETLINK, SOCK_RAW|SOCK_CLOEXEC, 0);
+	if (s < 0) return -1;
+	args.sock = s;
+
+	if (sev->sigev_notify_attributes) attr = *sev->sigev_notify_attributes;
+	else pthread_attr_init(&attr);
+	pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
+	pthread_barrier_init(&args.barrier, 0, 2);
+
+	if (pthread_create(&td, &attr, start, &args)) {
+		__syscall(SYS_close, s);
+		errno = EAGAIN;
+		return -1;
+	}
+
+	pthread_barrier_wait(&args.barrier);
+	pthread_barrier_destroy(&args.barrier);
+
+	sev2.sigev_notify = SIGEV_THREAD;
+	sev2.sigev_signo = s;
+	sev2.sigev_value.sival_ptr = (void *)&zeros;
+
+	if (syscall(SYS_mq_notify, mqd, &sev2) < 0) {
+		pthread_cancel(td);
+		__syscall(SYS_close, s);
+		return -1;
+	}
+
+	return 0;
+}
libc/musl/src/mq/mq_open.c
@@ -0,0 +1,19 @@
+#include <mqueue.h>
+#include <fcntl.h>
+#include <stdarg.h>
+#include "syscall.h"
+
+mqd_t mq_open(const char *name, int flags, ...)
+{
+	mode_t mode = 0;
+	struct mq_attr *attr = 0;
+	if (*name == '/') name++;
+	if (flags & O_CREAT) {
+		va_list ap;
+		va_start(ap, flags);
+		mode = va_arg(ap, mode_t);
+		attr = va_arg(ap, struct mq_attr *);
+		va_end(ap);
+	}
+	return syscall(SYS_mq_open, name, flags, mode, attr);
+}
libc/musl/src/mq/mq_receive.c
@@ -0,0 +1,6 @@
+#include <mqueue.h>
+
+ssize_t mq_receive(mqd_t mqd, char *msg, size_t len, unsigned *prio)
+{
+	return mq_timedreceive(mqd, msg, len, prio, 0);
+}
libc/musl/src/mq/mq_send.c
@@ -0,0 +1,6 @@
+#include <mqueue.h>
+
+int mq_send(mqd_t mqd, const char *msg, size_t len, unsigned prio)
+{
+	return mq_timedsend(mqd, msg, len, prio, 0);
+}
libc/musl/src/mq/mq_setattr.c
@@ -0,0 +1,7 @@
+#include <mqueue.h>
+#include "syscall.h"
+
+int mq_setattr(mqd_t mqd, const struct mq_attr *restrict new, struct mq_attr *restrict old)
+{
+	return syscall(SYS_mq_getsetattr, mqd, new, old);
+}
libc/musl/src/mq/mq_timedreceive.c
@@ -0,0 +1,7 @@
+#include <mqueue.h>
+#include "syscall.h"
+
+ssize_t mq_timedreceive(mqd_t mqd, char *restrict msg, size_t len, unsigned *restrict prio, const struct timespec *restrict at)
+{
+	return syscall_cp(SYS_mq_timedreceive, mqd, msg, len, prio, at);
+}
libc/musl/src/mq/mq_timedsend.c
@@ -0,0 +1,7 @@
+#include <mqueue.h>
+#include "syscall.h"
+
+int mq_timedsend(mqd_t mqd, const char *msg, size_t len, unsigned prio, const struct timespec *at)
+{
+	return syscall_cp(SYS_mq_timedsend, mqd, msg, len, prio, at);
+}
libc/musl/src/mq/mq_unlink.c
@@ -0,0 +1,16 @@
+#include <mqueue.h>
+#include <errno.h>
+#include "syscall.h"
+
+int mq_unlink(const char *name)
+{
+	int ret;
+	if (*name == '/') name++;
+	ret = __syscall(SYS_mq_unlink, name);
+	if (ret < 0) {
+		if (ret == -EPERM) ret = -EACCES;
+		errno = -ret;
+		return -1;
+	}
+	return ret;
+}
libc/musl/src/multibyte/btowc.c
@@ -0,0 +1,10 @@
+#include <stdio.h>
+#include <wchar.h>
+#include <stdlib.h>
+#include "internal.h"
+
+wint_t btowc(int c)
+{
+	int b = (unsigned char)c;
+	return b<128U ? b : (MB_CUR_MAX==1 && c!=EOF) ? CODEUNIT(c) : WEOF;
+}
libc/musl/src/multibyte/c16rtomb.c
@@ -0,0 +1,35 @@
+#include <uchar.h>
+#include <errno.h>
+#include <wchar.h>
+
+size_t c16rtomb(char *restrict s, char16_t c16, mbstate_t *restrict ps)
+{
+	static unsigned internal_state;
+	if (!ps) ps = (void *)&internal_state;
+	unsigned *x = (unsigned *)ps;
+	wchar_t wc;
+
+	if (!s) {
+		if (*x) goto ilseq;
+		return 1;
+	}
+
+	if (!*x && c16 - 0xd800u < 0x400) {
+		*x = c16 - 0xd7c0 << 10;
+		return 0;
+	}
+
+	if (*x) {
+		if (c16 - 0xdc00u >= 0x400) goto ilseq;
+		else wc = *x + c16 - 0xdc00;
+		*x = 0;
+	} else {
+		wc = c16;
+	}
+	return wcrtomb(s, wc, 0);
+
+ilseq:
+	*x = 0;
+	errno = EILSEQ;
+	return -1;
+}
libc/musl/src/multibyte/c32rtomb.c
@@ -0,0 +1,7 @@
+#include <uchar.h>
+#include <wchar.h>
+
+size_t c32rtomb(char *restrict s, char32_t c32, mbstate_t *restrict ps)
+{
+	return wcrtomb(s, c32, ps);
+}
libc/musl/src/multibyte/internal.c
@@ -0,0 +1,26 @@
+#include "internal.h"
+
+#define C(x) ( x<2 ? -1 : ( R(0x80,0xc0) | x ) )
+#define D(x) C((x+16))
+#define E(x) ( ( x==0 ? R(0xa0,0xc0) : \
+                 x==0xd ? R(0x80,0xa0) : \
+                 R(0x80,0xc0) ) \
+             | ( R(0x80,0xc0) >> 6 ) \
+             | x )
+#define F(x) ( ( x>=5 ? 0 : \
+                 x==0 ? R(0x90,0xc0) : \
+                 x==4 ? R(0x80,0x90) : \
+                 R(0x80,0xc0) ) \
+             | ( R(0x80,0xc0) >> 6 ) \
+             | ( R(0x80,0xc0) >> 12 ) \
+             | x )
+
+const uint32_t bittab[] = {
+	              C(0x2),C(0x3),C(0x4),C(0x5),C(0x6),C(0x7),
+	C(0x8),C(0x9),C(0xa),C(0xb),C(0xc),C(0xd),C(0xe),C(0xf),
+	D(0x0),D(0x1),D(0x2),D(0x3),D(0x4),D(0x5),D(0x6),D(0x7),
+	D(0x8),D(0x9),D(0xa),D(0xb),D(0xc),D(0xd),D(0xe),D(0xf),
+	E(0x0),E(0x1),E(0x2),E(0x3),E(0x4),E(0x5),E(0x6),E(0x7),
+	E(0x8),E(0x9),E(0xa),E(0xb),E(0xc),E(0xd),E(0xe),E(0xf),
+	F(0x0),F(0x1),F(0x2),F(0x3),F(0x4)
+};
libc/musl/src/multibyte/internal.h
@@ -0,0 +1,24 @@
+#define bittab __fsmu8
+
+#include <stdint.h>
+#include <features.h>
+
+extern hidden const uint32_t bittab[];
+
+/* Upper 6 state bits are a negative integer offset to bound-check next byte */
+/*    equivalent to: ( (b-0x80) | (b+offset) ) & ~0x3f      */
+#define OOB(c,b) (((((b)>>3)-0x10)|(((b)>>3)+((int32_t)(c)>>26))) & ~7)
+
+/* Interval [a,b). Either a must be 80 or b must be c0, lower 3 bits clear. */
+#define R(a,b) ((uint32_t)((a==0x80 ? 0x40u-b : 0u-a) << 23))
+#define FAILSTATE R(0x80,0x80)
+
+#define SA 0xc2u
+#define SB 0xf4u
+
+/* Arbitrary encoding for representing code units instead of characters. */
+#define CODEUNIT(c) (0xdfff & (signed char)(c))
+#define IS_CODEUNIT(c) ((unsigned)(c)-0xdf80 < 0x80)
+
+/* Get inline definition of MB_CUR_MAX. */
+#include "locale_impl.h"
libc/musl/src/multibyte/mblen.c
@@ -0,0 +1,6 @@
+#include <stdlib.h>
+
+int mblen(const char *s, size_t n)
+{
+	return mbtowc(0, s, n);
+}
libc/musl/src/multibyte/mbrlen.c
@@ -0,0 +1,7 @@
+#include <wchar.h>
+
+size_t mbrlen(const char *restrict s, size_t n, mbstate_t *restrict st)
+{
+	static unsigned internal;
+	return mbrtowc(0, s, n, st ? st : (mbstate_t *)&internal);
+}
libc/musl/src/multibyte/mbrtoc16.c
@@ -0,0 +1,30 @@
+#include <uchar.h>
+#include <wchar.h>
+
+size_t mbrtoc16(char16_t *restrict pc16, const char *restrict s, size_t n, mbstate_t *restrict ps)
+{
+	static unsigned internal_state;
+	if (!ps) ps = (void *)&internal_state;
+	unsigned *pending = (unsigned *)ps;
+
+	if (!s) return mbrtoc16(0, "", 1, ps);
+
+	/* mbrtowc states for partial UTF-8 characters have the high bit set;
+	 * we use nonzero states without high bit for pending surrogates. */
+	if ((int)*pending > 0) {
+ 		if (pc16) *pc16 = *pending;
+		*pending = 0;
+		return -3;
+	}
+
+	wchar_t wc;
+	size_t ret = mbrtowc(&wc, s, n, ps);
+	if (ret <= 4) {
+		if (wc >= 0x10000) {
+			*pending = (wc & 0x3ff) + 0xdc00;
+			wc = 0xd7c0 + (wc >> 10);
+		}
+		if (pc16) *pc16 = wc;
+	}
+	return ret;
+}
libc/musl/src/multibyte/mbrtoc32.c
@@ -0,0 +1,13 @@
+#include <uchar.h>
+#include <wchar.h>
+
+size_t mbrtoc32(char32_t *restrict pc32, const char *restrict s, size_t n, mbstate_t *restrict ps)
+{
+	static unsigned internal_state;
+	if (!ps) ps = (void *)&internal_state;
+	if (!s) return mbrtoc32(0, "", 1, ps);
+	wchar_t wc;
+	size_t ret = mbrtowc(&wc, s, n, ps);
+	if (ret <= 4 && pc32) *pc32 = wc;
+	return ret;
+}
libc/musl/src/multibyte/mbrtowc.c
@@ -0,0 +1,51 @@
+#include <stdlib.h>
+#include <wchar.h>
+#include <errno.h>
+#include "internal.h"
+
+size_t mbrtowc(wchar_t *restrict wc, const char *restrict src, size_t n, mbstate_t *restrict st)
+{
+	static unsigned internal_state;
+	unsigned c;
+	const unsigned char *s = (const void *)src;
+	const unsigned N = n;
+	wchar_t dummy;
+
+	if (!st) st = (void *)&internal_state;
+	c = *(unsigned *)st;
+	
+	if (!s) {
+		if (c) goto ilseq;
+		return 0;
+	} else if (!wc) wc = &dummy;
+
+	if (!n) return -2;
+	if (!c) {
+		if (*s < 0x80) return !!(*wc = *s);
+		if (MB_CUR_MAX==1) return (*wc = CODEUNIT(*s)), 1;
+		if (*s-SA > SB-SA) goto ilseq;
+		c = bittab[*s++-SA]; n--;
+	}
+
+	if (n) {
+		if (OOB(c,*s)) goto ilseq;
+loop:
+		c = c<<6 | *s++-0x80; n--;
+		if (!(c&(1U<<31))) {
+			*(unsigned *)st = 0;
+			*wc = c;
+			return N-n;
+		}
+		if (n) {
+			if (*s-0x80u >= 0x40) goto ilseq;
+			goto loop;
+		}
+	}
+
+	*(unsigned *)st = c;
+	return -2;
+ilseq:
+	*(unsigned *)st = 0;
+	errno = EILSEQ;
+	return -1;
+}
libc/musl/src/multibyte/mbsinit.c
@@ -0,0 +1,6 @@
+#include <wchar.h>
+
+int mbsinit(const mbstate_t *st)
+{
+	return !st || !*(unsigned *)st;
+}
libc/musl/src/multibyte/mbsnrtowcs.c
@@ -0,0 +1,55 @@
+#include <wchar.h>
+
+size_t mbsnrtowcs(wchar_t *restrict wcs, const char **restrict src, size_t n, size_t wn, mbstate_t *restrict st)
+{
+	size_t l, cnt=0, n2;
+	wchar_t *ws, wbuf[256];
+	const char *s = *src;
+	const char *tmp_s;
+
+	if (!wcs) ws = wbuf, wn = sizeof wbuf / sizeof *wbuf;
+	else ws = wcs;
+
+	/* making sure output buffer size is at most n/4 will ensure
+	 * that mbsrtowcs never reads more than n input bytes. thus
+	 * we can use mbsrtowcs as long as it's practical.. */
+
+	while ( s && wn && ( (n2=n/4)>=wn || n2>32 ) ) {
+		if (n2>=wn) n2=wn;
+		tmp_s = s;
+		l = mbsrtowcs(ws, &s, n2, st);
+		if (!(l+1)) {
+			cnt = l;
+			wn = 0;
+			break;
+		}
+		if (ws != wbuf) {
+			ws += l;
+			wn -= l;
+		}
+		n = s ? n - (s - tmp_s) : 0;
+		cnt += l;
+	}
+	if (s) while (wn && n) {
+		l = mbrtowc(ws, s, n, st);
+		if (l+2<=2) {
+			if (!(l+1)) {
+				cnt = l;
+				break;
+			}
+			if (!l) {
+				s = 0;
+				break;
+			}
+			/* have to roll back partial character */
+			*(unsigned *)st = 0;
+			break;
+		}
+		s += l; n -= l;
+		/* safe - this loop runs fewer than sizeof(wbuf)/8 times */
+		ws++; wn--;
+		cnt++;
+	}
+	if (wcs) *src = s;
+	return cnt;
+}
libc/musl/src/multibyte/mbsrtowcs.c
@@ -0,0 +1,114 @@
+#include <stdint.h>
+#include <wchar.h>
+#include <errno.h>
+#include <string.h>
+#include <stdlib.h>
+#include "internal.h"
+
+size_t mbsrtowcs(wchar_t *restrict ws, const char **restrict src, size_t wn, mbstate_t *restrict st)
+{
+	const unsigned char *s = (const void *)*src;
+	size_t wn0 = wn;
+	unsigned c = 0;
+
+	if (st && (c = *(unsigned *)st)) {
+		if (ws) {
+			*(unsigned *)st = 0;
+			goto resume;
+		} else {
+			goto resume0;
+		}
+	}
+
+	if (MB_CUR_MAX==1) {
+		if (!ws) return strlen((const char *)s);
+		for (;;) {
+			if (!wn) {
+				*src = (const void *)s;
+				return wn0;
+			}
+			if (!*s) break;
+			c = *s++;
+			*ws++ = CODEUNIT(c);
+			wn--;
+		}
+		*ws = 0;
+		*src = 0;
+		return wn0-wn;
+	}
+
+	if (!ws) for (;;) {
+		if (*s-1u < 0x7f && (uintptr_t)s%4 == 0) {
+			while (!(( *(uint32_t*)s | *(uint32_t*)s-0x01010101) & 0x80808080)) {
+				s += 4;
+				wn -= 4;
+			}
+		}
+		if (*s-1u < 0x7f) {
+			s++;
+			wn--;
+			continue;
+		}
+		if (*s-SA > SB-SA) break;
+		c = bittab[*s++-SA];
+resume0:
+		if (OOB(c,*s)) { s--; break; }
+		s++;
+		if (c&(1U<<25)) {
+			if (*s-0x80u >= 0x40) { s-=2; break; }
+			s++;
+			if (c&(1U<<19)) {
+				if (*s-0x80u >= 0x40) { s-=3; break; }
+				s++;
+			}
+		}
+		wn--;
+		c = 0;
+	} else for (;;) {
+		if (!wn) {
+			*src = (const void *)s;
+			return wn0;
+		}
+		if (*s-1u < 0x7f && (uintptr_t)s%4 == 0) {
+			while (wn>=5 && !(( *(uint32_t*)s | *(uint32_t*)s-0x01010101) & 0x80808080)) {
+				*ws++ = *s++;
+				*ws++ = *s++;
+				*ws++ = *s++;
+				*ws++ = *s++;
+				wn -= 4;
+			}
+		}
+		if (*s-1u < 0x7f) {
+			*ws++ = *s++;
+			wn--;
+			continue;
+		}
+		if (*s-SA > SB-SA) break;
+		c = bittab[*s++-SA];
+resume:
+		if (OOB(c,*s)) { s--; break; }
+		c = (c<<6) | *s++-0x80;
+		if (c&(1U<<31)) {
+			if (*s-0x80u >= 0x40) { s-=2; break; }
+			c = (c<<6) | *s++-0x80;
+			if (c&(1U<<31)) {
+				if (*s-0x80u >= 0x40) { s-=3; break; }
+				c = (c<<6) | *s++-0x80;
+			}
+		}
+		*ws++ = c;
+		wn--;
+		c = 0;
+	}
+
+	if (!c && !*s) {
+		if (ws) {
+			*ws = 0;
+			*src = 0;
+		}
+		return wn0-wn;
+	}
+	errno = EILSEQ;
+	if (ws) *src = (const void *)s;
+	return -1;
+}
libc/musl/src/multibyte/mbstowcs.c
@@ -0,0 +1,7 @@
+#include <stdlib.h>
+#include <wchar.h>
+
+size_t mbstowcs(wchar_t *restrict ws, const char *restrict s, size_t wn)
+{
+	return mbsrtowcs(ws, (void*)&s, wn, 0);
+}
libc/musl/src/multibyte/mbtowc.c
@@ -0,0 +1,47 @@
+#include <stdlib.h>
+#include <wchar.h>
+#include <errno.h>
+#include "internal.h"
+
+int mbtowc(wchar_t *restrict wc, const char *restrict src, size_t n)
+{
+	unsigned c;
+	const unsigned char *s = (const void *)src;
+	wchar_t dummy;
+
+	if (!s) return 0;
+	if (!n) goto ilseq;
+	if (!wc) wc = &dummy;
+
+	if (*s < 0x80) return !!(*wc = *s);
+	if (MB_CUR_MAX==1) return (*wc = CODEUNIT(*s)), 1;
+	if (*s-SA > SB-SA) goto ilseq;
+	c = bittab[*s++-SA];
+
+	/* Avoid excessive checks against n: If shifting the state n-1
+	 * times does not clear the high bit, then the value of n is
+	 * insufficient to read a character */
+	if (n<4 && ((c<<(6*n-6)) & (1U<<31))) goto ilseq;
+
+	if (OOB(c,*s)) goto ilseq;
+	c = c<<6 | *s++-0x80;
+	if (!(c&(1U<<31))) {
+		*wc = c;
+		return 2;
+	}
+
+	if (*s-0x80u >= 0x40) goto ilseq;
+	c = c<<6 | *s++-0x80;
+	if (!(c&(1U<<31))) {
+		*wc = c;
+		return 3;
+	}
+
+	if (*s-0x80u >= 0x40) goto ilseq;
+	*wc = c<<6 | *s++-0x80;
+	return 4;
+
+ilseq:
+	errno = EILSEQ;
+	return -1;
+}
libc/musl/src/multibyte/wcrtomb.c
@@ -0,0 +1,37 @@
+#include <stdlib.h>
+#include <wchar.h>
+#include <errno.h>
+#include "internal.h"
+
+size_t wcrtomb(char *restrict s, wchar_t wc, mbstate_t *restrict st)
+{
+	if (!s) return 1;
+	if ((unsigned)wc < 0x80) {
+		*s = wc;
+		return 1;
+	} else if (MB_CUR_MAX == 1) {
+		if (!IS_CODEUNIT(wc)) {
+			errno = EILSEQ;
+			return -1;
+		}
+		*s = wc;
+		return 1;
+	} else if ((unsigned)wc < 0x800) {
+		*s++ = 0xc0 | (wc>>6);
+		*s = 0x80 | (wc&0x3f);
+		return 2;
+	} else if ((unsigned)wc < 0xd800 || (unsigned)wc-0xe000 < 0x2000) {
+		*s++ = 0xe0 | (wc>>12);
+		*s++ = 0x80 | ((wc>>6)&0x3f);
+		*s = 0x80 | (wc&0x3f);
+		return 3;
+	} else if ((unsigned)wc-0x10000 < 0x100000) {
+		*s++ = 0xf0 | (wc>>18);
+		*s++ = 0x80 | ((wc>>12)&0x3f);
+		*s++ = 0x80 | ((wc>>6)&0x3f);
+		*s = 0x80 | (wc&0x3f);
+		return 4;
+	}
+	errno = EILSEQ;
+	return -1;
+}
libc/musl/src/multibyte/wcsnrtombs.c
@@ -0,0 +1,43 @@
+#include <wchar.h>
+
+size_t wcsnrtombs(char *restrict dst, const wchar_t **restrict wcs, size_t wn, size_t n, mbstate_t *restrict st)
+{
+	size_t l, cnt=0, n2;
+	char *s, buf[256];
+	const wchar_t *ws = *wcs;
+	const wchar_t *tmp_ws;
+
+	if (!dst) s = buf, n = sizeof buf;
+	else s = dst;
+
+	while ( ws && n && ( (n2=wn)>=n || n2>32 ) ) {
+		if (n2>=n) n2=n;
+		tmp_ws = ws;
+		l = wcsrtombs(s, &ws, n2, 0);
+		if (!(l+1)) {
+			cnt = l;
+			n = 0;
+			break;
+		}
+		if (s != buf) {
+			s += l;
+			n -= l;
+		}
+		wn = ws ? wn - (ws - tmp_ws) : 0;
+		cnt += l;
+	}
+	if (ws) while (n && wn) {
+		l = wcrtomb(s, *ws, 0);
+		if ((l+1)<=1) {
+			if (!l) ws = 0;
+			else cnt = l;
+			break;
+		}
+		ws++; wn--;
+		/* safe - this loop runs fewer than sizeof(buf) times */
+		s+=l; n-=l;
+		cnt += l;
+	}
+	if (dst) *wcs = ws;
+	return cnt;
+}
libc/musl/src/multibyte/wcsrtombs.c
@@ -0,0 +1,55 @@
+#include <wchar.h>
+
+size_t wcsrtombs(char *restrict s, const wchar_t **restrict ws, size_t n, mbstate_t *restrict st)
+{
+	const wchar_t *ws2;
+	char buf[4];
+	size_t N = n, l;
+	if (!s) {
+		for (n=0, ws2=*ws; *ws2; ws2++) {
+			if (*ws2 >= 0x80u) {
+				l = wcrtomb(buf, *ws2, 0);
+				if (!(l+1)) return -1;
+				n += l;
+			} else n++;
+		}
+		return n;
+	}
+	while (n>=4) {
+		if (**ws-1u >= 0x7fu) {
+			if (!**ws) {
+				*s = 0;
+				*ws = 0;
+				return N-n;
+			}
+			l = wcrtomb(s, **ws, 0);
+			if (!(l+1)) return -1;
+			s += l;
+			n -= l;
+		} else {
+			*s++ = **ws;
+			n--;
+		}
+		(*ws)++;
+	}
+	while (n) {
+		if (**ws-1u >= 0x7fu) {
+			if (!**ws) {
+				*s = 0;
+				*ws = 0;
+				return N-n;
+			}
+			l = wcrtomb(buf, **ws, 0);
+			if (!(l+1)) return -1;
+			if (l>n) return N-n;
+			wcrtomb(s, **ws, 0);
+			s += l;
+			n -= l;
+		} else {
+			*s++ = **ws;
+			n--;
+		}
+		(*ws)++;
+	}
+	return N;
+}
libc/musl/src/multibyte/wcstombs.c
@@ -0,0 +1,7 @@
+#include <stdlib.h>
+#include <wchar.h>
+
+size_t wcstombs(char *restrict s, const wchar_t *restrict ws, size_t n)
+{
+	return wcsrtombs(s, &(const wchar_t *){ws}, n, 0);
+}
libc/musl/src/multibyte/wctob.c
@@ -0,0 +1,11 @@
+#include <wchar.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include "internal.h"
+
+int wctob(wint_t c)
+{
+	if (c < 128U) return c;
+	if (MB_CUR_MAX==1 && IS_CODEUNIT(c)) return (unsigned char)c;
+	return EOF;
+}
libc/musl/src/multibyte/wctomb.c
@@ -0,0 +1,8 @@
+#include <stdlib.h>
+#include <wchar.h>
+
+int wctomb(char *s, wchar_t wc)
+{
+	if (!s) return 0;
+	return wcrtomb(s, wc, 0);
+}
libc/musl/src/network/accept.c
@@ -0,0 +1,7 @@
+#include <sys/socket.h>
+#include "syscall.h"
+
+int accept(int fd, struct sockaddr *restrict addr, socklen_t *restrict len)
+{
+	return socketcall_cp(accept, fd, addr, len, 0, 0, 0);
+}
libc/musl/src/network/accept4.c
@@ -0,0 +1,19 @@
+#define _GNU_SOURCE
+#include <sys/socket.h>
+#include <errno.h>
+#include <fcntl.h>
+#include "syscall.h"
+
+int accept4(int fd, struct sockaddr *restrict addr, socklen_t *restrict len, int flg)
+{
+	if (!flg) return accept(fd, addr, len);
+	int ret = socketcall_cp(accept4, fd, addr, len, flg, 0, 0);
+	if (ret>=0 || (errno != ENOSYS && errno != EINVAL)) return ret;
+	ret = accept(fd, addr, len);
+	if (ret<0) return ret;
+	if (flg & SOCK_CLOEXEC)
+		__syscall(SYS_fcntl, ret, F_SETFD, FD_CLOEXEC);
+	if (flg & SOCK_NONBLOCK)
+		__syscall(SYS_fcntl, ret, F_SETFL, O_NONBLOCK);
+	return ret;
+}
libc/musl/src/network/bind.c
@@ -0,0 +1,7 @@
+#include <sys/socket.h>
+#include "syscall.h"
+
+int bind(int fd, const struct sockaddr *addr, socklen_t len)
+{
+	return socketcall(bind, fd, addr, len, 0, 0, 0);
+}
libc/musl/src/network/connect.c
@@ -0,0 +1,7 @@
+#include <sys/socket.h>
+#include "syscall.h"
+
+int connect(int fd, const struct sockaddr *addr, socklen_t len)
+{
+	return socketcall_cp(connect, fd, addr, len, 0, 0, 0);
+}
libc/musl/src/network/dn_comp.c
@@ -0,0 +1,107 @@
+#include <string.h>
+#include <resolv.h>
+
+/* RFC 1035 message compression */
+
+/* label start offsets of a compressed domain name s */
+static int getoffs(short *offs, const unsigned char *base, const unsigned char *s)
+{
+	int i=0;
+	for (;;) {
+		while (*s & 0xc0) {
+			if ((*s & 0xc0) != 0xc0) return 0;
+			s = base + ((s[0]&0x3f)<<8 | s[1]);
+		}
+		if (!*s) return i;
+		if (s-base >= 0x4000) return 0;
+		offs[i++] = s-base;
+		s += *s + 1;
+	}
+}
+
+/* label lengths of an ascii domain name s */
+static int getlens(unsigned char *lens, const char *s, int l)
+{
+	int i=0,j=0,k=0;
+	for (;;) {
+		for (; j<l && s[j]!='.'; j++);
+		if (j-k-1u > 62) return 0;
+		lens[i++] = j-k;
+		if (j==l) return i;
+		k = ++j;
+	}
+}
+
+/* longest suffix match of an ascii domain with a compressed domain name dn */
+static int match(int *offset, const unsigned char *base, const unsigned char *dn,
+	const char *end, const unsigned char *lens, int nlen)
+{
+	int l, o, m=0;
+	short offs[128];
+	int noff = getoffs(offs, base, dn);
+	if (!noff) return 0;
+	for (;;) {
+		l = lens[--nlen];
+		o = offs[--noff];
+		end -= l;
+		if (l != base[o] || memcmp(base+o+1, end, l))
+			return m;
+		*offset = o;
+		m += l;
+		if (nlen) m++;
+		if (!nlen || !noff) return m;
+		end--;
+	}
+}
+
+int dn_comp(const char *src, unsigned char *dst, int space, unsigned char **dnptrs, unsigned char **lastdnptr)
+{
+	int i, j, n, m=0, offset, bestlen=0, bestoff;
+	unsigned char lens[127];
+	unsigned char **p;
+	const char *end;
+	size_t l = strnlen(src, 255);
+	if (l && src[l-1] == '.') l--;
+	if (l>253 || space<=0) return -1;
+	if (!l) {
+		*dst = 0;
+		return 1;
+	}
+	end = src+l;
+	n = getlens(lens, src, l);
+	if (!n) return -1;
+
+	p = dnptrs;
+	if (p && *p) for (p++; *p; p++) {
+		m = match(&offset, *dnptrs, *p, end, lens, n);
+		if (m > bestlen) {
+			bestlen = m;
+			bestoff = offset;
+			if (m == l)
+				break;
+		}
+	}
+
+	/* encode unmatched part */
+	if (space < l-bestlen+2+(bestlen-1 < l-1)) return -1;
+	memcpy(dst+1, src, l-bestlen);
+	for (i=j=0; i<l-bestlen; i+=lens[j++]+1)
+		dst[i] = lens[j];
+
+	/* add tail */
+	if (bestlen) {
+		dst[i++] = 0xc0 | bestoff>>8;
+		dst[i++] = bestoff;
+	} else
+		dst[i++] = 0;
+
+	/* save dst pointer */
+	if (i>2 && lastdnptr && dnptrs && *dnptrs) {
+		while (*p) p++;
+		if (p+1 < lastdnptr) {
+			*p++ = dst;
+			*p=0;
+		}
+	}
+	return i;
+}
libc/musl/src/network/dn_expand.c
@@ -0,0 +1,33 @@
+#include <resolv.h>
+
+int __dn_expand(const unsigned char *base, const unsigned char *end, const unsigned char *src, char *dest, int space)
+{
+	const unsigned char *p = src;
+	char *dend, *dbegin = dest;
+	int len = -1, i, j;
+	if (p==end || space <= 0) return -1;
+	dend = dest + (space > 254 ? 254 : space);
+	/* detect reference loop using an iteration counter */
+	for (i=0; i < end-base; i+=2) {
+		/* loop invariants: p<end, dest<dend */
+		if (*p & 0xc0) {
+			if (p+1==end) return -1;
+			j = ((p[0] & 0x3f) << 8) | p[1];
+			if (len < 0) len = p+2-src;
+			if (j >= end-base) return -1;
+			p = base+j;
+		} else if (*p) {
+			if (dest != dbegin) *dest++ = '.';
+			j = *p++;
+			if (j >= end-p || j >= dend-dest) return -1;
+			while (j--) *dest++ = *p++;
+		} else {
+			*dest = 0;
+			if (len < 0) len = p+1-src;
+			return len;
+		}
+	}
+	return -1;
+}
+
+weak_alias(__dn_expand, dn_expand);
libc/musl/src/network/dn_skipname.c
@@ -0,0 +1,12 @@
+#include <resolv.h>
+
+int dn_skipname(const unsigned char *s, const unsigned char *end)
+{
+	const unsigned char *p;
+	for (p=s; p<end; p++)
+		if (!*p) return p-s+1;
+		else if (*p>=192)
+			if (p+1<end) return p-s+2;
+			else break;
+	return -1;
+}
libc/musl/src/network/dns_parse.c
@@ -0,0 +1,33 @@
+#include <string.h>
+#include "lookup.h"
+
+int __dns_parse(const unsigned char *r, int rlen, int (*callback)(void *, int, const void *, int, const void *), void *ctx)
+{
+	int qdcount, ancount;
+	const unsigned char *p;
+	int len;
+
+	if (rlen<12) return -1;
+	if ((r[3]&15)) return 0;
+	p = r+12;
+	qdcount = r[4]*256 + r[5];
+	ancount = r[6]*256 + r[7];
+	if (qdcount+ancount > 64) return -1;
+	while (qdcount--) {
+		while (p-r < rlen && *p-1U < 127) p++;
+		if (*p>193 || (*p==193 && p[1]>254) || p>r+rlen-6)
+			return -1;
+		p += 5 + !!*p;
+	}
+	while (ancount--) {
+		while (p-r < rlen && *p-1U < 127) p++;
+		if (*p>193 || (*p==193 && p[1]>254) || p>r+rlen-6)
+			return -1;
+		p += 1 + !!*p;
+		len = p[8]*256 + p[9];
+		if (p+len > r+rlen) return -1;
+		if (callback(ctx, p[1], p+10, len, r) < 0) return -1;
+		p += 10 + len;
+	}
+	return 0;
+}
libc/musl/src/network/ent.c
@@ -0,0 +1,22 @@
+#include <netdb.h>
+
+void sethostent(int x)
+{
+}
+
+struct hostent *gethostent()
+{
+	return 0;
+}
+
+struct netent *getnetent()
+{
+	return 0;
+}
+
+void endhostent(void)
+{
+}
+
+weak_alias(sethostent, setnetent);
+weak_alias(endhostent, endnetent);
libc/musl/src/network/ether.c
@@ -0,0 +1,58 @@
+#include <stdlib.h>
+#include <netinet/ether.h>
+#include <stdio.h>
+
+struct ether_addr *ether_aton_r (const char *x, struct ether_addr *p_a)
+{
+	struct ether_addr a;
+	char *y;
+	for (int ii = 0; ii < 6; ii++) {
+		unsigned long int n;
+		if (ii != 0) {
+			if (x[0] != ':') return 0; /* bad format */
+			else x++;
+		}
+		n = strtoul (x, &y, 16);
+		x = y;
+		if (n > 0xFF) return 0; /* bad byte */
+		a.ether_addr_octet[ii] = n;
+	}
+	if (x[0] != 0) return 0; /* bad format */
+	*p_a = a;
+	return p_a;
+}
+
+struct ether_addr *ether_aton (const char *x)
+{
+	static struct ether_addr a;
+	return ether_aton_r (x, &a);
+}
+
+char *ether_ntoa_r (const struct ether_addr *p_a, char *x) {
+	char *y;
+	y = x;
+	for (int ii = 0; ii < 6; ii++) {
+		x += sprintf (x, ii == 0 ? "%.2X" : ":%.2X", p_a->ether_addr_octet[ii]);
+	}
+	return y;
+}
+
+char *ether_ntoa (const struct ether_addr *p_a) {
+	static char x[18];
+	return ether_ntoa_r (p_a, x);
+}
+
+int ether_line(const char *l, struct ether_addr *e, char *hostname)
+{
+	return -1;
+}
+
+int ether_ntohost(char *hostname, const struct ether_addr *e)
+{
+	return -1;
+}
+
+int ether_hostton(const char *hostname, struct ether_addr *e)
+{
+	return -1;
+}
libc/musl/src/network/freeaddrinfo.c
@@ -0,0 +1,16 @@
+#include <stdlib.h>
+#include <stddef.h>
+#include <netdb.h>
+#include "lookup.h"
+#include "lock.h"
+
+void freeaddrinfo(struct addrinfo *p)
+{
+	size_t cnt;
+	for (cnt=1; p->ai_next; cnt++, p=p->ai_next);
+	struct aibuf *b = (void *)((char *)p - offsetof(struct aibuf, ai));
+	b -= b->slot;
+	LOCK(b->lock);
+	if (!(b->ref -= cnt)) free(b);
+	else UNLOCK(b->lock);
+}
libc/musl/src/network/gai_strerror.c
@@ -0,0 +1,25 @@
+#include <netdb.h>
+#include "locale_impl.h"
+
+static const char msgs[] =
+	"Invalid flags\0"
+	"Name does not resolve\0"
+	"Try again\0"
+	"Non-recoverable error\0"
+	"Unknown error\0"
+	"Unrecognized address family or invalid length\0"
+	"Unrecognized socket type\0"
+	"Unrecognized service\0"
+	"Unknown error\0"
+	"Out of memory\0"
+	"System error\0"
+	"Overflow\0"
+	"\0Unknown error";
+
+const char *gai_strerror(int ecode)
+{
+	const char *s;
+	for (s=msgs, ecode++; ecode && *s; ecode++, s++) for (; *s; s++);
+	if (!*s) s++;
+	return LCTRANS_CUR(s);
+}
libc/musl/src/network/getaddrinfo.c
@@ -0,0 +1,136 @@
+#include <stdlib.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <netdb.h>
+#include <string.h>
+#include <pthread.h>
+#include <unistd.h>
+#include <endian.h>
+#include <errno.h>
+#include "lookup.h"
+
+int getaddrinfo(const char *restrict host, const char *restrict serv, const struct addrinfo *restrict hint, struct addrinfo **restrict res)
+{
+	struct service ports[MAXSERVS];
+	struct address addrs[MAXADDRS];
+	char canon[256], *outcanon;
+	int nservs, naddrs, nais, canon_len, i, j, k;
+	int family = AF_UNSPEC, flags = 0, proto = 0, socktype = 0;
+	struct aibuf *out;
+
+	if (!host && !serv) return EAI_NONAME;
+
+	if (hint) {
+		family = hint->ai_family;
+		flags = hint->ai_flags;
+		proto = hint->ai_protocol;
+		socktype = hint->ai_socktype;
+
+		const int mask = AI_PASSIVE | AI_CANONNAME | AI_NUMERICHOST |
+			AI_V4MAPPED | AI_ALL | AI_ADDRCONFIG | AI_NUMERICSERV;
+		if ((flags & mask) != flags)
+			return EAI_BADFLAGS;
+
+		switch (family) {
+		case AF_INET:
+		case AF_INET6:
+		case AF_UNSPEC:
+			break;
+		default:
+			return EAI_FAMILY;
+		}
+	}
+
+	if (flags & AI_ADDRCONFIG) {
+		/* Define the "an address is configured" condition for address
+		 * families via ability to create a socket for the family plus
+		 * routability of the loopback address for the family. */
+		static const struct sockaddr_in lo4 = {
+			.sin_family = AF_INET, .sin_port = 65535,
+			.sin_addr.s_addr = __BYTE_ORDER == __BIG_ENDIAN
+				? 0x7f000001 : 0x0100007f
+		};
+		static const struct sockaddr_in6 lo6 = {
+			.sin6_family = AF_INET6, .sin6_port = 65535,
+			.sin6_addr = IN6ADDR_LOOPBACK_INIT
+		};
+		int tf[2] = { AF_INET, AF_INET6 };
+		const void *ta[2] = { &lo4, &lo6 };
+		socklen_t tl[2] = { sizeof lo4, sizeof lo6 };
+		for (i=0; i<2; i++) {
+			if (family==tf[1-i]) continue;
+			int s = socket(tf[i], SOCK_CLOEXEC|SOCK_DGRAM,
+				IPPROTO_UDP);
+			if (s>=0) {
+				int cs;
+				pthread_setcancelstate(
+					PTHREAD_CANCEL_DISABLE, &cs);
+				int r = connect(s, ta[i], tl[i]);
+				pthread_setcancelstate(cs, 0);
+				close(s);
+				if (!r) continue;
+			}
+			switch (errno) {
+			case EADDRNOTAVAIL:
+			case EAFNOSUPPORT:
+			case EHOSTUNREACH:
+			case ENETDOWN:
+			case ENETUNREACH:
+				break;
+			default:
+				return EAI_SYSTEM;
+			}
+			if (family == tf[i]) return EAI_NONAME;
+			family = tf[1-i];
+		}
+	}
+
+	nservs = __lookup_serv(ports, serv, proto, socktype, flags);
+	if (nservs < 0) return nservs;
+
+	naddrs = __lookup_name(addrs, canon, host, family, flags);
+	if (naddrs < 0) return naddrs;
+
+	nais = nservs * naddrs;
+	canon_len = strlen(canon);
+	out = calloc(1, nais * sizeof(*out) + canon_len + 1);
+	if (!out) return EAI_MEMORY;
+
+	if (canon_len) {
+		outcanon = (void *)&out[nais];
+		memcpy(outcanon, canon, canon_len+1);
+	} else {
+		outcanon = 0;
+	}
+
+	for (k=i=0; i<naddrs; i++) for (j=0; j<nservs; j++, k++) {
+		out[k].slot = i;
+		out[k].ai = (struct addrinfo){
+			.ai_family = addrs[i].family,
+			.ai_socktype = ports[j].socktype,
+			.ai_protocol = ports[j].proto,
+			.ai_addrlen = addrs[i].family == AF_INET
+				? sizeof(struct sockaddr_in)
+				: sizeof(struct sockaddr_in6),
+			.ai_addr = (void *)&out[k].sa,
+			.ai_canonname = outcanon,
+			.ai_next = &out[k+1].ai };
+		switch (addrs[i].family) {
+		case AF_INET:
+			out[k].sa.sin.sin_family = AF_INET;
+			out[k].sa.sin.sin_port = htons(ports[j].port);
+			memcpy(&out[k].sa.sin.sin_addr, &addrs[i].addr, 4);
+			break;
+		case AF_INET6:
+			out[k].sa.sin6.sin6_family = AF_INET6;
+			out[k].sa.sin6.sin6_port = htons(ports[j].port);
+			out[k].sa.sin6.sin6_scope_id = addrs[i].scopeid;
+			memcpy(&out[k].sa.sin6.sin6_addr, &addrs[i].addr, 16);
+			break;			
+		}
+	}
+	out[0].ref = nais;
+	out[nais-1].ai.ai_next = 0;
+	*res = &out->ai;
+	return 0;
+}
libc/musl/src/network/gethostbyaddr.c
@@ -0,0 +1,24 @@
+#define _GNU_SOURCE
+
+#include <netdb.h>
+#include <errno.h>
+#include <stdlib.h>
+
+struct hostent *gethostbyaddr(const void *a, socklen_t l, int af)
+{
+	static struct hostent *h;
+	size_t size = 63;
+	struct hostent *res;
+	int err;
+	do {
+		free(h);
+		h = malloc(size+=size+1);
+		if (!h) {
+			h_errno = NO_RECOVERY;
+			return 0;
+		}
+		err = gethostbyaddr_r(a, l, af, h,
+			(void *)(h+1), size-sizeof *h, &res, &h_errno);
+	} while (err == ERANGE);
+	return err ? 0 : h;
+}
libc/musl/src/network/gethostbyaddr_r.c
@@ -0,0 +1,71 @@
+#define _GNU_SOURCE
+
+#include <sys/socket.h>
+#include <netdb.h>
+#include <string.h>
+#include <netinet/in.h>
+#include <errno.h>
+#include <inttypes.h>
+
+int gethostbyaddr_r(const void *a, socklen_t l, int af,
+	struct hostent *h, char *buf, size_t buflen,
+	struct hostent **res, int *err)
+{
+	union {
+		struct sockaddr_in sin;
+		struct sockaddr_in6 sin6;
+	} sa = { .sin.sin_family = af };
+	socklen_t sl = af==AF_INET6 ? sizeof sa.sin6 : sizeof sa.sin;
+	int i;
+
+	*res = 0;
+
+	/* Load address argument into sockaddr structure */
+	if (af==AF_INET6 && l==16) memcpy(&sa.sin6.sin6_addr, a, 16);
+	else if (af==AF_INET && l==4) memcpy(&sa.sin.sin_addr, a, 4);
+	else {
+		*err = NO_RECOVERY;
+		return EINVAL;
+	}
+
+	/* Align buffer and check for space for pointers and ip address */
+	i = (uintptr_t)buf & sizeof(char *)-1;
+	if (!i) i = sizeof(char *);
+	if (buflen <= 5*sizeof(char *)-i + l) return ERANGE;
+	buf += sizeof(char *)-i;
+	buflen -= 5*sizeof(char *)-i + l;
+
+	h->h_addr_list = (void *)buf;
+	buf += 2*sizeof(char *);
+	h->h_aliases = (void *)buf;
+	buf += 2*sizeof(char *);
+
+	h->h_addr_list[0] = buf;
+	memcpy(h->h_addr_list[0], a, l);
+	buf += l;
+	h->h_addr_list[1] = 0;
+	h->h_aliases[0] = buf;
+	h->h_aliases[1] = 0;
+
+	switch (getnameinfo((void *)&sa, sl, buf, buflen, 0, 0, 0)) {
+	case EAI_AGAIN:
+		*err = TRY_AGAIN;
+		return EAGAIN;
+	case EAI_OVERFLOW:
+		return ERANGE;
+	default:
+	case EAI_MEMORY:
+	case EAI_SYSTEM:
+	case EAI_FAIL:
+		*err = NO_RECOVERY;
+		return errno;
+	case 0:
+		break;
+	}
+
+	h->h_addrtype = af;
+	h->h_length = l;
+	h->h_name = h->h_aliases[0];
+	*res = h;
+	return 0;
+}
libc/musl/src/network/gethostbyname.c
@@ -0,0 +1,11 @@
+#define _GNU_SOURCE
+
+#include <sys/socket.h>
+#include <netdb.h>
+#include <string.h>
+#include <netinet/in.h>
+
+struct hostent *gethostbyname(const char *name)
+{
+	return gethostbyname2(name, AF_INET);
+}
libc/musl/src/network/gethostbyname2.c
@@ -0,0 +1,25 @@
+#define _GNU_SOURCE
+
+#include <sys/socket.h>
+#include <netdb.h>
+#include <errno.h>
+#include <stdlib.h>
+
+struct hostent *gethostbyname2(const char *name, int af)
+{
+	static struct hostent *h;
+	size_t size = 63;
+	struct hostent *res;
+	int err;
+	do {
+		free(h);
+		h = malloc(size+=size+1);
+		if (!h) {
+			h_errno = NO_RECOVERY;
+			return 0;
+		}
+		err = gethostbyname2_r(name, af, h,
+			(void *)(h+1), size-sizeof *h, &res, &h_errno);
+	} while (err == ERANGE);
+	return err ? 0 : h;
+}
libc/musl/src/network/gethostbyname2_r.c
@@ -0,0 +1,80 @@
+#define _GNU_SOURCE
+
+#include <sys/socket.h>
+#include <netdb.h>
+#include <string.h>
+#include <netinet/in.h>
+#include <errno.h>
+#include <stdint.h>
+#include "lookup.h"
+
+int gethostbyname2_r(const char *name, int af,
+	struct hostent *h, char *buf, size_t buflen,
+	struct hostent **res, int *err)
+{
+	struct address addrs[MAXADDRS];
+	char canon[256];
+	int i, cnt;
+	size_t align, need;
+
+	*res = 0;
+	cnt = __lookup_name(addrs, canon, name, af, AI_CANONNAME);
+	if (cnt<0) switch (cnt) {
+	case EAI_NONAME:
+		*err = HOST_NOT_FOUND;
+		return ENOENT;
+	case EAI_AGAIN:
+		*err = TRY_AGAIN;
+		return EAGAIN;
+	default:
+	case EAI_FAIL:
+		*err = NO_RECOVERY;
+		return EBADMSG;
+	case EAI_MEMORY:
+	case EAI_SYSTEM:
+		*err = NO_RECOVERY;
+		return errno;
+	}
+
+	h->h_addrtype = af;
+	h->h_length = af==AF_INET6 ? 16 : 4;
+
+	/* Align buffer */
+	align = -(uintptr_t)buf & sizeof(char *)-1;
+
+	need = 4*sizeof(char *);
+	need += (cnt + 1) * (sizeof(char *) + h->h_length);
+	need += strlen(name)+1;
+	need += strlen(canon)+1;
+	need += align;
+
+	if (need > buflen) return ERANGE;
+
+	buf += align;
+	h->h_aliases = (void *)buf;
+	buf += 3*sizeof(char *);
+	h->h_addr_list = (void *)buf;
+	buf += (cnt+1)*sizeof(char *);
+
+	for (i=0; i<cnt; i++) {
+		h->h_addr_list[i] = (void *)buf;
+		buf += h->h_length;
+		memcpy(h->h_addr_list[i], addrs[i].addr, h->h_length);
+	}
+	h->h_addr_list[i] = 0;
+
+	h->h_name = h->h_aliases[0] = buf;
+	strcpy(h->h_name, canon);
+	buf += strlen(h->h_name)+1;
+
+	if (strcmp(h->h_name, name)) {
+		h->h_aliases[1] = buf;
+		strcpy(h->h_aliases[1], name);
+		buf += strlen(h->h_aliases[1])+1;
+	} else h->h_aliases[1] = 0;
+
+	h->h_aliases[2] = 0;
+
+	*res = h;
+	return 0;
+}
libc/musl/src/network/gethostbyname_r.c
@@ -0,0 +1,11 @@
+#define _GNU_SOURCE
+
+#include <sys/socket.h>
+#include <netdb.h>
+
+int gethostbyname_r(const char *name,
+	struct hostent *h, char *buf, size_t buflen,
+	struct hostent **res, int *err)
+{
+	return gethostbyname2_r(name, AF_INET, h, buf, buflen, res, err);
+}
libc/musl/src/network/getifaddrs.c
@@ -0,0 +1,216 @@
+#define _GNU_SOURCE
+#include <errno.h>
+#include <string.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <ifaddrs.h>
+#include <syscall.h>
+#include <net/if.h>
+#include <netinet/in.h>
+#include "netlink.h"
+
+#define IFADDRS_HASH_SIZE 64
+
+/* getifaddrs() reports hardware addresses with PF_PACKET that implies
+ * struct sockaddr_ll.  But e.g. Infiniband socket address length is
+ * longer than sockaddr_ll.ssl_addr[8] can hold. Use this hack struct
+ * to extend ssl_addr - callers should be able to still use it. */
+struct sockaddr_ll_hack {
+	unsigned short sll_family, sll_protocol;
+	int sll_ifindex;
+	unsigned short sll_hatype;
+	unsigned char sll_pkttype, sll_halen;
+	unsigned char sll_addr[24];
+};
+
+union sockany {
+	struct sockaddr sa;
+	struct sockaddr_ll_hack ll;
+	struct sockaddr_in v4;
+	struct sockaddr_in6 v6;
+};
+
+struct ifaddrs_storage {
+	struct ifaddrs ifa;
+	struct ifaddrs_storage *hash_next;
+	union sockany addr, netmask, ifu;
+	unsigned int index;
+	char name[IFNAMSIZ+1];
+};
+
+struct ifaddrs_ctx {
+	struct ifaddrs_storage *first;
+	struct ifaddrs_storage *last;
+	struct ifaddrs_storage *hash[IFADDRS_HASH_SIZE];
+};
+
+void freeifaddrs(struct ifaddrs *ifp)
+{
+	struct ifaddrs *n;
+	while (ifp) {
+		n = ifp->ifa_next;
+		free(ifp);
+		ifp = n;
+	}
+}
+
+static void copy_addr(struct sockaddr **r, int af, union sockany *sa, void *addr, size_t addrlen, int ifindex)
+{
+	uint8_t *dst;
+	int len;
+
+	switch (af) {
+	case AF_INET:
+		dst = (uint8_t*) &sa->v4.sin_addr;
+		len = 4;
+		break;
+	case AF_INET6:
+		dst = (uint8_t*) &sa->v6.sin6_addr;
+		len = 16;
+		if (IN6_IS_ADDR_LINKLOCAL(addr) || IN6_IS_ADDR_MC_LINKLOCAL(addr))
+			sa->v6.sin6_scope_id = ifindex;
+		break;
+	default:
+		return;
+	}
+	if (addrlen < len) return;
+	sa->sa.sa_family = af;
+	memcpy(dst, addr, len);
+	*r = &sa->sa;
+}
+
+static void gen_netmask(struct sockaddr **r, int af, union sockany *sa, int prefixlen)
+{
+	uint8_t addr[16] = {0};
+	int i;
+
+	if (prefixlen > 8*sizeof(addr)) prefixlen = 8*sizeof(addr);
+	i = prefixlen / 8;
+	memset(addr, 0xff, i);
+	if (i < sizeof(addr)) addr[i++] = 0xff << (8 - (prefixlen % 8));
+	copy_addr(r, af, sa, addr, sizeof(addr), 0);
+}
+
+static void copy_lladdr(struct sockaddr **r, union sockany *sa, void *addr, size_t addrlen, int ifindex, unsigned short hatype)
+{
+	if (addrlen > sizeof(sa->ll.sll_addr)) return;
+	sa->ll.sll_family = AF_PACKET;
+	sa->ll.sll_ifindex = ifindex;
+	sa->ll.sll_hatype = hatype;
+	sa->ll.sll_halen = addrlen;
+	memcpy(sa->ll.sll_addr, addr, addrlen);
+	*r = &sa->sa;
+}
+
+static int netlink_msg_to_ifaddr(void *pctx, struct nlmsghdr *h)
+{
+	struct ifaddrs_ctx *ctx = pctx;
+	struct ifaddrs_storage *ifs, *ifs0;
+	struct ifinfomsg *ifi = NLMSG_DATA(h);
+	struct ifaddrmsg *ifa = NLMSG_DATA(h);
+	struct rtattr *rta;
+	int stats_len = 0;
+
+	if (h->nlmsg_type == RTM_NEWLINK) {
+		for (rta = NLMSG_RTA(h, sizeof(*ifi)); NLMSG_RTAOK(rta, h); rta = RTA_NEXT(rta)) {
+			if (rta->rta_type != IFLA_STATS) continue;
+			stats_len = RTA_DATALEN(rta);
+			break;
+		}
+	} else {
+		for (ifs0 = ctx->hash[ifa->ifa_index % IFADDRS_HASH_SIZE]; ifs0; ifs0 = ifs0->hash_next)
+			if (ifs0->index == ifa->ifa_index)
+				break;
+		if (!ifs0) return 0;
+	}
+
+	ifs = calloc(1, sizeof(struct ifaddrs_storage) + stats_len);
+	if (ifs == 0) return -1;
+
+	if (h->nlmsg_type == RTM_NEWLINK) {
+		ifs->index = ifi->ifi_index;
+		ifs->ifa.ifa_flags = ifi->ifi_flags;
+
+		for (rta = NLMSG_RTA(h, sizeof(*ifi)); NLMSG_RTAOK(rta, h); rta = RTA_NEXT(rta)) {
+			switch (rta->rta_type) {
+			case IFLA_IFNAME:
+				if (RTA_DATALEN(rta) < sizeof(ifs->name)) {
+					memcpy(ifs->name, RTA_DATA(rta), RTA_DATALEN(rta));
+					ifs->ifa.ifa_name = ifs->name;
+				}
+				break;
+			case IFLA_ADDRESS:
+				copy_lladdr(&ifs->ifa.ifa_addr, &ifs->addr, RTA_DATA(rta), RTA_DATALEN(rta), ifi->ifi_index, ifi->ifi_type);
+				break;
+			case IFLA_BROADCAST:
+				copy_lladdr(&ifs->ifa.ifa_broadaddr, &ifs->ifu, RTA_DATA(rta), RTA_DATALEN(rta), ifi->ifi_index, ifi->ifi_type);
+				break;
+			case IFLA_STATS:
+				ifs->ifa.ifa_data = (void*)(ifs+1);
+				memcpy(ifs->ifa.ifa_data, RTA_DATA(rta), RTA_DATALEN(rta));
+				break;
+			}
+		}
+		if (ifs->ifa.ifa_name) {
+			unsigned int bucket = ifs->index % IFADDRS_HASH_SIZE;
+			ifs->hash_next = ctx->hash[bucket];
+			ctx->hash[bucket] = ifs;
+		}
+	} else {
+		ifs->ifa.ifa_name = ifs0->ifa.ifa_name;
+		ifs->ifa.ifa_flags = ifs0->ifa.ifa_flags;
+		for (rta = NLMSG_RTA(h, sizeof(*ifa)); NLMSG_RTAOK(rta, h); rta = RTA_NEXT(rta)) {
+			switch (rta->rta_type) {
+			case IFA_ADDRESS:
+				/* If ifa_addr is already set we, received an IFA_LOCAL before
+				 * so treat this as destination address */
+				if (ifs->ifa.ifa_addr)
+					copy_addr(&ifs->ifa.ifa_dstaddr, ifa->ifa_family, &ifs->ifu, RTA_DATA(rta), RTA_DATALEN(rta), ifa->ifa_index);
+				else
+					copy_addr(&ifs->ifa.ifa_addr, ifa->ifa_family, &ifs->addr, RTA_DATA(rta), RTA_DATALEN(rta), ifa->ifa_index);
+				break;
+			case IFA_BROADCAST:
+				copy_addr(&ifs->ifa.ifa_broadaddr, ifa->ifa_family, &ifs->ifu, RTA_DATA(rta), RTA_DATALEN(rta), ifa->ifa_index);
+				break;
+			case IFA_LOCAL:
+				/* If ifa_addr is set and we get IFA_LOCAL, assume we have
+				 * a point-to-point network. Move address to correct field. */
+				if (ifs->ifa.ifa_addr) {
+					ifs->ifu = ifs->addr;
+					ifs->ifa.ifa_dstaddr = &ifs->ifu.sa;
+					memset(&ifs->addr, 0, sizeof(ifs->addr));
+				}
+				copy_addr(&ifs->ifa.ifa_addr, ifa->ifa_family, &ifs->addr, RTA_DATA(rta), RTA_DATALEN(rta), ifa->ifa_index);
+				break;
+			case IFA_LABEL:
+				if (RTA_DATALEN(rta) < sizeof(ifs->name)) {
+					memcpy(ifs->name, RTA_DATA(rta), RTA_DATALEN(rta));
+					ifs->ifa.ifa_name = ifs->name;
+				}
+				break;
+			}
+		}
+		if (ifs->ifa.ifa_addr)
+			gen_netmask(&ifs->ifa.ifa_netmask, ifa->ifa_family, &ifs->netmask, ifa->ifa_prefixlen);
+	}
+
+	if (ifs->ifa.ifa_name) {
+		if (!ctx->first) ctx->first = ifs;
+		if (ctx->last) ctx->last->ifa.ifa_next = &ifs->ifa;
+		ctx->last = ifs;
+	} else {
+		free(ifs);
+	}
+	return 0;
+}
+
+int getifaddrs(struct ifaddrs **ifap)
+{
+	struct ifaddrs_ctx _ctx, *ctx = &_ctx;
+	int r;
+	memset(ctx, 0, sizeof *ctx);
+	r = __rtnetlink_enumerate(AF_UNSPEC, AF_UNSPEC, netlink_msg_to_ifaddr, ctx);
+	if (r == 0) *ifap = &ctx->first->ifa;
+	else freeifaddrs(&ctx->first->ifa);
+	return r;
+}
libc/musl/src/network/getnameinfo.c
@@ -0,0 +1,199 @@
+#include <netdb.h>
+#include <limits.h>
+#include <string.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <net/if.h>
+#include <ctype.h>
+#include <resolv.h>
+#include "lookup.h"
+#include "stdio_impl.h"
+
+#define PTR_MAX (64 + sizeof ".in-addr.arpa")
+#define RR_PTR 12
+
+static char *itoa(char *p, unsigned x) {
+	p += 3*sizeof(int);
+	*--p = 0;
+	do {
+		*--p = '0' + x % 10;
+		x /= 10;
+	} while (x);
+	return p;
+}
+
+static void mkptr4(char *s, const unsigned char *ip)
+{
+	sprintf(s, "%d.%d.%d.%d.in-addr.arpa",
+		ip[3], ip[2], ip[1], ip[0]);
+}
+
+static void mkptr6(char *s, const unsigned char *ip)
+{
+	static const char xdigits[] = "0123456789abcdef";
+	int i;
+	for (i=15; i>=0; i--) {
+		*s++ = xdigits[ip[i]&15]; *s++ = '.';
+		*s++ = xdigits[ip[i]>>4]; *s++ = '.';
+	}
+	strcpy(s, "ip6.arpa");
+}
+
+static void reverse_hosts(char *buf, const unsigned char *a, unsigned scopeid, int family)
+{
+	char line[512], *p, *z;
+	unsigned char _buf[1032], atmp[16];
+	struct address iplit;
+	FILE _f, *f = __fopen_rb_ca("/etc/hosts", &_f, _buf, sizeof _buf);
+	if (!f) return;
+	if (family == AF_INET) {
+		memcpy(atmp+12, a, 4);
+		memcpy(atmp, "\0\0\0\0\0\0\0\0\0\0\xff\xff", 12);
+		a = atmp;
+	}
+	while (fgets(line, sizeof line, f)) {
+		if ((p=strchr(line, '#'))) *p++='\n', *p=0;
+
+		for (p=line; *p && !isspace(*p); p++);
+		*p++ = 0;
+		if (__lookup_ipliteral(&iplit, line, AF_UNSPEC)<=0)
+			continue;
+
+		if (iplit.family == AF_INET) {
+			memcpy(iplit.addr+12, iplit.addr, 4);
+			memcpy(iplit.addr, "\0\0\0\0\0\0\0\0\0\0\xff\xff", 12);
+			iplit.scopeid = 0;
+		}
+
+		if (memcmp(a, iplit.addr, 16) || iplit.scopeid != scopeid)
+			continue;
+			
+		for (; *p && isspace(*p); p++);
+		for (z=p; *z && !isspace(*z); z++);
+		*z = 0;
+		if (z-p < 256) {
+			memcpy(buf, p, z-p+1);
+			break;
+		}
+	}
+	__fclose_ca(f);
+}
+
+static void reverse_services(char *buf, int port, int dgram)
+{
+	unsigned long svport;
+	char line[128], *p, *z;
+	unsigned char _buf[1032];
+	FILE _f, *f = __fopen_rb_ca("/etc/services", &_f, _buf, sizeof _buf);
+	if (!f) return;
+	while (fgets(line, sizeof line, f)) {
+		if ((p=strchr(line, '#'))) *p++='\n', *p=0;
+
+		for (p=line; *p && !isspace(*p); p++);
+		if (!*p) continue;
+		*p++ = 0;
+		svport = strtoul(p, &z, 10);
+
+		if (svport != port || z==p) continue;
+		if (dgram && strncmp(z, "/udp", 4)) continue;
+		if (!dgram && strncmp(z, "/tcp", 4)) continue;
+		if (p-line > 32) continue;
+
+		memcpy(buf, line, p-line);
+		break;
+	}
+	__fclose_ca(f);
+}
+
+static int dns_parse_callback(void *c, int rr, const void *data, int len, const void *packet)
+{
+	if (rr != RR_PTR) return 0;
+	if (__dn_expand(packet, (const unsigned char *)packet + 512,
+	    data, c, 256) <= 0)
+		*(char *)c = 0;
+	return 0;
+	
+}
+
+int getnameinfo(const struct sockaddr *restrict sa, socklen_t sl,
+	char *restrict node, socklen_t nodelen,
+	char *restrict serv, socklen_t servlen,
+	int flags)
+{
+	char ptr[PTR_MAX];
+	char buf[256], num[3*sizeof(int)+1];
+	int af = sa->sa_family;
+	unsigned char *a;
+	unsigned scopeid;
+
+	switch (af) {
+	case AF_INET:
+		a = (void *)&((struct sockaddr_in *)sa)->sin_addr;
+		if (sl < sizeof(struct sockaddr_in)) return EAI_FAMILY;
+		mkptr4(ptr, a);
+		scopeid = 0;
+		break;
+	case AF_INET6:
+		a = (void *)&((struct sockaddr_in6 *)sa)->sin6_addr;
+		if (sl < sizeof(struct sockaddr_in6)) return EAI_FAMILY;
+		if (memcmp(a, "\0\0\0\0\0\0\0\0\0\0\xff\xff", 12))
+			mkptr6(ptr, a);
+		else
+			mkptr4(ptr, a+12);
+		scopeid = ((struct sockaddr_in6 *)sa)->sin6_scope_id;
+		break;
+	default:
+		return EAI_FAMILY;
+	}
+
+	if (node && nodelen) {
+		buf[0] = 0;
+		if (!(flags & NI_NUMERICHOST)) {
+			reverse_hosts(buf, a, scopeid, af);
+		}
+		if (!*buf && !(flags & NI_NUMERICHOST)) {
+			unsigned char query[18+PTR_MAX], reply[512];
+			int qlen = __res_mkquery(0, ptr, 1, RR_PTR,
+				0, 0, 0, query, sizeof query);
+			int rlen = __res_send(query, qlen, reply, sizeof reply);
+			buf[0] = 0;
+			if (rlen > 0)
+				__dns_parse(reply, rlen, dns_parse_callback, buf);
+		}
+		if (!*buf) {
+			if (flags & NI_NAMEREQD) return EAI_NONAME;
+			inet_ntop(af, a, buf, sizeof buf);
+			if (scopeid) {
+				char *p = 0, tmp[IF_NAMESIZE+1];
+				if (!(flags & NI_NUMERICSCOPE) &&
+				    (IN6_IS_ADDR_LINKLOCAL(a) ||
+				     IN6_IS_ADDR_MC_LINKLOCAL(a)))
+					p = if_indextoname(scopeid, tmp+1);
+				if (!p)
+					p = itoa(num, scopeid);
+				*--p = '%';
+				strcat(buf, p);
+			}
+		}
+		if (strlen(buf) >= nodelen) return EAI_OVERFLOW;
+		strcpy(node, buf);
+	}
+
+	if (serv && servlen) {
+		char *p = buf;
+		int port = ntohs(((struct sockaddr_in *)sa)->sin_port);
+		buf[0] = 0;
+		if (!(flags & NI_NUMERICSERV))
+			reverse_services(buf, port, flags & NI_DGRAM);
+		if (!*p)
+			p = itoa(num, port);
+		if (strlen(p) >= servlen)
+			return EAI_OVERFLOW;
+		strcpy(serv, p);
+	}
+
+	return 0;
+}
libc/musl/src/network/getpeername.c
@@ -0,0 +1,7 @@
+#include <sys/socket.h>
+#include "syscall.h"
+
+int getpeername(int fd, struct sockaddr *restrict addr, socklen_t *restrict len)
+{
+	return socketcall(getpeername, fd, addr, len, 0, 0, 0);
+}
libc/musl/src/network/getservbyname.c
@@ -0,0 +1,12 @@
+#define _GNU_SOURCE
+#include <netdb.h>
+
+struct servent *getservbyname(const char *name, const char *prots)
+{
+	static struct servent se;
+	static char *buf[2];
+	struct servent *res;
+	if (getservbyname_r(name, prots, &se, (void *)buf, sizeof buf, &res))
+		return 0;
+	return &se;
+}
libc/musl/src/network/getservbyname_r.c
@@ -0,0 +1,55 @@
+#define _GNU_SOURCE
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <netdb.h>
+#include <inttypes.h>
+#include <errno.h>
+#include <string.h>
+#include <stdlib.h>
+#include "lookup.h"
+
+#define ALIGN (sizeof(struct { char a; char *b; }) - sizeof(char *))
+
+int getservbyname_r(const char *name, const char *prots,
+	struct servent *se, char *buf, size_t buflen, struct servent **res)
+{
+	struct service servs[MAXSERVS];
+	int cnt, proto, align;
+
+	*res = 0;
+
+	/* Don't treat numeric port number strings as service records. */
+	char *end = "";
+	strtoul(name, &end, 10);
+	if (!*end) return ENOENT;
+
+	/* Align buffer */
+	align = -(uintptr_t)buf & ALIGN-1;
+	if (buflen < 2*sizeof(char *)+align)
+		return ERANGE;
+	buf += align;
+
+	if (!prots) proto = 0;
+	else if (!strcmp(prots, "tcp")) proto = IPPROTO_TCP;
+	else if (!strcmp(prots, "udp")) proto = IPPROTO_UDP;
+	else return EINVAL;
+
+	cnt = __lookup_serv(servs, name, proto, 0, 0);
+	if (cnt<0) switch (cnt) {
+	case EAI_MEMORY:
+	case EAI_SYSTEM:
+		return ENOMEM;
+	default:
+		return ENOENT;
+	}
+
+	se->s_name = (char *)name;
+	se->s_aliases = (void *)buf;
+	se->s_aliases[0] = se->s_name;
+	se->s_aliases[1] = 0;
+	se->s_port = htons(servs[0].port);
+	se->s_proto = servs[0].proto == IPPROTO_TCP ? "tcp" : "udp";
+
+	*res = se;
+	return 0;
+}
libc/musl/src/network/getservbyport.c
@@ -0,0 +1,12 @@
+#define _GNU_SOURCE
+#include <netdb.h>
+
+struct servent *getservbyport(int port, const char *prots)
+{
+	static struct servent se;
+	static long buf[32/sizeof(long)];
+	struct servent *res;
+	if (getservbyport_r(port, prots, &se, (void *)buf, sizeof buf, &res))
+		return 0;
+	return &se;
+}
libc/musl/src/network/getservbyport_r.c
@@ -0,0 +1,60 @@
+#define _GNU_SOURCE
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <netdb.h>
+#include <inttypes.h>
+#include <errno.h>
+#include <string.h>
+#include <stdlib.h>
+
+int getservbyport_r(int port, const char *prots,
+	struct servent *se, char *buf, size_t buflen, struct servent **res)
+{
+	int i;
+	struct sockaddr_in sin = {
+		.sin_family = AF_INET,
+		.sin_port = port,
+	};
+
+	if (!prots) {
+		int r = getservbyport_r(port, "tcp", se, buf, buflen, res);
+		if (r) r = getservbyport_r(port, "udp", se, buf, buflen, res);
+		return r;
+	}
+	*res = 0;
+
+	/* Align buffer */
+	i = (uintptr_t)buf & sizeof(char *)-1;
+	if (!i) i = sizeof(char *);
+	if (buflen < 3*sizeof(char *)-i)
+		return ERANGE;
+	buf += sizeof(char *)-i;
+	buflen -= sizeof(char *)-i;
+
+	if (strcmp(prots, "tcp") && strcmp(prots, "udp")) return EINVAL;
+
+	se->s_port = port;
+	se->s_proto = (char *)prots;
+	se->s_aliases = (void *)buf;
+	buf += 2*sizeof(char *);
+	buflen -= 2*sizeof(char *);
+	se->s_aliases[1] = 0;
+	se->s_aliases[0] = se->s_name = buf;
+
+	switch (getnameinfo((void *)&sin, sizeof sin, 0, 0, buf, buflen,
+		strcmp(prots, "udp") ? 0 : NI_DGRAM)) {
+	case EAI_MEMORY:
+	case EAI_SYSTEM:
+		return ENOMEM;
+	default:
+		return ENOENT;
+	case 0:
+		break;
+	}
+
+	/* A numeric port string is not a service record. */
+	if (strtol(buf, 0, 10)==ntohs(port)) return ENOENT;
+
+	*res = se;
+	return 0;
+}
libc/musl/src/network/getsockname.c
@@ -0,0 +1,7 @@
+#include <sys/socket.h>
+#include "syscall.h"
+
+int getsockname(int fd, struct sockaddr *restrict addr, socklen_t *restrict len)
+{
+	return socketcall(getsockname, fd, addr, len, 0, 0, 0);
+}
libc/musl/src/network/getsockopt.c
@@ -0,0 +1,7 @@
+#include <sys/socket.h>
+#include "syscall.h"
+
+int getsockopt(int fd, int level, int optname, void *restrict optval, socklen_t *restrict optlen)
+{
+	return socketcall(getsockopt, fd, level, optname, optval, optlen, 0);
+}
libc/musl/src/network/h_errno.c
@@ -0,0 +1,9 @@
+#include <netdb.h>
+
+#undef h_errno
+int h_errno;
+
+int *__h_errno_location(void)
+{
+	return &h_errno;
+}
libc/musl/src/network/herror.c
@@ -0,0 +1,8 @@
+#define _GNU_SOURCE
+#include <stdio.h>
+#include <netdb.h>
+
+void herror(const char *msg)
+{
+	fprintf(stderr, "%s%s%s", msg?msg:"", msg?": ":"", hstrerror(h_errno));
+}
libc/musl/src/network/hstrerror.c
@@ -0,0 +1,18 @@
+#define _GNU_SOURCE
+#include <netdb.h>
+#include "locale_impl.h"
+
+static const char msgs[] =
+	"Host not found\0"
+	"Try again\0"
+	"Non-recoverable error\0"
+	"Address not available\0"
+	"\0Unknown error";
+
+const char *hstrerror(int ecode)
+{
+	const char *s;
+	for (s=msgs, ecode--; ecode && *s; ecode--, s++) for (; *s; s++);
+	if (!*s) s++;
+	return LCTRANS_CUR(s);
+}
libc/musl/src/network/htonl.c
@@ -0,0 +1,8 @@
+#include <netinet/in.h>
+#include <byteswap.h>
+
+uint32_t htonl(uint32_t n)
+{
+	union { int i; char c; } u = { 1 };
+	return u.c ? bswap_32(n) : n;
+}
libc/musl/src/network/htons.c
@@ -0,0 +1,8 @@
+#include <netinet/in.h>
+#include <byteswap.h>
+
+uint16_t htons(uint16_t n)
+{
+	union { int i; char c; } u = { 1 };
+	return u.c ? bswap_16(n) : n;
+}
libc/musl/src/network/if_freenameindex.c
@@ -0,0 +1,7 @@
+#include <net/if.h>
+#include <stdlib.h>
+
+void if_freenameindex(struct if_nameindex *idx)
+{
+	free(idx);
+}
libc/musl/src/network/if_indextoname.c
@@ -0,0 +1,23 @@
+#define _GNU_SOURCE
+#include <net/if.h>
+#include <sys/socket.h>
+#include <sys/ioctl.h>
+#include <string.h>
+#include <errno.h>
+#include "syscall.h"
+
+char *if_indextoname(unsigned index, char *name)
+{
+	struct ifreq ifr;
+	int fd, r;
+
+	if ((fd = socket(AF_UNIX, SOCK_DGRAM|SOCK_CLOEXEC, 0)) < 0) return 0;
+	ifr.ifr_ifindex = index;
+	r = ioctl(fd, SIOCGIFNAME, &ifr);
+	__syscall(SYS_close, fd);
+	if (r < 0) {
+		if (errno == ENODEV) errno = ENXIO;
+		return 0;
+	}
+	return strncpy(name, ifr.ifr_name, IF_NAMESIZE);
+}
libc/musl/src/network/if_nameindex.c
@@ -0,0 +1,114 @@
+#define _GNU_SOURCE
+#include <net/if.h>
+#include <errno.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <string.h>
+#include <pthread.h>
+#include "netlink.h"
+
+#define IFADDRS_HASH_SIZE 64
+
+struct ifnamemap {
+	unsigned int hash_next;
+	unsigned int index;
+	unsigned char namelen;
+	char name[IFNAMSIZ];
+};
+
+struct ifnameindexctx {
+	unsigned int num, allocated, str_bytes;
+	struct ifnamemap *list;
+	unsigned int hash[IFADDRS_HASH_SIZE];
+};
+
+static int netlink_msg_to_nameindex(void *pctx, struct nlmsghdr *h)
+{
+	struct ifnameindexctx *ctx = pctx;
+	struct ifnamemap *map;
+	struct rtattr *rta;
+	unsigned int i;
+	int index, type, namelen, bucket;
+
+	if (h->nlmsg_type == RTM_NEWLINK) {
+		struct ifinfomsg *ifi = NLMSG_DATA(h);
+		index = ifi->ifi_index;
+		type = IFLA_IFNAME;
+		rta = NLMSG_RTA(h, sizeof(*ifi));
+	} else {
+		struct ifaddrmsg *ifa = NLMSG_DATA(h);
+		index = ifa->ifa_index;
+		type = IFA_LABEL;
+		rta = NLMSG_RTA(h, sizeof(*ifa));
+	}
+	for (; NLMSG_RTAOK(rta, h); rta = RTA_NEXT(rta)) {
+		if (rta->rta_type != type) continue;
+
+		namelen = RTA_DATALEN(rta) - 1;
+		if (namelen > IFNAMSIZ) return 0;
+
+		/* suppress duplicates */
+		bucket = index % IFADDRS_HASH_SIZE;
+		i = ctx->hash[bucket];
+		while (i) {
+			map = &ctx->list[i-1];
+			if (map->index == index &&
+			    map->namelen == namelen &&
+			    memcmp(map->name, RTA_DATA(rta), namelen) == 0)
+				return 0;
+			i = map->hash_next;
+		}
+
+		if (ctx->num >= ctx->allocated) {
+			size_t a = ctx->allocated ? ctx->allocated * 2 + 1 : 8;
+			if (a > SIZE_MAX/sizeof *map) return -1;
+			map = realloc(ctx->list, a * sizeof *map);
+			if (!map) return -1;
+			ctx->list = map;
+			ctx->allocated = a;
+		}
+		map = &ctx->list[ctx->num];
+		map->index = index;
+		map->namelen = namelen;
+		memcpy(map->name, RTA_DATA(rta), namelen);
+		ctx->str_bytes += namelen + 1;
+		ctx->num++;
+		map->hash_next = ctx->hash[bucket];
+		ctx->hash[bucket] = ctx->num;
+		return 0;
+	}
+	return 0;
+}
+
+struct if_nameindex *if_nameindex()
+{
+	struct ifnameindexctx _ctx, *ctx = &_ctx;
+	struct if_nameindex *ifs = 0, *d;
+	struct ifnamemap *s;
+	char *p;
+	int i;
+	int cs;
+
+	pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cs);
+	memset(ctx, 0, sizeof(*ctx));
+	if (__rtnetlink_enumerate(AF_UNSPEC, AF_INET, netlink_msg_to_nameindex, ctx) < 0) goto err;
+
+	ifs = malloc(sizeof(struct if_nameindex[ctx->num+1]) + ctx->str_bytes);
+	if (!ifs) goto err;
+
+	p = (char*)(ifs + ctx->num + 1);
+	for (i = ctx->num, d = ifs, s = ctx->list; i; i--, s++, d++) {
+		d->if_index = s->index;
+		d->if_name = p;
+		memcpy(p, s->name, s->namelen);
+		p += s->namelen;
+		*p++ = 0;
+	}
+	d->if_index = 0;
+	d->if_name = 0;
+err:
+	pthread_setcancelstate(cs, 0);
+	free(ctx->list);
+	errno = ENOBUFS;
+	return ifs;
+}
libc/musl/src/network/if_nametoindex.c
@@ -0,0 +1,18 @@
+#define _GNU_SOURCE
+#include <net/if.h>
+#include <sys/socket.h>
+#include <sys/ioctl.h>
+#include <string.h>
+#include "syscall.h"
+
+unsigned if_nametoindex(const char *name)
+{
+	struct ifreq ifr;
+	int fd, r;
+
+	if ((fd = socket(AF_UNIX, SOCK_DGRAM|SOCK_CLOEXEC, 0)) < 0) return 0;
+	strncpy(ifr.ifr_name, name, sizeof ifr.ifr_name);
+	r = ioctl(fd, SIOCGIFINDEX, &ifr);
+	__syscall(SYS_close, fd);
+	return r < 0 ? 0 : ifr.ifr_ifindex;
+}
libc/musl/src/network/in6addr_any.c
@@ -0,0 +1,3 @@
+#include <netinet/in.h>
+
+const struct in6_addr in6addr_any = IN6ADDR_ANY_INIT;
libc/musl/src/network/in6addr_loopback.c
@@ -0,0 +1,3 @@
+#include <netinet/in.h>
+
+const struct in6_addr in6addr_loopback = IN6ADDR_LOOPBACK_INIT;
libc/musl/src/network/inet_addr.c
@@ -0,0 +1,10 @@
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+
+in_addr_t inet_addr(const char *p)
+{
+	struct in_addr a;
+	if (!__inet_aton(p, &a)) return -1;
+	return a.s_addr;
+}
libc/musl/src/network/inet_aton.c
@@ -0,0 +1,41 @@
+#include <ctype.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <stdlib.h>
+
+int __inet_aton(const char *s0, struct in_addr *dest)
+{
+	const char *s = s0;
+	unsigned char *d = (void *)dest;
+	unsigned long a[4] = { 0 };
+	char *z;
+	int i;
+
+	for (i=0; i<4; i++) {
+		a[i] = strtoul(s, &z, 0);
+		if (z==s || (*z && *z != '.') || !isdigit(*s))
+			return 0;
+		if (!*z) break;
+		s=z+1;
+	}
+	if (i==4) return 0;
+	switch (i) {
+	case 0:
+		a[1] = a[0] & 0xffffff;
+		a[0] >>= 24;
+	case 1:
+		a[2] = a[1] & 0xffff;
+		a[1] >>= 16;
+	case 2:
+		a[3] = a[2] & 0xff;
+		a[2] >>= 8;
+	}
+	for (i=0; i<4; i++) {
+		if (a[i] > 255) return 0;
+		d[i] = a[i];
+	}
+	return 1;
+}
+
+weak_alias(__inet_aton, inet_aton);
libc/musl/src/network/inet_legacy.c
@@ -0,0 +1,32 @@
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+
+in_addr_t inet_network(const char *p)
+{
+	return ntohl(inet_addr(p));
+}
+
+struct in_addr inet_makeaddr(in_addr_t n, in_addr_t h)
+{
+	if (n < 256) h |= n<<24;
+	else if (n < 65536) h |= n<<16;
+	else h |= n<<8;
+	return (struct in_addr){ h };
+}
+
+in_addr_t inet_lnaof(struct in_addr in)
+{
+	uint32_t h = in.s_addr;
+	if (h>>24 < 128) return h & 0xffffff;
+	if (h>>24 < 192) return h & 0xffff;
+	return h & 0xff;
+}
+
+in_addr_t inet_netof(struct in_addr in)
+{
+	uint32_t h = in.s_addr;
+	if (h>>24 < 128) return h >> 24;
+	if (h>>24 < 192) return h >> 16;
+	return h >> 8;
+}
libc/musl/src/network/inet_ntoa.c
@@ -0,0 +1,10 @@
+#include <arpa/inet.h>
+#include <stdio.h>
+
+char *inet_ntoa(struct in_addr in)
+{
+	static char buf[16];
+	unsigned char *a = (void *)&in;
+	snprintf(buf, sizeof buf, "%d.%d.%d.%d", a[0], a[1], a[2], a[3]);
+	return buf;
+}
libc/musl/src/network/inet_ntop.c
@@ -0,0 +1,54 @@
+#include <sys/socket.h>
+#include <arpa/inet.h>
+#include <errno.h>
+#include <stdio.h>
+#include <string.h>
+
+const char *inet_ntop(int af, const void *restrict a0, char *restrict s, socklen_t l)
+{
+	const unsigned char *a = a0;
+	int i, j, max, best;
+	char buf[100];
+
+	switch (af) {
+	case AF_INET:
+		if (snprintf(s, l, "%d.%d.%d.%d", a[0],a[1],a[2],a[3]) < l)
+			return s;
+		break;
+	case AF_INET6:
+		if (memcmp(a, "\0\0\0\0\0\0\0\0\0\0\377\377", 12))
+			snprintf(buf, sizeof buf,
+				"%x:%x:%x:%x:%x:%x:%x:%x",
+				256*a[0]+a[1],256*a[2]+a[3],
+				256*a[4]+a[5],256*a[6]+a[7],
+				256*a[8]+a[9],256*a[10]+a[11],
+				256*a[12]+a[13],256*a[14]+a[15]);
+		else
+			snprintf(buf, sizeof buf,
+				"%x:%x:%x:%x:%x:%x:%d.%d.%d.%d",
+				256*a[0]+a[1],256*a[2]+a[3],
+				256*a[4]+a[5],256*a[6]+a[7],
+				256*a[8]+a[9],256*a[10]+a[11],
+				a[12],a[13],a[14],a[15]);
+		/* Replace longest /(^0|:)[:0]{2,}/ with "::" */
+		for (i=best=0, max=2; buf[i]; i++) {
+			if (i && buf[i] != ':') continue;
+			j = strspn(buf+i, ":0");
+			if (j>max) best=i, max=j;
+		}
+		if (max>3) {
+			buf[best] = buf[best+1] = ':';
+			memmove(buf+best+2, buf+best+max, i-best-max+1);
+		}
+		if (strlen(buf) < l) {
+			strcpy(s, buf);
+			return s;
+		}
+		break;
+	default:
+		errno = EAFNOSUPPORT;
+		return 0;
+	}
+	errno = ENOSPC;
+	return 0;
+}
libc/musl/src/network/inet_pton.c
@@ -0,0 +1,71 @@
+#include <sys/socket.h>
+#include <arpa/inet.h>
+#include <ctype.h>
+#include <errno.h>
+#include <string.h>
+
+static int hexval(unsigned c)
+{
+	if (c-'0'<10) return c-'0';
+	c |= 32;
+	if (c-'a'<6) return c-'a'+10;
+	return -1;
+}
+
+int inet_pton(int af, const char *restrict s, void *restrict a0)
+{
+	uint16_t ip[8];
+	unsigned char *a = a0;
+	int i, j, v, d, brk=-1, need_v4=0;
+
+	if (af==AF_INET) {
+		for (i=0; i<4; i++) {
+			for (v=j=0; j<3 && isdigit(s[j]); j++)
+				v = 10*v + s[j]-'0';
+			if (j==0 || (j>1 && s[0]=='0') || v>255) return 0;
+			a[i] = v;
+			if (s[j]==0 && i==3) return 1;
+			if (s[j]!='.') return 0;
+			s += j+1;
+		}
+		return 0;
+	} else if (af!=AF_INET6) {
+		errno = EAFNOSUPPORT;
+		return -1;
+	}
+
+	if (*s==':' && *++s!=':') return 0;
+
+	for (i=0; ; i++) {
+		if (s[0]==':' && brk<0) {
+			brk=i;
+			ip[i&7]=0;
+			if (!*++s) break;
+			if (i==7) return 0;
+			continue;
+		}
+		for (v=j=0; j<4 && (d=hexval(s[j]))>=0; j++)
+			v=16*v+d;
+		if (j==0) return 0;
+		ip[i&7] = v;
+		if (!s[j] && (brk>=0 || i==7)) break;
+		if (i==7) return 0;
+		if (s[j]!=':') {
+			if (s[j]!='.' || (i<6 && brk<0)) return 0;
+			need_v4=1;
+			i++;
+			break;
+		}
+		s += j+1;
+	}
+	if (brk>=0) {
+		memmove(ip+brk+7-i, ip+brk, 2*(i+1-brk));
+		for (j=0; j<7-i; j++) ip[brk+j] = 0;
+	}
+	for (j=0; j<8; j++) {
+		*a++ = ip[j]>>8;
+		*a++ = ip[j];
+	}
+	if (need_v4 && inet_pton(AF_INET, (void *)s, a-4) <= 0) return 0;
+	return 1;
+}
libc/musl/src/network/listen.c
@@ -0,0 +1,7 @@
+#include <sys/socket.h>
+#include "syscall.h"
+
+int listen(int fd, int backlog)
+{
+	return socketcall(listen, fd, backlog, 0, 0, 0, 0);
+}
libc/musl/src/network/lookup.h
@@ -0,0 +1,55 @@
+#ifndef LOOKUP_H
+#define LOOKUP_H
+
+#include <stdint.h>
+#include <stddef.h>
+#include <features.h>
+#include <netinet/in.h>
+#include <netdb.h>
+
+struct aibuf {
+	struct addrinfo ai;
+	union sa {
+		struct sockaddr_in sin;
+		struct sockaddr_in6 sin6;
+	} sa;
+	volatile int lock[1];
+	short slot, ref;
+};
+
+struct address {
+	int family;
+	unsigned scopeid;
+	uint8_t addr[16];
+	int sortkey;
+};
+
+struct service {
+	uint16_t port;
+	unsigned char proto, socktype;
+};
+
+#define MAXNS 3
+
+struct resolvconf {
+	struct address ns[MAXNS];
+	unsigned nns, attempts, ndots;
+	unsigned timeout;
+};
+
+/* The limit of 48 results is a non-sharp bound on the number of addresses
+ * that can fit in one 512-byte DNS packet full of v4 results and a second
+ * packet full of v6 results. Due to headers, the actual limit is lower. */
+#define MAXADDRS 48
+#define MAXSERVS 2
+
+hidden int __lookup_serv(struct service buf[static MAXSERVS], const char *name, int proto, int socktype, int flags);
+hidden int __lookup_name(struct address buf[static MAXADDRS], char canon[static 256], const char *name, int family, int flags);
+hidden int __lookup_ipliteral(struct address buf[static 1], const char *name, int family);
+
+hidden int __get_resolv_conf(struct resolvconf *, char *, size_t);
+hidden int __res_msend_rc(int, const unsigned char *const *, const int *, unsigned char *const *, int *, int, const struct resolvconf *);
+
+hidden int __dns_parse(const unsigned char *, int, int (*)(void *, int, const void *, int, const void *), void *);
+
+#endif
libc/musl/src/network/lookup_ipliteral.c
@@ -0,0 +1,55 @@
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <netdb.h>
+#include <net/if.h>
+#include <arpa/inet.h>
+#include <limits.h>
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+#include "lookup.h"
+
+int __lookup_ipliteral(struct address buf[static 1], const char *name, int family)
+{
+	struct in_addr a4;
+	struct in6_addr a6;
+	if (__inet_aton(name, &a4) > 0) {
+		if (family == AF_INET6) /* wrong family */
+			return EAI_NONAME;
+		memcpy(&buf[0].addr, &a4, sizeof a4);
+		buf[0].family = AF_INET;
+		buf[0].scopeid = 0;
+		return 1;
+	}
+
+	char tmp[64];
+	char *p = strchr(name, '%'), *z;
+	unsigned long long scopeid = 0;
+	if (p && p-name < 64) {
+		memcpy(tmp, name, p-name);
+		tmp[p-name] = 0;
+		name = tmp;
+	}
+
+	if (inet_pton(AF_INET6, name, &a6) <= 0)
+		return 0;
+	if (family == AF_INET) /* wrong family */
+		return EAI_NONAME;
+
+	memcpy(&buf[0].addr, &a6, sizeof a6);
+	buf[0].family = AF_INET6;
+	if (p) {
+		if (isdigit(*++p)) scopeid = strtoull(p, &z, 10);
+		else z = p-1;
+		if (*z) {
+			if (!IN6_IS_ADDR_LINKLOCAL(&a6) &&
+			    !IN6_IS_ADDR_MC_LINKLOCAL(&a6))
+				return EAI_NONAME;
+			scopeid = if_nametoindex(p);
+			if (!scopeid) return EAI_NONAME;
+		}
+		if (scopeid > UINT_MAX) return EAI_NONAME;
+	}
+	buf[0].scopeid = scopeid;
+	return 1;
+}
libc/musl/src/network/lookup_name.c
@@ -0,0 +1,416 @@
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <netdb.h>
+#include <net/if.h>
+#include <arpa/inet.h>
+#include <ctype.h>
+#include <stdlib.h>
+#include <string.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <pthread.h>
+#include <errno.h>
+#include <resolv.h>
+#include "lookup.h"
+#include "stdio_impl.h"
+#include "syscall.h"
+
+static int is_valid_hostname(const char *host)
+{
+	const unsigned char *s;
+	if (strnlen(host, 255)-1 >= 254 || mbstowcs(0, host, 0) == -1) return 0;
+	for (s=(void *)host; *s>=0x80 || *s=='.' || *s=='-' || isalnum(*s); s++);
+	return !*s;
+}
+
+static int name_from_null(struct address buf[static 2], const char *name, int family, int flags)
+{
+	int cnt = 0;
+	if (name) return 0;
+	if (flags & AI_PASSIVE) {
+		if (family != AF_INET6)
+			buf[cnt++] = (struct address){ .family = AF_INET };
+		if (family != AF_INET)
+			buf[cnt++] = (struct address){ .family = AF_INET6 };
+	} else {
+		if (family != AF_INET6)
+			buf[cnt++] = (struct address){ .family = AF_INET, .addr = { 127,0,0,1 } };
+		if (family != AF_INET)
+			buf[cnt++] = (struct address){ .family = AF_INET6, .addr = { [15] = 1 } };
+	}
+	return cnt;
+}
+
+static int name_from_numeric(struct address buf[static 1], const char *name, int family)
+{
+	return __lookup_ipliteral(buf, name, family);
+}
+
+static int name_from_hosts(struct address buf[static MAXADDRS], char canon[static 256], const char *name, int family)
+{
+	char line[512];
+	size_t l = strlen(name);
+	int cnt = 0, badfam = 0;
+	unsigned char _buf[1032];
+	FILE _f, *f = __fopen_rb_ca("/etc/hosts", &_f, _buf, sizeof _buf);
+	if (!f) switch (errno) {
+	case ENOENT:
+	case ENOTDIR:
+	case EACCES:
+		return 0;
+	default:
+		return EAI_SYSTEM;
+	}
+	while (fgets(line, sizeof line, f) && cnt < MAXADDRS) {
+		char *p, *z;
+
+		if ((p=strchr(line, '#'))) *p++='\n', *p=0;
+		for(p=line+1; (p=strstr(p, name)) &&
+			(!isspace(p[-1]) || !isspace(p[l])); p++);
+		if (!p) continue;
+
+		/* Isolate IP address to parse */
+		for (p=line; *p && !isspace(*p); p++);
+		*p++ = 0;
+		switch (name_from_numeric(buf+cnt, line, family)) {
+		case 1:
+			cnt++;
+			break;
+		case 0:
+			continue;
+		default:
+			badfam = EAI_NONAME;
+			continue;
+		}
+
+		/* Extract first name as canonical name */
+		for (; *p && isspace(*p); p++);
+		for (z=p; *z && !isspace(*z); z++);
+		*z = 0;
+		if (is_valid_hostname(p)) memcpy(canon, p, z-p+1);
+	}
+	__fclose_ca(f);
+	return cnt ? cnt : badfam;
+}
+
+struct dpc_ctx {
+	struct address *addrs;
+	char *canon;
+	int cnt;
+};
+
+#define RR_A 1
+#define RR_CNAME 5
+#define RR_AAAA 28
+
+static int dns_parse_callback(void *c, int rr, const void *data, int len, const void *packet)
+{
+	char tmp[256];
+	struct dpc_ctx *ctx = c;
+	if (ctx->cnt >= MAXADDRS) return -1;
+	switch (rr) {
+	case RR_A:
+		if (len != 4) return -1;
+		ctx->addrs[ctx->cnt].family = AF_INET;
+		ctx->addrs[ctx->cnt].scopeid = 0;
+		memcpy(ctx->addrs[ctx->cnt++].addr, data, 4);
+		break;
+	case RR_AAAA:
+		if (len != 16) return -1;
+		ctx->addrs[ctx->cnt].family = AF_INET6;
+		ctx->addrs[ctx->cnt].scopeid = 0;
+		memcpy(ctx->addrs[ctx->cnt++].addr, data, 16);
+		break;
+	case RR_CNAME:
+		if (__dn_expand(packet, (const unsigned char *)packet + 512,
+		    data, tmp, sizeof tmp) > 0 && is_valid_hostname(tmp))
+			strcpy(ctx->canon, tmp);
+		break;
+	}
+	return 0;
+}
+
+static int name_from_dns(struct address buf[static MAXADDRS], char canon[static 256], const char *name, int family, const struct resolvconf *conf)
+{
+	unsigned char qbuf[2][280], abuf[2][512];
+	const unsigned char *qp[2] = { qbuf[0], qbuf[1] };
+	unsigned char *ap[2] = { abuf[0], abuf[1] };
+	int qlens[2], alens[2];
+	int i, nq = 0;
+	struct dpc_ctx ctx = { .addrs = buf, .canon = canon };
+	static const struct { int af; int rr; } afrr[2] = {
+		{ .af = AF_INET6, .rr = RR_A },
+		{ .af = AF_INET, .rr = RR_AAAA },
+	};
+
+	for (i=0; i<2; i++) {
+		if (family != afrr[i].af) {
+			qlens[nq] = __res_mkquery(0, name, 1, afrr[i].rr,
+				0, 0, 0, qbuf[nq], sizeof *qbuf);
+			if (qlens[nq] == -1)
+				return EAI_NONAME;
+			nq++;
+		}
+	}
+
+	if (__res_msend_rc(nq, qp, qlens, ap, alens, sizeof *abuf, conf) < 0)
+		return EAI_SYSTEM;
+
+	for (i=0; i<nq; i++)
+		__dns_parse(abuf[i], alens[i], dns_parse_callback, &ctx);
+
+	if (ctx.cnt) return ctx.cnt;
+	if (alens[0] < 4 || (abuf[0][3] & 15) == 2) return EAI_AGAIN;
+	if ((abuf[0][3] & 15) == 0) return EAI_NONAME;
+	if ((abuf[0][3] & 15) == 3) return 0;
+	return EAI_FAIL;
+}
+
+static int name_from_dns_search(struct address buf[static MAXADDRS], char canon[static 256], const char *name, int family)
+{
+	char search[256];
+	struct resolvconf conf;
+	size_t l, dots;
+	char *p, *z;
+
+	if (__get_resolv_conf(&conf, search, sizeof search) < 0) return -1;
+
+	/* Count dots, suppress search when >=ndots or name ends in
+	 * a dot, which is an explicit request for global scope. */
+	for (dots=l=0; name[l]; l++) if (name[l]=='.') dots++;
+	if (dots >= conf.ndots || name[l-1]=='.') *search = 0;
+
+	/* Strip final dot for canon, fail if multiple trailing dots. */
+	if (name[l-1]=='.') l--;
+	if (!l || name[l-1]=='.') return EAI_NONAME;
+
+	/* This can never happen; the caller already checked length. */
+	if (l >= 256) return EAI_NONAME;
+
+	/* Name with search domain appended is setup in canon[]. This both
+	 * provides the desired default canonical name (if the requested
+	 * name is not a CNAME record) and serves as a buffer for passing
+	 * the full requested name to name_from_dns. */
+	memcpy(canon, name, l);
+	canon[l] = '.';
+
+	for (p=search; *p; p=z) {
+		for (; isspace(*p); p++);
+		for (z=p; *z && !isspace(*z); z++);
+		if (z==p) break;
+		if (z-p < 256 - l - 1) {
+			memcpy(canon+l+1, p, z-p);
+			canon[z-p+1+l] = 0;
+			int cnt = name_from_dns(buf, canon, canon, family, &conf);
+			if (cnt) return cnt;
+		}
+	}
+
+	canon[l] = 0;
+	return name_from_dns(buf, canon, name, family, &conf);
+}
+
+static const struct policy {
+	unsigned char addr[16];
+	unsigned char len, mask;
+	unsigned char prec, label;
+} defpolicy[] = {
+	{ "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\1", 15, 0xff, 50, 0 },
+	{ "\0\0\0\0\0\0\0\0\0\0\xff\xff", 11, 0xff, 35, 4 },
+	{ "\x20\2", 1, 0xff, 30, 2 },
+	{ "\x20\1", 3, 0xff, 5, 5 },
+	{ "\xfc", 0, 0xfe, 3, 13 },
+#if 0
+	/* These are deprecated and/or returned to the address
+	 * pool, so despite the RFC, treating them as special
+	 * is probably wrong. */
+	{ "", 11, 0xff, 1, 3 },
+	{ "\xfe\xc0", 1, 0xc0, 1, 11 },
+	{ "\x3f\xfe", 1, 0xff, 1, 12 },
+#endif
+	/* Last rule must match all addresses to stop loop. */
+	{ "", 0, 0, 40, 1 },
+};
+
+static const struct policy *policyof(const struct in6_addr *a)
+{
+	int i;
+	for (i=0; ; i++) {
+		if (memcmp(a->s6_addr, defpolicy[i].addr, defpolicy[i].len))
+			continue;
+		if ((a->s6_addr[defpolicy[i].len] & defpolicy[i].mask)
+		    != defpolicy[i].addr[defpolicy[i].len])
+			continue;
+		return defpolicy+i;
+	}
+}
+
+static int labelof(const struct in6_addr *a)
+{
+	return policyof(a)->label;
+}
+
+static int scopeof(const struct in6_addr *a)
+{
+	if (IN6_IS_ADDR_MULTICAST(a)) return a->s6_addr[1] & 15;
+	if (IN6_IS_ADDR_LINKLOCAL(a)) return 2;
+	if (IN6_IS_ADDR_LOOPBACK(a)) return 2;
+	if (IN6_IS_ADDR_SITELOCAL(a)) return 5;
+	return 14;
+}
+
+static int prefixmatch(const struct in6_addr *s, const struct in6_addr *d)
+{
+	/* FIXME: The common prefix length should be limited to no greater
+	 * than the nominal length of the prefix portion of the source
+	 * address. However the definition of the source prefix length is
+	 * not clear and thus this limiting is not yet implemented. */
+	unsigned i;
+	for (i=0; i<128 && !((s->s6_addr[i/8]^d->s6_addr[i/8])&(128>>(i%8))); i++);
+	return i;
+}
+
+#define DAS_USABLE              0x40000000
+#define DAS_MATCHINGSCOPE       0x20000000
+#define DAS_MATCHINGLABEL       0x10000000
+#define DAS_PREC_SHIFT          20
+#define DAS_SCOPE_SHIFT         16
+#define DAS_PREFIX_SHIFT        8
+#define DAS_ORDER_SHIFT         0
+
+static int addrcmp(const void *_a, const void *_b)
+{
+	const struct address *a = _a, *b = _b;
+	return b->sortkey - a->sortkey;
+}
+
+int __lookup_name(struct address buf[static MAXADDRS], char canon[static 256], const char *name, int family, int flags)
+{
+	int cnt = 0, i, j;
+
+	*canon = 0;
+	if (name) {
+		/* reject empty name and check len so it fits into temp bufs */
+		size_t l = strnlen(name, 255);
+		if (l-1 >= 254)
+			return EAI_NONAME;
+		memcpy(canon, name, l+1);
+	}
+
+	/* Procedurally, a request for v6 addresses with the v4-mapped
+	 * flag set is like a request for unspecified family, followed
+	 * by filtering of the results. */
+	if (flags & AI_V4MAPPED) {
+		if (family == AF_INET6) family = AF_UNSPEC;
+		else flags -= AI_V4MAPPED;
+	}
+
+	/* Try each backend until there's at least one result. */
+	cnt = name_from_null(buf, name, family, flags);
+	if (!cnt) cnt = name_from_numeric(buf, name, family);
+	if (!cnt && !(flags & AI_NUMERICHOST)) {
+		cnt = name_from_hosts(buf, canon, name, family);
+		if (!cnt) cnt = name_from_dns_search(buf, canon, name, family);
+	}
+	if (cnt<=0) return cnt ? cnt : EAI_NONAME;
+
+	/* Filter/transform results for v4-mapped lookup, if requested. */
+	if (flags & AI_V4MAPPED) {
+		if (!(flags & AI_ALL)) {
+			/* If any v6 results exist, remove v4 results. */
+			for (i=0; i<cnt && buf[i].family != AF_INET6; i++);
+			if (i<cnt) {
+				for (j=0; i<cnt; i++) {
+					if (buf[i].family == AF_INET6)
+						buf[j++] = buf[i];
+				}
+				cnt = i = j;
+			}
+		}
+		/* Translate any remaining v4 results to v6 */
+		for (i=0; i<cnt; i++) {
+			if (buf[i].family != AF_INET) continue;
+			memcpy(buf[i].addr+12, buf[i].addr, 4);
+			memcpy(buf[i].addr, "\0\0\0\0\0\0\0\0\0\0\xff\xff", 12);
+			buf[i].family = AF_INET6;
+		}
+	}
+
+	/* No further processing is needed if there are fewer than 2
+	 * results or if there are only IPv4 results. */
+	if (cnt<2 || family==AF_INET) return cnt;
+	for (i=0; i<cnt; i++) if (buf[i].family != AF_INET) break;
+	if (i==cnt) return cnt;
+
+	int cs;
+	pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cs);
+
+	/* The following implements a subset of RFC 3484/6724 destination
+	 * address selection by generating a single 31-bit sort key for
+	 * each address. Rules 3, 4, and 7 are omitted for having
+	 * excessive runtime and code size cost and dubious benefit.
+	 * So far the label/precedence table cannot be customized. */
+	for (i=0; i<cnt; i++) {
+		int family = buf[i].family;
+		int key = 0;
+		struct sockaddr_in6 sa6 = { 0 }, da6 = {
+			.sin6_family = AF_INET6,
+			.sin6_scope_id = buf[i].scopeid,
+			.sin6_port = 65535
+		};
+		struct sockaddr_in sa4 = { 0 }, da4 = {
+			.sin_family = AF_INET,
+			.sin_port = 65535
+		};
+		void *sa, *da;
+		socklen_t salen, dalen;
+		if (family == AF_INET6) {
+			memcpy(da6.sin6_addr.s6_addr, buf[i].addr, 16);
+			da = &da6; dalen = sizeof da6;
+			sa = &sa6; salen = sizeof sa6;
+		} else {
+			memcpy(sa6.sin6_addr.s6_addr,
+				"\0\0\0\0\0\0\0\0\0\0\xff\xff", 12);
+			memcpy(da6.sin6_addr.s6_addr+12, buf[i].addr, 4);
+			memcpy(da6.sin6_addr.s6_addr,
+				"\0\0\0\0\0\0\0\0\0\0\xff\xff", 12);
+			memcpy(da6.sin6_addr.s6_addr+12, buf[i].addr, 4);
+			memcpy(&da4.sin_addr, buf[i].addr, 4);
+			da = &da4; dalen = sizeof da4;
+			sa = &sa4; salen = sizeof sa4;
+		}
+		const struct policy *dpolicy = policyof(&da6.sin6_addr);
+		int dscope = scopeof(&da6.sin6_addr);
+		int dlabel = dpolicy->label;
+		int dprec = dpolicy->prec;
+		int prefixlen = 0;
+		int fd = socket(family, SOCK_DGRAM|SOCK_CLOEXEC, IPPROTO_UDP);
+		if (fd >= 0) {
+			if (!connect(fd, da, dalen)) {
+				key |= DAS_USABLE;
+				if (!getsockname(fd, sa, &salen)) {
+					if (family == AF_INET) memcpy(
+						sa6.sin6_addr.s6_addr+12,
+						&sa4.sin_addr, 4);
+					if (dscope == scopeof(&sa6.sin6_addr))
+						key |= DAS_MATCHINGSCOPE;
+					if (dlabel == labelof(&sa6.sin6_addr))
+						key |= DAS_MATCHINGLABEL;
+					prefixlen = prefixmatch(&sa6.sin6_addr,
+						&da6.sin6_addr);
+				}
+			}
+			close(fd);
+		}
+		key |= dprec << DAS_PREC_SHIFT;
+		key |= (15-dscope) << DAS_SCOPE_SHIFT;
+		key |= prefixlen << DAS_PREFIX_SHIFT;
+		key |= (MAXADDRS-i) << DAS_ORDER_SHIFT;
+		buf[i].sortkey = key;
+	}
+	qsort(buf, cnt, sizeof *buf, addrcmp);
+
+	pthread_setcancelstate(cs, 0);
+
+	return cnt;
+}
libc/musl/src/network/lookup_serv.c
@@ -0,0 +1,114 @@
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <netdb.h>
+#include <ctype.h>
+#include <string.h>
+#include <stdlib.h>
+#include <fcntl.h>
+#include <errno.h>
+#include "lookup.h"
+#include "stdio_impl.h"
+
+int __lookup_serv(struct service buf[static MAXSERVS], const char *name, int proto, int socktype, int flags)
+{
+	char line[128];
+	int cnt = 0;
+	char *p, *z = "";
+	unsigned long port = 0;
+
+	switch (socktype) {
+	case SOCK_STREAM:
+		switch (proto) {
+		case 0:
+			proto = IPPROTO_TCP;
+		case IPPROTO_TCP:
+			break;
+		default:
+			return EAI_SERVICE;
+		}
+		break;
+	case SOCK_DGRAM:
+		switch (proto) {
+		case 0:
+			proto = IPPROTO_UDP;
+		case IPPROTO_UDP:
+			break;
+		default:
+			return EAI_SERVICE;
+		}
+	case 0:
+		break;
+	default:
+		if (name) return EAI_SERVICE;
+		buf[0].port = 0;
+		buf[0].proto = proto;
+		buf[0].socktype = socktype;
+		return 1;
+	}
+
+	if (name) {
+		if (!*name) return EAI_SERVICE;
+		port = strtoul(name, &z, 10);
+	}
+	if (!*z) {
+		if (port > 65535) return EAI_SERVICE;
+		if (proto != IPPROTO_UDP) {
+			buf[cnt].port = port;
+			buf[cnt].socktype = SOCK_STREAM;
+			buf[cnt++].proto = IPPROTO_TCP;
+		}
+		if (proto != IPPROTO_TCP) {
+			buf[cnt].port = port;
+			buf[cnt].socktype = SOCK_DGRAM;
+			buf[cnt++].proto = IPPROTO_UDP;
+		}
+		return cnt;
+	}
+
+	if (flags & AI_NUMERICSERV) return EAI_NONAME;
+
+	size_t l = strlen(name);
+
+	unsigned char _buf[1032];
+	FILE _f, *f = __fopen_rb_ca("/etc/services", &_f, _buf, sizeof _buf);
+	if (!f) switch (errno) {
+	case ENOENT:
+	case ENOTDIR:
+	case EACCES:
+		return EAI_SERVICE;
+	default:
+		return EAI_SYSTEM;
+	}
+
+	while (fgets(line, sizeof line, f) && cnt < MAXSERVS) {
+		if ((p=strchr(line, '#'))) *p++='\n', *p=0;
+
+		/* Find service name */
+		for(p=line; (p=strstr(p, name)); p++) {
+			if (p>line && !isspace(p[-1])) continue;
+			if (p[l] && !isspace(p[l])) continue;
+			break;
+		}
+		if (!p) continue;
+
+		/* Skip past canonical name at beginning of line */
+		for (p=line; *p && !isspace(*p); p++);
+
+		port = strtoul(p, &z, 10);
+		if (port > 65535 || z==p) continue;
+		if (!strncmp(z, "/udp", 4)) {
+			if (proto == IPPROTO_TCP) continue;
+			buf[cnt].port = port;
+			buf[cnt].socktype = SOCK_DGRAM;
+			buf[cnt++].proto = IPPROTO_UDP;
+		}
+		if (!strncmp(z, "/tcp", 4)) {
+			if (proto == IPPROTO_UDP) continue;
+			buf[cnt].port = port;
+			buf[cnt].socktype = SOCK_STREAM;
+			buf[cnt++].proto = IPPROTO_TCP;
+		}
+	}
+	__fclose_ca(f);
+	return cnt > 0 ? cnt : EAI_SERVICE;
+}
libc/musl/src/network/netlink.c
@@ -0,0 +1,52 @@
+#include <errno.h>
+#include <string.h>
+#include <syscall.h>
+#include <sys/socket.h>
+#include "netlink.h"
+
+static int __netlink_enumerate(int fd, unsigned int seq, int type, int af,
+	int (*cb)(void *ctx, struct nlmsghdr *h), void *ctx)
+{
+	struct nlmsghdr *h;
+	union {
+		uint8_t buf[8192];
+		struct {
+			struct nlmsghdr nlh;
+			struct rtgenmsg g;
+		} req;
+		struct nlmsghdr reply;
+	} u;
+	int r, ret;
+
+	memset(&u.req, 0, sizeof(u.req));
+	u.req.nlh.nlmsg_len = sizeof(u.req);
+	u.req.nlh.nlmsg_type = type;
+	u.req.nlh.nlmsg_flags = NLM_F_DUMP | NLM_F_REQUEST;
+	u.req.nlh.nlmsg_seq = seq;
+	u.req.g.rtgen_family = af;
+	r = send(fd, &u.req, sizeof(u.req), 0);
+	if (r < 0) return r;
+
+	while (1) {
+		r = recv(fd, u.buf, sizeof(u.buf), MSG_DONTWAIT);
+		if (r <= 0) return -1;
+		for (h = &u.reply; NLMSG_OK(h, (void*)&u.buf[r]); h = NLMSG_NEXT(h)) {
+			if (h->nlmsg_type == NLMSG_DONE) return 0;
+			if (h->nlmsg_type == NLMSG_ERROR) return -1;
+			ret = cb(ctx, h);
+			if (ret) return ret;
+		}
+	}
+}
+
+int __rtnetlink_enumerate(int link_af, int addr_af, int (*cb)(void *ctx, struct nlmsghdr *h), void *ctx)
+{
+	int fd, r;
+
+	fd = socket(PF_NETLINK, SOCK_RAW|SOCK_CLOEXEC, NETLINK_ROUTE);
+	if (fd < 0) return -1;
+	r = __netlink_enumerate(fd, 1, RTM_GETLINK, link_af, cb, ctx);
+	if (!r) r = __netlink_enumerate(fd, 2, RTM_GETADDR, addr_af, cb, ctx);
+	__syscall(SYS_close,fd);
+	return r;
+}
libc/musl/src/network/netlink.h
@@ -0,0 +1,94 @@
+#include <stdint.h>
+
+/* linux/netlink.h */
+
+#define NETLINK_ROUTE 0
+
+struct nlmsghdr {
+	uint32_t	nlmsg_len;
+	uint16_t	nlmsg_type;
+	uint16_t	nlmsg_flags;
+	uint32_t	nlmsg_seq;
+	uint32_t	nlmsg_pid;
+};
+
+#define NLM_F_REQUEST	1
+#define NLM_F_MULTI	2
+#define NLM_F_ACK	4
+
+#define NLM_F_ROOT	0x100
+#define NLM_F_MATCH	0x200
+#define NLM_F_ATOMIC	0x400
+#define NLM_F_DUMP	(NLM_F_ROOT|NLM_F_MATCH)
+
+#define NLMSG_NOOP	0x1
+#define NLMSG_ERROR	0x2
+#define NLMSG_DONE	0x3
+#define NLMSG_OVERRUN	0x4
+
+/* linux/rtnetlink.h */
+
+#define RTM_NEWLINK	16
+#define RTM_GETLINK	18
+#define RTM_NEWADDR	20
+#define RTM_GETADDR	22
+
+struct rtattr {
+	unsigned short	rta_len;
+	unsigned short	rta_type;
+};
+
+struct rtgenmsg {
+	unsigned char	rtgen_family;
+};
+
+struct ifinfomsg {
+	unsigned char	ifi_family;
+	unsigned char	__ifi_pad;
+	unsigned short	ifi_type;
+	int		ifi_index;
+	unsigned	ifi_flags;
+	unsigned	ifi_change;
+};
+
+/* linux/if_link.h */
+
+#define IFLA_ADDRESS	1
+#define IFLA_BROADCAST	2
+#define IFLA_IFNAME	3
+#define IFLA_STATS	7
+
+/* linux/if_addr.h */
+
+struct ifaddrmsg {
+	uint8_t		ifa_family;
+	uint8_t		ifa_prefixlen;
+	uint8_t		ifa_flags;
+	uint8_t		ifa_scope;
+	uint32_t	ifa_index;
+};
+
+#define IFA_ADDRESS	1
+#define IFA_LOCAL	2
+#define IFA_LABEL	3
+#define IFA_BROADCAST	4
+
+/* musl */
+
+#define NETLINK_ALIGN(len)	(((len)+3) & ~3)
+#define NLMSG_DATA(nlh)		((void*)((char*)(nlh)+sizeof(struct nlmsghdr)))
+#define NLMSG_DATALEN(nlh)	((nlh)->nlmsg_len-sizeof(struct nlmsghdr))
+#define NLMSG_DATAEND(nlh)	((char*)(nlh)+(nlh)->nlmsg_len)
+#define NLMSG_NEXT(nlh)		(struct nlmsghdr*)((char*)(nlh)+NETLINK_ALIGN((nlh)->nlmsg_len))
+#define NLMSG_OK(nlh,end)	((char*)(end)-(char*)(nlh) >= sizeof(struct nlmsghdr))
+
+#define RTA_DATA(rta)		((void*)((char*)(rta)+sizeof(struct rtattr)))
+#define RTA_DATALEN(rta)	((rta)->rta_len-sizeof(struct rtattr))
+#define RTA_DATAEND(rta)	((char*)(rta)+(rta)->rta_len)
+#define RTA_NEXT(rta)		(struct rtattr*)((char*)(rta)+NETLINK_ALIGN((rta)->rta_len))
+#define RTA_OK(nlh,end)		((char*)(end)-(char*)(rta) >= sizeof(struct rtattr))
+
+#define NLMSG_RTA(nlh,len)	((void*)((char*)(nlh)+sizeof(struct nlmsghdr)+NETLINK_ALIGN(len)))
+#define NLMSG_RTAOK(rta,nlh)	RTA_OK(rta,NLMSG_DATAEND(nlh))
+
+hidden int __rtnetlink_enumerate(int link_af, int addr_af, int (*cb)(void *ctx, struct nlmsghdr *h), void *ctx);
libc/musl/src/network/netname.c
@@ -0,0 +1,12 @@
+#include <netdb.h>
+
+struct netent *getnetbyaddr(uint32_t net, int type)
+{
+	return 0;
+}
+
+struct netent *getnetbyname(const char *name)
+{
+	return 0;
+}
+
libc/musl/src/network/ns_parse.c
@@ -0,0 +1,171 @@
+#define _BSD_SOURCE
+#include <errno.h>
+#include <stddef.h>
+#include <resolv.h>
+#include <arpa/nameser.h>
+
+const struct _ns_flagdata _ns_flagdata[16] = {
+	{ 0x8000, 15 },
+	{ 0x7800, 11 },
+	{ 0x0400, 10 },
+	{ 0x0200, 9 },
+	{ 0x0100, 8 },
+	{ 0x0080, 7 },
+	{ 0x0040, 6 },
+	{ 0x0020, 5 },
+	{ 0x0010, 4 },
+	{ 0x000f, 0 },
+	{ 0x0000, 0 },
+	{ 0x0000, 0 },
+	{ 0x0000, 0 },
+	{ 0x0000, 0 },
+	{ 0x0000, 0 },
+	{ 0x0000, 0 },
+};
+
+unsigned ns_get16(const unsigned char *cp)
+{
+	return cp[0]<<8 | cp[1];
+}
+
+unsigned long ns_get32(const unsigned char *cp)
+{
+	return (unsigned)cp[0]<<24 | cp[1]<<16 | cp[2]<<8 | cp[3];
+}
+
+void ns_put16(unsigned s, unsigned char *cp)
+{
+	*cp++ = s>>8;
+	*cp++ = s;
+}
+
+void ns_put32(unsigned long l, unsigned char *cp)
+{
+	*cp++ = l>>24;
+	*cp++ = l>>16;
+	*cp++ = l>>8;
+	*cp++ = l;
+}
+
+int ns_initparse(const unsigned char *msg, int msglen, ns_msg *handle)
+{
+	int i, r;
+
+	handle->_msg = msg;
+	handle->_eom = msg + msglen;
+	if (msglen < (2 + ns_s_max) * NS_INT16SZ) goto bad;
+	NS_GET16(handle->_id, msg);
+	NS_GET16(handle->_flags, msg);
+	for (i = 0; i < ns_s_max; i++) NS_GET16(handle->_counts[i], msg);
+	for (i = 0; i < ns_s_max; i++) {
+		if (handle->_counts[i]) {
+			handle->_sections[i] = msg;
+			r = ns_skiprr(msg, handle->_eom, i, handle->_counts[i]);
+			if (r < 0) return -1;
+			msg += r;
+		} else {
+			handle->_sections[i] = NULL;
+		}
+	}
+	if (msg != handle->_eom) goto bad;
+	handle->_sect = ns_s_max;
+	handle->_rrnum = -1;
+	handle->_msg_ptr = NULL;
+	return 0;
+bad:
+	errno = EMSGSIZE;
+	return -1;
+}
+
+int ns_skiprr(const unsigned char *ptr, const unsigned char *eom, ns_sect section, int count)
+{
+	const unsigned char *p = ptr;
+	int r;
+
+	while (count--) {
+		r = dn_skipname(p, eom);
+		if (r < 0) goto bad;
+		if (r + 2 * NS_INT16SZ > eom - p) goto bad;
+		p += r + 2 * NS_INT16SZ;
+		if (section != ns_s_qd) {
+			if (NS_INT32SZ + NS_INT16SZ > eom - p) goto bad;
+			p += NS_INT32SZ;
+			NS_GET16(r, p);
+			if (r > eom - p) goto bad;
+			p += r;
+		}
+	}
+	return p - ptr;
+bad:
+	errno = EMSGSIZE;
+	return -1;
+}
+
+int ns_parserr(ns_msg *handle, ns_sect section, int rrnum, ns_rr *rr)
+{
+	int r;
+
+	if (section < 0 || section >= ns_s_max) goto bad;
+	if (section != handle->_sect) {
+		handle->_sect = section;
+		handle->_rrnum = 0;
+		handle->_msg_ptr = handle->_sections[section];
+	}
+	if (rrnum == -1) rrnum = handle->_rrnum;
+	if (rrnum < 0 || rrnum >= handle->_counts[section]) goto bad;
+	if (rrnum < handle->_rrnum) {
+		handle->_rrnum = 0;
+		handle->_msg_ptr = handle->_sections[section];
+	}
+	if (rrnum > handle->_rrnum) {
+		r = ns_skiprr(handle->_msg_ptr, handle->_eom, section, rrnum - handle->_rrnum);
+		if (r < 0) return -1;
+		handle->_msg_ptr += r;
+		handle->_rrnum = rrnum;
+	}
+	r = ns_name_uncompress(handle->_msg, handle->_eom, handle->_msg_ptr, rr->name, NS_MAXDNAME);
+	if (r < 0) return -1;
+	handle->_msg_ptr += r;
+	if (2 * NS_INT16SZ > handle->_eom - handle->_msg_ptr) goto size;
+	NS_GET16(rr->type, handle->_msg_ptr);
+	NS_GET16(rr->rr_class, handle->_msg_ptr);
+	if (section != ns_s_qd) {
+		if (NS_INT32SZ + NS_INT16SZ > handle->_eom - handle->_msg_ptr) goto size;
+		NS_GET32(rr->ttl, handle->_msg_ptr);
+		NS_GET16(rr->rdlength, handle->_msg_ptr);
+		if (rr->rdlength > handle->_eom - handle->_msg_ptr) goto size;
+		rr->rdata = handle->_msg_ptr;
+		handle->_msg_ptr += rr->rdlength;
+	} else {
+		rr->ttl = 0;
+		rr->rdlength = 0;
+		rr->rdata = NULL;
+	}
+	handle->_rrnum++;
+	if (handle->_rrnum > handle->_counts[section]) {
+		handle->_sect = section + 1;
+		if (handle->_sect == ns_s_max) {
+			handle->_rrnum = -1;
+			handle->_msg_ptr = NULL;
+		} else {
+			handle->_rrnum = 0;
+		}
+	}
+	return 0;
+bad:
+	errno = ENODEV;
+	return -1;
+size:
+	errno = EMSGSIZE;
+	return -1;
+}
+
+int ns_name_uncompress(const unsigned char *msg, const unsigned char *eom,
+                       const unsigned char *src, char *dst, size_t dstsiz)
+{
+	int r;
+	r = dn_expand(msg, eom, src, dst, dstsiz);
+	if (r < 0) errno = EMSGSIZE;
+	return r;
+}
+
libc/musl/src/network/ntohl.c
@@ -0,0 +1,8 @@
+#include <netinet/in.h>
+#include <byteswap.h>
+
+uint32_t ntohl(uint32_t n)
+{
+	union { int i; char c; } u = { 1 };
+	return u.c ? bswap_32(n) : n;
+}
libc/musl/src/network/ntohs.c
@@ -0,0 +1,8 @@
+#include <netinet/in.h>
+#include <byteswap.h>
+
+uint16_t ntohs(uint16_t n)
+{
+	union { int i; char c; } u = { 1 };
+	return u.c ? bswap_16(n) : n;
+}
libc/musl/src/network/proto.c
@@ -0,0 +1,84 @@
+#include <netdb.h>
+#include <string.h>
+
+/* do we really need all these?? */
+
+static int idx;
+static const unsigned char protos[] = {
+	"\000ip\0"
+	"\001icmp\0"
+	"\002igmp\0"
+	"\003ggp\0"
+	"\004ipencap\0"
+	"\005st\0"
+	"\006tcp\0"
+	"\010egp\0"
+	"\014pup\0"
+	"\021udp\0"
+	"\024hmp\0"
+	"\026xns-idp\0"
+	"\033rdp\0"
+	"\035iso-tp4\0"
+	"\044xtp\0"
+	"\045ddp\0"
+	"\046idpr-cmtp\0"
+	"\051ipv6\0"
+	"\053ipv6-route\0"
+	"\054ipv6-frag\0"
+	"\055idrp\0"
+	"\056rsvp\0"
+	"\057gre\0"
+	"\062esp\0"
+	"\063ah\0"
+	"\071skip\0"
+	"\072ipv6-icmp\0"
+	"\073ipv6-nonxt\0"
+	"\074ipv6-opts\0"
+	"\111rspf\0"
+	"\121vmtp\0"
+	"\131ospf\0"
+	"\136ipip\0"
+	"\142encap\0"
+	"\147pim\0"
+	"\377raw"
+};
+
+void endprotoent(void)
+{
+	idx = 0;
+}
+
+void setprotoent(int stayopen)
+{
+	idx = 0;
+}
+
+struct protoent *getprotoent(void)
+{
+	static struct protoent p;
+	static const char *aliases;
+	if (idx >= sizeof protos) return NULL;
+	p.p_proto = protos[idx];
+	p.p_name = (char *)&protos[idx+1];
+	p.p_aliases = (char **)&aliases;
+	idx += strlen(p.p_name) + 2;
+	return &p;
+}
+
+struct protoent *getprotobyname(const char *name)
+{
+	struct protoent *p;
+	endprotoent();
+	do p = getprotoent();
+	while (p && strcmp(name, p->p_name));
+	return p;
+}
+
+struct protoent *getprotobynumber(int num)
+{
+	struct protoent *p;
+	endprotoent();
+	do p = getprotoent();
+	while (p && p->p_proto != num);
+	return p;
+}
libc/musl/src/network/recv.c
@@ -0,0 +1,6 @@
+#include <sys/socket.h>
+
+ssize_t recv(int fd, void *buf, size_t len, int flags)
+{
+	return recvfrom(fd, buf, len, flags, 0, 0);
+}
libc/musl/src/network/recvfrom.c
@@ -0,0 +1,7 @@
+#include <sys/socket.h>
+#include "syscall.h"
+
+ssize_t recvfrom(int fd, void *restrict buf, size_t len, int flags, struct sockaddr *restrict addr, socklen_t *restrict alen)
+{
+	return socketcall_cp(recvfrom, fd, buf, len, flags, addr, alen);
+}
libc/musl/src/network/recvmmsg.c
@@ -0,0 +1,15 @@
+#define _GNU_SOURCE
+#include <sys/socket.h>
+#include <limits.h>
+#include "syscall.h"
+
+int recvmmsg(int fd, struct mmsghdr *msgvec, unsigned int vlen, unsigned int flags, struct timespec *timeout)
+{
+#if LONG_MAX > INT_MAX
+	struct mmsghdr *mh = msgvec;
+	unsigned int i;
+	for (i = vlen; i; i--, mh++)
+		mh->msg_hdr.__pad1 = mh->msg_hdr.__pad2 = 0;
+#endif
+	return syscall_cp(SYS_recvmmsg, fd, msgvec, vlen, flags, timeout);
+}
libc/musl/src/network/recvmsg.c
@@ -0,0 +1,21 @@
+#include <sys/socket.h>
+#include <limits.h>
+#include "syscall.h"
+
+ssize_t recvmsg(int fd, struct msghdr *msg, int flags)
+{
+	ssize_t r;
+#if LONG_MAX > INT_MAX
+	struct msghdr h, *orig = msg;
+	if (msg) {
+		h = *msg;
+		h.__pad1 = h.__pad2 = 0;
+		msg = &h;
+	}
+#endif
+	r = socketcall_cp(recvmsg, fd, msg, flags, 0, 0, 0);
+#if LONG_MAX > INT_MAX
+	if (orig) *orig = h;
+#endif
+	return r;
+}
libc/musl/src/network/res_init.c
@@ -0,0 +1,6 @@
+#include <resolv.h>
+
+int res_init()
+{
+	return 0;
+}
libc/musl/src/network/res_mkquery.c
@@ -0,0 +1,43 @@
+#include <resolv.h>
+#include <string.h>
+#include <time.h>
+
+int __res_mkquery(int op, const char *dname, int class, int type,
+	const unsigned char *data, int datalen,
+	const unsigned char *newrr, unsigned char *buf, int buflen)
+{
+	int id, i, j;
+	unsigned char q[280];
+	struct timespec ts;
+	size_t l = strnlen(dname, 255);
+	int n;
+
+	if (l && dname[l-1]=='.') l--;
+	n = 17+l+!!l;
+	if (l>253 || buflen<n || op>15u || class>255u || type>255u)
+		return -1;
+
+	/* Construct query template - ID will be filled later */
+	memset(q, 0, n);
+	q[2] = op*8 + 1;
+	q[5] = 1;
+	memcpy((char *)q+13, dname, l);
+	for (i=13; q[i]; i=j+1) {
+		for (j=i; q[j] && q[j] != '.'; j++);
+		if (j-i-1u > 62u) return -1;
+		q[i-1] = j-i;
+	}
+	q[i+1] = type;
+	q[i+3] = class;
+
+	/* Make a reasonably unpredictable id */
+	clock_gettime(CLOCK_REALTIME, &ts);
+	id = ts.tv_nsec + ts.tv_nsec/65536UL & 0xffff;
+	q[0] = id/256;
+	q[1] = id;
+
+	memcpy(buf, q, n);
+	return n;
+}
+
+weak_alias(__res_mkquery, res_mkquery);
libc/musl/src/network/res_msend.c
@@ -0,0 +1,188 @@
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <netdb.h>
+#include <arpa/inet.h>
+#include <stdint.h>
+#include <string.h>
+#include <poll.h>
+#include <time.h>
+#include <ctype.h>
+#include <unistd.h>
+#include <errno.h>
+#include <pthread.h>
+#include "stdio_impl.h"
+#include "syscall.h"
+#include "lookup.h"
+
+static void cleanup(void *p)
+{
+	__syscall(SYS_close, (intptr_t)p);
+}
+
+static unsigned long mtime()
+{
+	struct timespec ts;
+	clock_gettime(CLOCK_REALTIME, &ts);
+	return (unsigned long)ts.tv_sec * 1000
+		+ ts.tv_nsec / 1000000;
+}
+
+int __res_msend_rc(int nqueries, const unsigned char *const *queries,
+	const int *qlens, unsigned char *const *answers, int *alens, int asize,
+	const struct resolvconf *conf)
+{
+	int fd;
+	int timeout, attempts, retry_interval, servfail_retry;
+	union {
+		struct sockaddr_in sin;
+		struct sockaddr_in6 sin6;
+	} sa = {0}, ns[MAXNS] = {{0}};
+	socklen_t sl = sizeof sa.sin;
+	int nns = 0;
+	int family = AF_INET;
+	int rlen;
+	int next;
+	int i, j;
+	int cs;
+	struct pollfd pfd;
+	unsigned long t0, t1, t2;
+
+	pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cs);
+
+	timeout = 1000*conf->timeout;
+	attempts = conf->attempts;
+
+	for (nns=0; nns<conf->nns; nns++) {
+		const struct address *iplit = &conf->ns[nns];
+		if (iplit->family == AF_INET) {
+			memcpy(&ns[nns].sin.sin_addr, iplit->addr, 4);
+			ns[nns].sin.sin_port = htons(53);
+			ns[nns].sin.sin_family = AF_INET;
+		} else {
+			sl = sizeof sa.sin6;
+			memcpy(&ns[nns].sin6.sin6_addr, iplit->addr, 16);
+			ns[nns].sin6.sin6_port = htons(53);
+			ns[nns].sin6.sin6_scope_id = iplit->scopeid;
+			ns[nns].sin6.sin6_family = family = AF_INET6;
+		}
+	}
+
+	/* Get local address and open/bind a socket */
+	sa.sin.sin_family = family;
+	fd = socket(family, SOCK_DGRAM|SOCK_CLOEXEC|SOCK_NONBLOCK, 0);
+
+	/* Handle case where system lacks IPv6 support */
+	if (fd < 0 && family == AF_INET6 && errno == EAFNOSUPPORT) {
+		fd = socket(AF_INET, SOCK_DGRAM|SOCK_CLOEXEC|SOCK_NONBLOCK, 0);
+		family = AF_INET;
+	}
+	if (fd < 0 || bind(fd, (void *)&sa, sl) < 0) {
+		if (fd >= 0) close(fd);
+		pthread_setcancelstate(cs, 0);
+		return -1;
+	}
+
+	/* Past this point, there are no errors. Each individual query will
+	 * yield either no reply (indicated by zero length) or an answer
+	 * packet which is up to the caller to interpret. */
+
+	pthread_cleanup_push(cleanup, (void *)(intptr_t)fd);
+	pthread_setcancelstate(cs, 0);
+
+	/* Convert any IPv4 addresses in a mixed environment to v4-mapped */
+	if (family == AF_INET6) {
+		setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY, &(int){0}, sizeof 0);
+		for (i=0; i<nns; i++) {
+			if (ns[i].sin.sin_family != AF_INET) continue;
+			memcpy(ns[i].sin6.sin6_addr.s6_addr+12,
+				&ns[i].sin.sin_addr, 4);
+			memcpy(ns[i].sin6.sin6_addr.s6_addr,
+				"\0\0\0\0\0\0\0\0\0\0\xff\xff", 12);
+			ns[i].sin6.sin6_family = AF_INET6;
+			ns[i].sin6.sin6_flowinfo = 0;
+			ns[i].sin6.sin6_scope_id = 0;
+		}
+	}
+
+	memset(alens, 0, sizeof *alens * nqueries);
+
+	pfd.fd = fd;
+	pfd.events = POLLIN;
+	retry_interval = timeout / attempts;
+	next = 0;
+	t0 = t2 = mtime();
+	t1 = t2 - retry_interval;
+
+	for (; t2-t0 < timeout; t2=mtime()) {
+		if (t2-t1 >= retry_interval) {
+			/* Query all configured namservers in parallel */
+			for (i=0; i<nqueries; i++)
+				if (!alens[i])
+					for (j=0; j<nns; j++)
+						sendto(fd, queries[i],
+							qlens[i], MSG_NOSIGNAL,
+							(void *)&ns[j], sl);
+			t1 = t2;
+			servfail_retry = 2 * nqueries;
+		}
+
+		/* Wait for a response, or until time to retry */
+		if (poll(&pfd, 1, t1+retry_interval-t2) <= 0) continue;
+
+		while ((rlen = recvfrom(fd, answers[next], asize, 0,
+		  (void *)&sa, (socklen_t[1]){sl})) >= 0) {
+
+			/* Ignore non-identifiable packets */
+			if (rlen < 4) continue;
+
+			/* Ignore replies from addresses we didn't send to */
+			for (j=0; j<nns && memcmp(ns+j, &sa, sl); j++);
+			if (j==nns) continue;
+
+			/* Find which query this answer goes with, if any */
+			for (i=next; i<nqueries && (
+				answers[next][0] != queries[i][0] ||
+				answers[next][1] != queries[i][1] ); i++);
+			if (i==nqueries) continue;
+			if (alens[i]) continue;
+
+			/* Only accept positive or negative responses;
+			 * retry immediately on server failure, and ignore
+			 * all other codes such as refusal. */
+			switch (answers[next][3] & 15) {
+			case 0:
+			case 3:
+				break;
+			case 2:
+				if (servfail_retry && servfail_retry--)
+					sendto(fd, queries[i],
+						qlens[i], MSG_NOSIGNAL,
+						(void *)&ns[j], sl);
+			default:
+				continue;
+			}
+
+			/* Store answer in the right slot, or update next
+			 * available temp slot if it's already in place. */
+			alens[i] = rlen;
+			if (i == next)
+				for (; next<nqueries && alens[next]; next++);
+			else
+				memcpy(answers[i], answers[next], rlen);
+
+			if (next == nqueries) goto out;
+		}
+	}
+out:
+	pthread_cleanup_pop(1);
+
+	return 0;
+}
+
+int __res_msend(int nqueries, const unsigned char *const *queries,
+	const int *qlens, unsigned char *const *answers, int *alens, int asize)
+{
+	struct resolvconf conf;
+	if (__get_resolv_conf(&conf, 0, 0) < 0) return -1;
+	return __res_msend_rc(nqueries, queries, qlens, answers, alens, asize, &conf);
+}
libc/musl/src/network/res_query.c
@@ -0,0 +1,12 @@
+#include <resolv.h>
+#include <netdb.h>
+
+int res_query(const char *name, int class, int type, unsigned char *dest, int len)
+{
+	unsigned char q[280];
+	int ql = __res_mkquery(0, name, class, type, 0, 0, 0, q, sizeof q);
+	if (ql < 0) return ql;
+	return __res_send(q, ql, dest, len);
+}
+
+weak_alias(res_query, res_search);
libc/musl/src/network/res_querydomain.c
@@ -0,0 +1,14 @@
+#include <resolv.h>
+#include <string.h>
+
+int res_querydomain(const char *name, const char *domain, int class, int type, unsigned char *dest, int len)
+{
+	char tmp[255];
+	size_t nl = strnlen(name, 255);
+	size_t dl = strnlen(domain, 255);
+	if (nl+dl+1 > 254) return -1;
+	memcpy(tmp, name, nl);
+	tmp[nl] = '.';
+	memcpy(tmp+nl+1, domain, dl+1);
+	return res_query(tmp, class, type, dest, len);
+}
libc/musl/src/network/res_send.c
@@ -0,0 +1,9 @@
+#include <resolv.h>
+
+int __res_send(const unsigned char *msg, int msglen, unsigned char *answer, int anslen)
+{
+	int r = __res_msend(1, &msg, &msglen, &answer, &anslen, anslen);
+	return r<0 ? r : anslen;
+}
+
+weak_alias(__res_send, res_send);
libc/musl/src/network/res_state.c
@@ -0,0 +1,9 @@
+#include <resolv.h>
+
+/* This is completely unused, and exists purely to satisfy broken apps. */
+
+struct __res_state *__res_state()
+{
+	static struct __res_state res;
+	return &res;
+}
libc/musl/src/network/resolvconf.c
@@ -0,0 +1,94 @@
+#include "lookup.h"
+#include "stdio_impl.h"
+#include <ctype.h>
+#include <errno.h>
+#include <string.h>
+#include <stdlib.h>
+#include <netinet/in.h>
+
+int __get_resolv_conf(struct resolvconf *conf, char *search, size_t search_sz)
+{
+	char line[256];
+	unsigned char _buf[256];
+	FILE *f, _f;
+	int nns = 0;
+
+	conf->ndots = 1;
+	conf->timeout = 5;
+	conf->attempts = 2;
+	if (search) *search = 0;
+
+	f = __fopen_rb_ca("/etc/resolv.conf", &_f, _buf, sizeof _buf);
+	if (!f) switch (errno) {
+	case ENOENT:
+	case ENOTDIR:
+	case EACCES:
+		goto no_resolv_conf;
+	default:
+		return -1;
+	}
+
+	while (fgets(line, sizeof line, f)) {
+		char *p, *z;
+		if (!strchr(line, '\n') && !feof(f)) {
+			/* Ignore lines that get truncated rather than
+			 * potentially misinterpreting them. */
+			int c;
+			do c = getc(f);
+			while (c != '\n' && c != EOF);
+			continue;
+		}
+		if (!strncmp(line, "options", 7) && isspace(line[7])) {
+			p = strstr(line, "ndots:");
+			if (p && isdigit(p[6])) {
+				p += 6;
+				unsigned long x = strtoul(p, &z, 10);
+				if (z != p) conf->ndots = x > 15 ? 15 : x;
+			}
+			p = strstr(line, "attempts:");
+			if (p && isdigit(p[9])) {
+				p += 9;
+				unsigned long x = strtoul(p, &z, 10);
+				if (z != p) conf->attempts = x > 10 ? 10 : x;
+			}
+			p = strstr(line, "timeout:");
+			if (p && (isdigit(p[8]) || p[8]=='.')) {
+				p += 8;
+				unsigned long x = strtoul(p, &z, 10);
+				if (z != p) conf->timeout = x > 60 ? 60 : x;
+			}
+			continue;
+		}
+		if (!strncmp(line, "nameserver", 10) && isspace(line[10])) {
+			if (nns >= MAXNS) continue;
+			for (p=line+11; isspace(*p); p++);
+			for (z=p; *z && !isspace(*z); z++);
+			*z=0;
+			if (__lookup_ipliteral(conf->ns+nns, p, AF_UNSPEC) > 0)
+				nns++;
+			continue;
+		}
+
+		if (!search) continue;
+		if ((strncmp(line, "domain", 6) && strncmp(line, "search", 6))
+		    || !isspace(line[6]))
+			continue;
+		for (p=line+7; isspace(*p); p++);
+		size_t l = strlen(p);
+		/* This can never happen anyway with chosen buffer sizes. */
+		if (l >= search_sz) continue;
+		memcpy(search, p, l+1);
+	}
+
+	__fclose_ca(f);
+
+no_resolv_conf:
+	if (!nns) {
+		__lookup_ipliteral(conf->ns, "127.0.0.1", AF_UNSPEC);
+		nns = 1;
+	}
+
+	conf->nns = nns;
+
+	return 0;
+}
libc/musl/src/network/send.c
@@ -0,0 +1,6 @@
+#include <sys/socket.h>
+
+ssize_t send(int fd, const void *buf, size_t len, int flags)
+{
+	return sendto(fd, buf, len, flags, 0, 0);
+}
libc/musl/src/network/sendmmsg.c
@@ -0,0 +1,30 @@
+#define _GNU_SOURCE
+#include <sys/socket.h>
+#include <limits.h>
+#include <errno.h>
+#include "syscall.h"
+
+int sendmmsg(int fd, struct mmsghdr *msgvec, unsigned int vlen, unsigned int flags)
+{
+#if LONG_MAX > INT_MAX
+	/* Can't use the syscall directly because the kernel has the wrong
+	 * idea for the types of msg_iovlen, msg_controllen, and cmsg_len,
+	 * and the cmsg blocks cannot be modified in-place. */
+	int i;
+	if (vlen > IOV_MAX) vlen = IOV_MAX; /* This matches the kernel. */
+	if (!vlen) return 0;
+	for (i=0; i<vlen; i++) {
+		/* As an unfortunate inconsistency, the sendmmsg API uses
+		 * unsigned int for the resulting msg_len, despite sendmsg
+		 * returning ssize_t. However Linux limits the total bytes
+		 * sent by sendmsg to INT_MAX, so the assignment is safe. */
+		ssize_t r = sendmsg(fd, &msgvec[i].msg_hdr, flags);
+		if (r < 0) goto error;
+		msgvec[i].msg_len = r;
+	}
+error:
+	return i ? i : -1;
+#else
+	return syscall_cp(SYS_sendmmsg, fd, msgvec, vlen, flags);
+#endif
+}
libc/musl/src/network/sendmsg.c
@@ -0,0 +1,29 @@
+#include <sys/socket.h>
+#include <limits.h>
+#include <string.h>
+#include <errno.h>
+#include "syscall.h"
+
+ssize_t sendmsg(int fd, const struct msghdr *msg, int flags)
+{
+#if LONG_MAX > INT_MAX
+	struct msghdr h;
+	struct cmsghdr chbuf[1024/sizeof(struct cmsghdr)+1], *c;
+	if (msg) {
+		h = *msg;
+		h.__pad1 = h.__pad2 = 0;
+		msg = &h;
+		if (h.msg_controllen) {
+			if (h.msg_controllen > 1024) {
+				errno = ENOMEM;
+				return -1;
+			}
+			memcpy(chbuf, h.msg_control, h.msg_controllen);
+			h.msg_control = chbuf;
+			for (c=CMSG_FIRSTHDR(&h); c; c=CMSG_NXTHDR(&h,c))
+				c->__pad1 = 0;
+		}
+	}
+#endif
+	return socketcall_cp(sendmsg, fd, msg, flags, 0, 0, 0);
+}
libc/musl/src/network/sendto.c
@@ -0,0 +1,7 @@
+#include <sys/socket.h>
+#include "syscall.h"
+
+ssize_t sendto(int fd, const void *buf, size_t len, int flags, const struct sockaddr *addr, socklen_t alen)
+{
+	return socketcall_cp(sendto, fd, buf, len, flags, addr, alen);
+}
libc/musl/src/network/serv.c
@@ -0,0 +1,14 @@
+#include <netdb.h>
+
+void endservent(void)
+{
+}
+
+void setservent(int stayopen)
+{
+}
+
+struct servent *getservent(void)
+{
+	return 0;
+}
libc/musl/src/network/setsockopt.c
@@ -0,0 +1,7 @@
+#include <sys/socket.h>
+#include "syscall.h"
+
+int setsockopt(int fd, int level, int optname, const void *optval, socklen_t optlen)
+{
+	return socketcall(setsockopt, fd, level, optname, optval, optlen, 0);
+}
libc/musl/src/network/shutdown.c
@@ -0,0 +1,7 @@
+#include <sys/socket.h>
+#include "syscall.h"
+
+int shutdown(int fd, int how)
+{
+	return socketcall(shutdown, fd, how, 0, 0, 0, 0);
+}
libc/musl/src/network/sockatmark.c
@@ -0,0 +1,10 @@
+#include <sys/socket.h>
+#include <sys/ioctl.h>
+
+int sockatmark(int s)
+{
+	int ret;
+	if (ioctl(s, SIOCATMARK, &ret) < 0)
+		return -1;
+	return ret;
+}
libc/musl/src/network/socket.c
@@ -0,0 +1,21 @@
+#include <sys/socket.h>
+#include <fcntl.h>
+#include <errno.h>
+#include "syscall.h"
+
+int socket(int domain, int type, int protocol)
+{
+	int s = socketcall(socket, domain, type, protocol, 0, 0, 0);
+	if (s<0 && (errno==EINVAL || errno==EPROTONOSUPPORT)
+	    && (type&(SOCK_CLOEXEC|SOCK_NONBLOCK))) {
+		s = socketcall(socket, domain,
+			type & ~(SOCK_CLOEXEC|SOCK_NONBLOCK),
+			protocol, 0, 0, 0);
+		if (s < 0) return s;
+		if (type & SOCK_CLOEXEC)
+			__syscall(SYS_fcntl, s, F_SETFD, FD_CLOEXEC);
+		if (type & SOCK_NONBLOCK)
+			__syscall(SYS_fcntl, s, F_SETFL, O_NONBLOCK);
+	}
+	return s;
+}
libc/musl/src/network/socketpair.c
@@ -0,0 +1,25 @@
+#include <sys/socket.h>
+#include <fcntl.h>
+#include <errno.h>
+#include "syscall.h"
+
+int socketpair(int domain, int type, int protocol, int fd[2])
+{
+	int r = socketcall(socketpair, domain, type, protocol, fd, 0, 0);
+	if (r<0 && (errno==EINVAL || errno==EPROTONOSUPPORT)
+	    && (type&(SOCK_CLOEXEC|SOCK_NONBLOCK))) {
+		r = socketcall(socketpair, domain,
+			type & ~(SOCK_CLOEXEC|SOCK_NONBLOCK),
+			protocol, fd, 0, 0);
+		if (r < 0) return r;
+		if (type & SOCK_CLOEXEC) {
+			__syscall(SYS_fcntl, fd[0], F_SETFD, FD_CLOEXEC);
+			__syscall(SYS_fcntl, fd[1], F_SETFD, FD_CLOEXEC);
+		}
+		if (type & SOCK_NONBLOCK) {
+			__syscall(SYS_fcntl, fd[0], F_SETFL, O_NONBLOCK);
+			__syscall(SYS_fcntl, fd[1], F_SETFL, O_NONBLOCK);
+		}
+	}
+	return r;
+}
libc/musl/src/passwd/fgetgrent.c
@@ -0,0 +1,12 @@
+#define _GNU_SOURCE
+#include "pwf.h"
+
+struct group *fgetgrent(FILE *f)
+{
+	static char *line, **mem;
+	static struct group gr;
+	struct group *res;
+	size_t size=0, nmem=0;
+	__getgrent_a(f, &gr, &line, &size, &mem, &nmem, &res);
+	return res;
+}
libc/musl/src/passwd/fgetpwent.c
@@ -0,0 +1,12 @@
+#define _GNU_SOURCE
+#include "pwf.h"
+
+struct passwd *fgetpwent(FILE *f)
+{
+	static char *line;
+	static struct passwd pw;
+	size_t size=0;
+	struct passwd *res;
+	__getpwent_a(f, &pw, &line, &size, &res);
+	return res;
+}
libc/musl/src/passwd/fgetspent.c
@@ -0,0 +1,15 @@
+#include "pwf.h"
+#include <pthread.h>
+
+struct spwd *fgetspent(FILE *f)
+{
+	static char *line;
+	static struct spwd sp;
+	size_t size = 0;
+	struct spwd *res = 0;
+	int cs;
+	pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cs);
+	if (getline(&line, &size, f) >= 0 && __parsespent(line, &sp) >= 0) res = &sp;
+	pthread_setcancelstate(cs, 0);
+	return res;
+}
libc/musl/src/passwd/getgr_a.c
@@ -0,0 +1,169 @@
+#include <pthread.h>
+#include <byteswap.h>
+#include <string.h>
+#include <unistd.h>
+#include "pwf.h"
+#include "nscd.h"
+
+static char *itoa(char *p, uint32_t x)
+{
+	// number of digits in a uint32_t + NUL
+	p += 11;
+	*--p = 0;
+	do {
+		*--p = '0' + x % 10;
+		x /= 10;
+	} while (x);
+	return p;
+}
+
+int __getgr_a(const char *name, gid_t gid, struct group *gr, char **buf, size_t *size, char ***mem, size_t *nmem, struct group **res)
+{
+	FILE *f;
+	int rv = 0;
+	int cs;
+
+	*res = 0;
+
+	pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cs);
+	f = fopen("/etc/group", "rbe");
+	if (!f) {
+		rv = errno;
+		goto done;
+	}
+
+	while (!(rv = __getgrent_a(f, gr, buf, size, mem, nmem, res)) && *res) {
+		if (name && !strcmp(name, (*res)->gr_name)
+		|| !name && (*res)->gr_gid == gid) {
+			break;
+		}
+	}
+	fclose(f);
+
+	if (!*res && (rv == 0 || rv == ENOENT || rv == ENOTDIR)) {
+		int32_t req = name ? GETGRBYNAME : GETGRBYGID;
+		int32_t i;
+		const char *key;
+		int32_t groupbuf[GR_LEN] = {0};
+		size_t len = 0;
+		size_t grlist_len = 0;
+		char gidbuf[11] = {0};
+		int swap = 0;
+		char *ptr;
+
+		if (name) {
+			key = name;
+		} else {
+			if (gid < 0 || gid > UINT32_MAX) {
+				rv = 0;
+				goto done;
+			}
+			key = itoa(gidbuf, gid);
+		}
+
+		f = __nscd_query(req, key, groupbuf, sizeof groupbuf, &swap);
+		if (!f) { rv = errno; goto done; }
+
+		if (!groupbuf[GRFOUND]) { rv = 0; goto cleanup_f; }
+
+		if (!groupbuf[GRNAMELEN] || !groupbuf[GRPASSWDLEN]) {
+			rv = EIO;
+			goto cleanup_f;
+		}
+
+		if (groupbuf[GRNAMELEN] > SIZE_MAX - groupbuf[GRPASSWDLEN]) {
+			rv = ENOMEM;
+			goto cleanup_f;
+		}
+		len = groupbuf[GRNAMELEN] + groupbuf[GRPASSWDLEN];
+
+		for (i = 0; i < groupbuf[GRMEMCNT]; i++) {
+			uint32_t name_len;
+			if (fread(&name_len, sizeof name_len, 1, f) < 1) {
+				rv = ferror(f) ? errno : EIO;
+				goto cleanup_f;
+			}
+			if (swap) {
+				name_len = bswap_32(name_len);
+			}
+			if (name_len > SIZE_MAX - grlist_len
+			|| name_len > SIZE_MAX - len) {
+				rv = ENOMEM;
+				goto cleanup_f;
+			}
+			len += name_len;
+			grlist_len += name_len;
+		}
+
+		if (len > *size || !*buf) {
+			char *tmp = realloc(*buf, len);
+			if (!tmp) {
+				rv = errno;
+				goto cleanup_f;
+			}
+			*buf = tmp;
+			*size = len;
+		}
+
+		if (!fread(*buf, len, 1, f)) {
+			rv = ferror(f) ? errno : EIO;
+			goto cleanup_f;
+		}
+
+		if (groupbuf[GRMEMCNT] + 1 > *nmem) {
+			if (groupbuf[GRMEMCNT] + 1 > SIZE_MAX/sizeof(char*)) {
+				rv = ENOMEM;
+				goto cleanup_f;
+			}
+			char **tmp = realloc(*mem, (groupbuf[GRMEMCNT]+1)*sizeof(char*));
+			if (!tmp) {
+				rv = errno;
+				goto cleanup_f;
+			}
+			*mem = tmp;
+			*nmem = groupbuf[GRMEMCNT] + 1;
+		}
+
+		if (groupbuf[GRMEMCNT]) {
+			mem[0][0] = *buf + groupbuf[GRNAMELEN] + groupbuf[GRPASSWDLEN];
+			for (ptr = mem[0][0], i = 0; ptr != mem[0][0]+grlist_len; ptr++)
+				if (!*ptr) mem[0][++i] = ptr+1;
+			mem[0][i] = 0;
+
+			if (i != groupbuf[GRMEMCNT]) {
+				rv = EIO;
+				goto cleanup_f;
+			}
+		} else {
+			mem[0][0] = 0;
+		}
+
+		gr->gr_name = *buf;
+		gr->gr_passwd = gr->gr_name + groupbuf[GRNAMELEN];
+		gr->gr_gid = groupbuf[GRGID];
+		gr->gr_mem = *mem;
+
+		if (gr->gr_passwd[-1]
+		|| gr->gr_passwd[groupbuf[GRPASSWDLEN]-1]) {
+			rv = EIO;
+			goto cleanup_f;
+		}
+
+		if (name && strcmp(name, gr->gr_name)
+		|| !name && gid != gr->gr_gid) {
+			rv = EIO;
+			goto cleanup_f;
+		}
+
+		*res = gr;
+
+cleanup_f:
+		fclose(f);
+		goto done;
+	}
+
+done:
+	pthread_setcancelstate(cs, 0);
+	if (rv) errno = rv;
+	return rv;
+}
libc/musl/src/passwd/getgr_r.c
@@ -0,0 +1,49 @@
+#include "pwf.h"
+#include <pthread.h>
+
+#define FIX(x) (gr->gr_##x = gr->gr_##x-line+buf)
+
+static int getgr_r(const char *name, gid_t gid, struct group *gr, char *buf, size_t size, struct group **res)
+{
+	char *line = 0;
+	size_t len = 0;
+	char **mem = 0;
+	size_t nmem = 0;
+	int rv = 0;
+	size_t i;
+	int cs;
+
+	pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cs);
+
+	rv = __getgr_a(name, gid, gr, &line, &len, &mem, &nmem, res);
+	if (*res && size < len + (nmem+1)*sizeof(char *) + 32) {
+		*res = 0;
+		rv = ERANGE;
+	}
+	if (*res) {
+		buf += (16-(uintptr_t)buf)%16;
+		gr->gr_mem = (void *)buf;
+		buf += (nmem+1)*sizeof(char *);
+		memcpy(buf, line, len);
+		FIX(name);
+		FIX(passwd);
+		for (i=0; mem[i]; i++)
+			gr->gr_mem[i] = mem[i]-line+buf;
+		gr->gr_mem[i] = 0;
+	}
+ 	free(mem);
+ 	free(line);
+	pthread_setcancelstate(cs, 0);
+	if (rv) errno = rv;
+	return rv;
+}
+
+int getgrnam_r(const char *name, struct group *gr, char *buf, size_t size, struct group **res)
+{
+	return getgr_r(name, 0, gr, buf, size, res);
+}
+
+int getgrgid_r(gid_t gid, struct group *gr, char *buf, size_t size, struct group **res)
+{
+	return getgr_r(0, gid, gr, buf, size, res);
+}
libc/musl/src/passwd/getgrent.c
@@ -0,0 +1,39 @@
+#include "pwf.h"
+
+static FILE *f;
+static char *line, **mem;
+static struct group gr;
+
+void setgrent()
+{
+	if (f) fclose(f);
+	f = 0;
+}
+
+weak_alias(setgrent, endgrent);
+
+struct group *getgrent()
+{
+	struct group *res;
+	size_t size=0, nmem=0;
+	if (!f) f = fopen("/etc/group", "rbe");
+	if (!f) return 0;
+	__getgrent_a(f, &gr, &line, &size, &mem, &nmem, &res);
+	return res;
+}
+
+struct group *getgrgid(gid_t gid)
+{
+	struct group *res;
+	size_t size=0, nmem=0;
+	__getgr_a(0, gid, &gr, &line, &size, &mem, &nmem, &res);
+	return res;
+}
+
+struct group *getgrnam(const char *name)
+{
+	struct group *res;
+	size_t size=0, nmem=0;
+	__getgr_a(name, 0, &gr, &line, &size, &mem, &nmem, &res);
+	return res;
+}
libc/musl/src/passwd/getgrent_a.c
@@ -0,0 +1,68 @@
+#include "pwf.h"
+#include <pthread.h>
+
+static unsigned atou(char **s)
+{
+	unsigned x;
+	for (x=0; **s-'0'<10U; ++*s) x=10*x+(**s-'0');
+	return x;
+}
+
+int __getgrent_a(FILE *f, struct group *gr, char **line, size_t *size, char ***mem, size_t *nmem, struct group **res)
+{
+	ssize_t l;
+	char *s, *mems;
+	size_t i;
+	int rv = 0;
+	int cs;
+	pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cs);
+	for (;;) {
+		if ((l=getline(line, size, f)) < 0) {
+			rv = ferror(f) ? errno : 0;
+			free(*line);
+			*line = 0;
+			gr = 0;
+			goto end;
+		}
+		line[0][l-1] = 0;
+
+		s = line[0];
+		gr->gr_name = s++;
+		if (!(s = strchr(s, ':'))) continue;
+
+		*s++ = 0; gr->gr_passwd = s;
+		if (!(s = strchr(s, ':'))) continue;
+
+		*s++ = 0; gr->gr_gid = atou(&s);
+		if (*s != ':') continue;
+
+		*s++ = 0; mems = s;
+		break;
+	}
+
+	for (*nmem=!!*s; *s; s++)
+		if (*s==',') ++*nmem;
+	free(*mem);
+	*mem = calloc(sizeof(char *), *nmem+1);
+	if (!*mem) {
+		rv = errno;
+		free(*line);
+		*line = 0;
+		gr = 0;
+		goto end;
+	}
+	if (*mems) {
+		mem[0][0] = mems;
+		for (s=mems, i=0; *s; s++)
+			if (*s==',') *s++ = 0, mem[0][++i] = s;
+		mem[0][++i] = 0;
+	} else {
+		mem[0][0] = 0;
+	}
+	gr->gr_mem = *mem;
+end:
+	pthread_setcancelstate(cs, 0);
+	*res = gr;
+	if(rv) errno = rv;
+	return rv;
+}
libc/musl/src/passwd/getgrouplist.c
@@ -0,0 +1,80 @@
+#define _GNU_SOURCE
+#include "pwf.h"
+#include <grp.h>
+#include <string.h>
+#include <limits.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <byteswap.h>
+#include <errno.h>
+#include "nscd.h"
+
+int getgrouplist(const char *user, gid_t gid, gid_t *groups, int *ngroups)
+{
+	int rv, nlim, ret = -1;
+	ssize_t i, n = 1;
+	struct group gr;
+	struct group *res;
+	FILE *f;
+	int swap = 0;
+	int32_t resp[INITGR_LEN];
+	uint32_t *nscdbuf = 0;
+	char *buf = 0;
+	char **mem = 0;
+	size_t nmem = 0;
+	size_t size;
+	nlim = *ngroups;
+	if (nlim >= 1) *groups++ = gid;
+
+	f = __nscd_query(GETINITGR, user, resp, sizeof resp, &swap);
+	if (!f) goto cleanup;
+	if (resp[INITGRFOUND]) {
+		nscdbuf = calloc(resp[INITGRNGRPS], sizeof(uint32_t));
+		if (!nscdbuf) goto cleanup;
+		if (!fread(nscdbuf, sizeof(*nscdbuf)*resp[INITGRNGRPS], 1, f)) {
+			if (!ferror(f)) errno = EIO;
+			goto cleanup;
+		}
+		if (swap) {
+			for (i = 0; i < resp[INITGRNGRPS]; i++)
+				nscdbuf[i] = bswap_32(nscdbuf[i]);
+		}
+	}
+	fclose(f);
+
+	f = fopen("/etc/group", "rbe");
+	if (!f && errno != ENOENT && errno != ENOTDIR)
+		goto cleanup;
+
+	if (f) {
+		while (!(rv = __getgrent_a(f, &gr, &buf, &size, &mem, &nmem, &res)) && res) {
+			if (nscdbuf)
+				for (i=0; i < resp[INITGRNGRPS]; i++) {
+					if (nscdbuf[i] == gr.gr_gid) nscdbuf[i] = gid;
+				}
+			for (i=0; gr.gr_mem[i] && strcmp(user, gr.gr_mem[i]); i++);
+			if (!gr.gr_mem[i]) continue;
+			if (++n <= nlim) *groups++ = gr.gr_gid;
+		}
+		if (rv) {
+			errno = rv;
+			goto cleanup;
+		}
+	}
+	if (nscdbuf) {
+		for(i=0; i < resp[INITGRNGRPS]; i++) {
+			if (nscdbuf[i] != gid)
+				if(++n <= nlim) *groups++ = nscdbuf[i];
+		}
+	}
+
+	ret = n > nlim ? -1 : n;
+	*ngroups = n;
+
+cleanup:
+	if (f) fclose(f);
+	free(nscdbuf);
+	free(buf);
+	free(mem);
+	return ret;
+}
libc/musl/src/passwd/getpw_a.c
@@ -0,0 +1,142 @@
+#include <pthread.h>
+#include <byteswap.h>
+#include <string.h>
+#include <unistd.h>
+#include "pwf.h"
+#include "nscd.h"
+
+static char *itoa(char *p, uint32_t x)
+{
+	// number of digits in a uint32_t + NUL
+	p += 11;
+	*--p = 0;
+	do {
+		*--p = '0' + x % 10;
+		x /= 10;
+	} while (x);
+	return p;
+}
+
+int __getpw_a(const char *name, uid_t uid, struct passwd *pw, char **buf, size_t *size, struct passwd **res)
+{
+	FILE *f;
+	int cs;
+	int rv = 0;
+
+	*res = 0;
+
+	pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cs);
+
+	f = fopen("/etc/passwd", "rbe");
+	if (!f) {
+		rv = errno;
+		goto done;
+	}
+
+	while (!(rv = __getpwent_a(f, pw, buf, size, res)) && *res) {
+		if (name && !strcmp(name, (*res)->pw_name)
+		|| !name && (*res)->pw_uid == uid)
+			break;
+	}
+	fclose(f);
+
+	if (!*res && (rv == 0 || rv == ENOENT || rv == ENOTDIR)) {
+		int32_t req = name ? GETPWBYNAME : GETPWBYUID;
+		const char *key;
+		int32_t passwdbuf[PW_LEN] = {0};
+		size_t len = 0;
+		char uidbuf[11] = {0};
+
+		if (name) {
+			key = name;
+		} else {
+			/* uid outside of this range can't be queried with the
+			 * nscd interface, but might happen if uid_t ever
+			 * happens to be a larger type (this is not true as of
+			 * now)
+			 */
+			if(uid < 0 || uid > UINT32_MAX) {
+				rv = 0;
+				goto done;
+			}
+			key = itoa(uidbuf, uid);
+		}
+
+		f = __nscd_query(req, key, passwdbuf, sizeof passwdbuf, (int[]){0});
+		if (!f) { rv = errno; goto done; }
+
+		if(!passwdbuf[PWFOUND]) { rv = 0; goto cleanup_f; }
+
+		/* A zero length response from nscd is invalid. We ignore
+		 * invalid responses and just report an error, rather than
+		 * trying to do something with them.
+		 */
+		if (!passwdbuf[PWNAMELEN] || !passwdbuf[PWPASSWDLEN]
+		|| !passwdbuf[PWGECOSLEN] || !passwdbuf[PWDIRLEN]
+		|| !passwdbuf[PWSHELLLEN]) {
+			rv = EIO;
+			goto cleanup_f;
+		}
+
+		if ((passwdbuf[PWNAMELEN]|passwdbuf[PWPASSWDLEN]
+		     |passwdbuf[PWGECOSLEN]|passwdbuf[PWDIRLEN]
+		     |passwdbuf[PWSHELLLEN]) >= SIZE_MAX/8) {
+			rv = ENOMEM;
+			goto cleanup_f;
+		}
+
+		len = passwdbuf[PWNAMELEN] + passwdbuf[PWPASSWDLEN]
+		    + passwdbuf[PWGECOSLEN] + passwdbuf[PWDIRLEN]
+		    + passwdbuf[PWSHELLLEN];
+
+		if (len > *size || !*buf) {
+			char *tmp = realloc(*buf, len);
+			if (!tmp) {
+				rv = errno;
+				goto cleanup_f;
+			}
+			*buf = tmp;
+			*size = len;
+		}
+
+		if (!fread(*buf, len, 1, f)) {
+			rv = ferror(f) ? errno : EIO;
+			goto cleanup_f;
+		}
+
+		pw->pw_name = *buf;
+		pw->pw_passwd = pw->pw_name + passwdbuf[PWNAMELEN];
+		pw->pw_gecos = pw->pw_passwd + passwdbuf[PWPASSWDLEN];
+		pw->pw_dir = pw->pw_gecos + passwdbuf[PWGECOSLEN];
+		pw->pw_shell = pw->pw_dir + passwdbuf[PWDIRLEN];
+		pw->pw_uid = passwdbuf[PWUID];
+		pw->pw_gid = passwdbuf[PWGID];
+
+		/* Don't assume that nscd made sure to null terminate strings.
+		 * It's supposed to, but malicious nscd should be ignored
+		 * rather than causing a crash.
+		 */
+		if (pw->pw_passwd[-1] || pw->pw_gecos[-1] || pw->pw_dir[-1]
+		|| pw->pw_shell[passwdbuf[PWSHELLLEN]-1]) {
+			rv = EIO;
+			goto cleanup_f;
+		}
+
+		if (name && strcmp(name, pw->pw_name)
+		|| !name && uid != pw->pw_uid) {
+			rv = EIO;
+			goto cleanup_f;
+		}
+
+
+		*res = pw;
+cleanup_f:
+		fclose(f);
+		goto done;
+	}
+
+done:
+	pthread_setcancelstate(cs, 0);
+	if (rv) errno = rv;
+	return rv;
+}
libc/musl/src/passwd/getpw_r.c
@@ -0,0 +1,42 @@
+#include "pwf.h"
+#include <pthread.h>
+
+#define FIX(x) (pw->pw_##x = pw->pw_##x-line+buf)
+
+static int getpw_r(const char *name, uid_t uid, struct passwd *pw, char *buf, size_t size, struct passwd **res)
+{
+	char *line = 0;
+	size_t len = 0;
+	int rv = 0;
+	int cs;
+
+	pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cs);
+
+	rv = __getpw_a(name, uid, pw, &line, &len, res);
+	if (*res && size < len) {
+		*res = 0;
+		rv = ERANGE;
+	}
+	if (*res) {
+		memcpy(buf, line, len);
+		FIX(name);
+		FIX(passwd);
+		FIX(gecos);
+		FIX(dir);
+		FIX(shell);
+	}
+ 	free(line);
+	pthread_setcancelstate(cs, 0);
+	if (rv) errno = rv;
+	return rv;
+}
+
+int getpwnam_r(const char *name, struct passwd *pw, char *buf, size_t size, struct passwd **res)
+{
+	return getpw_r(name, 0, pw, buf, size, res);
+}
+
+int getpwuid_r(uid_t uid, struct passwd *pw, char *buf, size_t size, struct passwd **res)
+{
+	return getpw_r(0, uid, pw, buf, size, res);
+}
libc/musl/src/passwd/getpwent.c
@@ -0,0 +1,37 @@
+#include "pwf.h"
+
+static FILE *f;
+static char *line;
+static struct passwd pw;
+static size_t size;
+
+void setpwent()
+{
+	if (f) fclose(f);
+	f = 0;
+}
+
+weak_alias(setpwent, endpwent);
+
+struct passwd *getpwent()
+{
+	struct passwd *res;
+	if (!f) f = fopen("/etc/passwd", "rbe");
+	if (!f) return 0;
+	__getpwent_a(f, &pw, &line, &size, &res);
+	return res;
+}
+
+struct passwd *getpwuid(uid_t uid)
+{
+	struct passwd *res;
+	__getpw_a(0, uid, &pw, &line, &size, &res);
+	return res;
+}
+
+struct passwd *getpwnam(const char *name)
+{
+	struct passwd *res;
+	__getpw_a(name, 0, &pw, &line, &size, &res);
+	return res;
+}
libc/musl/src/passwd/getpwent_a.c
@@ -0,0 +1,54 @@
+#include "pwf.h"
+#include <pthread.h>
+
+static unsigned atou(char **s)
+{
+	unsigned x;
+	for (x=0; **s-'0'<10U; ++*s) x=10*x+(**s-'0');
+	return x;
+}
+
+int __getpwent_a(FILE *f, struct passwd *pw, char **line, size_t *size, struct passwd **res)
+{
+	ssize_t l;
+	char *s;
+	int rv = 0;
+	int cs;
+	pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cs);
+	for (;;) {
+		if ((l=getline(line, size, f)) < 0) {
+			rv = ferror(f) ? errno : 0;
+			free(*line);
+			*line = 0;
+			pw = 0;
+			break;
+		}
+		line[0][l-1] = 0;
+
+		s = line[0];
+		pw->pw_name = s++;
+		if (!(s = strchr(s, ':'))) continue;
+
+		*s++ = 0; pw->pw_passwd = s;
+		if (!(s = strchr(s, ':'))) continue;
+
+		*s++ = 0; pw->pw_uid = atou(&s);
+		if (*s != ':') continue;
+
+		*s++ = 0; pw->pw_gid = atou(&s);
+		if (*s != ':') continue;
+
+		*s++ = 0; pw->pw_gecos = s;
+		if (!(s = strchr(s, ':'))) continue;
+
+		*s++ = 0; pw->pw_dir = s;
+		if (!(s = strchr(s, ':'))) continue;
+
+		*s++ = 0; pw->pw_shell = s;
+		break;
+	}
+	pthread_setcancelstate(cs, 0);
+	*res = pw;
+	if (rv) errno = rv;
+	return rv;
+}
libc/musl/src/passwd/getspent.c
@@ -0,0 +1,14 @@
+#include "pwf.h"
+
+void setspent()
+{
+}
+
+void endspent()
+{
+}
+
+struct spwd *getspent()
+{
+	return 0;
+}
libc/musl/src/passwd/getspnam.c
@@ -0,0 +1,18 @@
+#include "pwf.h"
+
+#define LINE_LIM 256
+
+struct spwd *getspnam(const char *name)
+{
+	static struct spwd sp;
+	static char *line;
+	struct spwd *res;
+	int e;
+	int orig_errno = errno;
+
+	if (!line) line = malloc(LINE_LIM);
+	if (!line) return 0;
+	e = getspnam_r(name, &sp, line, LINE_LIM, &res);
+	errno = e ? e : orig_errno;
+	return res;
+}
libc/musl/src/passwd/getspnam_r.c
@@ -0,0 +1,125 @@
+#include <fcntl.h>
+#include <unistd.h>
+#include <sys/stat.h>
+#include <ctype.h>
+#include <pthread.h>
+#include "pwf.h"
+
+/* This implementation support Openwall-style TCB passwords in place of
+ * traditional shadow, if the appropriate directories and files exist.
+ * Thus, it is careful to avoid following symlinks or blocking on fifos
+ * which a malicious user might create in place of his or her TCB shadow
+ * file. It also avoids any allocation to prevent memory-exhaustion
+ * attacks via huge TCB shadow files. */
+
+static long xatol(char **s)
+{
+	long x;
+	if (**s == ':' || **s == '\n') return -1;
+	for (x=0; **s-'0'<10U; ++*s) x=10*x+(**s-'0');
+	return x;
+}
+
+int __parsespent(char *s, struct spwd *sp)
+{
+	sp->sp_namp = s;
+	if (!(s = strchr(s, ':'))) return -1;
+	*s = 0;
+
+	sp->sp_pwdp = ++s;
+	if (!(s = strchr(s, ':'))) return -1;
+	*s = 0;
+
+	s++; sp->sp_lstchg = xatol(&s);
+	if (*s != ':') return -1;
+
+	s++; sp->sp_min = xatol(&s);
+	if (*s != ':') return -1;
+
+	s++; sp->sp_max = xatol(&s);
+	if (*s != ':') return -1;
+
+	s++; sp->sp_warn = xatol(&s);
+	if (*s != ':') return -1;
+
+	s++; sp->sp_inact = xatol(&s);
+	if (*s != ':') return -1;
+
+	s++; sp->sp_expire = xatol(&s);
+	if (*s != ':') return -1;
+
+	s++; sp->sp_flag = xatol(&s);
+	if (*s != '\n') return -1;
+	return 0;
+}
+
+static void cleanup(void *p)
+{
+	fclose(p);
+}
+
+int getspnam_r(const char *name, struct spwd *sp, char *buf, size_t size, struct spwd **res)
+{
+	char path[20+NAME_MAX];
+	FILE *f = 0;
+	int rv = 0;
+	int fd;
+	size_t k, l = strlen(name);
+	int skip = 0;
+	int cs;
+	int orig_errno = errno;
+
+	*res = 0;
+
+	/* Disallow potentially-malicious user names */
+	if (*name=='.' || strchr(name, '/') || !l)
+		return errno = EINVAL;
+
+	/* Buffer size must at least be able to hold name, plus some.. */
+	if (size < l+100)
+		return errno = ERANGE;
+
+	/* Protect against truncation */
+	if (snprintf(path, sizeof path, "/etc/tcb/%s/shadow", name) >= sizeof path)
+		return errno = EINVAL;
+
+	fd = open(path, O_RDONLY|O_NOFOLLOW|O_NONBLOCK|O_CLOEXEC);
+	if (fd >= 0) {
+		struct stat st = { 0 };
+		errno = EINVAL;
+		if (fstat(fd, &st) || !S_ISREG(st.st_mode) || !(f = fdopen(fd, "rb"))) {
+			pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cs);
+			close(fd);
+			pthread_setcancelstate(cs, 0);
+			return errno;
+		}
+	} else {
+		if (errno != ENOENT && errno != ENOTDIR)
+			return errno;
+		f = fopen("/etc/shadow", "rbe");
+		if (!f) {
+			if (errno != ENOENT && errno != ENOTDIR)
+				return errno;
+			return 0;
+		}
+	}
+
+	pthread_cleanup_push(cleanup, f);
+	while (fgets(buf, size, f) && (k=strlen(buf))>0) {
+		if (skip || strncmp(name, buf, l) || buf[l]!=':') {
+			skip = buf[k-1] != '\n';
+			continue;
+		}
+		if (buf[k-1] != '\n') {
+			rv = ERANGE;
+			break;
+		}
+
+		if (__parsespent(buf, sp) < 0) continue;
+		*res = sp;
+		break;
+	}
+	pthread_cleanup_pop(1);
+	errno = rv ? rv : orig_errno;
+	return rv;
+}
libc/musl/src/passwd/lckpwdf.c
@@ -0,0 +1,11 @@
+#include <shadow.h>
+
+int lckpwdf()
+{
+	return 0;
+}
+
+int ulckpwdf()
+{
+	return 0;
+}
libc/musl/src/passwd/nscd.h
@@ -0,0 +1,44 @@
+#ifndef NSCD_H
+#define NSCD_H
+
+#include <stdint.h>
+
+#define NSCDVERSION 2
+#define GETPWBYNAME 0
+#define GETPWBYUID 1
+#define GETGRBYNAME 2
+#define GETGRBYGID 3
+#define GETINITGR 15
+
+#define REQVERSION 0
+#define REQTYPE 1
+#define REQKEYLEN 2
+#define REQ_LEN 3
+
+#define PWVERSION 0
+#define PWFOUND 1
+#define PWNAMELEN 2
+#define PWPASSWDLEN 3
+#define PWUID 4
+#define PWGID 5
+#define PWGECOSLEN 6
+#define PWDIRLEN 7
+#define PWSHELLLEN 8
+#define PW_LEN 9
+
+#define GRVERSION 0
+#define GRFOUND 1
+#define GRNAMELEN 2
+#define GRPASSWDLEN 3
+#define GRGID 4
+#define GRMEMCNT 5
+#define GR_LEN 6
+
+#define INITGRVERSION 0
+#define INITGRFOUND 1
+#define INITGRNGRPS 2
+#define INITGR_LEN 3
+
+hidden FILE *__nscd_query(int32_t req, const char *key, int32_t *buf, size_t len, int *swap);
+
+#endif
libc/musl/src/passwd/nscd_query.c
@@ -0,0 +1,107 @@
+#include <sys/socket.h>
+#include <byteswap.h>
+#include <unistd.h>
+#include <stdio.h>
+#include <string.h>
+#include <errno.h>
+#include <limits.h>
+#include "nscd.h"
+
+static const struct {
+	short sun_family;
+	char sun_path[21];
+} addr = {
+	AF_UNIX,
+	"/var/run/nscd/socket"
+};
+
+FILE *__nscd_query(int32_t req, const char *key, int32_t *buf, size_t len, int *swap)
+{
+	size_t i;
+	int fd;
+	FILE *f = 0;
+	int32_t req_buf[REQ_LEN] = {
+		NSCDVERSION,
+		req,
+		strnlen(key,LOGIN_NAME_MAX)+1
+	};
+	struct msghdr msg = {
+		.msg_iov = (struct iovec[]){
+			{&req_buf, sizeof(req_buf)},
+			{(char*)key, strlen(key)+1}
+		},
+		.msg_iovlen = 2
+	};
+	int errno_save = errno;
+
+	*swap = 0;
+retry:
+	memset(buf, 0, len);
+	buf[0] = NSCDVERSION;
+
+	fd = socket(PF_UNIX, SOCK_STREAM | SOCK_CLOEXEC, 0);
+	if (fd < 0) return NULL;
+
+	if(!(f = fdopen(fd, "r"))) {
+		close(fd);
+		return 0;
+	}
+
+	if (req_buf[2] > LOGIN_NAME_MAX)
+		return f;
+
+	if (connect(fd, (struct sockaddr*)&addr, sizeof(addr)) < 0) {
+		/* If there isn't a running nscd we simulate a "not found"
+		 * result and the caller is responsible for calling
+		 * fclose on the (unconnected) socket. The value of
+		 * errno must be left unchanged in this case.  */
+		if (errno == EACCES || errno == ECONNREFUSED || errno == ENOENT) {
+			errno = errno_save;
+			return f;
+		}
+		goto error;
+	}
+
+	if (sendmsg(fd, &msg, MSG_NOSIGNAL) < 0)
+		goto error;
+
+	if (!fread(buf, len, 1, f)) {
+		/* If the VERSION entry mismatches nscd will disconnect. The
+		 * most likely cause is that the endianness mismatched. So, we
+		 * byteswap and try once more. (if we already swapped, just
+		 * fail out)
+		 */
+		if (ferror(f)) goto error;
+		if (!*swap) {
+			fclose(f);
+			for (i = 0; i < sizeof(req_buf)/sizeof(req_buf[0]); i++) {
+				req_buf[i] = bswap_32(req_buf[i]);
+			}
+			*swap = 1;
+			goto retry;
+		} else {
+			errno = EIO;
+			goto error;
+		}
+	}
+
+	if (*swap) {
+		for (i = 0; i < len/sizeof(buf[0]); i++) {
+			buf[i] = bswap_32(buf[i]);
+		}
+	}
+
+	/* The first entry in every nscd response is the version number. This
+	 * really shouldn't happen, and is evidence of some form of malformed
+	 * response.
+	 */
+	if(buf[0] != NSCDVERSION) {
+		errno = EIO;
+		goto error;
+	}
+
+	return f;
+error:
+	fclose(f);
+	return 0;
+}
libc/musl/src/passwd/putgrent.c
@@ -0,0 +1,17 @@
+#define _GNU_SOURCE
+#include <grp.h>
+#include <stdio.h>
+
+int putgrent(const struct group *gr, FILE *f)
+{
+	int r;
+	size_t i;
+	flockfile(f);
+	if ((r = fprintf(f, "%s:%s:%d:", gr->gr_name, gr->gr_passwd, gr->gr_gid))<0) goto done;
+	if (gr->gr_mem) for (i=0; gr->gr_mem[i]; i++)
+		if ((r = fprintf(f, "%s%s", i?",":"", gr->gr_mem[i]))<0) goto done;
+	r = fputc('\n', f);
+done:
+	funlockfile(f);
+	return r<0 ? -1 : 0;
+}
libc/musl/src/passwd/putpwent.c
@@ -0,0 +1,10 @@
+#define _GNU_SOURCE
+#include <pwd.h>
+#include <stdio.h>
+
+int putpwent(const struct passwd *pw, FILE *f)
+{
+	return fprintf(f, "%s:%s:%d:%d:%s:%s:%s\n",
+		pw->pw_name, pw->pw_passwd, pw->pw_uid, pw->pw_gid,
+		pw->pw_gecos, pw->pw_dir, pw->pw_shell)<0 ? -1 : 0;
+}
libc/musl/src/passwd/putspent.c
@@ -0,0 +1,13 @@
+#include <shadow.h>
+#include <stdio.h>
+
+#define NUM(n) ((n) == -1 ? 0 : -1), ((n) == -1 ? 0 : (n))
+#define STR(s) ((s) ? (s) : "")
+
+int putspent(const struct spwd *sp, FILE *f)
+{
+	return fprintf(f, "%s:%s:%.*ld:%.*ld:%.*ld:%.*ld:%.*ld:%.*ld:%.*lu\n",
+		STR(sp->sp_namp), STR(sp->sp_pwdp), NUM(sp->sp_lstchg),
+		NUM(sp->sp_min), NUM(sp->sp_max), NUM(sp->sp_warn),
+		NUM(sp->sp_inact), NUM(sp->sp_expire), NUM(sp->sp_flag)) < 0 ? -1 : 0;
+}
libc/musl/src/passwd/pwf.h
@@ -0,0 +1,15 @@
+#include <pwd.h>
+#include <grp.h>
+#include <shadow.h>
+#include <stdio.h>
+#include <errno.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <string.h>
+#include <limits.h>
+
+hidden int __getpwent_a(FILE *f, struct passwd *pw, char **line, size_t *size, struct passwd **res);
+hidden int __getpw_a(const char *name, uid_t uid, struct passwd *pw, char **buf, size_t *size, struct passwd **res);
+hidden int __getgrent_a(FILE *f, struct group *gr, char **line, size_t *size, char ***mem, size_t *nmem, struct group **res);
+hidden int __getgr_a(const char *name, gid_t gid, struct group *gr, char **buf, size_t *size, char ***mem, size_t *nmem, struct group **res);
+hidden int __parsespent(char *s, struct spwd *sp);
libc/musl/src/prng/__rand48_step.c
@@ -0,0 +1,14 @@
+#include <stdint.h>
+#include "rand48.h"
+
+uint64_t __rand48_step(unsigned short *xi, unsigned short *lc)
+{
+	uint64_t a, x;
+	x = xi[0] | xi[1]+0U<<16 | xi[2]+0ULL<<32;
+	a = lc[0] | lc[1]+0U<<16 | lc[2]+0ULL<<32;
+	x = a*x + lc[3];
+	xi[0] = x;
+	xi[1] = x>>16;
+	xi[2] = x>>32;
+	return x & 0xffffffffffffull;
+}
libc/musl/src/prng/__seed48.c
@@ -0,0 +1,3 @@
+#include "rand48.h"
+
+unsigned short __seed48[7] = { 0, 0, 0, 0xe66d, 0xdeec, 0x5, 0xb };
libc/musl/src/prng/drand48.c
@@ -0,0 +1,17 @@
+#include <stdlib.h>
+#include <inttypes.h>
+#include "rand48.h"
+
+double erand48(unsigned short s[3])
+{
+	union {
+		uint64_t u;
+		double f;
+	} x = { 0x3ff0000000000000ULL | __rand48_step(s, __seed48+3)<<4 };
+	return x.f - 1.0;
+}
+
+double drand48(void)
+{
+	return erand48(__seed48);
+}
libc/musl/src/prng/lcong48.c
@@ -0,0 +1,8 @@
+#include <stdlib.h>
+#include <string.h>
+#include "rand48.h"
+
+void lcong48(unsigned short p[7])
+{
+	memcpy(__seed48, p, sizeof __seed48);
+}
libc/musl/src/prng/lrand48.c
@@ -0,0 +1,13 @@
+#include <stdlib.h>
+#include <inttypes.h>
+#include "rand48.h"
+
+long nrand48(unsigned short s[3])
+{
+	return __rand48_step(s, __seed48+3) >> 17;
+}
+
+long lrand48(void)
+{
+	return nrand48(__seed48);
+}
libc/musl/src/prng/mrand48.c
@@ -0,0 +1,13 @@
+#include <stdlib.h>
+#include <inttypes.h>
+#include "rand48.h"
+
+long jrand48(unsigned short s[3])
+{
+	return (int32_t)(__rand48_step(s, __seed48+3) >> 16);
+}
+
+long mrand48(void)
+{
+	return jrand48(__seed48);
+}
libc/musl/src/prng/rand.c
@@ -0,0 +1,15 @@
+#include <stdlib.h>
+#include <stdint.h>
+
+static uint64_t seed;
+
+void srand(unsigned s)
+{
+	seed = s-1;
+}
+
+int rand(void)
+{
+	seed = 6364136223846793005ULL*seed + 1;
+	return seed>>33;
+}
libc/musl/src/prng/rand48.h
@@ -0,0 +1,5 @@
+#include <stdint.h>
+#include <features.h>
+
+hidden uint64_t __rand48_step(unsigned short *xi, unsigned short *lc);
+extern hidden unsigned short __seed48[7];
libc/musl/src/prng/rand_r.c
@@ -0,0 +1,15 @@
+#include <stdlib.h>
+
+static unsigned temper(unsigned x)
+{
+	x ^= x>>11;
+	x ^= x<<7 & 0x9D2C5680;
+	x ^= x<<15 & 0xEFC60000;
+	x ^= x>>18;
+	return x;
+}
+
+int rand_r(unsigned *seed)
+{
+	return temper(*seed = *seed * 1103515245 + 12345)/2;
+}
libc/musl/src/prng/random.c
@@ -0,0 +1,122 @@
+#include <stdlib.h>
+#include <stdint.h>
+#include "lock.h"
+
+/*
+this code uses the same lagged fibonacci generator as the
+original bsd random implementation except for the seeding
+which was broken in the original
+*/
+
+static uint32_t init[] = {
+0x00000000,0x5851f42d,0xc0b18ccf,0xcbb5f646,
+0xc7033129,0x30705b04,0x20fd5db4,0x9a8b7f78,
+0x502959d8,0xab894868,0x6c0356a7,0x88cdb7ff,
+0xb477d43f,0x70a3a52b,0xa8e4baf1,0xfd8341fc,
+0x8ae16fd9,0x742d2f7a,0x0d1f0796,0x76035e09,
+0x40f7702c,0x6fa72ca5,0xaaa84157,0x58a0df74,
+0xc74a0364,0xae533cc4,0x04185faf,0x6de3b115,
+0x0cab8628,0xf043bfa4,0x398150e9,0x37521657};
+
+static int n = 31;
+static int i = 3;
+static int j = 0;
+static uint32_t *x = init+1;
+static volatile int lock[1];
+
+static uint32_t lcg31(uint32_t x) {
+	return (1103515245*x + 12345) & 0x7fffffff;
+}
+
+static uint64_t lcg64(uint64_t x) {
+	return 6364136223846793005ull*x + 1;
+}
+
+static void *savestate() {
+	x[-1] = (n<<16)|(i<<8)|j;
+	return x-1;
+}
+
+static void loadstate(uint32_t *state) {
+	x = state+1;
+	n = x[-1]>>16;
+	i = (x[-1]>>8)&0xff;
+	j = x[-1]&0xff;
+}
+
+static void __srandom(unsigned seed) {
+	int k;
+	uint64_t s = seed;
+
+	if (n == 0) {
+		x[0] = s;
+		return;
+	}
+	i = n == 31 || n == 7 ? 3 : 1;
+	j = 0;
+	for (k = 0; k < n; k++) {
+		s = lcg64(s);
+		x[k] = s>>32;
+	}
+	/* make sure x contains at least one odd number */
+	x[0] |= 1;
+}
+
+void srandom(unsigned seed) {
+	LOCK(lock);
+	__srandom(seed);
+	UNLOCK(lock);
+}
+
+char *initstate(unsigned seed, char *state, size_t size) {
+	void *old;
+
+	if (size < 8)
+		return 0;
+	LOCK(lock);
+	old = savestate();
+	if (size < 32)
+		n = 0;
+	else if (size < 64)
+		n = 7;
+	else if (size < 128)
+		n = 15;
+	else if (size < 256)
+		n = 31;
+	else
+		n = 63;
+	x = (uint32_t*)state + 1;
+	__srandom(seed);
+	savestate();
+	UNLOCK(lock);
+	return old;
+}
+
+char *setstate(char *state) {
+	void *old;
+
+	LOCK(lock);
+	old = savestate();
+	loadstate((uint32_t*)state);
+	UNLOCK(lock);
+	return old;
+}
+
+long random(void) {
+	long k;
+
+	LOCK(lock);
+	if (n == 0) {
+		k = x[0] = lcg31(x[0]);
+		goto end;
+	}
+	x[i] += x[j];
+	k = x[i]>>1;
+	if (++i == n)
+		i = 0;
+	if (++j == n)
+		j = 0;
+end:
+	UNLOCK(lock);
+	return k;
+}
libc/musl/src/prng/seed48.c
@@ -0,0 +1,11 @@
+#include <stdlib.h>
+#include <string.h>
+#include "rand48.h"
+
+unsigned short *seed48(unsigned short *s)
+{
+	static unsigned short p[3];
+	memcpy(p, __seed48, sizeof p);
+	memcpy(__seed48, s, sizeof p);
+	return p;
+}
libc/musl/src/prng/srand48.c
@@ -0,0 +1,6 @@
+#include <stdlib.h>
+
+void srand48(long seed)
+{
+	seed48((unsigned short [3]){ 0x330e, seed, seed>>16 });
+}
libc/musl/src/process/arm/vfork.s
@@ -0,0 +1,10 @@
+.syntax unified
+.global vfork
+.type vfork,%function
+vfork:
+	mov ip, r7
+	mov r7, 190
+	svc 0
+	mov r7, ip
+	.hidden __syscall_ret
+	b __syscall_ret
libc/musl/src/process/i386/vfork.s
@@ -0,0 +1,12 @@
+.global vfork
+.type vfork,@function
+vfork:
+	pop %edx
+	mov $190,%eax
+	int $128
+	push %edx
+	push %eax
+	.hidden __syscall_ret
+	call __syscall_ret
+	pop %edx
+	ret
libc/musl/src/process/s390x/vfork.s
@@ -0,0 +1,6 @@
+	.global vfork
+	.type vfork,%function
+vfork:
+	svc 190
+	.hidden __syscall_ret
+	jg  __syscall_ret
libc/musl/src/process/sh/vfork.s
@@ -0,0 +1,20 @@
+.global vfork
+.type vfork,@function
+vfork:
+	mov #95, r3
+	add r3, r3
+
+	trapa #31
+	or    r0, r0
+	or    r0, r0
+	or    r0, r0
+	or    r0, r0
+	or    r0, r0
+
+	mov r0, r4
+	mov.l 1f, r0
+2:	braf r0
+	 nop
+	.align 2
+	.hidden __syscall_ret
+1:	.long __syscall_ret@PLT-(2b+4-.)
libc/musl/src/process/x32/vfork.s
@@ -0,0 +1,10 @@
+.global vfork
+.type vfork,@function
+vfork:
+	pop %rdx
+	mov $0x4000003a,%eax /* SYS_vfork */
+	syscall
+	push %rdx
+	mov %rax,%rdi
+	.hidden __syscall_ret
+	jmp __syscall_ret
libc/musl/src/process/x86_64/vfork.s
@@ -0,0 +1,10 @@
+.global vfork
+.type vfork,@function
+vfork:
+	pop %rdx
+	mov $58,%eax
+	syscall
+	push %rdx
+	mov %rax,%rdi
+	.hidden __syscall_ret
+	jmp __syscall_ret
libc/musl/src/process/execl.c
@@ -0,0 +1,22 @@
+#include <unistd.h>
+#include <stdarg.h>
+
+int execl(const char *path, const char *argv0, ...)
+{
+	int argc;
+	va_list ap;
+	va_start(ap, argv0);
+	for (argc=1; va_arg(ap, const char *); argc++);
+	va_end(ap);
+	{
+		int i;
+		char *argv[argc+1];
+		va_start(ap, argv0);
+		argv[0] = (char *)argv0;
+		for (i=1; i<argc; i++)
+			argv[i] = va_arg(ap, char *);
+		argv[i] = NULL;
+		va_end(ap);
+		return execv(path, argv);
+	}
+}
libc/musl/src/process/execle.c
@@ -0,0 +1,23 @@
+#include <unistd.h>
+#include <stdarg.h>
+
+int execle(const char *path, const char *argv0, ...)
+{
+	int argc;
+	va_list ap;
+	va_start(ap, argv0);
+	for (argc=1; va_arg(ap, const char *); argc++);
+	va_end(ap);
+	{
+		int i;
+		char *argv[argc+1];
+		char **envp;
+		va_start(ap, argv0);
+		argv[0] = (char *)argv0;
+		for (i=1; i<=argc; i++)
+			argv[i] = va_arg(ap, char *);
+		envp = va_arg(ap, char **);
+		va_end(ap);
+		return execve(path, argv, envp);
+	}
+}
libc/musl/src/process/execlp.c
@@ -0,0 +1,22 @@
+#include <unistd.h>
+#include <stdarg.h>
+
+int execlp(const char *file, const char *argv0, ...)
+{
+	int argc;
+	va_list ap;
+	va_start(ap, argv0);
+	for (argc=1; va_arg(ap, const char *); argc++);
+	va_end(ap);
+	{
+		int i;
+		char *argv[argc+1];
+		va_start(ap, argv0);
+		argv[0] = (char *)argv0;
+		for (i=1; i<argc; i++)
+			argv[i] = va_arg(ap, char *);
+		argv[i] = NULL;
+		va_end(ap);
+		return execvp(file, argv);
+	}
+}
libc/musl/src/process/execv.c
@@ -0,0 +1,8 @@
+#include <unistd.h>
+
+extern char **__environ;
+
+int execv(const char *path, char *const argv[])
+{
+	return execve(path, argv, __environ);
+}
libc/musl/src/process/execve.c
@@ -0,0 +1,8 @@
+#include <unistd.h>
+#include "syscall.h"
+
+int execve(const char *path, char *const argv[], char *const envp[])
+{
+	/* do we need to use environ if envp is null? */
+	return syscall(SYS_execve, path, argv, envp);
+}
libc/musl/src/process/execvp.c
@@ -0,0 +1,61 @@
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <errno.h>
+#include <limits.h>
+
+extern char **__environ;
+
+int __execvpe(const char *file, char *const argv[], char *const envp[])
+{
+	const char *p, *z, *path = getenv("PATH");
+	size_t l, k;
+	int seen_eacces = 0;
+
+	errno = ENOENT;
+	if (!*file) return -1;
+
+	if (strchr(file, '/'))
+		return execve(file, argv, envp);
+
+	if (!path) path = "/usr/local/bin:/bin:/usr/bin";
+	k = strnlen(file, NAME_MAX+1);
+	if (k > NAME_MAX) {
+		errno = ENAMETOOLONG;
+		return -1;
+	}
+	l = strnlen(path, PATH_MAX-1)+1;
+
+	for(p=path; ; p=z) {
+		char b[l+k+1];
+		z = strchr(p, ':');
+		if (!z) z = p+strlen(p);
+		if (z-p >= l) {
+			if (!*z++) break;
+			continue;
+		}
+		memcpy(b, p, z-p);
+		b[z-p] = '/';
+		memcpy(b+(z-p)+(z>p), file, k+1);
+		execve(b, argv, envp);
+		switch (errno) {
+		case EACCES:
+			seen_eacces = 1;
+		case ENOENT:
+		case ENOTDIR:
+			break;
+		default:
+			return -1;
+		}
+		if (!*z++) break;
+	}
+	if (seen_eacces) errno = EACCES;
+	return -1;
+}
+
+int execvp(const char *file, char *const argv[])
+{
+	return __execvpe(file, argv, __environ);
+}
+
+weak_alias(__execvpe, execvpe);
libc/musl/src/process/fdop.h
@@ -0,0 +1,10 @@
+#define FDOP_CLOSE 1
+#define FDOP_DUP2 2
+#define FDOP_OPEN 3
+
+struct fdop {
+	struct fdop *next, *prev;
+	int cmd, fd, srcfd, oflag;
+	mode_t mode;
+	char path[];
+};
libc/musl/src/process/fexecve.c
@@ -0,0 +1,16 @@
+#define _GNU_SOURCE
+#include <unistd.h>
+#include <errno.h>
+#include <fcntl.h>
+#include "syscall.h"
+
+int fexecve(int fd, char *const argv[], char *const envp[])
+{
+	int r = __syscall(SYS_execveat, fd, "", argv, envp, AT_EMPTY_PATH);
+	if (r != -ENOSYS) return __syscall_ret(r);
+	char buf[15 + 3*sizeof(int)];
+	__procfdname(buf, fd);
+	execve(buf, argv, envp);
+	if (errno == ENOENT) errno = EBADF;
+	return -1;
+}
libc/musl/src/process/fork.c
@@ -0,0 +1,35 @@
+#include <unistd.h>
+#include <string.h>
+#include <signal.h>
+#include "syscall.h"
+#include "libc.h"
+#include "pthread_impl.h"
+
+static void dummy(int x)
+{
+}
+
+weak_alias(dummy, __fork_handler);
+
+pid_t fork(void)
+{
+	pid_t ret;
+	sigset_t set;
+	__fork_handler(-1);
+	__block_all_sigs(&set);
+#ifdef SYS_fork
+	ret = __syscall(SYS_fork);
+#else
+	ret = __syscall(SYS_clone, SIGCHLD, 0);
+#endif
+	if (!ret) {
+		pthread_t self = __pthread_self();
+		self->tid = __syscall(SYS_gettid);
+		self->robust_list.off = 0;
+		self->robust_list.pending = 0;
+		libc.threads_minus_1 = 0;
+	}
+	__restore_sigs(&set);
+	__fork_handler(!ret);
+	return __syscall_ret(ret);
+}
libc/musl/src/process/posix_spawn.c
@@ -0,0 +1,192 @@
+#define _GNU_SOURCE
+#include <spawn.h>
+#include <sched.h>
+#include <unistd.h>
+#include <signal.h>
+#include <fcntl.h>
+#include <sys/wait.h>
+#include "syscall.h"
+#include "pthread_impl.h"
+#include "fdop.h"
+
+struct args {
+	int p[2];
+	sigset_t oldmask;
+	const char *path;
+	const posix_spawn_file_actions_t *fa;
+	const posix_spawnattr_t *restrict attr;
+	char *const *argv, *const *envp;
+};
+
+static int __sys_dup2(int old, int new)
+{
+#ifdef SYS_dup2
+	return __syscall(SYS_dup2, old, new);
+#else
+	return __syscall(SYS_dup3, old, new, 0);
+#endif
+}
+
+static int child(void *args_vp)
+{
+	int i, ret;
+	struct sigaction sa = {0};
+	struct args *args = args_vp;
+	int p = args->p[1];
+	const posix_spawn_file_actions_t *fa = args->fa;
+	const posix_spawnattr_t *restrict attr = args->attr;
+	sigset_t hset;
+
+	close(args->p[0]);
+
+	/* All signal dispositions must be either SIG_DFL or SIG_IGN
+	 * before signals are unblocked. Otherwise a signal handler
+	 * from the parent might get run in the child while sharing
+	 * memory, with unpredictable and dangerous results. To
+	 * reduce overhead, sigaction has tracked for us which signals
+	 * potentially have a signal handler. */
+	__get_handler_set(&hset);
+	for (i=1; i<_NSIG; i++) {
+		if ((attr->__flags & POSIX_SPAWN_SETSIGDEF)
+		     && sigismember(&attr->__def, i)) {
+			sa.sa_handler = SIG_DFL;
+		} else if (sigismember(&hset, i)) {
+			if (i-32<3U) {
+				sa.sa_handler = SIG_IGN;
+			} else {
+				__libc_sigaction(i, 0, &sa);
+				if (sa.sa_handler==SIG_IGN) continue;
+				sa.sa_handler = SIG_DFL;
+			}
+		} else {
+			continue;
+		}
+		__libc_sigaction(i, &sa, 0);
+	}
+
+	if (attr->__flags & POSIX_SPAWN_SETSID)
+		if ((ret=__syscall(SYS_setsid)) < 0)
+			goto fail;
+
+	if (attr->__flags & POSIX_SPAWN_SETPGROUP)
+		if ((ret=__syscall(SYS_setpgid, 0, attr->__pgrp)))
+			goto fail;
+
+	/* Use syscalls directly because the library functions attempt
+	 * to do a multi-threaded synchronized id-change, which would
+	 * trash the parent's state. */
+	if (attr->__flags & POSIX_SPAWN_RESETIDS)
+		if ((ret=__syscall(SYS_setgid, __syscall(SYS_getgid))) ||
+		    (ret=__syscall(SYS_setuid, __syscall(SYS_getuid))) )
+			goto fail;
+
+	if (fa && fa->__actions) {
+		struct fdop *op;
+		int fd;
+		for (op = fa->__actions; op->next; op = op->next);
+		for (; op; op = op->prev) {
+			/* It's possible that a file operation would clobber
+			 * the pipe fd used for synchronizing with the
+			 * parent. To avoid that, we dup the pipe onto
+			 * an unoccupied fd. */
+			if (op->fd == p) {
+				ret = __syscall(SYS_dup, p);
+				if (ret < 0) goto fail;
+				__syscall(SYS_close, p);
+				p = ret;
+			}
+			switch(op->cmd) {
+			case FDOP_CLOSE:
+				__syscall(SYS_close, op->fd);
+				break;
+			case FDOP_DUP2:
+				fd = op->srcfd;
+				if (fd != op->fd) {
+					if ((ret=__sys_dup2(fd, op->fd))<0)
+						goto fail;
+				} else {
+					ret = __syscall(SYS_fcntl, fd, F_GETFD);
+					ret = __syscall(SYS_fcntl, fd, F_SETFD,
+					                ret & ~FD_CLOEXEC);
+					if (ret<0)
+						goto fail;
+				}
+				break;
+			case FDOP_OPEN:
+				fd = __sys_open(op->path, op->oflag, op->mode);
+				if ((ret=fd) < 0) goto fail;
+				if (fd != op->fd) {
+					if ((ret=__sys_dup2(fd, op->fd))<0)
+						goto fail;
+					__syscall(SYS_close, fd);
+				}
+				break;
+			}
+		}
+	}
+
+	/* Close-on-exec flag may have been lost if we moved the pipe
+	 * to a different fd. We don't use F_DUPFD_CLOEXEC above because
+	 * it would fail on older kernels and atomicity is not needed --
+	 * in this process there are no threads or signal handlers. */
+	__syscall(SYS_fcntl, p, F_SETFD, FD_CLOEXEC);
+
+	pthread_sigmask(SIG_SETMASK, (attr->__flags & POSIX_SPAWN_SETSIGMASK)
+		? &attr->__mask : &args->oldmask, 0);
+
+	int (*exec)(const char *, char *const *, char *const *) =
+		attr->__fn ? (int (*)())attr->__fn : execve;
+
+	exec(args->path, args->argv, args->envp);
+	ret = -errno;
+
+fail:
+	/* Since sizeof errno < PIPE_BUF, the write is atomic. */
+	ret = -ret;
+	if (ret) while (__syscall(SYS_write, p, &ret, sizeof ret) < 0);
+	_exit(127);
+}
+
+
+int posix_spawn(pid_t *restrict res, const char *restrict path,
+	const posix_spawn_file_actions_t *fa,
+	const posix_spawnattr_t *restrict attr,
+	char *const argv[restrict], char *const envp[restrict])
+{
+	pid_t pid;
+	char stack[1024+PATH_MAX];
+	int ec=0, cs;
+	struct args args;
+
+	if (pipe2(args.p, O_CLOEXEC))
+		return errno;
+
+	pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cs);
+
+	args.path = path;
+	args.fa = fa;
+	args.attr = attr ? attr : &(const posix_spawnattr_t){0};
+	args.argv = argv;
+	args.envp = envp;
+	pthread_sigmask(SIG_BLOCK, SIGALL_SET, &args.oldmask);
+
+	pid = __clone(child, stack+sizeof stack,
+		CLONE_VM|CLONE_VFORK|SIGCHLD, &args);
+	close(args.p[1]);
+
+	if (pid > 0) {
+		if (read(args.p[0], &ec, sizeof ec) != sizeof ec) ec = 0;
+		else waitpid(pid, &(int){0}, 0);
+	} else {
+		ec = -pid;
+	}
+
+	close(args.p[0]);
+
+	if (!ec && res) *res = pid;
+
+	pthread_sigmask(SIG_SETMASK, &args.oldmask, 0);
+	pthread_setcancelstate(cs, 0);
+
+	return ec;
+}
libc/musl/src/process/posix_spawn_file_actions_addclose.c
@@ -0,0 +1,16 @@
+#include <spawn.h>
+#include <stdlib.h>
+#include <errno.h>
+#include "fdop.h"
+
+int posix_spawn_file_actions_addclose(posix_spawn_file_actions_t *fa, int fd)
+{
+	struct fdop *op = malloc(sizeof *op);
+	if (!op) return ENOMEM;
+	op->cmd = FDOP_CLOSE;
+	op->fd = fd;
+	if ((op->next = fa->__actions)) op->next->prev = op;
+	op->prev = 0;
+	fa->__actions = op;
+	return 0;
+}
libc/musl/src/process/posix_spawn_file_actions_adddup2.c
@@ -0,0 +1,17 @@
+#include <spawn.h>
+#include <stdlib.h>
+#include <errno.h>
+#include "fdop.h"
+
+int posix_spawn_file_actions_adddup2(posix_spawn_file_actions_t *fa, int srcfd, int fd)
+{
+	struct fdop *op = malloc(sizeof *op);
+	if (!op) return ENOMEM;
+	op->cmd = FDOP_DUP2;
+	op->srcfd = srcfd;
+	op->fd = fd;
+	if ((op->next = fa->__actions)) op->next->prev = op;
+	op->prev = 0;
+	fa->__actions = op;
+	return 0;
+}
libc/musl/src/process/posix_spawn_file_actions_addopen.c
@@ -0,0 +1,20 @@
+#include <spawn.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include "fdop.h"
+
+int posix_spawn_file_actions_addopen(posix_spawn_file_actions_t *restrict fa, int fd, const char *restrict path, int flags, mode_t mode)
+{
+	struct fdop *op = malloc(sizeof *op + strlen(path) + 1);
+	if (!op) return ENOMEM;
+	op->cmd = FDOP_OPEN;
+	op->fd = fd;
+	op->oflag = flags;
+	op->mode = mode;
+	strcpy(op->path, path);
+	if ((op->next = fa->__actions)) op->next->prev = op;
+	op->prev = 0;
+	fa->__actions = op;
+	return 0;
+}
libc/musl/src/process/posix_spawn_file_actions_destroy.c
@@ -0,0 +1,14 @@
+#include <spawn.h>
+#include <stdlib.h>
+#include "fdop.h"
+
+int posix_spawn_file_actions_destroy(posix_spawn_file_actions_t *fa)
+{
+	struct fdop *op = fa->__actions, *next;
+	while (op) {
+		next = op->next;
+		free(op);
+		op = next;
+	}
+	return 0;
+}
libc/musl/src/process/posix_spawn_file_actions_init.c
@@ -0,0 +1,7 @@
+#include <spawn.h>
+
+int posix_spawn_file_actions_init(posix_spawn_file_actions_t *fa)
+{
+	fa->__actions = 0;
+	return 0;
+}
libc/musl/src/process/posix_spawnattr_destroy.c
@@ -0,0 +1,6 @@
+#include <spawn.h>
+
+int posix_spawnattr_destroy(posix_spawnattr_t *attr)
+{
+	return 0;
+}
libc/musl/src/process/posix_spawnattr_getflags.c
@@ -0,0 +1,7 @@
+#include <spawn.h>
+
+int posix_spawnattr_getflags(const posix_spawnattr_t *restrict attr, short *restrict flags)
+{
+	*flags = attr->__flags;
+	return 0;
+}
libc/musl/src/process/posix_spawnattr_getpgroup.c
@@ -0,0 +1,7 @@
+#include <spawn.h>
+
+int posix_spawnattr_getpgroup(const posix_spawnattr_t *restrict attr, pid_t *restrict pgrp)
+{
+	*pgrp = attr->__pgrp;
+	return 0;
+}
libc/musl/src/process/posix_spawnattr_getsigdefault.c
@@ -0,0 +1,7 @@
+#include <spawn.h>
+
+int posix_spawnattr_getsigdefault(const posix_spawnattr_t *restrict attr, sigset_t *restrict def)
+{
+	*def = attr->__def;
+	return 0;
+}
libc/musl/src/process/posix_spawnattr_getsigmask.c
@@ -0,0 +1,7 @@
+#include <spawn.h>
+
+int posix_spawnattr_getsigmask(const posix_spawnattr_t *restrict attr, sigset_t *restrict mask)
+{
+	*mask = attr->__mask;
+	return 0;
+}
libc/musl/src/process/posix_spawnattr_init.c
@@ -0,0 +1,7 @@
+#include <spawn.h>
+
+int posix_spawnattr_init(posix_spawnattr_t *attr)
+{
+	*attr = (posix_spawnattr_t){ 0 };
+	return 0;
+}
libc/musl/src/process/posix_spawnattr_sched.c
@@ -0,0 +1,25 @@
+#include <spawn.h>
+#include <sched.h>
+#include <errno.h>
+
+int posix_spawnattr_getschedparam(const posix_spawnattr_t *restrict attr,
+	struct sched_param *restrict schedparam)
+{
+	return ENOSYS;
+}
+
+int posix_spawnattr_setschedparam(posix_spawnattr_t *restrict attr,
+	const struct sched_param *restrict schedparam)
+{
+	return ENOSYS;
+}
+
+int posix_spawnattr_getschedpolicy(const posix_spawnattr_t *restrict attr, int *restrict policy)
+{
+	return ENOSYS;
+}
+
+int posix_spawnattr_setschedpolicy(posix_spawnattr_t *attr, int policy)
+{
+	return ENOSYS;
+}
libc/musl/src/process/posix_spawnattr_setflags.c
@@ -0,0 +1,18 @@
+#include <spawn.h>
+#include <errno.h>
+
+int posix_spawnattr_setflags(posix_spawnattr_t *attr, short flags)
+{
+	const unsigned all_flags =
+		POSIX_SPAWN_RESETIDS |
+		POSIX_SPAWN_SETPGROUP |
+		POSIX_SPAWN_SETSIGDEF |
+		POSIX_SPAWN_SETSIGMASK |
+		POSIX_SPAWN_SETSCHEDPARAM |
+		POSIX_SPAWN_SETSCHEDULER |
+		POSIX_SPAWN_USEVFORK |
+		POSIX_SPAWN_SETSID;
+	if (flags & ~all_flags) return EINVAL;
+	attr->__flags = flags;
+	return 0;
+}
libc/musl/src/process/posix_spawnattr_setpgroup.c
@@ -0,0 +1,7 @@
+#include <spawn.h>
+
+int posix_spawnattr_setpgroup(posix_spawnattr_t *attr, pid_t pgrp)
+{
+	attr->__pgrp = pgrp;
+	return 0;
+}
libc/musl/src/process/posix_spawnattr_setsigdefault.c
@@ -0,0 +1,7 @@
+#include <spawn.h>
+
+int posix_spawnattr_setsigdefault(posix_spawnattr_t *restrict attr, const sigset_t *restrict def)
+{
+	attr->__def = *def;
+	return 0;
+}
libc/musl/src/process/posix_spawnattr_setsigmask.c
@@ -0,0 +1,7 @@
+#include <spawn.h>
+
+int posix_spawnattr_setsigmask(posix_spawnattr_t *restrict attr, const sigset_t *restrict mask)
+{
+	attr->__mask = *mask;
+	return 0;
+}
libc/musl/src/process/posix_spawnp.c
@@ -0,0 +1,13 @@
+#include <spawn.h>
+#include <unistd.h>
+
+int posix_spawnp(pid_t *restrict res, const char *restrict file,
+	const posix_spawn_file_actions_t *fa,
+	const posix_spawnattr_t *restrict attr,
+	char *const argv[restrict], char *const envp[restrict])
+{
+	posix_spawnattr_t spawnp_attr = { 0 };
+	if (attr) spawnp_attr = *attr;
+	spawnp_attr.__fn = (void *)__execvpe;	
+	return posix_spawn(res, file, fa, &spawnp_attr, argv, envp);
+}
libc/musl/src/process/system.c
@@ -0,0 +1,46 @@
+#include <unistd.h>
+#include <stdlib.h>
+#include <signal.h>
+#include <sys/wait.h>
+#include <spawn.h>
+#include <errno.h>
+#include "pthread_impl.h"
+
+extern char **__environ;
+
+int system(const char *cmd)
+{
+	pid_t pid;
+	sigset_t old, reset;
+	struct sigaction sa = { .sa_handler = SIG_IGN }, oldint, oldquit;
+	int status = -1, ret;
+	posix_spawnattr_t attr;
+
+	pthread_testcancel();
+
+	if (!cmd) return 1;
+
+	sigaction(SIGINT, &sa, &oldint);
+	sigaction(SIGQUIT, &sa, &oldquit);
+	sigaddset(&sa.sa_mask, SIGCHLD);
+	sigprocmask(SIG_BLOCK, &sa.sa_mask, &old);
+
+	sigemptyset(&reset);
+	if (oldint.sa_handler != SIG_IGN) sigaddset(&reset, SIGINT);
+	if (oldquit.sa_handler != SIG_IGN) sigaddset(&reset, SIGQUIT);
+	posix_spawnattr_init(&attr);
+	posix_spawnattr_setsigmask(&attr, &old);
+	posix_spawnattr_setsigdefault(&attr, &reset);
+	posix_spawnattr_setflags(&attr, POSIX_SPAWN_SETSIGDEF|POSIX_SPAWN_SETSIGMASK);
+	ret = posix_spawn(&pid, "/bin/sh", 0, &attr,
+		(char *[]){"sh", "-c", (char *)cmd, 0}, __environ);
+	posix_spawnattr_destroy(&attr);
+
+	if (!ret) while (waitpid(pid, &status, 0)<0 && errno == EINTR);
+	sigaction(SIGINT, &oldint, NULL);
+	sigaction(SIGQUIT, &oldquit, NULL);
+	sigprocmask(SIG_SETMASK, &old, NULL);
+
+	if (ret) errno = ret;
+	return status;
+}
libc/musl/src/process/vfork.c
@@ -0,0 +1,14 @@
+#define _GNU_SOURCE
+#include <unistd.h>
+#include <signal.h>
+#include "syscall.h"
+
+pid_t vfork(void)
+{
+	/* vfork syscall cannot be made from C code */
+#ifdef SYS_fork
+	return syscall(SYS_fork);
+#else
+	return syscall(SYS_clone, SIGCHLD, 0);
+#endif
+}
libc/musl/src/process/wait.c
@@ -0,0 +1,6 @@
+#include <sys/wait.h>
+
+pid_t wait(int *status)
+{
+	return waitpid((pid_t)-1, status, 0);
+}
libc/musl/src/process/waitid.c
@@ -0,0 +1,7 @@
+#include <sys/wait.h>
+#include "syscall.h"
+
+int waitid(idtype_t type, id_t id, siginfo_t *info, int options)
+{
+	return syscall_cp(SYS_waitid, type, id, info, options, 0);
+}
libc/musl/src/process/waitpid.c
@@ -0,0 +1,7 @@
+#include <sys/wait.h>
+#include "syscall.h"
+
+pid_t waitpid(pid_t pid, int *status, int options)
+{
+	return syscall_cp(SYS_wait4, pid, status, options, 0);
+}
libc/musl/src/regex/fnmatch.c
@@ -0,0 +1,321 @@
+/*
+ * An implementation of what I call the "Sea of Stars" algorithm for
+ * POSIX fnmatch(). The basic idea is that we factor the pattern into
+ * a head component (which we match first and can reject without ever
+ * measuring the length of the string), an optional tail component
+ * (which only exists if the pattern contains at least one star), and
+ * an optional "sea of stars", a set of star-separated components
+ * between the head and tail. After the head and tail matches have
+ * been removed from the input string, the components in the "sea of
+ * stars" are matched sequentially by searching for their first
+ * occurrence past the end of the previous match.
+ *
+ * - Rich Felker, April 2012
+ */
+
+#include <string.h>
+#include <fnmatch.h>
+#include <stdlib.h>
+#include <wchar.h>
+#include <wctype.h>
+#include "locale_impl.h"
+
+#define END 0
+#define UNMATCHABLE -2
+#define BRACKET -3
+#define QUESTION -4
+#define STAR -5
+
+static int str_next(const char *str, size_t n, size_t *step)
+{
+	if (!n) {
+		*step = 0;
+		return 0;
+	}
+	if (str[0] >= 128U) {
+		wchar_t wc;
+		int k = mbtowc(&wc, str, n);
+		if (k<0) {
+			*step = 1;
+			return -1;
+		}
+		*step = k;
+		return wc;
+	}
+	*step = 1;
+	return str[0];
+}
+
+static int pat_next(const char *pat, size_t m, size_t *step, int flags)
+{
+	int esc = 0;
+	if (!m || !*pat) {
+		*step = 0;
+		return END;
+	}
+	*step = 1;
+	if (pat[0]=='\\' && pat[1] && !(flags & FNM_NOESCAPE)) {
+		*step = 2;
+		pat++;
+		esc = 1;
+		goto escaped;
+	}
+	if (pat[0]=='[') {
+		size_t k = 1;
+		if (k<m) if (pat[k] == '^' || pat[k] == '!') k++;
+		if (k<m) if (pat[k] == ']') k++;
+		for (; k<m && pat[k] && pat[k]!=']'; k++) {
+			if (k+1<m && pat[k+1] && pat[k]=='[' && (pat[k+1]==':' || pat[k+1]=='.' || pat[k+1]=='=')) {
+				int z = pat[k+1];
+				k+=2;
+				if (k<m && pat[k]) k++;
+				while (k<m && pat[k] && (pat[k-1]!=z || pat[k]!=']')) k++;
+				if (k==m || !pat[k]) break;
+			}
+		}
+		if (k==m || !pat[k]) {
+			*step = 1;
+			return '[';
+		}
+		*step = k+1;
+		return BRACKET;
+	}
+	if (pat[0] == '*')
+		return STAR;
+	if (pat[0] == '?')
+		return QUESTION;
+escaped:
+	if (pat[0] >= 128U) {
+		wchar_t wc;
+		int k = mbtowc(&wc, pat, m);
+		if (k<0) {
+			*step = 0;
+			return UNMATCHABLE;
+		}
+		*step = k + esc;
+		return wc;
+	}
+	return pat[0];
+}
+
+static int casefold(int k)
+{
+	int c = towupper(k);
+	return c == k ? towlower(k) : c;
+}
+
+static int match_bracket(const char *p, int k, int kfold)
+{
+	wchar_t wc;
+	int inv = 0;
+	p++;
+	if (*p=='^' || *p=='!') {
+		inv = 1;
+		p++;
+	}
+	if (*p==']') {
+		if (k==']') return !inv;
+		p++;
+	} else if (*p=='-') {
+		if (k=='-') return !inv;
+		p++;
+	}
+	wc = p[-1];
+	for (; *p != ']'; p++) {
+		if (p[0]=='-' && p[1]!=']') {
+			wchar_t wc2;
+			int l = mbtowc(&wc2, p+1, 4);
+			if (l < 0) return 0;
+			if (wc <= wc2)
+				if ((unsigned)k-wc <= wc2-wc ||
+				    (unsigned)kfold-wc <= wc2-wc)
+					return !inv;
+			p += l-1;
+			continue;
+		}
+		if (p[0]=='[' && (p[1]==':' || p[1]=='.' || p[1]=='=')) {
+			const char *p0 = p+2;
+			int z = p[1];
+			p+=3;
+			while (p[-1]!=z || p[0]!=']') p++;
+			if (z == ':' && p-1-p0 < 16) {
+				char buf[16];
+				memcpy(buf, p0, p-1-p0);
+				buf[p-1-p0] = 0;
+				if (iswctype(k, wctype(buf)) ||
+				    iswctype(kfold, wctype(buf)))
+					return !inv;
+			}
+			continue;
+		}
+		if (*p < 128U) {
+			wc = (unsigned char)*p;
+		} else {
+			int l = mbtowc(&wc, p, 4);
+			if (l < 0) return 0;
+			p += l-1;
+		}
+		if (wc==k || wc==kfold) return !inv;
+	}
+	return inv;
+}
+
+static int fnmatch_internal(const char *pat, size_t m, const char *str, size_t n, int flags)
+{
+	const char *p, *ptail, *endpat;
+	const char *s, *stail, *endstr;
+	size_t pinc, sinc, tailcnt=0;
+	int c, k, kfold;
+
+	if (flags & FNM_PERIOD) {
+		if (*str == '.' && *pat != '.')
+			return FNM_NOMATCH;
+	}
+	for (;;) {
+		switch ((c = pat_next(pat, m, &pinc, flags))) {
+		case UNMATCHABLE:
+			return FNM_NOMATCH;
+		case STAR:
+			pat++;
+			m--;
+			break;
+		default:
+			k = str_next(str, n, &sinc);
+			if (k <= 0)
+				return (c==END) ? 0 : FNM_NOMATCH;
+			str += sinc;
+			n -= sinc;
+			kfold = flags & FNM_CASEFOLD ? casefold(k) : k;
+			if (c == BRACKET) {
+				if (!match_bracket(pat, k, kfold))
+					return FNM_NOMATCH;
+			} else if (c != QUESTION && k != c && kfold != c) {
+				return FNM_NOMATCH;
+			}
+			pat+=pinc;
+			m-=pinc;
+			continue;
+		}
+		break;
+	}
+
+	/* Compute real pat length if it was initially unknown/-1 */
+	m = strnlen(pat, m);
+	endpat = pat + m;
+
+	/* Find the last * in pat and count chars needed after it */
+	for (p=ptail=pat; p<endpat; p+=pinc) {
+		switch (pat_next(p, endpat-p, &pinc, flags)) {
+		case UNMATCHABLE:
+			return FNM_NOMATCH;
+		case STAR:
+			tailcnt=0;
+			ptail = p+1;
+			break;
+		default:
+			tailcnt++;
+			break;
+		}
+	}
+
+	/* Past this point we need not check for UNMATCHABLE in pat,
+	 * because all of pat has already been parsed once. */
+
+	/* Compute real str length if it was initially unknown/-1 */
+	n = strnlen(str, n);
+	endstr = str + n;
+	if (n < tailcnt) return FNM_NOMATCH;
+
+	/* Find the final tailcnt chars of str, accounting for UTF-8.
+	 * On illegal sequences we may get it wrong, but in that case
+	 * we necessarily have a matching failure anyway. */
+	for (s=endstr; s>str && tailcnt; tailcnt--) {
+		if (s[-1] < 128U || MB_CUR_MAX==1) s--;
+		else while ((unsigned char)*--s-0x80U<0x40 && s>str);
+	}
+	if (tailcnt) return FNM_NOMATCH;
+	stail = s;
+
+	/* Check that the pat and str tails match */
+	p = ptail;
+	for (;;) {
+		c = pat_next(p, endpat-p, &pinc, flags);
+		p += pinc;
+		if ((k = str_next(s, endstr-s, &sinc)) <= 0) {
+			if (c != END) return FNM_NOMATCH;
+			break;
+		}
+		s += sinc;
+		kfold = flags & FNM_CASEFOLD ? casefold(k) : k;
+		if (c == BRACKET) {
+			if (!match_bracket(p-pinc, k, kfold))
+				return FNM_NOMATCH;
+		} else if (c != QUESTION && k != c && kfold != c) {
+			return FNM_NOMATCH;
+		}
+	}
+
+	/* We're all done with the tails now, so throw them out */
+	endstr = stail;
+	endpat = ptail;
+
+	/* Match pattern components until there are none left */
+	while (pat<endpat) {
+		p = pat;
+		s = str;
+		for (;;) {
+			c = pat_next(p, endpat-p, &pinc, flags);
+			p += pinc;
+			/* Encountering * completes/commits a component */
+			if (c == STAR) {
+				pat = p;
+				str = s;
+				break;
+			}
+			k = str_next(s, endstr-s, &sinc);
+			if (!k)
+				return FNM_NOMATCH;
+			kfold = flags & FNM_CASEFOLD ? casefold(k) : k;
+			if (c == BRACKET) {
+				if (!match_bracket(p-pinc, k, kfold))
+					break;
+			} else if (c != QUESTION && k != c && kfold != c) {
+				break;
+			}
+			s += sinc;
+		}
+		if (c == STAR) continue;
+		/* If we failed, advance str, by 1 char if it's a valid
+		 * char, or past all invalid bytes otherwise. */
+		k = str_next(str, endstr-str, &sinc);
+		if (k > 0) str += sinc;
+		else for (str++; str_next(str, endstr-str, &sinc)<0; str++);
+	}
+
+	return 0;
+}
+
+int fnmatch(const char *pat, const char *str, int flags)
+{
+	const char *s, *p;
+	size_t inc;
+	int c;
+	if (flags & FNM_PATHNAME) for (;;) {
+		for (s=str; *s && *s!='/'; s++);
+		for (p=pat; (c=pat_next(p, -1, &inc, flags))!=END && c!='/'; p+=inc);
+		if (c!=*s && (!*s || !(flags & FNM_LEADING_DIR)))
+			return FNM_NOMATCH;
+		if (fnmatch_internal(pat, p-pat, str, s-str, flags))
+			return FNM_NOMATCH;
+		if (!c) return 0;
+		str = s+1;
+		pat = p+inc;
+	} else if (flags & FNM_LEADING_DIR) {
+		for (s=str; *s; s++) {
+			if (*s != '/') continue;
+			if (!fnmatch_internal(pat, -1, str, s-str, flags))
+				return 0;
+		}
+	}
+	return fnmatch_internal(pat, -1, str, -1, flags);
+}
libc/musl/src/regex/glob.c
@@ -0,0 +1,264 @@
+#define _BSD_SOURCE
+#include <glob.h>
+#include <fnmatch.h>
+#include <sys/stat.h>
+#include <dirent.h>
+#include <limits.h>
+#include <string.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <stddef.h>
+
+struct match
+{
+	struct match *next;
+	char name[];
+};
+
+static int append(struct match **tail, const char *name, size_t len, int mark)
+{
+	struct match *new = malloc(sizeof(struct match) + len + 2);
+	if (!new) return -1;
+	(*tail)->next = new;
+	new->next = NULL;
+	memcpy(new->name, name, len+1);
+	if (mark && len && name[len-1]!='/') {
+		new->name[len] = '/';
+		new->name[len+1] = 0;
+	}
+	*tail = new;
+	return 0;
+}
+
+static int do_glob(char *buf, size_t pos, int type, char *pat, int flags, int (*errfunc)(const char *path, int err), struct match **tail)
+{
+	/* If GLOB_MARK is unused, we don't care about type. */
+	if (!type && !(flags & GLOB_MARK)) type = DT_REG;
+
+	/* Special-case the remaining pattern being all slashes, in
+	 * which case we can use caller-passed type if it's a dir. */
+	if (*pat && type!=DT_DIR) type = 0;
+	while (pos+1 < PATH_MAX && *pat=='/') buf[pos++] = *pat++;
+
+	/* Consume maximal [escaped-]literal prefix of pattern, copying
+	 * and un-escaping it to the running buffer as we go. */
+	ptrdiff_t i=0, j=0;
+	int in_bracket = 0, overflow = 0;
+	for (; pat[i]!='*' && pat[i]!='?' && (!in_bracket || pat[i]!=']'); i++) {
+		if (!pat[i]) {
+			if (overflow) return 0;
+			pat += i;
+			pos += j;
+			i = j = 0;
+			break;
+		} else if (pat[i] == '[') {
+			in_bracket = 1;
+		} else if (pat[i] == '\\' && !(flags & GLOB_NOESCAPE)) {
+			/* Backslashes inside a bracket are (at least by
+			 * our interpretation) non-special, so if next
+			 * char is ']' we have a complete expression. */
+			if (in_bracket && pat[i+1]==']') break;
+			/* Unpaired final backslash never matches. */
+			if (!pat[i+1]) return 0;
+			i++;
+		}
+		if (pat[i] == '/') {
+			if (overflow) return 0;
+			in_bracket = 0;
+			pat += i+1;
+			i = -1;
+			pos += j+1;
+			j = -1;
+		}
+		/* Only store a character if it fits in the buffer, but if
+		 * a potential bracket expression is open, the overflow
+		 * must be remembered and handled later only if the bracket
+		 * is unterminated (and thereby a literal), so as not to
+		 * disallow long bracket expressions with short matches. */
+		if (pos+(j+1) < PATH_MAX) {
+			buf[pos+j++] = pat[i];
+		} else if (in_bracket) {
+			overflow = 1;
+		} else {
+			return 0;
+		}
+		/* If we consume any new components, the caller-passed type
+		 * or dummy type from above is no longer valid. */
+		type = 0;
+	}
+	buf[pos] = 0;
+	if (!*pat) {
+		/* If we consumed any components above, or if GLOB_MARK is
+		 * requested and we don't yet know if the match is a dir,
+		 * we must call stat to confirm the file exists and/or
+		 * determine its type. */
+		struct stat st;
+		if ((flags & GLOB_MARK) && type==DT_LNK) type = 0;
+		if (!type && stat(buf, &st)) {
+			if (errno!=ENOENT && (errfunc(buf, errno) || (flags & GLOB_ERR)))
+				return GLOB_ABORTED;
+			return 0;
+		}
+		if (!type && S_ISDIR(st.st_mode)) type = DT_DIR;
+		if (append(tail, buf, pos, (flags & GLOB_MARK) && type==DT_DIR))
+			return GLOB_NOSPACE;
+		return 0;
+	}
+	char *p2 = strchr(pat, '/'), saved_sep = '/';
+	/* Check if the '/' was escaped and, if so, remove the escape char
+	 * so that it will not be unpaired when passed to fnmatch. */
+	if (p2 && !(flags & GLOB_NOESCAPE)) {
+		char *p;
+		for (p=p2; p>pat && p[-1]=='\\'; p--);
+		if ((p2-p)%2) {
+			p2--;
+			saved_sep = '\\';
+		}
+	}
+	DIR *dir = opendir(pos ? buf : ".");
+	if (!dir) {
+		if (errfunc(buf, errno) || (flags & GLOB_ERR))
+			return GLOB_ABORTED;
+		return 0;
+	}
+	int old_errno = errno;
+	struct dirent *de;
+	while (errno=0, de=readdir(dir)) {
+		/* Quickly skip non-directories when there's pattern left. */
+		if (p2 && de->d_type && de->d_type!=DT_DIR && de->d_type!=DT_LNK)
+			continue;
+
+		size_t l = strlen(de->d_name);
+		if (l >= PATH_MAX-pos) continue;
+
+		if (p2) *p2 = 0;
+
+		int fnm_flags= ((flags & GLOB_NOESCAPE) ? FNM_NOESCAPE : 0)
+			| ((!(flags & GLOB_PERIOD)) ? FNM_PERIOD : 0);
+
+		if (fnmatch(pat, de->d_name, fnm_flags))
+			continue;
+
+		/* With GLOB_PERIOD, don't allow matching . or .. unless
+		 * fnmatch would match them with FNM_PERIOD rules in effect. */
+		if (p2 && (flags & GLOB_PERIOD) && de->d_name[0]=='.'
+		    && (!de->d_name[1] || de->d_name[1]=='.' && !de->d_name[2])
+		    && fnmatch(pat, de->d_name, fnm_flags | FNM_PERIOD))
+			continue;
+
+		memcpy(buf+pos, de->d_name, l+1);
+		if (p2) *p2 = saved_sep;
+		int r = do_glob(buf, pos+l, de->d_type, p2 ? p2 : "", flags, errfunc, tail);
+		if (r) {
+			closedir(dir);
+			return r;
+		}
+	}
+	int readerr = errno;
+	if (p2) *p2 = saved_sep;
+	closedir(dir);
+	if (readerr && (errfunc(buf, errno) || (flags & GLOB_ERR)))
+		return GLOB_ABORTED;
+	errno = old_errno;
+	return 0;
+}
+
+static int ignore_err(const char *path, int err)
+{
+	return 0;
+}
+
+static void freelist(struct match *head)
+{
+	struct match *match, *next;
+	for (match=head->next; match; match=next) {
+		next = match->next;
+		free(match);
+	}
+}
+
+static int sort(const void *a, const void *b)
+{
+	return strcmp(*(const char **)a, *(const char **)b);
+}
+
+int glob(const char *restrict pat, int flags, int (*errfunc)(const char *path, int err), glob_t *restrict g)
+{
+	struct match head = { .next = NULL }, *tail = &head;
+	size_t cnt, i;
+	size_t offs = (flags & GLOB_DOOFFS) ? g->gl_offs : 0;
+	int error = 0;
+	char buf[PATH_MAX];
+	
+	if (!errfunc) errfunc = ignore_err;
+
+	if (!(flags & GLOB_APPEND)) {
+		g->gl_offs = offs;
+		g->gl_pathc = 0;
+		g->gl_pathv = NULL;
+	}
+
+	if (*pat) {
+		char *p = strdup(pat);
+		if (!p) return GLOB_NOSPACE;
+		buf[0] = 0;
+		error = do_glob(buf, 0, 0, p, flags, errfunc, &tail);
+		free(p);
+	}
+
+	if (error == GLOB_NOSPACE) {
+		freelist(&head);
+		return error;
+	}
+	
+	for (cnt=0, tail=head.next; tail; tail=tail->next, cnt++);
+	if (!cnt) {
+		if (flags & GLOB_NOCHECK) {
+			tail = &head;
+			if (append(&tail, pat, strlen(pat), 0))
+				return GLOB_NOSPACE;
+			cnt++;
+		} else
+			return GLOB_NOMATCH;
+	}
+
+	if (flags & GLOB_APPEND) {
+		char **pathv = realloc(g->gl_pathv, (offs + g->gl_pathc + cnt + 1) * sizeof(char *));
+		if (!pathv) {
+			freelist(&head);
+			return GLOB_NOSPACE;
+		}
+		g->gl_pathv = pathv;
+		offs += g->gl_pathc;
+	} else {
+		g->gl_pathv = malloc((offs + cnt + 1) * sizeof(char *));
+		if (!g->gl_pathv) {
+			freelist(&head);
+			return GLOB_NOSPACE;
+		}
+		for (i=0; i<offs; i++)
+			g->gl_pathv[i] = NULL;
+	}
+	for (i=0, tail=head.next; i<cnt; tail=tail->next, i++)
+		g->gl_pathv[offs + i] = tail->name;
+	g->gl_pathv[offs + i] = NULL;
+	g->gl_pathc += cnt;
+
+	if (!(flags & GLOB_NOSORT))
+		qsort(g->gl_pathv+offs, cnt, sizeof(char *), sort);
+	
+	return error;
+}
+
+void globfree(glob_t *g)
+{
+	size_t i;
+	for (i=0; i<g->gl_pathc; i++)
+		free(g->gl_pathv[g->gl_offs + i] - offsetof(struct match, name));
+	free(g->gl_pathv);
+	g->gl_pathc = 0;
+	g->gl_pathv = NULL;
+}
+
+weak_alias(glob, glob64);
+weak_alias(globfree, globfree64);
libc/musl/src/regex/regcomp.c
@@ -0,0 +1,2953 @@
+/*
+  regcomp.c - TRE POSIX compatible regex compilation functions.
+
+  Copyright (c) 2001-2009 Ville Laurikari <vl@iki.fi>
+  All rights reserved.
+
+  Redistribution and use in source and binary forms, with or without
+  modification, are permitted provided that the following conditions
+  are met:
+
+    1. Redistributions of source code must retain the above copyright
+       notice, this list of conditions and the following disclaimer.
+
+    2. Redistributions in binary form must reproduce the above copyright
+       notice, this list of conditions and the following disclaimer in the
+       documentation and/or other materials provided with the distribution.
+
+  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER AND CONTRIBUTORS
+  ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+  A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT
+  HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+*/
+
+#include <string.h>
+#include <stdlib.h>
+#include <regex.h>
+#include <limits.h>
+#include <stdint.h>
+#include <ctype.h>
+
+#include "tre.h"
+
+#include <assert.h>
+
+/***********************************************************************
+ from tre-compile.h
+***********************************************************************/
+
+typedef struct {
+  int position;
+  int code_min;
+  int code_max;
+  int *tags;
+  int assertions;
+  tre_ctype_t class;
+  tre_ctype_t *neg_classes;
+  int backref;
+} tre_pos_and_tags_t;
+
+
+/***********************************************************************
+ from tre-ast.c and tre-ast.h
+***********************************************************************/
+
+/* The different AST node types. */
+typedef enum {
+  LITERAL,
+  CATENATION,
+  ITERATION,
+  UNION
+} tre_ast_type_t;
+
+/* Special subtypes of TRE_LITERAL. */
+#define EMPTY	  -1   /* Empty leaf (denotes empty string). */
+#define ASSERTION -2   /* Assertion leaf. */
+#define TAG	  -3   /* Tag leaf. */
+#define BACKREF	  -4   /* Back reference leaf. */
+
+#define IS_SPECIAL(x)	((x)->code_min < 0)
+#define IS_EMPTY(x)	((x)->code_min == EMPTY)
+#define IS_ASSERTION(x) ((x)->code_min == ASSERTION)
+#define IS_TAG(x)	((x)->code_min == TAG)
+#define IS_BACKREF(x)	((x)->code_min == BACKREF)
+
+
+/* A generic AST node.  All AST nodes consist of this node on the top
+   level with `obj' pointing to the actual content. */
+typedef struct {
+  tre_ast_type_t type;   /* Type of the node. */
+  void *obj;             /* Pointer to actual node. */
+  int nullable;
+  int submatch_id;
+  int num_submatches;
+  int num_tags;
+  tre_pos_and_tags_t *firstpos;
+  tre_pos_and_tags_t *lastpos;
+} tre_ast_node_t;
+
+
+/* A "literal" node.  These are created for assertions, back references,
+   tags, matching parameter settings, and all expressions that match one
+   character. */
+typedef struct {
+  long code_min;
+  long code_max;
+  int position;
+  tre_ctype_t class;
+  tre_ctype_t *neg_classes;
+} tre_literal_t;
+
+/* A "catenation" node.	 These are created when two regexps are concatenated.
+   If there are more than one subexpressions in sequence, the `left' part
+   holds all but the last, and `right' part holds the last subexpression
+   (catenation is left associative). */
+typedef struct {
+  tre_ast_node_t *left;
+  tre_ast_node_t *right;
+} tre_catenation_t;
+
+/* An "iteration" node.	 These are created for the "*", "+", "?", and "{m,n}"
+   operators. */
+typedef struct {
+  /* Subexpression to match. */
+  tre_ast_node_t *arg;
+  /* Minimum number of consecutive matches. */
+  int min;
+  /* Maximum number of consecutive matches. */
+  int max;
+  /* If 0, match as many characters as possible, if 1 match as few as
+     possible.	Note that this does not always mean the same thing as
+     matching as many/few repetitions as possible. */
+  unsigned int minimal:1;
+} tre_iteration_t;
+
+/* An "union" node.  These are created for the "|" operator. */
+typedef struct {
+  tre_ast_node_t *left;
+  tre_ast_node_t *right;
+} tre_union_t;
+
+
+static tre_ast_node_t *
+tre_ast_new_node(tre_mem_t mem, int type, void *obj)
+{
+	tre_ast_node_t *node = tre_mem_calloc(mem, sizeof *node);
+	if (!node || !obj)
+		return 0;
+	node->obj = obj;
+	node->type = type;
+	node->nullable = -1;
+	node->submatch_id = -1;
+	return node;
+}
+
+static tre_ast_node_t *
+tre_ast_new_literal(tre_mem_t mem, int code_min, int code_max, int position)
+{
+	tre_ast_node_t *node;
+	tre_literal_t *lit;
+
+	lit = tre_mem_calloc(mem, sizeof *lit);
+	node = tre_ast_new_node(mem, LITERAL, lit);
+	if (!node)
+		return 0;
+	lit->code_min = code_min;
+	lit->code_max = code_max;
+	lit->position = position;
+	return node;
+}
+
+static tre_ast_node_t *
+tre_ast_new_iter(tre_mem_t mem, tre_ast_node_t *arg, int min, int max, int minimal)
+{
+	tre_ast_node_t *node;
+	tre_iteration_t *iter;
+
+	iter = tre_mem_calloc(mem, sizeof *iter);
+	node = tre_ast_new_node(mem, ITERATION, iter);
+	if (!node)
+		return 0;
+	iter->arg = arg;
+	iter->min = min;
+	iter->max = max;
+	iter->minimal = minimal;
+	node->num_submatches = arg->num_submatches;
+	return node;
+}
+
+static tre_ast_node_t *
+tre_ast_new_union(tre_mem_t mem, tre_ast_node_t *left, tre_ast_node_t *right)
+{
+	tre_ast_node_t *node;
+	tre_union_t *un;
+
+	if (!left)
+		return right;
+	un = tre_mem_calloc(mem, sizeof *un);
+	node = tre_ast_new_node(mem, UNION, un);
+	if (!node || !right)
+		return 0;
+	un->left = left;
+	un->right = right;
+	node->num_submatches = left->num_submatches + right->num_submatches;
+	return node;
+}
+
+static tre_ast_node_t *
+tre_ast_new_catenation(tre_mem_t mem, tre_ast_node_t *left, tre_ast_node_t *right)
+{
+	tre_ast_node_t *node;
+	tre_catenation_t *cat;
+
+	if (!left)
+		return right;
+	cat = tre_mem_calloc(mem, sizeof *cat);
+	node = tre_ast_new_node(mem, CATENATION, cat);
+	if (!node)
+		return 0;
+	cat->left = left;
+	cat->right = right;
+	node->num_submatches = left->num_submatches + right->num_submatches;
+	return node;
+}
+
+
+/***********************************************************************
+ from tre-stack.c and tre-stack.h
+***********************************************************************/
+
+typedef struct tre_stack_rec tre_stack_t;
+
+/* Creates a new stack object.	`size' is initial size in bytes, `max_size'
+   is maximum size, and `increment' specifies how much more space will be
+   allocated with realloc() if all space gets used up.	Returns the stack
+   object or NULL if out of memory. */
+static tre_stack_t *
+tre_stack_new(int size, int max_size, int increment);
+
+/* Frees the stack object. */
+static void
+tre_stack_destroy(tre_stack_t *s);
+
+/* Returns the current number of objects in the stack. */
+static int
+tre_stack_num_objects(tre_stack_t *s);
+
+/* Each tre_stack_push_*(tre_stack_t *s, <type> value) function pushes
+   `value' on top of stack `s'.  Returns REG_ESPACE if out of memory.
+   This tries to realloc() more space before failing if maximum size
+   has not yet been reached.  Returns REG_OK if successful. */
+#define declare_pushf(typetag, type)					      \
+  static reg_errcode_t tre_stack_push_ ## typetag(tre_stack_t *s, type value)
+
+declare_pushf(voidptr, void *);
+declare_pushf(int, int);
+
+/* Each tre_stack_pop_*(tre_stack_t *s) function pops the topmost
+   element off of stack `s' and returns it.  The stack must not be
+   empty. */
+#define declare_popf(typetag, type)		  \
+  static type tre_stack_pop_ ## typetag(tre_stack_t *s)
+
+declare_popf(voidptr, void *);
+declare_popf(int, int);
+
+/* Just to save some typing. */
+#define STACK_PUSH(s, typetag, value)					      \
+  do									      \
+    {									      \
+      status = tre_stack_push_ ## typetag(s, value);			      \
+    }									      \
+  while (/*CONSTCOND*/0)
+
+#define STACK_PUSHX(s, typetag, value)					      \
+  {									      \
+    status = tre_stack_push_ ## typetag(s, value);			      \
+    if (status != REG_OK)						      \
+      break;								      \
+  }
+
+#define STACK_PUSHR(s, typetag, value)					      \
+  {									      \
+    reg_errcode_t _status;						      \
+    _status = tre_stack_push_ ## typetag(s, value);			      \
+    if (_status != REG_OK)						      \
+      return _status;							      \
+  }
+
+union tre_stack_item {
+  void *voidptr_value;
+  int int_value;
+};
+
+struct tre_stack_rec {
+  int size;
+  int max_size;
+  int increment;
+  int ptr;
+  union tre_stack_item *stack;
+};
+
+
+static tre_stack_t *
+tre_stack_new(int size, int max_size, int increment)
+{
+  tre_stack_t *s;
+
+  s = xmalloc(sizeof(*s));
+  if (s != NULL)
+    {
+      s->stack = xmalloc(sizeof(*s->stack) * size);
+      if (s->stack == NULL)
+	{
+	  xfree(s);
+	  return NULL;
+	}
+      s->size = size;
+      s->max_size = max_size;
+      s->increment = increment;
+      s->ptr = 0;
+    }
+  return s;
+}
+
+static void
+tre_stack_destroy(tre_stack_t *s)
+{
+  xfree(s->stack);
+  xfree(s);
+}
+
+static int
+tre_stack_num_objects(tre_stack_t *s)
+{
+  return s->ptr;
+}
+
+static reg_errcode_t
+tre_stack_push(tre_stack_t *s, union tre_stack_item value)
+{
+  if (s->ptr < s->size)
+    {
+      s->stack[s->ptr] = value;
+      s->ptr++;
+    }
+  else
+    {
+      if (s->size >= s->max_size)
+	{
+	  return REG_ESPACE;
+	}
+      else
+	{
+	  union tre_stack_item *new_buffer;
+	  int new_size;
+	  new_size = s->size + s->increment;
+	  if (new_size > s->max_size)
+	    new_size = s->max_size;
+	  new_buffer = xrealloc(s->stack, sizeof(*new_buffer) * new_size);
+	  if (new_buffer == NULL)
+	    {
+	      return REG_ESPACE;
+	    }
+	  assert(new_size > s->size);
+	  s->size = new_size;
+	  s->stack = new_buffer;
+	  tre_stack_push(s, value);
+	}
+    }
+  return REG_OK;
+}
+
+#define define_pushf(typetag, type)  \
+  declare_pushf(typetag, type) {     \
+    union tre_stack_item item;	     \
+    item.typetag ## _value = value;  \
+    return tre_stack_push(s, item);  \
+}
+
+define_pushf(int, int)
+define_pushf(voidptr, void *)
+
+#define define_popf(typetag, type)		    \
+  declare_popf(typetag, type) {			    \
+    return s->stack[--s->ptr].typetag ## _value;    \
+  }
+
+define_popf(int, int)
+define_popf(voidptr, void *)
+
+
+/***********************************************************************
+ from tre-parse.c and tre-parse.h
+***********************************************************************/
+
+/* Parse context. */
+typedef struct {
+	/* Memory allocator. The AST is allocated using this. */
+	tre_mem_t mem;
+	/* Stack used for keeping track of regexp syntax. */
+	tre_stack_t *stack;
+	/* The parsed node after a parse function returns. */
+	tre_ast_node_t *n;
+	/* Position in the regexp pattern after a parse function returns. */
+	const char *s;
+	/* The first character of the last subexpression parsed. */
+	const char *start;
+	/* Current submatch ID. */
+	int submatch_id;
+	/* Current position (number of literal). */
+	int position;
+	/* The highest back reference or -1 if none seen so far. */
+	int max_backref;
+	/* Compilation flags. */
+	int cflags;
+} tre_parse_ctx_t;
+
+/* Some macros for expanding \w, \s, etc. */
+static const struct {
+	char c;
+	const char *expansion;
+} tre_macros[] = {
+	{'t', "\t"}, {'n', "\n"}, {'r', "\r"},
+	{'f', "\f"}, {'a', "\a"}, {'e', "\033"},
+	{'w', "[[:alnum:]_]"}, {'W', "[^[:alnum:]_]"}, {'s', "[[:space:]]"},
+	{'S', "[^[:space:]]"}, {'d', "[[:digit:]]"}, {'D', "[^[:digit:]]"},
+	{ 0, 0 }
+};
+
+/* Expands a macro delimited by `regex' and `regex_end' to `buf', which
+   must have at least `len' items.  Sets buf[0] to zero if the there
+   is no match in `tre_macros'. */
+static const char *tre_expand_macro(const char *s)
+{
+	int i;
+	for (i = 0; tre_macros[i].c && tre_macros[i].c != *s; i++);
+	return tre_macros[i].expansion;
+}
+
+static int
+tre_compare_lit(const void *a, const void *b)
+{
+	const tre_literal_t *const *la = a;
+	const tre_literal_t *const *lb = b;
+	/* assumes the range of valid code_min is < INT_MAX */
+	return la[0]->code_min - lb[0]->code_min;
+}
+
+struct literals {
+	tre_mem_t mem;
+	tre_literal_t **a;
+	int len;
+	int cap;
+};
+
+static tre_literal_t *tre_new_lit(struct literals *p)
+{
+	tre_literal_t **a;
+	if (p->len >= p->cap) {
+		if (p->cap >= 1<<15)
+			return 0;
+		p->cap *= 2;
+		a = xrealloc(p->a, p->cap * sizeof *p->a);
+		if (!a)
+			return 0;
+		p->a = a;
+	}
+	a = p->a + p->len++;
+	*a = tre_mem_calloc(p->mem, sizeof **a);
+	return *a;
+}
+
+static int add_icase_literals(struct literals *ls, int min, int max)
+{
+	tre_literal_t *lit;
+	int b, e, c;
+	for (c=min; c<=max; ) {
+		/* assumes islower(c) and isupper(c) are exclusive
+		   and toupper(c)!=c if islower(c).
+		   multiple opposite case characters are not supported */
+		if (tre_islower(c)) {
+			b = e = tre_toupper(c);
+			for (c++, e++; c<=max; c++, e++)
+				if (tre_toupper(c) != e) break;
+		} else if (tre_isupper(c)) {
+			b = e = tre_tolower(c);
+			for (c++, e++; c<=max; c++, e++)
+				if (tre_tolower(c) != e) break;
+		} else {
+			c++;
+			continue;
+		}
+		lit = tre_new_lit(ls);
+		if (!lit)
+			return -1;
+		lit->code_min = b;
+		lit->code_max = e-1;
+		lit->position = -1;
+	}
+	return 0;
+}
+
+
+/* Maximum number of character classes in a negated bracket expression. */
+#define MAX_NEG_CLASSES 64
+
+struct neg {
+	int negate;
+	int len;
+	tre_ctype_t a[MAX_NEG_CLASSES];
+};
+
+// TODO: parse bracket into a set of non-overlapping [lo,hi] ranges
+
+/*
+bracket grammar:
+Bracket  =  '[' List ']'  |  '[^' List ']'
+List     =  Term  |  List Term
+Term     =  Char  |  Range  |  Chclass  |  Eqclass
+Range    =  Char '-' Char  |  Char '-' '-'
+Char     =  Coll  |  coll_single
+Meta     =  ']'  |  '-'
+Coll     =  '[.' coll_single '.]'  |  '[.' coll_multi '.]'  |  '[.' Meta '.]'
+Eqclass  =  '[=' coll_single '=]'  |  '[=' coll_multi '=]'
+Chclass  =  '[:' class ':]'
+
+coll_single is a single char collating element but it can be
+ '-' only at the beginning or end of a List and
+ ']' only at the beginning of a List and
+ '^' anywhere except after the openning '['
+*/
+
+static reg_errcode_t parse_bracket_terms(tre_parse_ctx_t *ctx, const char *s, struct literals *ls, struct neg *neg)
+{
+	const char *start = s;
+	tre_ctype_t class;
+	int min, max;
+	wchar_t wc;
+	int len;
+
+	for (;;) {
+		class = 0;
+		len = mbtowc(&wc, s, -1);
+		if (len <= 0)
+			return *s ? REG_BADPAT : REG_EBRACK;
+		if (*s == ']' && s != start) {
+			ctx->s = s+1;
+			return REG_OK;
+		}
+		if (*s == '-' && s != start && s[1] != ']' &&
+		    /* extension: [a-z--@] is accepted as [a-z]|[--@] */
+		    (s[1] != '-' || s[2] == ']'))
+			return REG_ERANGE;
+		if (*s == '[' && (s[1] == '.' || s[1] == '='))
+			/* collating symbols and equivalence classes are not supported */
+			return REG_ECOLLATE;
+		if (*s == '[' && s[1] == ':') {
+			char tmp[CHARCLASS_NAME_MAX+1];
+			s += 2;
+			for (len=0; len < CHARCLASS_NAME_MAX && s[len]; len++) {
+				if (s[len] == ':') {
+					memcpy(tmp, s, len);
+					tmp[len] = 0;
+					class = tre_ctype(tmp);
+					break;
+				}
+			}
+			if (!class || s[len+1] != ']')
+				return REG_ECTYPE;
+			min = 0;
+			max = TRE_CHAR_MAX;
+			s += len+2;
+		} else {
+			min = max = wc;
+			s += len;
+			if (*s == '-' && s[1] != ']') {
+				s++;
+				len = mbtowc(&wc, s, -1);
+				max = wc;
+				/* XXX - Should use collation order instead of
+				   encoding values in character ranges. */
+				if (len <= 0 || min > max)
+					return REG_ERANGE;
+				s += len;
+			}
+		}
+
+		if (class && neg->negate) {
+			if (neg->len >= MAX_NEG_CLASSES)
+				return REG_ESPACE;
+			neg->a[neg->len++] = class;
+		} else  {
+			tre_literal_t *lit = tre_new_lit(ls);
+			if (!lit)
+				return REG_ESPACE;
+			lit->code_min = min;
+			lit->code_max = max;
+			lit->class = class;
+			lit->position = -1;
+
+			/* Add opposite-case codepoints if REG_ICASE is present.
+			   It seems that POSIX requires that bracket negation
+			   should happen before case-folding, but most practical
+			   implementations do it the other way around. Changing
+			   the order would need efficient representation of
+			   case-fold ranges and bracket range sets even with
+			   simple patterns so this is ok for now. */
+			if (ctx->cflags & REG_ICASE && !class)
+				if (add_icase_literals(ls, min, max))
+					return REG_ESPACE;
+		}
+	}
+}
+
+static reg_errcode_t parse_bracket(tre_parse_ctx_t *ctx, const char *s)
+{
+	int i, max, min, negmax, negmin;
+	tre_ast_node_t *node = 0, *n;
+	tre_ctype_t *nc = 0;
+	tre_literal_t *lit;
+	struct literals ls;
+	struct neg neg;
+	reg_errcode_t err;
+
+	ls.mem = ctx->mem;
+	ls.len = 0;
+	ls.cap = 32;
+	ls.a = xmalloc(ls.cap * sizeof *ls.a);
+	if (!ls.a)
+		return REG_ESPACE;
+	neg.len = 0;
+	neg.negate = *s == '^';
+	if (neg.negate)
+		s++;
+
+	err = parse_bracket_terms(ctx, s, &ls, &neg);
+	if (err != REG_OK)
+		goto parse_bracket_done;
+
+	if (neg.negate) {
+		/*
+		 * With REG_NEWLINE, POSIX requires that newlines are not matched by
+		 * any form of a non-matching list.
+		 */
+		if (ctx->cflags & REG_NEWLINE) {
+			lit = tre_new_lit(&ls);
+			if (!lit) {
+				err = REG_ESPACE;
+				goto parse_bracket_done;
+			}
+			lit->code_min = '\n';
+			lit->code_max = '\n';
+			lit->position = -1;
+		}
+		/* Sort the array if we need to negate it. */
+		qsort(ls.a, ls.len, sizeof *ls.a, tre_compare_lit);
+		/* extra lit for the last negated range */
+		lit = tre_new_lit(&ls);
+		if (!lit) {
+			err = REG_ESPACE;
+			goto parse_bracket_done;
+		}
+		lit->code_min = TRE_CHAR_MAX+1;
+		lit->code_max = TRE_CHAR_MAX+1;
+		lit->position = -1;
+		/* negated classes */
+		if (neg.len) {
+			nc = tre_mem_alloc(ctx->mem, (neg.len+1)*sizeof *neg.a);
+			if (!nc) {
+				err = REG_ESPACE;
+				goto parse_bracket_done;
+			}
+			memcpy(nc, neg.a, neg.len*sizeof *neg.a);
+			nc[neg.len] = 0;
+		}
+	}
+
+	/* Build a union of the items in the array, negated if necessary. */
+	negmax = negmin = 0;
+	for (i = 0; i < ls.len; i++) {
+		lit = ls.a[i];
+		min = lit->code_min;
+		max = lit->code_max;
+		if (neg.negate) {
+			if (min <= negmin) {
+				/* Overlap. */
+				negmin = MAX(max + 1, negmin);
+				continue;
+			}
+			negmax = min - 1;
+			lit->code_min = negmin;
+			lit->code_max = negmax;
+			negmin = max + 1;
+		}
+		lit->position = ctx->position;
+		lit->neg_classes = nc;
+		n = tre_ast_new_node(ctx->mem, LITERAL, lit);
+		node = tre_ast_new_union(ctx->mem, node, n);
+		if (!node) {
+			err = REG_ESPACE;
+			break;
+		}
+	}
+
+parse_bracket_done:
+	xfree(ls.a);
+	ctx->position++;
+	ctx->n = node;
+	return err;
+}
+
+static const char *parse_dup_count(const char *s, int *n)
+{
+	*n = -1;
+	if (!isdigit(*s))
+		return s;
+	*n = 0;
+	for (;;) {
+		*n = 10 * *n + (*s - '0');
+		s++;
+		if (!isdigit(*s) || *n > RE_DUP_MAX)
+			break;
+	}
+	return s;
+}
+
+static const char *parse_dup(const char *s, int ere, int *pmin, int *pmax)
+{
+	int min, max;
+
+	s = parse_dup_count(s, &min);
+	if (*s == ',')
+		s = parse_dup_count(s+1, &max);
+	else
+		max = min;
+
+	if (
+		(max < min && max >= 0) ||
+		max > RE_DUP_MAX ||
+		min > RE_DUP_MAX ||
+		min < 0 ||
+		(!ere && *s++ != '\\') ||
+		*s++ != '}'
+	)
+		return 0;
+	*pmin = min;
+	*pmax = max;
+	return s;
+}
+
+static int hexval(unsigned c)
+{
+	if (c-'0'<10) return c-'0';
+	c |= 32;
+	if (c-'a'<6) return c-'a'+10;
+	return -1;
+}
+
+static reg_errcode_t marksub(tre_parse_ctx_t *ctx, tre_ast_node_t *node, int subid)
+{
+	if (node->submatch_id >= 0) {
+		tre_ast_node_t *n = tre_ast_new_literal(ctx->mem, EMPTY, -1, -1);
+		if (!n)
+			return REG_ESPACE;
+		n = tre_ast_new_catenation(ctx->mem, n, node);
+		if (!n)
+			return REG_ESPACE;
+		n->num_submatches = node->num_submatches;
+		node = n;
+	}
+	node->submatch_id = subid;
+	node->num_submatches++;
+	ctx->n = node;
+	return REG_OK;
+}
+
+/*
+BRE grammar:
+Regex  =  Branch  |  '^'  |  '$'  |  '^$'  |  '^' Branch  |  Branch '$'  |  '^' Branch '$'
+Branch =  Atom  |  Branch Atom
+Atom   =  char  |  quoted_char  |  '.'  |  Bracket  |  Atom Dup  |  '\(' Branch '\)'  |  back_ref
+Dup    =  '*'  |  '\{' Count '\}'  |  '\{' Count ',\}'  |  '\{' Count ',' Count '\}'
+
+(leading ^ and trailing $ in a sub expr may be an anchor or literal as well)
+
+ERE grammar:
+Regex  =  Branch  |  Regex '|' Branch
+Branch =  Atom  |  Branch Atom
+Atom   =  char  |  quoted_char  |  '.'  |  Bracket  |  Atom Dup  |  '(' Regex ')'  |  '^'  |  '$'
+Dup    =  '*'  |  '+'  |  '?'  |  '{' Count '}'  |  '{' Count ',}'  |  '{' Count ',' Count '}'
+
+(a*+?, ^*, $+, \X, {, (|a) are unspecified)
+*/
+
+static reg_errcode_t parse_atom(tre_parse_ctx_t *ctx, const char *s)
+{
+	int len, ere = ctx->cflags & REG_EXTENDED;
+	const char *p;
+	tre_ast_node_t *node;
+	wchar_t wc;
+	switch (*s) {
+	case '[':
+		return parse_bracket(ctx, s+1);
+	case '\\':
+		p = tre_expand_macro(s+1);
+		if (p) {
+			/* assume \X expansion is a single atom */
+			reg_errcode_t err = parse_atom(ctx, p);
+			ctx->s = s+2;
+			return err;
+		}
+		/* extensions: \b, \B, \<, \>, \xHH \x{HHHH} */
+		switch (*++s) {
+		case 0:
+			return REG_EESCAPE;
+		case 'b':
+			node = tre_ast_new_literal(ctx->mem, ASSERTION, ASSERT_AT_WB, -1);
+			break;
+		case 'B':
+			node = tre_ast_new_literal(ctx->mem, ASSERTION, ASSERT_AT_WB_NEG, -1);
+			break;
+		case '<':
+			node = tre_ast_new_literal(ctx->mem, ASSERTION, ASSERT_AT_BOW, -1);
+			break;
+		case '>':
+			node = tre_ast_new_literal(ctx->mem, ASSERTION, ASSERT_AT_EOW, -1);
+			break;
+		case 'x':
+			s++;
+			int i, v = 0, c;
+			len = 2;
+			if (*s == '{') {
+				len = 8;
+				s++;
+			}
+			for (i=0; i<len && v<0x110000; i++) {
+				c = hexval(s[i]);
+				if (c < 0) break;
+				v = 16*v + c;
+			}
+			s += i;
+			if (len == 8) {
+				if (*s != '}')
+					return REG_EBRACE;
+				s++;
+			}
+			node = tre_ast_new_literal(ctx->mem, v, v, ctx->position++);
+			s--;
+			break;
+		case '{':
+		case '+':
+		case '?':
+			/* extension: treat \+, \? as repetitions in BRE */
+			/* reject repetitions after empty expression in BRE */
+			if (!ere)
+				return REG_BADRPT;
+		case '|':
+			/* extension: treat \| as alternation in BRE */
+			if (!ere) {
+				node = tre_ast_new_literal(ctx->mem, EMPTY, -1, -1);
+				s--;
+				goto end;
+			}
+			/* fallthrough */
+		default:
+			if (!ere && (unsigned)*s-'1' < 9) {
+				/* back reference */
+				int val = *s - '0';
+				node = tre_ast_new_literal(ctx->mem, BACKREF, val, ctx->position++);
+				ctx->max_backref = MAX(val, ctx->max_backref);
+			} else {
+				/* extension: accept unknown escaped char
+				   as a literal */
+				goto parse_literal;
+			}
+		}
+		s++;
+		break;
+	case '.':
+		if (ctx->cflags & REG_NEWLINE) {
+			tre_ast_node_t *tmp1, *tmp2;
+			tmp1 = tre_ast_new_literal(ctx->mem, 0, '\n'-1, ctx->position++);
+			tmp2 = tre_ast_new_literal(ctx->mem, '\n'+1, TRE_CHAR_MAX, ctx->position++);
+			if (tmp1 && tmp2)
+				node = tre_ast_new_union(ctx->mem, tmp1, tmp2);
+			else
+				node = 0;
+		} else {
+			node = tre_ast_new_literal(ctx->mem, 0, TRE_CHAR_MAX, ctx->position++);
+		}
+		s++;
+		break;
+	case '^':
+		/* '^' has a special meaning everywhere in EREs, and at beginning of BRE. */
+		if (!ere && s != ctx->start)
+			goto parse_literal;
+		node = tre_ast_new_literal(ctx->mem, ASSERTION, ASSERT_AT_BOL, -1);
+		s++;
+		break;
+	case '$':
+		/* '$' is special everywhere in EREs, and at the end of a BRE subexpression. */
+		if (!ere && s[1] && (s[1]!='\\'|| (s[2]!=')' && s[2]!='|')))
+			goto parse_literal;
+		node = tre_ast_new_literal(ctx->mem, ASSERTION, ASSERT_AT_EOL, -1);
+		s++;
+		break;
+	case '*':
+	case '{':
+	case '+':
+	case '?':
+		/* reject repetitions after empty expression in ERE */
+		if (ere)
+			return REG_BADRPT;
+	case '|':
+		if (!ere)
+			goto parse_literal;
+	case 0:
+		node = tre_ast_new_literal(ctx->mem, EMPTY, -1, -1);
+		break;
+	default:
+parse_literal:
+		len = mbtowc(&wc, s, -1);
+		if (len < 0)
+			return REG_BADPAT;
+		if (ctx->cflags & REG_ICASE && (tre_isupper(wc) || tre_islower(wc))) {
+			tre_ast_node_t *tmp1, *tmp2;
+			/* multiple opposite case characters are not supported */
+			tmp1 = tre_ast_new_literal(ctx->mem, tre_toupper(wc), tre_toupper(wc), ctx->position);
+			tmp2 = tre_ast_new_literal(ctx->mem, tre_tolower(wc), tre_tolower(wc), ctx->position);
+			if (tmp1 && tmp2)
+				node = tre_ast_new_union(ctx->mem, tmp1, tmp2);
+			else
+				node = 0;
+		} else {
+			node = tre_ast_new_literal(ctx->mem, wc, wc, ctx->position);
+		}
+		ctx->position++;
+		s += len;
+		break;
+	}
+end:
+	if (!node)
+		return REG_ESPACE;
+	ctx->n = node;
+	ctx->s = s;
+	return REG_OK;
+}
+
+#define PUSHPTR(err, s, v) do { \
+	if ((err = tre_stack_push_voidptr(s, v)) != REG_OK) \
+		return err; \
+} while(0)
+
+#define PUSHINT(err, s, v) do { \
+	if ((err = tre_stack_push_int(s, v)) != REG_OK) \
+		return err; \
+} while(0)
+
+static reg_errcode_t tre_parse(tre_parse_ctx_t *ctx)
+{
+	tre_ast_node_t *nbranch=0, *nunion=0;
+	int ere = ctx->cflags & REG_EXTENDED;
+	const char *s = ctx->start;
+	int subid = 0;
+	int depth = 0;
+	reg_errcode_t err;
+	tre_stack_t *stack = ctx->stack;
+
+	PUSHINT(err, stack, subid++);
+	for (;;) {
+		if ((!ere && *s == '\\' && s[1] == '(') ||
+		    (ere && *s == '(')) {
+			PUSHPTR(err, stack, nunion);
+			PUSHPTR(err, stack, nbranch);
+			PUSHINT(err, stack, subid++);
+			s++;
+			if (!ere)
+				s++;
+			depth++;
+			nbranch = nunion = 0;
+			ctx->start = s;
+			continue;
+		}
+		if ((!ere && *s == '\\' && s[1] == ')') ||
+		    (ere && *s == ')' && depth)) {
+			ctx->n = tre_ast_new_literal(ctx->mem, EMPTY, -1, -1);
+			if (!ctx->n)
+				return REG_ESPACE;
+		} else {
+			err = parse_atom(ctx, s);
+			if (err != REG_OK)
+				return err;
+			s = ctx->s;
+		}
+
+	parse_iter:
+		for (;;) {
+			int min, max;
+
+			if (*s!='\\' && *s!='*') {
+				if (!ere)
+					break;
+				if (*s!='+' && *s!='?' && *s!='{')
+					break;
+			}
+			if (*s=='\\' && ere)
+				break;
+			/* extension: treat \+, \? as repetitions in BRE */
+			if (*s=='\\' && s[1]!='+' && s[1]!='?' && s[1]!='{')
+				break;
+			if (*s=='\\')
+				s++;
+
+			/* handle ^* at the start of a BRE. */
+			if (!ere && s==ctx->start+1 && s[-1]=='^')
+				break;
+
+			/* extension: multiple consecutive *+?{,} is unspecified,
+			   but (a+)+ has to be supported so accepting a++ makes
+			   sense, note however that the RE_DUP_MAX limit can be
+			   circumvented: (a{255}){255} uses a lot of memory.. */
+			if (*s=='{') {
+				s = parse_dup(s+1, ere, &min, &max);
+				if (!s)
+					return REG_BADBR;
+			} else {
+				min=0;
+				max=-1;
+				if (*s == '+')
+					min = 1;
+				if (*s == '?')
+					max = 1;
+				s++;
+			}
+			if (max == 0)
+				ctx->n = tre_ast_new_literal(ctx->mem, EMPTY, -1, -1);
+			else
+				ctx->n = tre_ast_new_iter(ctx->mem, ctx->n, min, max, 0);
+			if (!ctx->n)
+				return REG_ESPACE;
+		}
+
+		nbranch = tre_ast_new_catenation(ctx->mem, nbranch, ctx->n);
+		if ((ere && *s == '|') ||
+		    (ere && *s == ')' && depth) ||
+		    (!ere && *s == '\\' && s[1] == ')') ||
+		    /* extension: treat \| as alternation in BRE */
+		    (!ere && *s == '\\' && s[1] == '|') ||
+		    !*s) {
+			/* extension: empty branch is unspecified (), (|a), (a|)
+			   here they are not rejected but match on empty string */
+			int c = *s;
+			nunion = tre_ast_new_union(ctx->mem, nunion, nbranch);
+			nbranch = 0;
+
+			if (c == '\\' && s[1] == '|') {
+				s+=2;
+				ctx->start = s;
+			} else if (c == '|') {
+				s++;
+				ctx->start = s;
+			} else {
+				if (c == '\\') {
+					if (!depth) return REG_EPAREN;
+					s+=2;
+				} else if (c == ')')
+					s++;
+				depth--;
+				err = marksub(ctx, nunion, tre_stack_pop_int(stack));
+				if (err != REG_OK)
+					return err;
+				if (!c && depth<0) {
+					ctx->submatch_id = subid;
+					return REG_OK;
+				}
+				if (!c || depth<0)
+					return REG_EPAREN;
+				nbranch = tre_stack_pop_voidptr(stack);
+				nunion = tre_stack_pop_voidptr(stack);
+				goto parse_iter;
+			}
+		}
+	}
+}
+
+
+/***********************************************************************
+ from tre-compile.c
+***********************************************************************/
+
+
+/*
+  TODO:
+   - Fix tre_ast_to_tnfa() to recurse using a stack instead of recursive
+     function calls.
+*/
+
+/*
+  Algorithms to setup tags so that submatch addressing can be done.
+*/
+
+
+/* Inserts a catenation node to the root of the tree given in `node'.
+   As the left child a new tag with number `tag_id' to `node' is added,
+   and the right child is the old root. */
+static reg_errcode_t
+tre_add_tag_left(tre_mem_t mem, tre_ast_node_t *node, int tag_id)
+{
+  tre_catenation_t *c;
+
+  c = tre_mem_alloc(mem, sizeof(*c));
+  if (c == NULL)
+    return REG_ESPACE;
+  c->left = tre_ast_new_literal(mem, TAG, tag_id, -1);
+  if (c->left == NULL)
+    return REG_ESPACE;
+  c->right = tre_mem_alloc(mem, sizeof(tre_ast_node_t));
+  if (c->right == NULL)
+    return REG_ESPACE;
+
+  c->right->obj = node->obj;
+  c->right->type = node->type;
+  c->right->nullable = -1;
+  c->right->submatch_id = -1;
+  c->right->firstpos = NULL;
+  c->right->lastpos = NULL;
+  c->right->num_tags = 0;
+  c->right->num_submatches = 0;
+  node->obj = c;
+  node->type = CATENATION;
+  return REG_OK;
+}
+
+/* Inserts a catenation node to the root of the tree given in `node'.
+   As the right child a new tag with number `tag_id' to `node' is added,
+   and the left child is the old root. */
+static reg_errcode_t
+tre_add_tag_right(tre_mem_t mem, tre_ast_node_t *node, int tag_id)
+{
+  tre_catenation_t *c;
+
+  c = tre_mem_alloc(mem, sizeof(*c));
+  if (c == NULL)
+    return REG_ESPACE;
+  c->right = tre_ast_new_literal(mem, TAG, tag_id, -1);
+  if (c->right == NULL)
+    return REG_ESPACE;
+  c->left = tre_mem_alloc(mem, sizeof(tre_ast_node_t));
+  if (c->left == NULL)
+    return REG_ESPACE;
+
+  c->left->obj = node->obj;
+  c->left->type = node->type;
+  c->left->nullable = -1;
+  c->left->submatch_id = -1;
+  c->left->firstpos = NULL;
+  c->left->lastpos = NULL;
+  c->left->num_tags = 0;
+  c->left->num_submatches = 0;
+  node->obj = c;
+  node->type = CATENATION;
+  return REG_OK;
+}
+
+typedef enum {
+  ADDTAGS_RECURSE,
+  ADDTAGS_AFTER_ITERATION,
+  ADDTAGS_AFTER_UNION_LEFT,
+  ADDTAGS_AFTER_UNION_RIGHT,
+  ADDTAGS_AFTER_CAT_LEFT,
+  ADDTAGS_AFTER_CAT_RIGHT,
+  ADDTAGS_SET_SUBMATCH_END
+} tre_addtags_symbol_t;
+
+
+typedef struct {
+  int tag;
+  int next_tag;
+} tre_tag_states_t;
+
+
+/* Go through `regset' and set submatch data for submatches that are
+   using this tag. */
+static void
+tre_purge_regset(int *regset, tre_tnfa_t *tnfa, int tag)
+{
+  int i;
+
+  for (i = 0; regset[i] >= 0; i++)
+    {
+      int id = regset[i] / 2;
+      int start = !(regset[i] % 2);
+      if (start)
+	tnfa->submatch_data[id].so_tag = tag;
+      else
+	tnfa->submatch_data[id].eo_tag = tag;
+    }
+  regset[0] = -1;
+}
+
+
+/* Adds tags to appropriate locations in the parse tree in `tree', so that
+   subexpressions marked for submatch addressing can be traced. */
+static reg_errcode_t
+tre_add_tags(tre_mem_t mem, tre_stack_t *stack, tre_ast_node_t *tree,
+	     tre_tnfa_t *tnfa)
+{
+  reg_errcode_t status = REG_OK;
+  tre_addtags_symbol_t symbol;
+  tre_ast_node_t *node = tree; /* Tree node we are currently looking at. */
+  int bottom = tre_stack_num_objects(stack);
+  /* True for first pass (counting number of needed tags) */
+  int first_pass = (mem == NULL || tnfa == NULL);
+  int *regset, *orig_regset;
+  int num_tags = 0; /* Total number of tags. */
+  int num_minimals = 0;	 /* Number of special minimal tags. */
+  int tag = 0;	    /* The tag that is to be added next. */
+  int next_tag = 1; /* Next tag to use after this one. */
+  int *parents;	    /* Stack of submatches the current submatch is
+		       contained in. */
+  int minimal_tag = -1; /* Tag that marks the beginning of a minimal match. */
+  tre_tag_states_t *saved_states;
+
+  tre_tag_direction_t direction = TRE_TAG_MINIMIZE;
+  if (!first_pass)
+    {
+      tnfa->end_tag = 0;
+      tnfa->minimal_tags[0] = -1;
+    }
+
+  regset = xmalloc(sizeof(*regset) * ((tnfa->num_submatches + 1) * 2));
+  if (regset == NULL)
+    return REG_ESPACE;
+  regset[0] = -1;
+  orig_regset = regset;
+
+  parents = xmalloc(sizeof(*parents) * (tnfa->num_submatches + 1));
+  if (parents == NULL)
+    {
+      xfree(regset);
+      return REG_ESPACE;
+    }
+  parents[0] = -1;
+
+  saved_states = xmalloc(sizeof(*saved_states) * (tnfa->num_submatches + 1));
+  if (saved_states == NULL)
+    {
+      xfree(regset);
+      xfree(parents);
+      return REG_ESPACE;
+    }
+  else
+    {
+      unsigned int i;
+      for (i = 0; i <= tnfa->num_submatches; i++)
+	saved_states[i].tag = -1;
+    }
+
+  STACK_PUSH(stack, voidptr, node);
+  STACK_PUSH(stack, int, ADDTAGS_RECURSE);
+
+  while (tre_stack_num_objects(stack) > bottom)
+    {
+      if (status != REG_OK)
+	break;
+
+      symbol = (tre_addtags_symbol_t)tre_stack_pop_int(stack);
+      switch (symbol)
+	{
+
+	case ADDTAGS_SET_SUBMATCH_END:
+	  {
+	    int id = tre_stack_pop_int(stack);
+	    int i;
+
+	    /* Add end of this submatch to regset. */
+	    for (i = 0; regset[i] >= 0; i++);
+	    regset[i] = id * 2 + 1;
+	    regset[i + 1] = -1;
+
+	    /* Pop this submatch from the parents stack. */
+	    for (i = 0; parents[i] >= 0; i++);
+	    parents[i - 1] = -1;
+	    break;
+	  }
+
+	case ADDTAGS_RECURSE:
+	  node = tre_stack_pop_voidptr(stack);
+
+	  if (node->submatch_id >= 0)
+	    {
+	      int id = node->submatch_id;
+	      int i;
+
+
+	      /* Add start of this submatch to regset. */
+	      for (i = 0; regset[i] >= 0; i++);
+	      regset[i] = id * 2;
+	      regset[i + 1] = -1;
+
+	      if (!first_pass)
+		{
+		  for (i = 0; parents[i] >= 0; i++);
+		  tnfa->submatch_data[id].parents = NULL;
+		  if (i > 0)
+		    {
+		      int *p = xmalloc(sizeof(*p) * (i + 1));
+		      if (p == NULL)
+			{
+			  status = REG_ESPACE;
+			  break;
+			}
+		      assert(tnfa->submatch_data[id].parents == NULL);
+		      tnfa->submatch_data[id].parents = p;
+		      for (i = 0; parents[i] >= 0; i++)
+			p[i] = parents[i];
+		      p[i] = -1;
+		    }
+		}
+
+	      /* Add end of this submatch to regset after processing this
+		 node. */
+	      STACK_PUSHX(stack, int, node->submatch_id);
+	      STACK_PUSHX(stack, int, ADDTAGS_SET_SUBMATCH_END);
+	    }
+
+	  switch (node->type)
+	    {
+	    case LITERAL:
+	      {
+		tre_literal_t *lit = node->obj;
+
+		if (!IS_SPECIAL(lit) || IS_BACKREF(lit))
+		  {
+		    int i;
+		    if (regset[0] >= 0)
+		      {
+			/* Regset is not empty, so add a tag before the
+			   literal or backref. */
+			if (!first_pass)
+			  {
+			    status = tre_add_tag_left(mem, node, tag);
+			    tnfa->tag_directions[tag] = direction;
+			    if (minimal_tag >= 0)
+			      {
+				for (i = 0; tnfa->minimal_tags[i] >= 0; i++);
+				tnfa->minimal_tags[i] = tag;
+				tnfa->minimal_tags[i + 1] = minimal_tag;
+				tnfa->minimal_tags[i + 2] = -1;
+				minimal_tag = -1;
+				num_minimals++;
+			      }
+			    tre_purge_regset(regset, tnfa, tag);
+			  }
+			else
+			  {
+			    node->num_tags = 1;
+			  }
+
+			regset[0] = -1;
+			tag = next_tag;
+			num_tags++;
+			next_tag++;
+		      }
+		  }
+		else
+		  {
+		    assert(!IS_TAG(lit));
+		  }
+		break;
+	      }
+	    case CATENATION:
+	      {
+		tre_catenation_t *cat = node->obj;
+		tre_ast_node_t *left = cat->left;
+		tre_ast_node_t *right = cat->right;
+		int reserved_tag = -1;
+
+
+		/* After processing right child. */
+		STACK_PUSHX(stack, voidptr, node);
+		STACK_PUSHX(stack, int, ADDTAGS_AFTER_CAT_RIGHT);
+
+		/* Process right child. */
+		STACK_PUSHX(stack, voidptr, right);
+		STACK_PUSHX(stack, int, ADDTAGS_RECURSE);
+
+		/* After processing left child. */
+		STACK_PUSHX(stack, int, next_tag + left->num_tags);
+		if (left->num_tags > 0 && right->num_tags > 0)
+		  {
+		    /* Reserve the next tag to the right child. */
+		    reserved_tag = next_tag;
+		    next_tag++;
+		  }
+		STACK_PUSHX(stack, int, reserved_tag);
+		STACK_PUSHX(stack, int, ADDTAGS_AFTER_CAT_LEFT);
+
+		/* Process left child. */
+		STACK_PUSHX(stack, voidptr, left);
+		STACK_PUSHX(stack, int, ADDTAGS_RECURSE);
+
+		}
+	      break;
+	    case ITERATION:
+	      {
+		tre_iteration_t *iter = node->obj;
+
+		if (first_pass)
+		  {
+		    STACK_PUSHX(stack, int, regset[0] >= 0 || iter->minimal);
+		  }
+		else
+		  {
+		    STACK_PUSHX(stack, int, tag);
+		    STACK_PUSHX(stack, int, iter->minimal);
+		  }
+		STACK_PUSHX(stack, voidptr, node);
+		STACK_PUSHX(stack, int, ADDTAGS_AFTER_ITERATION);
+
+		STACK_PUSHX(stack, voidptr, iter->arg);
+		STACK_PUSHX(stack, int, ADDTAGS_RECURSE);
+
+		/* Regset is not empty, so add a tag here. */
+		if (regset[0] >= 0 || iter->minimal)
+		  {
+		    if (!first_pass)
+		      {
+			int i;
+			status = tre_add_tag_left(mem, node, tag);
+			if (iter->minimal)
+			  tnfa->tag_directions[tag] = TRE_TAG_MAXIMIZE;
+			else
+			  tnfa->tag_directions[tag] = direction;
+			if (minimal_tag >= 0)
+			  {
+			    for (i = 0; tnfa->minimal_tags[i] >= 0; i++);
+			    tnfa->minimal_tags[i] = tag;
+			    tnfa->minimal_tags[i + 1] = minimal_tag;
+			    tnfa->minimal_tags[i + 2] = -1;
+			    minimal_tag = -1;
+			    num_minimals++;
+			  }
+			tre_purge_regset(regset, tnfa, tag);
+		      }
+
+		    regset[0] = -1;
+		    tag = next_tag;
+		    num_tags++;
+		    next_tag++;
+		  }
+		direction = TRE_TAG_MINIMIZE;
+	      }
+	      break;
+	    case UNION:
+	      {
+		tre_union_t *uni = node->obj;
+		tre_ast_node_t *left = uni->left;
+		tre_ast_node_t *right = uni->right;
+		int left_tag;
+		int right_tag;
+
+		if (regset[0] >= 0)
+		  {
+		    left_tag = next_tag;
+		    right_tag = next_tag + 1;
+		  }
+		else
+		  {
+		    left_tag = tag;
+		    right_tag = next_tag;
+		  }
+
+		/* After processing right child. */
+		STACK_PUSHX(stack, int, right_tag);
+		STACK_PUSHX(stack, int, left_tag);
+		STACK_PUSHX(stack, voidptr, regset);
+		STACK_PUSHX(stack, int, regset[0] >= 0);
+		STACK_PUSHX(stack, voidptr, node);
+		STACK_PUSHX(stack, voidptr, right);
+		STACK_PUSHX(stack, voidptr, left);
+		STACK_PUSHX(stack, int, ADDTAGS_AFTER_UNION_RIGHT);
+
+		/* Process right child. */
+		STACK_PUSHX(stack, voidptr, right);
+		STACK_PUSHX(stack, int, ADDTAGS_RECURSE);
+
+		/* After processing left child. */
+		STACK_PUSHX(stack, int, ADDTAGS_AFTER_UNION_LEFT);
+
+		/* Process left child. */
+		STACK_PUSHX(stack, voidptr, left);
+		STACK_PUSHX(stack, int, ADDTAGS_RECURSE);
+
+		/* Regset is not empty, so add a tag here. */
+		if (regset[0] >= 0)
+		  {
+		    if (!first_pass)
+		      {
+			int i;
+			status = tre_add_tag_left(mem, node, tag);
+			tnfa->tag_directions[tag] = direction;
+			if (minimal_tag >= 0)
+			  {
+			    for (i = 0; tnfa->minimal_tags[i] >= 0; i++);
+			    tnfa->minimal_tags[i] = tag;
+			    tnfa->minimal_tags[i + 1] = minimal_tag;
+			    tnfa->minimal_tags[i + 2] = -1;
+			    minimal_tag = -1;
+			    num_minimals++;
+			  }
+			tre_purge_regset(regset, tnfa, tag);
+		      }
+
+		    regset[0] = -1;
+		    tag = next_tag;
+		    num_tags++;
+		    next_tag++;
+		  }
+
+		if (node->num_submatches > 0)
+		  {
+		    /* The next two tags are reserved for markers. */
+		    next_tag++;
+		    tag = next_tag;
+		    next_tag++;
+		  }
+
+		break;
+	      }
+	    }
+
+	  if (node->submatch_id >= 0)
+	    {
+	      int i;
+	      /* Push this submatch on the parents stack. */
+	      for (i = 0; parents[i] >= 0; i++);
+	      parents[i] = node->submatch_id;
+	      parents[i + 1] = -1;
+	    }
+
+	  break; /* end case: ADDTAGS_RECURSE */
+
+	case ADDTAGS_AFTER_ITERATION:
+	  {
+	    int minimal = 0;
+	    int enter_tag;
+	    node = tre_stack_pop_voidptr(stack);
+	    if (first_pass)
+	      {
+		node->num_tags = ((tre_iteration_t *)node->obj)->arg->num_tags
+		  + tre_stack_pop_int(stack);
+		minimal_tag = -1;
+	      }
+	    else
+	      {
+		minimal = tre_stack_pop_int(stack);
+		enter_tag = tre_stack_pop_int(stack);
+		if (minimal)
+		  minimal_tag = enter_tag;
+	      }
+
+	    if (!first_pass)
+	      {
+		if (minimal)
+		  direction = TRE_TAG_MINIMIZE;
+		else
+		  direction = TRE_TAG_MAXIMIZE;
+	      }
+	    break;
+	  }
+
+	case ADDTAGS_AFTER_CAT_LEFT:
+	  {
+	    int new_tag = tre_stack_pop_int(stack);
+	    next_tag = tre_stack_pop_int(stack);
+	    if (new_tag >= 0)
+	      {
+		tag = new_tag;
+	      }
+	    break;
+	  }
+
+	case ADDTAGS_AFTER_CAT_RIGHT:
+	  node = tre_stack_pop_voidptr(stack);
+	  if (first_pass)
+	    node->num_tags = ((tre_catenation_t *)node->obj)->left->num_tags
+	      + ((tre_catenation_t *)node->obj)->right->num_tags;
+	  break;
+
+	case ADDTAGS_AFTER_UNION_LEFT:
+	  /* Lift the bottom of the `regset' array so that when processing
+	     the right operand the items currently in the array are
+	     invisible.	 The original bottom was saved at ADDTAGS_UNION and
+	     will be restored at ADDTAGS_AFTER_UNION_RIGHT below. */
+	  while (*regset >= 0)
+	    regset++;
+	  break;
+
+	case ADDTAGS_AFTER_UNION_RIGHT:
+	  {
+	    int added_tags, tag_left, tag_right;
+	    tre_ast_node_t *left = tre_stack_pop_voidptr(stack);
+	    tre_ast_node_t *right = tre_stack_pop_voidptr(stack);
+	    node = tre_stack_pop_voidptr(stack);
+	    added_tags = tre_stack_pop_int(stack);
+	    if (first_pass)
+	      {
+		node->num_tags = ((tre_union_t *)node->obj)->left->num_tags
+		  + ((tre_union_t *)node->obj)->right->num_tags + added_tags
+		  + ((node->num_submatches > 0) ? 2 : 0);
+	      }
+	    regset = tre_stack_pop_voidptr(stack);
+	    tag_left = tre_stack_pop_int(stack);
+	    tag_right = tre_stack_pop_int(stack);
+
+	    /* Add tags after both children, the left child gets a smaller
+	       tag than the right child.  This guarantees that we prefer
+	       the left child over the right child. */
+	    /* XXX - This is not always necessary (if the children have
+	       tags which must be seen for every match of that child). */
+	    /* XXX - Check if this is the only place where tre_add_tag_right
+	       is used.	 If so, use tre_add_tag_left (putting the tag before
+	       the child as opposed after the child) and throw away
+	       tre_add_tag_right. */
+	    if (node->num_submatches > 0)
+	      {
+		if (!first_pass)
+		  {
+		    status = tre_add_tag_right(mem, left, tag_left);
+		    tnfa->tag_directions[tag_left] = TRE_TAG_MAXIMIZE;
+		    if (status == REG_OK)
+		      status = tre_add_tag_right(mem, right, tag_right);
+		    tnfa->tag_directions[tag_right] = TRE_TAG_MAXIMIZE;
+		  }
+		num_tags += 2;
+	      }
+	    direction = TRE_TAG_MAXIMIZE;
+	    break;
+	  }
+
+	default:
+	  assert(0);
+	  break;
+
+	} /* end switch(symbol) */
+    } /* end while(tre_stack_num_objects(stack) > bottom) */
+
+  if (!first_pass)
+    tre_purge_regset(regset, tnfa, tag);
+
+  if (!first_pass && minimal_tag >= 0)
+    {
+      int i;
+      for (i = 0; tnfa->minimal_tags[i] >= 0; i++);
+      tnfa->minimal_tags[i] = tag;
+      tnfa->minimal_tags[i + 1] = minimal_tag;
+      tnfa->minimal_tags[i + 2] = -1;
+      minimal_tag = -1;
+      num_minimals++;
+    }
+
+  assert(tree->num_tags == num_tags);
+  tnfa->end_tag = num_tags;
+  tnfa->num_tags = num_tags;
+  tnfa->num_minimals = num_minimals;
+  xfree(orig_regset);
+  xfree(parents);
+  xfree(saved_states);
+  return status;
+}
+
+
+
+/*
+  AST to TNFA compilation routines.
+*/
+
+typedef enum {
+  COPY_RECURSE,
+  COPY_SET_RESULT_PTR
+} tre_copyast_symbol_t;
+
+/* Flags for tre_copy_ast(). */
+#define COPY_REMOVE_TAGS	 1
+#define COPY_MAXIMIZE_FIRST_TAG	 2
+
+static reg_errcode_t
+tre_copy_ast(tre_mem_t mem, tre_stack_t *stack, tre_ast_node_t *ast,
+	     int flags, int *pos_add, tre_tag_direction_t *tag_directions,
+	     tre_ast_node_t **copy, int *max_pos)
+{
+  reg_errcode_t status = REG_OK;
+  int bottom = tre_stack_num_objects(stack);
+  int num_copied = 0;
+  int first_tag = 1;
+  tre_ast_node_t **result = copy;
+  tre_copyast_symbol_t symbol;
+
+  STACK_PUSH(stack, voidptr, ast);
+  STACK_PUSH(stack, int, COPY_RECURSE);
+
+  while (status == REG_OK && tre_stack_num_objects(stack) > bottom)
+    {
+      tre_ast_node_t *node;
+      if (status != REG_OK)
+	break;
+
+      symbol = (tre_copyast_symbol_t)tre_stack_pop_int(stack);
+      switch (symbol)
+	{
+	case COPY_SET_RESULT_PTR:
+	  result = tre_stack_pop_voidptr(stack);
+	  break;
+	case COPY_RECURSE:
+	  node = tre_stack_pop_voidptr(stack);
+	  switch (node->type)
+	    {
+	    case LITERAL:
+	      {
+		tre_literal_t *lit = node->obj;
+		int pos = lit->position;
+		int min = lit->code_min;
+		int max = lit->code_max;
+		if (!IS_SPECIAL(lit) || IS_BACKREF(lit))
+		  {
+		    /* XXX - e.g. [ab] has only one position but two
+		       nodes, so we are creating holes in the state space
+		       here.  Not fatal, just wastes memory. */
+		    pos += *pos_add;
+		    num_copied++;
+		  }
+		else if (IS_TAG(lit) && (flags & COPY_REMOVE_TAGS))
+		  {
+		    /* Change this tag to empty. */
+		    min = EMPTY;
+		    max = pos = -1;
+		  }
+		else if (IS_TAG(lit) && (flags & COPY_MAXIMIZE_FIRST_TAG)
+			 && first_tag)
+		  {
+		    /* Maximize the first tag. */
+		    tag_directions[max] = TRE_TAG_MAXIMIZE;
+		    first_tag = 0;
+		  }
+		*result = tre_ast_new_literal(mem, min, max, pos);
+		if (*result == NULL)
+		  status = REG_ESPACE;
+		else {
+		  tre_literal_t *p = (*result)->obj;
+		  p->class = lit->class;
+		  p->neg_classes = lit->neg_classes;
+		}
+
+		if (pos > *max_pos)
+		  *max_pos = pos;
+		break;
+	      }
+	    case UNION:
+	      {
+		tre_union_t *uni = node->obj;
+		tre_union_t *tmp;
+		*result = tre_ast_new_union(mem, uni->left, uni->right);
+		if (*result == NULL)
+		  {
+		    status = REG_ESPACE;
+		    break;
+		  }
+		tmp = (*result)->obj;
+		result = &tmp->left;
+		STACK_PUSHX(stack, voidptr, uni->right);
+		STACK_PUSHX(stack, int, COPY_RECURSE);
+		STACK_PUSHX(stack, voidptr, &tmp->right);
+		STACK_PUSHX(stack, int, COPY_SET_RESULT_PTR);
+		STACK_PUSHX(stack, voidptr, uni->left);
+		STACK_PUSHX(stack, int, COPY_RECURSE);
+		break;
+	      }
+	    case CATENATION:
+	      {
+		tre_catenation_t *cat = node->obj;
+		tre_catenation_t *tmp;
+		*result = tre_ast_new_catenation(mem, cat->left, cat->right);
+		if (*result == NULL)
+		  {
+		    status = REG_ESPACE;
+		    break;
+		  }
+		tmp = (*result)->obj;
+		tmp->left = NULL;
+		tmp->right = NULL;
+		result = &tmp->left;
+
+		STACK_PUSHX(stack, voidptr, cat->right);
+		STACK_PUSHX(stack, int, COPY_RECURSE);
+		STACK_PUSHX(stack, voidptr, &tmp->right);
+		STACK_PUSHX(stack, int, COPY_SET_RESULT_PTR);
+		STACK_PUSHX(stack, voidptr, cat->left);
+		STACK_PUSHX(stack, int, COPY_RECURSE);
+		break;
+	      }
+	    case ITERATION:
+	      {
+		tre_iteration_t *iter = node->obj;
+		STACK_PUSHX(stack, voidptr, iter->arg);
+		STACK_PUSHX(stack, int, COPY_RECURSE);
+		*result = tre_ast_new_iter(mem, iter->arg, iter->min,
+					   iter->max, iter->minimal);
+		if (*result == NULL)
+		  {
+		    status = REG_ESPACE;
+		    break;
+		  }
+		iter = (*result)->obj;
+		result = &iter->arg;
+		break;
+	      }
+	    default:
+	      assert(0);
+	      break;
+	    }
+	  break;
+	}
+    }
+  *pos_add += num_copied;
+  return status;
+}
+
+typedef enum {
+  EXPAND_RECURSE,
+  EXPAND_AFTER_ITER
+} tre_expand_ast_symbol_t;
+
+/* Expands each iteration node that has a finite nonzero minimum or maximum
+   iteration count to a catenated sequence of copies of the node. */
+static reg_errcode_t
+tre_expand_ast(tre_mem_t mem, tre_stack_t *stack, tre_ast_node_t *ast,
+	       int *position, tre_tag_direction_t *tag_directions)
+{
+  reg_errcode_t status = REG_OK;
+  int bottom = tre_stack_num_objects(stack);
+  int pos_add = 0;
+  int pos_add_total = 0;
+  int max_pos = 0;
+  int iter_depth = 0;
+
+  STACK_PUSHR(stack, voidptr, ast);
+  STACK_PUSHR(stack, int, EXPAND_RECURSE);
+  while (status == REG_OK && tre_stack_num_objects(stack) > bottom)
+    {
+      tre_ast_node_t *node;
+      tre_expand_ast_symbol_t symbol;
+
+      if (status != REG_OK)
+	break;
+
+      symbol = (tre_expand_ast_symbol_t)tre_stack_pop_int(stack);
+      node = tre_stack_pop_voidptr(stack);
+      switch (symbol)
+	{
+	case EXPAND_RECURSE:
+	  switch (node->type)
+	    {
+	    case LITERAL:
+	      {
+		tre_literal_t *lit= node->obj;
+		if (!IS_SPECIAL(lit) || IS_BACKREF(lit))
+		  {
+		    lit->position += pos_add;
+		    if (lit->position > max_pos)
+		      max_pos = lit->position;
+		  }
+		break;
+	      }
+	    case UNION:
+	      {
+		tre_union_t *uni = node->obj;
+		STACK_PUSHX(stack, voidptr, uni->right);
+		STACK_PUSHX(stack, int, EXPAND_RECURSE);
+		STACK_PUSHX(stack, voidptr, uni->left);
+		STACK_PUSHX(stack, int, EXPAND_RECURSE);
+		break;
+	      }
+	    case CATENATION:
+	      {
+		tre_catenation_t *cat = node->obj;
+		STACK_PUSHX(stack, voidptr, cat->right);
+		STACK_PUSHX(stack, int, EXPAND_RECURSE);
+		STACK_PUSHX(stack, voidptr, cat->left);
+		STACK_PUSHX(stack, int, EXPAND_RECURSE);
+		break;
+	      }
+	    case ITERATION:
+	      {
+		tre_iteration_t *iter = node->obj;
+		STACK_PUSHX(stack, int, pos_add);
+		STACK_PUSHX(stack, voidptr, node);
+		STACK_PUSHX(stack, int, EXPAND_AFTER_ITER);
+		STACK_PUSHX(stack, voidptr, iter->arg);
+		STACK_PUSHX(stack, int, EXPAND_RECURSE);
+		/* If we are going to expand this node at EXPAND_AFTER_ITER
+		   then don't increase the `pos' fields of the nodes now, it
+		   will get done when expanding. */
+		if (iter->min > 1 || iter->max > 1)
+		  pos_add = 0;
+		iter_depth++;
+		break;
+	      }
+	    default:
+	      assert(0);
+	      break;
+	    }
+	  break;
+	case EXPAND_AFTER_ITER:
+	  {
+	    tre_iteration_t *iter = node->obj;
+	    int pos_add_last;
+	    pos_add = tre_stack_pop_int(stack);
+	    pos_add_last = pos_add;
+	    if (iter->min > 1 || iter->max > 1)
+	      {
+		tre_ast_node_t *seq1 = NULL, *seq2 = NULL;
+		int j;
+		int pos_add_save = pos_add;
+
+		/* Create a catenated sequence of copies of the node. */
+		for (j = 0; j < iter->min; j++)
+		  {
+		    tre_ast_node_t *copy;
+		    /* Remove tags from all but the last copy. */
+		    int flags = ((j + 1 < iter->min)
+				 ? COPY_REMOVE_TAGS
+				 : COPY_MAXIMIZE_FIRST_TAG);
+		    pos_add_save = pos_add;
+		    status = tre_copy_ast(mem, stack, iter->arg, flags,
+					  &pos_add, tag_directions, &copy,
+					  &max_pos);
+		    if (status != REG_OK)
+		      return status;
+		    if (seq1 != NULL)
+		      seq1 = tre_ast_new_catenation(mem, seq1, copy);
+		    else
+		      seq1 = copy;
+		    if (seq1 == NULL)
+		      return REG_ESPACE;
+		  }
+
+		if (iter->max == -1)
+		  {
+		    /* No upper limit. */
+		    pos_add_save = pos_add;
+		    status = tre_copy_ast(mem, stack, iter->arg, 0,
+					  &pos_add, NULL, &seq2, &max_pos);
+		    if (status != REG_OK)
+		      return status;
+		    seq2 = tre_ast_new_iter(mem, seq2, 0, -1, 0);
+		    if (seq2 == NULL)
+		      return REG_ESPACE;
+		  }
+		else
+		  {
+		    for (j = iter->min; j < iter->max; j++)
+		      {
+			tre_ast_node_t *tmp, *copy;
+			pos_add_save = pos_add;
+			status = tre_copy_ast(mem, stack, iter->arg, 0,
+					      &pos_add, NULL, &copy, &max_pos);
+			if (status != REG_OK)
+			  return status;
+			if (seq2 != NULL)
+			  seq2 = tre_ast_new_catenation(mem, copy, seq2);
+			else
+			  seq2 = copy;
+			if (seq2 == NULL)
+			  return REG_ESPACE;
+			tmp = tre_ast_new_literal(mem, EMPTY, -1, -1);
+			if (tmp == NULL)
+			  return REG_ESPACE;
+			seq2 = tre_ast_new_union(mem, tmp, seq2);
+			if (seq2 == NULL)
+			  return REG_ESPACE;
+		      }
+		  }
+
+		pos_add = pos_add_save;
+		if (seq1 == NULL)
+		  seq1 = seq2;
+		else if (seq2 != NULL)
+		  seq1 = tre_ast_new_catenation(mem, seq1, seq2);
+		if (seq1 == NULL)
+		  return REG_ESPACE;
+		node->obj = seq1->obj;
+		node->type = seq1->type;
+	      }
+
+	    iter_depth--;
+	    pos_add_total += pos_add - pos_add_last;
+	    if (iter_depth == 0)
+	      pos_add = pos_add_total;
+
+	    break;
+	  }
+	default:
+	  assert(0);
+	  break;
+	}
+    }
+
+  *position += pos_add_total;
+
+  /* `max_pos' should never be larger than `*position' if the above
+     code works, but just an extra safeguard let's make sure
+     `*position' is set large enough so enough memory will be
+     allocated for the transition table. */
+  if (max_pos > *position)
+    *position = max_pos;
+
+  return status;
+}
+
+static tre_pos_and_tags_t *
+tre_set_empty(tre_mem_t mem)
+{
+  tre_pos_and_tags_t *new_set;
+
+  new_set = tre_mem_calloc(mem, sizeof(*new_set));
+  if (new_set == NULL)
+    return NULL;
+
+  new_set[0].position = -1;
+  new_set[0].code_min = -1;
+  new_set[0].code_max = -1;
+
+  return new_set;
+}
+
+static tre_pos_and_tags_t *
+tre_set_one(tre_mem_t mem, int position, int code_min, int code_max,
+	    tre_ctype_t class, tre_ctype_t *neg_classes, int backref)
+{
+  tre_pos_and_tags_t *new_set;
+
+  new_set = tre_mem_calloc(mem, sizeof(*new_set) * 2);
+  if (new_set == NULL)
+    return NULL;
+
+  new_set[0].position = position;
+  new_set[0].code_min = code_min;
+  new_set[0].code_max = code_max;
+  new_set[0].class = class;
+  new_set[0].neg_classes = neg_classes;
+  new_set[0].backref = backref;
+  new_set[1].position = -1;
+  new_set[1].code_min = -1;
+  new_set[1].code_max = -1;
+
+  return new_set;
+}
+
+static tre_pos_and_tags_t *
+tre_set_union(tre_mem_t mem, tre_pos_and_tags_t *set1, tre_pos_and_tags_t *set2,
+	      int *tags, int assertions)
+{
+  int s1, s2, i, j;
+  tre_pos_and_tags_t *new_set;
+  int *new_tags;
+  int num_tags;
+
+  for (num_tags = 0; tags != NULL && tags[num_tags] >= 0; num_tags++);
+  for (s1 = 0; set1[s1].position >= 0; s1++);
+  for (s2 = 0; set2[s2].position >= 0; s2++);
+  new_set = tre_mem_calloc(mem, sizeof(*new_set) * (s1 + s2 + 1));
+  if (!new_set )
+    return NULL;
+
+  for (s1 = 0; set1[s1].position >= 0; s1++)
+    {
+      new_set[s1].position = set1[s1].position;
+      new_set[s1].code_min = set1[s1].code_min;
+      new_set[s1].code_max = set1[s1].code_max;
+      new_set[s1].assertions = set1[s1].assertions | assertions;
+      new_set[s1].class = set1[s1].class;
+      new_set[s1].neg_classes = set1[s1].neg_classes;
+      new_set[s1].backref = set1[s1].backref;
+      if (set1[s1].tags == NULL && tags == NULL)
+	new_set[s1].tags = NULL;
+      else
+	{
+	  for (i = 0; set1[s1].tags != NULL && set1[s1].tags[i] >= 0; i++);
+	  new_tags = tre_mem_alloc(mem, (sizeof(*new_tags)
+					 * (i + num_tags + 1)));
+	  if (new_tags == NULL)
+	    return NULL;
+	  for (j = 0; j < i; j++)
+	    new_tags[j] = set1[s1].tags[j];
+	  for (i = 0; i < num_tags; i++)
+	    new_tags[j + i] = tags[i];
+	  new_tags[j + i] = -1;
+	  new_set[s1].tags = new_tags;
+	}
+    }
+
+  for (s2 = 0; set2[s2].position >= 0; s2++)
+    {
+      new_set[s1 + s2].position = set2[s2].position;
+      new_set[s1 + s2].code_min = set2[s2].code_min;
+      new_set[s1 + s2].code_max = set2[s2].code_max;
+      /* XXX - why not | assertions here as well? */
+      new_set[s1 + s2].assertions = set2[s2].assertions;
+      new_set[s1 + s2].class = set2[s2].class;
+      new_set[s1 + s2].neg_classes = set2[s2].neg_classes;
+      new_set[s1 + s2].backref = set2[s2].backref;
+      if (set2[s2].tags == NULL)
+	new_set[s1 + s2].tags = NULL;
+      else
+	{
+	  for (i = 0; set2[s2].tags[i] >= 0; i++);
+	  new_tags = tre_mem_alloc(mem, sizeof(*new_tags) * (i + 1));
+	  if (new_tags == NULL)
+	    return NULL;
+	  for (j = 0; j < i; j++)
+	    new_tags[j] = set2[s2].tags[j];
+	  new_tags[j] = -1;
+	  new_set[s1 + s2].tags = new_tags;
+	}
+    }
+  new_set[s1 + s2].position = -1;
+  return new_set;
+}
+
+/* Finds the empty path through `node' which is the one that should be
+   taken according to POSIX.2 rules, and adds the tags on that path to
+   `tags'.   `tags' may be NULL.  If `num_tags_seen' is not NULL, it is
+   set to the number of tags seen on the path. */
+static reg_errcode_t
+tre_match_empty(tre_stack_t *stack, tre_ast_node_t *node, int *tags,
+		int *assertions, int *num_tags_seen)
+{
+  tre_literal_t *lit;
+  tre_union_t *uni;
+  tre_catenation_t *cat;
+  tre_iteration_t *iter;
+  int i;
+  int bottom = tre_stack_num_objects(stack);
+  reg_errcode_t status = REG_OK;
+  if (num_tags_seen)
+    *num_tags_seen = 0;
+
+  status = tre_stack_push_voidptr(stack, node);
+
+  /* Walk through the tree recursively. */
+  while (status == REG_OK && tre_stack_num_objects(stack) > bottom)
+    {
+      node = tre_stack_pop_voidptr(stack);
+
+      switch (node->type)
+	{
+	case LITERAL:
+	  lit = (tre_literal_t *)node->obj;
+	  switch (lit->code_min)
+	    {
+	    case TAG:
+	      if (lit->code_max >= 0)
+		{
+		  if (tags != NULL)
+		    {
+		      /* Add the tag to `tags'. */
+		      for (i = 0; tags[i] >= 0; i++)
+			if (tags[i] == lit->code_max)
+			  break;
+		      if (tags[i] < 0)
+			{
+			  tags[i] = lit->code_max;
+			  tags[i + 1] = -1;
+			}
+		    }
+		  if (num_tags_seen)
+		    (*num_tags_seen)++;
+		}
+	      break;
+	    case ASSERTION:
+	      assert(lit->code_max >= 1
+		     || lit->code_max <= ASSERT_LAST);
+	      if (assertions != NULL)
+		*assertions |= lit->code_max;
+	      break;
+	    case EMPTY:
+	      break;
+	    default:
+	      assert(0);
+	      break;
+	    }
+	  break;
+
+	case UNION:
+	  /* Subexpressions starting earlier take priority over ones
+	     starting later, so we prefer the left subexpression over the
+	     right subexpression. */
+	  uni = (tre_union_t *)node->obj;
+	  if (uni->left->nullable)
+	    STACK_PUSHX(stack, voidptr, uni->left)
+	  else if (uni->right->nullable)
+	    STACK_PUSHX(stack, voidptr, uni->right)
+	  else
+	    assert(0);
+	  break;
+
+	case CATENATION:
+	  /* The path must go through both children. */
+	  cat = (tre_catenation_t *)node->obj;
+	  assert(cat->left->nullable);
+	  assert(cat->right->nullable);
+	  STACK_PUSHX(stack, voidptr, cat->left);
+	  STACK_PUSHX(stack, voidptr, cat->right);
+	  break;
+
+	case ITERATION:
+	  /* A match with an empty string is preferred over no match at
+	     all, so we go through the argument if possible. */
+	  iter = (tre_iteration_t *)node->obj;
+	  if (iter->arg->nullable)
+	    STACK_PUSHX(stack, voidptr, iter->arg);
+	  break;
+
+	default:
+	  assert(0);
+	  break;
+	}
+    }
+
+  return status;
+}
+
+
+typedef enum {
+  NFL_RECURSE,
+  NFL_POST_UNION,
+  NFL_POST_CATENATION,
+  NFL_POST_ITERATION
+} tre_nfl_stack_symbol_t;
+
+
+/* Computes and fills in the fields `nullable', `firstpos', and `lastpos' for
+   the nodes of the AST `tree'. */
+static reg_errcode_t
+tre_compute_nfl(tre_mem_t mem, tre_stack_t *stack, tre_ast_node_t *tree)
+{
+  int bottom = tre_stack_num_objects(stack);
+
+  STACK_PUSHR(stack, voidptr, tree);
+  STACK_PUSHR(stack, int, NFL_RECURSE);
+
+  while (tre_stack_num_objects(stack) > bottom)
+    {
+      tre_nfl_stack_symbol_t symbol;
+      tre_ast_node_t *node;
+
+      symbol = (tre_nfl_stack_symbol_t)tre_stack_pop_int(stack);
+      node = tre_stack_pop_voidptr(stack);
+      switch (symbol)
+	{
+	case NFL_RECURSE:
+	  switch (node->type)
+	    {
+	    case LITERAL:
+	      {
+		tre_literal_t *lit = (tre_literal_t *)node->obj;
+		if (IS_BACKREF(lit))
+		  {
+		    /* Back references: nullable = false, firstpos = {i},
+		       lastpos = {i}. */
+		    node->nullable = 0;
+		    node->firstpos = tre_set_one(mem, lit->position, 0,
+					     TRE_CHAR_MAX, 0, NULL, -1);
+		    if (!node->firstpos)
+		      return REG_ESPACE;
+		    node->lastpos = tre_set_one(mem, lit->position, 0,
+						TRE_CHAR_MAX, 0, NULL,
+						(int)lit->code_max);
+		    if (!node->lastpos)
+		      return REG_ESPACE;
+		  }
+		else if (lit->code_min < 0)
+		  {
+		    /* Tags, empty strings, params, and zero width assertions:
+		       nullable = true, firstpos = {}, and lastpos = {}. */
+		    node->nullable = 1;
+		    node->firstpos = tre_set_empty(mem);
+		    if (!node->firstpos)
+		      return REG_ESPACE;
+		    node->lastpos = tre_set_empty(mem);
+		    if (!node->lastpos)
+		      return REG_ESPACE;
+		  }
+		else
+		  {
+		    /* Literal at position i: nullable = false, firstpos = {i},
+		       lastpos = {i}. */
+		    node->nullable = 0;
+		    node->firstpos =
+		      tre_set_one(mem, lit->position, (int)lit->code_min,
+				  (int)lit->code_max, 0, NULL, -1);
+		    if (!node->firstpos)
+		      return REG_ESPACE;
+		    node->lastpos = tre_set_one(mem, lit->position,
+						(int)lit->code_min,
+						(int)lit->code_max,
+						lit->class, lit->neg_classes,
+						-1);
+		    if (!node->lastpos)
+		      return REG_ESPACE;
+		  }
+		break;
+	      }
+
+	    case UNION:
+	      /* Compute the attributes for the two subtrees, and after that
+		 for this node. */
+	      STACK_PUSHR(stack, voidptr, node);
+	      STACK_PUSHR(stack, int, NFL_POST_UNION);
+	      STACK_PUSHR(stack, voidptr, ((tre_union_t *)node->obj)->right);
+	      STACK_PUSHR(stack, int, NFL_RECURSE);
+	      STACK_PUSHR(stack, voidptr, ((tre_union_t *)node->obj)->left);
+	      STACK_PUSHR(stack, int, NFL_RECURSE);
+	      break;
+
+	    case CATENATION:
+	      /* Compute the attributes for the two subtrees, and after that
+		 for this node. */
+	      STACK_PUSHR(stack, voidptr, node);
+	      STACK_PUSHR(stack, int, NFL_POST_CATENATION);
+	      STACK_PUSHR(stack, voidptr, ((tre_catenation_t *)node->obj)->right);
+	      STACK_PUSHR(stack, int, NFL_RECURSE);
+	      STACK_PUSHR(stack, voidptr, ((tre_catenation_t *)node->obj)->left);
+	      STACK_PUSHR(stack, int, NFL_RECURSE);
+	      break;
+
+	    case ITERATION:
+	      /* Compute the attributes for the subtree, and after that for
+		 this node. */
+	      STACK_PUSHR(stack, voidptr, node);
+	      STACK_PUSHR(stack, int, NFL_POST_ITERATION);
+	      STACK_PUSHR(stack, voidptr, ((tre_iteration_t *)node->obj)->arg);
+	      STACK_PUSHR(stack, int, NFL_RECURSE);
+	      break;
+	    }
+	  break; /* end case: NFL_RECURSE */
+
+	case NFL_POST_UNION:
+	  {
+	    tre_union_t *uni = (tre_union_t *)node->obj;
+	    node->nullable = uni->left->nullable || uni->right->nullable;
+	    node->firstpos = tre_set_union(mem, uni->left->firstpos,
+					   uni->right->firstpos, NULL, 0);
+	    if (!node->firstpos)
+	      return REG_ESPACE;
+	    node->lastpos = tre_set_union(mem, uni->left->lastpos,
+					  uni->right->lastpos, NULL, 0);
+	    if (!node->lastpos)
+	      return REG_ESPACE;
+	    break;
+	  }
+
+	case NFL_POST_ITERATION:
+	  {
+	    tre_iteration_t *iter = (tre_iteration_t *)node->obj;
+
+	    if (iter->min == 0 || iter->arg->nullable)
+	      node->nullable = 1;
+	    else
+	      node->nullable = 0;
+	    node->firstpos = iter->arg->firstpos;
+	    node->lastpos = iter->arg->lastpos;
+	    break;
+	  }
+
+	case NFL_POST_CATENATION:
+	  {
+	    int num_tags, *tags, assertions;
+	    reg_errcode_t status;
+	    tre_catenation_t *cat = node->obj;
+	    node->nullable = cat->left->nullable && cat->right->nullable;
+
+	    /* Compute firstpos. */
+	    if (cat->left->nullable)
+	      {
+		/* The left side matches the empty string.  Make a first pass
+		   with tre_match_empty() to get the number of tags and
+		   parameters. */
+		status = tre_match_empty(stack, cat->left,
+					 NULL, NULL, &num_tags);
+		if (status != REG_OK)
+		  return status;
+		/* Allocate arrays for the tags and parameters. */
+		tags = xmalloc(sizeof(*tags) * (num_tags + 1));
+		if (!tags)
+		  return REG_ESPACE;
+		tags[0] = -1;
+		assertions = 0;
+		/* Second pass with tre_mach_empty() to get the list of
+		   tags and parameters. */
+		status = tre_match_empty(stack, cat->left, tags,
+					 &assertions, NULL);
+		if (status != REG_OK)
+		  {
+		    xfree(tags);
+		    return status;
+		  }
+		node->firstpos =
+		  tre_set_union(mem, cat->right->firstpos, cat->left->firstpos,
+				tags, assertions);
+		xfree(tags);
+		if (!node->firstpos)
+		  return REG_ESPACE;
+	      }
+	    else
+	      {
+		node->firstpos = cat->left->firstpos;
+	      }
+
+	    /* Compute lastpos. */
+	    if (cat->right->nullable)
+	      {
+		/* The right side matches the empty string.  Make a first pass
+		   with tre_match_empty() to get the number of tags and
+		   parameters. */
+		status = tre_match_empty(stack, cat->right,
+					 NULL, NULL, &num_tags);
+		if (status != REG_OK)
+		  return status;
+		/* Allocate arrays for the tags and parameters. */
+		tags = xmalloc(sizeof(int) * (num_tags + 1));
+		if (!tags)
+		  return REG_ESPACE;
+		tags[0] = -1;
+		assertions = 0;
+		/* Second pass with tre_mach_empty() to get the list of
+		   tags and parameters. */
+		status = tre_match_empty(stack, cat->right, tags,
+					 &assertions, NULL);
+		if (status != REG_OK)
+		  {
+		    xfree(tags);
+		    return status;
+		  }
+		node->lastpos =
+		  tre_set_union(mem, cat->left->lastpos, cat->right->lastpos,
+				tags, assertions);
+		xfree(tags);
+		if (!node->lastpos)
+		  return REG_ESPACE;
+	      }
+	    else
+	      {
+		node->lastpos = cat->right->lastpos;
+	      }
+	    break;
+	  }
+
+	default:
+	  assert(0);
+	  break;
+	}
+    }
+
+  return REG_OK;
+}
+
+
+/* Adds a transition from each position in `p1' to each position in `p2'. */
+static reg_errcode_t
+tre_make_trans(tre_pos_and_tags_t *p1, tre_pos_and_tags_t *p2,
+	       tre_tnfa_transition_t *transitions,
+	       int *counts, int *offs)
+{
+  tre_pos_and_tags_t *orig_p2 = p2;
+  tre_tnfa_transition_t *trans;
+  int i, j, k, l, dup, prev_p2_pos;
+
+  if (transitions != NULL)
+    while (p1->position >= 0)
+      {
+	p2 = orig_p2;
+	prev_p2_pos = -1;
+	while (p2->position >= 0)
+	  {
+	    /* Optimization: if this position was already handled, skip it. */
+	    if (p2->position == prev_p2_pos)
+	      {
+		p2++;
+		continue;
+	      }
+	    prev_p2_pos = p2->position;
+	    /* Set `trans' to point to the next unused transition from
+	       position `p1->position'. */
+	    trans = transitions + offs[p1->position];
+	    while (trans->state != NULL)
+	      {
+#if 0
+		/* If we find a previous transition from `p1->position' to
+		   `p2->position', it is overwritten.  This can happen only
+		   if there are nested loops in the regexp, like in "((a)*)*".
+		   In POSIX.2 repetition using the outer loop is always
+		   preferred over using the inner loop.	 Therefore the
+		   transition for the inner loop is useless and can be thrown
+		   away. */
+		/* XXX - The same position is used for all nodes in a bracket
+		   expression, so this optimization cannot be used (it will
+		   break bracket expressions) unless I figure out a way to
+		   detect it here. */
+		if (trans->state_id == p2->position)
+		  {
+		    break;
+		  }
+#endif
+		trans++;
+	      }
+
+	    if (trans->state == NULL)
+	      (trans + 1)->state = NULL;
+	    /* Use the character ranges, assertions, etc. from `p1' for
+	       the transition from `p1' to `p2'. */
+	    trans->code_min = p1->code_min;
+	    trans->code_max = p1->code_max;
+	    trans->state = transitions + offs[p2->position];
+	    trans->state_id = p2->position;
+	    trans->assertions = p1->assertions | p2->assertions
+	      | (p1->class ? ASSERT_CHAR_CLASS : 0)
+	      | (p1->neg_classes != NULL ? ASSERT_CHAR_CLASS_NEG : 0);
+	    if (p1->backref >= 0)
+	      {
+		assert((trans->assertions & ASSERT_CHAR_CLASS) == 0);
+		assert(p2->backref < 0);
+		trans->u.backref = p1->backref;
+		trans->assertions |= ASSERT_BACKREF;
+	      }
+	    else
+	      trans->u.class = p1->class;
+	    if (p1->neg_classes != NULL)
+	      {
+		for (i = 0; p1->neg_classes[i] != (tre_ctype_t)0; i++);
+		trans->neg_classes =
+		  xmalloc(sizeof(*trans->neg_classes) * (i + 1));
+		if (trans->neg_classes == NULL)
+		  return REG_ESPACE;
+		for (i = 0; p1->neg_classes[i] != (tre_ctype_t)0; i++)
+		  trans->neg_classes[i] = p1->neg_classes[i];
+		trans->neg_classes[i] = (tre_ctype_t)0;
+	      }
+	    else
+	      trans->neg_classes = NULL;
+
+	    /* Find out how many tags this transition has. */
+	    i = 0;
+	    if (p1->tags != NULL)
+	      while(p1->tags[i] >= 0)
+		i++;
+	    j = 0;
+	    if (p2->tags != NULL)
+	      while(p2->tags[j] >= 0)
+		j++;
+
+	    /* If we are overwriting a transition, free the old tag array. */
+	    if (trans->tags != NULL)
+	      xfree(trans->tags);
+	    trans->tags = NULL;
+
+	    /* If there were any tags, allocate an array and fill it. */
+	    if (i + j > 0)
+	      {
+		trans->tags = xmalloc(sizeof(*trans->tags) * (i + j + 1));
+		if (!trans->tags)
+		  return REG_ESPACE;
+		i = 0;
+		if (p1->tags != NULL)
+		  while(p1->tags[i] >= 0)
+		    {
+		      trans->tags[i] = p1->tags[i];
+		      i++;
+		    }
+		l = i;
+		j = 0;
+		if (p2->tags != NULL)
+		  while (p2->tags[j] >= 0)
+		    {
+		      /* Don't add duplicates. */
+		      dup = 0;
+		      for (k = 0; k < i; k++)
+			if (trans->tags[k] == p2->tags[j])
+			  {
+			    dup = 1;
+			    break;
+			  }
+		      if (!dup)
+			trans->tags[l++] = p2->tags[j];
+		      j++;
+		    }
+		trans->tags[l] = -1;
+	      }
+
+	    p2++;
+	  }
+	p1++;
+      }
+  else
+    /* Compute a maximum limit for the number of transitions leaving
+       from each state. */
+    while (p1->position >= 0)
+      {
+	p2 = orig_p2;
+	while (p2->position >= 0)
+	  {
+	    counts[p1->position]++;
+	    p2++;
+	  }
+	p1++;
+      }
+  return REG_OK;
+}
+
+/* Converts the syntax tree to a TNFA.	All the transitions in the TNFA are
+   labelled with one character range (there are no transitions on empty
+   strings).  The TNFA takes O(n^2) space in the worst case, `n' is size of
+   the regexp. */
+static reg_errcode_t
+tre_ast_to_tnfa(tre_ast_node_t *node, tre_tnfa_transition_t *transitions,
+		int *counts, int *offs)
+{
+  tre_union_t *uni;
+  tre_catenation_t *cat;
+  tre_iteration_t *iter;
+  reg_errcode_t errcode = REG_OK;
+
+  /* XXX - recurse using a stack!. */
+  switch (node->type)
+    {
+    case LITERAL:
+      break;
+    case UNION:
+      uni = (tre_union_t *)node->obj;
+      errcode = tre_ast_to_tnfa(uni->left, transitions, counts, offs);
+      if (errcode != REG_OK)
+	return errcode;
+      errcode = tre_ast_to_tnfa(uni->right, transitions, counts, offs);
+      break;
+
+    case CATENATION:
+      cat = (tre_catenation_t *)node->obj;
+      /* Add a transition from each position in cat->left->lastpos
+	 to each position in cat->right->firstpos. */
+      errcode = tre_make_trans(cat->left->lastpos, cat->right->firstpos,
+			       transitions, counts, offs);
+      if (errcode != REG_OK)
+	return errcode;
+      errcode = tre_ast_to_tnfa(cat->left, transitions, counts, offs);
+      if (errcode != REG_OK)
+	return errcode;
+      errcode = tre_ast_to_tnfa(cat->right, transitions, counts, offs);
+      break;
+
+    case ITERATION:
+      iter = (tre_iteration_t *)node->obj;
+      assert(iter->max == -1 || iter->max == 1);
+
+      if (iter->max == -1)
+	{
+	  assert(iter->min == 0 || iter->min == 1);
+	  /* Add a transition from each last position in the iterated
+	     expression to each first position. */
+	  errcode = tre_make_trans(iter->arg->lastpos, iter->arg->firstpos,
+				   transitions, counts, offs);
+	  if (errcode != REG_OK)
+	    return errcode;
+	}
+      errcode = tre_ast_to_tnfa(iter->arg, transitions, counts, offs);
+      break;
+    }
+  return errcode;
+}
+
+
+#define ERROR_EXIT(err)		  \
+  do				  \
+    {				  \
+      errcode = err;		  \
+      if (/*CONSTCOND*/1)	  \
+      	goto error_exit;	  \
+    }				  \
+ while (/*CONSTCOND*/0)
+
+
+int
+regcomp(regex_t *restrict preg, const char *restrict regex, int cflags)
+{
+  tre_stack_t *stack;
+  tre_ast_node_t *tree, *tmp_ast_l, *tmp_ast_r;
+  tre_pos_and_tags_t *p;
+  int *counts = NULL, *offs = NULL;
+  int i, add = 0;
+  tre_tnfa_transition_t *transitions, *initial;
+  tre_tnfa_t *tnfa = NULL;
+  tre_submatch_data_t *submatch_data;
+  tre_tag_direction_t *tag_directions = NULL;
+  reg_errcode_t errcode;
+  tre_mem_t mem;
+
+  /* Parse context. */
+  tre_parse_ctx_t parse_ctx;
+
+  /* Allocate a stack used throughout the compilation process for various
+     purposes. */
+  stack = tre_stack_new(512, 1024000, 128);
+  if (!stack)
+    return REG_ESPACE;
+  /* Allocate a fast memory allocator. */
+  mem = tre_mem_new();
+  if (!mem)
+    {
+      tre_stack_destroy(stack);
+      return REG_ESPACE;
+    }
+
+  /* Parse the regexp. */
+  memset(&parse_ctx, 0, sizeof(parse_ctx));
+  parse_ctx.mem = mem;
+  parse_ctx.stack = stack;
+  parse_ctx.start = regex;
+  parse_ctx.cflags = cflags;
+  parse_ctx.max_backref = -1;
+  errcode = tre_parse(&parse_ctx);
+  if (errcode != REG_OK)
+    ERROR_EXIT(errcode);
+  preg->re_nsub = parse_ctx.submatch_id - 1;
+  tree = parse_ctx.n;
+
+#ifdef TRE_DEBUG
+  tre_ast_print(tree);
+#endif /* TRE_DEBUG */
+
+  /* Referring to nonexistent subexpressions is illegal. */
+  if (parse_ctx.max_backref > (int)preg->re_nsub)
+    ERROR_EXIT(REG_ESUBREG);
+
+  /* Allocate the TNFA struct. */
+  tnfa = xcalloc(1, sizeof(tre_tnfa_t));
+  if (tnfa == NULL)
+    ERROR_EXIT(REG_ESPACE);
+  tnfa->have_backrefs = parse_ctx.max_backref >= 0;
+  tnfa->have_approx = 0;
+  tnfa->num_submatches = parse_ctx.submatch_id;
+
+  /* Set up tags for submatch addressing.  If REG_NOSUB is set and the
+     regexp does not have back references, this can be skipped. */
+  if (tnfa->have_backrefs || !(cflags & REG_NOSUB))
+    {
+
+      /* Figure out how many tags we will need. */
+      errcode = tre_add_tags(NULL, stack, tree, tnfa);
+      if (errcode != REG_OK)
+	ERROR_EXIT(errcode);
+
+      if (tnfa->num_tags > 0)
+	{
+	  tag_directions = xmalloc(sizeof(*tag_directions)
+				   * (tnfa->num_tags + 1));
+	  if (tag_directions == NULL)
+	    ERROR_EXIT(REG_ESPACE);
+	  tnfa->tag_directions = tag_directions;
+	  memset(tag_directions, -1,
+		 sizeof(*tag_directions) * (tnfa->num_tags + 1));
+	}
+      tnfa->minimal_tags = xcalloc((unsigned)tnfa->num_tags * 2 + 1,
+				   sizeof(*tnfa->minimal_tags));
+      if (tnfa->minimal_tags == NULL)
+	ERROR_EXIT(REG_ESPACE);
+
+      submatch_data = xcalloc((unsigned)parse_ctx.submatch_id,
+			      sizeof(*submatch_data));
+      if (submatch_data == NULL)
+	ERROR_EXIT(REG_ESPACE);
+      tnfa->submatch_data = submatch_data;
+
+      errcode = tre_add_tags(mem, stack, tree, tnfa);
+      if (errcode != REG_OK)
+	ERROR_EXIT(errcode);
+
+    }
+
+  /* Expand iteration nodes. */
+  errcode = tre_expand_ast(mem, stack, tree, &parse_ctx.position,
+			   tag_directions);
+  if (errcode != REG_OK)
+    ERROR_EXIT(errcode);
+
+  /* Add a dummy node for the final state.
+     XXX - For certain patterns this dummy node can be optimized away,
+	   for example "a*" or "ab*".	Figure out a simple way to detect
+	   this possibility. */
+  tmp_ast_l = tree;
+  tmp_ast_r = tre_ast_new_literal(mem, 0, 0, parse_ctx.position++);
+  if (tmp_ast_r == NULL)
+    ERROR_EXIT(REG_ESPACE);
+
+  tree = tre_ast_new_catenation(mem, tmp_ast_l, tmp_ast_r);
+  if (tree == NULL)
+    ERROR_EXIT(REG_ESPACE);
+
+  errcode = tre_compute_nfl(mem, stack, tree);
+  if (errcode != REG_OK)
+    ERROR_EXIT(errcode);
+
+  counts = xmalloc(sizeof(int) * parse_ctx.position);
+  if (counts == NULL)
+    ERROR_EXIT(REG_ESPACE);
+
+  offs = xmalloc(sizeof(int) * parse_ctx.position);
+  if (offs == NULL)
+    ERROR_EXIT(REG_ESPACE);
+
+  for (i = 0; i < parse_ctx.position; i++)
+    counts[i] = 0;
+  tre_ast_to_tnfa(tree, NULL, counts, NULL);
+
+  add = 0;
+  for (i = 0; i < parse_ctx.position; i++)
+    {
+      offs[i] = add;
+      add += counts[i] + 1;
+      counts[i] = 0;
+    }
+  transitions = xcalloc((unsigned)add + 1, sizeof(*transitions));
+  if (transitions == NULL)
+    ERROR_EXIT(REG_ESPACE);
+  tnfa->transitions = transitions;
+  tnfa->num_transitions = add;
+
+  errcode = tre_ast_to_tnfa(tree, transitions, counts, offs);
+  if (errcode != REG_OK)
+    ERROR_EXIT(errcode);
+
+  tnfa->firstpos_chars = NULL;
+
+  p = tree->firstpos;
+  i = 0;
+  while (p->position >= 0)
+    {
+      i++;
+      p++;
+    }
+
+  initial = xcalloc((unsigned)i + 1, sizeof(tre_tnfa_transition_t));
+  if (initial == NULL)
+    ERROR_EXIT(REG_ESPACE);
+  tnfa->initial = initial;
+
+  i = 0;
+  for (p = tree->firstpos; p->position >= 0; p++)
+    {
+      initial[i].state = transitions + offs[p->position];
+      initial[i].state_id = p->position;
+      initial[i].tags = NULL;
+      /* Copy the arrays p->tags, and p->params, they are allocated
+	 from a tre_mem object. */
+      if (p->tags)
+	{
+	  int j;
+	  for (j = 0; p->tags[j] >= 0; j++);
+	  initial[i].tags = xmalloc(sizeof(*p->tags) * (j + 1));
+	  if (!initial[i].tags)
+	    ERROR_EXIT(REG_ESPACE);
+	  memcpy(initial[i].tags, p->tags, sizeof(*p->tags) * (j + 1));
+	}
+      initial[i].assertions = p->assertions;
+      i++;
+    }
+  initial[i].state = NULL;
+
+  tnfa->num_transitions = add;
+  tnfa->final = transitions + offs[tree->lastpos[0].position];
+  tnfa->num_states = parse_ctx.position;
+  tnfa->cflags = cflags;
+
+  tre_mem_destroy(mem);
+  tre_stack_destroy(stack);
+  xfree(counts);
+  xfree(offs);
+
+  preg->TRE_REGEX_T_FIELD = (void *)tnfa;
+  return REG_OK;
+
+ error_exit:
+  /* Free everything that was allocated and return the error code. */
+  tre_mem_destroy(mem);
+  if (stack != NULL)
+    tre_stack_destroy(stack);
+  if (counts != NULL)
+    xfree(counts);
+  if (offs != NULL)
+    xfree(offs);
+  preg->TRE_REGEX_T_FIELD = (void *)tnfa;
+  regfree(preg);
+  return errcode;
+}
+
+
+
+
+void
+regfree(regex_t *preg)
+{
+  tre_tnfa_t *tnfa;
+  unsigned int i;
+  tre_tnfa_transition_t *trans;
+
+  tnfa = (void *)preg->TRE_REGEX_T_FIELD;
+  if (!tnfa)
+    return;
+
+  for (i = 0; i < tnfa->num_transitions; i++)
+    if (tnfa->transitions[i].state)
+      {
+	if (tnfa->transitions[i].tags)
+	  xfree(tnfa->transitions[i].tags);
+	if (tnfa->transitions[i].neg_classes)
+	  xfree(tnfa->transitions[i].neg_classes);
+      }
+  if (tnfa->transitions)
+    xfree(tnfa->transitions);
+
+  if (tnfa->initial)
+    {
+      for (trans = tnfa->initial; trans->state; trans++)
+	{
+	  if (trans->tags)
+	    xfree(trans->tags);
+	}
+      xfree(tnfa->initial);
+    }
+
+  if (tnfa->submatch_data)
+    {
+      for (i = 0; i < tnfa->num_submatches; i++)
+	if (tnfa->submatch_data[i].parents)
+	  xfree(tnfa->submatch_data[i].parents);
+      xfree(tnfa->submatch_data);
+    }
+
+  if (tnfa->tag_directions)
+    xfree(tnfa->tag_directions);
+  if (tnfa->firstpos_chars)
+    xfree(tnfa->firstpos_chars);
+  if (tnfa->minimal_tags)
+    xfree(tnfa->minimal_tags);
+  xfree(tnfa);
+}
libc/musl/src/regex/regerror.c
@@ -0,0 +1,37 @@
+#include <string.h>
+#include <regex.h>
+#include <stdio.h>
+#include "locale_impl.h"
+
+/* Error message strings for error codes listed in `regex.h'.  This list
+   needs to be in sync with the codes listed there, naturally. */
+
+/* Converted to single string by Rich Felker to remove the need for
+ * data relocations at runtime, 27 Feb 2006. */
+
+static const char messages[] = {
+  "No error\0"
+  "No match\0"
+  "Invalid regexp\0"
+  "Unknown collating element\0"
+  "Unknown character class name\0"
+  "Trailing backslash\0"
+  "Invalid back reference\0"
+  "Missing ']'\0"
+  "Missing ')'\0"
+  "Missing '}'\0"
+  "Invalid contents of {}\0"
+  "Invalid character range\0"
+  "Out of memory\0"
+  "Repetition not preceded by valid expression\0"
+  "\0Unknown error"
+};
+
+size_t regerror(int e, const regex_t *restrict preg, char *restrict buf, size_t size)
+{
+	const char *s;
+	for (s=messages; e && *s; e--, s+=strlen(s)+1);
+	if (!*s) s++;
+	s = LCTRANS_CUR(s);
+	return 1+snprintf(buf, size, "%s", s);
+}
libc/musl/src/regex/regexec.c
@@ -0,0 +1,1028 @@
+/*
+  regexec.c - TRE POSIX compatible matching functions (and more).
+
+  Copyright (c) 2001-2009 Ville Laurikari <vl@iki.fi>
+  All rights reserved.
+
+  Redistribution and use in source and binary forms, with or without
+  modification, are permitted provided that the following conditions
+  are met:
+
+    1. Redistributions of source code must retain the above copyright
+       notice, this list of conditions and the following disclaimer.
+
+    2. Redistributions in binary form must reproduce the above copyright
+       notice, this list of conditions and the following disclaimer in the
+       documentation and/or other materials provided with the distribution.
+
+  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER AND CONTRIBUTORS
+  ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+  A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT
+  HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+*/
+
+#include <stdlib.h>
+#include <string.h>
+#include <wchar.h>
+#include <wctype.h>
+#include <limits.h>
+#include <stdint.h>
+
+#include <regex.h>
+
+#include "tre.h"
+
+#include <assert.h>
+
+static void
+tre_fill_pmatch(size_t nmatch, regmatch_t pmatch[], int cflags,
+		const tre_tnfa_t *tnfa, regoff_t *tags, regoff_t match_eo);
+
+/***********************************************************************
+ from tre-match-utils.h
+***********************************************************************/
+
+#define GET_NEXT_WCHAR() do {                                                 \
+    prev_c = next_c; pos += pos_add_next;                                     \
+    if ((pos_add_next = mbtowc(&next_c, str_byte, MB_LEN_MAX)) <= 0) {        \
+        if (pos_add_next < 0) { ret = REG_NOMATCH; goto error_exit; }         \
+        else pos_add_next++;                                                  \
+    }                                                                         \
+    str_byte += pos_add_next;                                                 \
+  } while (0)
+
+#define IS_WORD_CHAR(c)	 ((c) == L'_' || tre_isalnum(c))
+
+#define CHECK_ASSERTIONS(assertions)					      \
+  (((assertions & ASSERT_AT_BOL)					      \
+    && (pos > 0 || reg_notbol)						      \
+    && (prev_c != L'\n' || !reg_newline))				      \
+   || ((assertions & ASSERT_AT_EOL)					      \
+       && (next_c != L'\0' || reg_noteol)				      \
+       && (next_c != L'\n' || !reg_newline))				      \
+   || ((assertions & ASSERT_AT_BOW)					      \
+       && (IS_WORD_CHAR(prev_c) || !IS_WORD_CHAR(next_c)))	              \
+   || ((assertions & ASSERT_AT_EOW)					      \
+       && (!IS_WORD_CHAR(prev_c) || IS_WORD_CHAR(next_c)))		      \
+   || ((assertions & ASSERT_AT_WB)					      \
+       && (pos != 0 && next_c != L'\0'					      \
+	   && IS_WORD_CHAR(prev_c) == IS_WORD_CHAR(next_c)))		      \
+   || ((assertions & ASSERT_AT_WB_NEG)					      \
+       && (pos == 0 || next_c == L'\0'					      \
+	   || IS_WORD_CHAR(prev_c) != IS_WORD_CHAR(next_c))))
+
+#define CHECK_CHAR_CLASSES(trans_i, tnfa, eflags)                             \
+  (((trans_i->assertions & ASSERT_CHAR_CLASS)                                 \
+       && !(tnfa->cflags & REG_ICASE)                                         \
+       && !tre_isctype((tre_cint_t)prev_c, trans_i->u.class))                 \
+    || ((trans_i->assertions & ASSERT_CHAR_CLASS)                             \
+        && (tnfa->cflags & REG_ICASE)                                         \
+        && !tre_isctype(tre_tolower((tre_cint_t)prev_c),trans_i->u.class)     \
+	&& !tre_isctype(tre_toupper((tre_cint_t)prev_c),trans_i->u.class))    \
+    || ((trans_i->assertions & ASSERT_CHAR_CLASS_NEG)                         \
+        && tre_neg_char_classes_match(trans_i->neg_classes,(tre_cint_t)prev_c,\
+                                      tnfa->cflags & REG_ICASE)))
+
+
+
+
+/* Returns 1 if `t1' wins `t2', 0 otherwise. */
+static int
+tre_tag_order(int num_tags, tre_tag_direction_t *tag_directions,
+	      regoff_t *t1, regoff_t *t2)
+{
+  int i;
+  for (i = 0; i < num_tags; i++)
+    {
+      if (tag_directions[i] == TRE_TAG_MINIMIZE)
+	{
+	  if (t1[i] < t2[i])
+	    return 1;
+	  if (t1[i] > t2[i])
+	    return 0;
+	}
+      else
+	{
+	  if (t1[i] > t2[i])
+	    return 1;
+	  if (t1[i] < t2[i])
+	    return 0;
+	}
+    }
+  /*  assert(0);*/
+  return 0;
+}
+
+static int
+tre_neg_char_classes_match(tre_ctype_t *classes, tre_cint_t wc, int icase)
+{
+  while (*classes != (tre_ctype_t)0)
+    if ((!icase && tre_isctype(wc, *classes))
+	|| (icase && (tre_isctype(tre_toupper(wc), *classes)
+		      || tre_isctype(tre_tolower(wc), *classes))))
+      return 1; /* Match. */
+    else
+      classes++;
+  return 0; /* No match. */
+}
+
+
+/***********************************************************************
+ from tre-match-parallel.c
+***********************************************************************/
+
+/*
+  This algorithm searches for matches basically by reading characters
+  in the searched string one by one, starting at the beginning.	 All
+  matching paths in the TNFA are traversed in parallel.	 When two or
+  more paths reach the same state, exactly one is chosen according to
+  tag ordering rules; if returning submatches is not required it does
+  not matter which path is chosen.
+
+  The worst case time required for finding the leftmost and longest
+  match, or determining that there is no match, is always linearly
+  dependent on the length of the text being searched.
+
+  This algorithm cannot handle TNFAs with back referencing nodes.
+  See `tre-match-backtrack.c'.
+*/
+
+typedef struct {
+  tre_tnfa_transition_t *state;
+  regoff_t *tags;
+} tre_tnfa_reach_t;
+
+typedef struct {
+  regoff_t pos;
+  regoff_t **tags;
+} tre_reach_pos_t;
+
+
+static reg_errcode_t
+tre_tnfa_run_parallel(const tre_tnfa_t *tnfa, const void *string,
+		      regoff_t *match_tags, int eflags,
+		      regoff_t *match_end_ofs)
+{
+  /* State variables required by GET_NEXT_WCHAR. */
+  tre_char_t prev_c = 0, next_c = 0;
+  const char *str_byte = string;
+  regoff_t pos = -1;
+  regoff_t pos_add_next = 1;
+#ifdef TRE_MBSTATE
+  mbstate_t mbstate;
+#endif /* TRE_MBSTATE */
+  int reg_notbol = eflags & REG_NOTBOL;
+  int reg_noteol = eflags & REG_NOTEOL;
+  int reg_newline = tnfa->cflags & REG_NEWLINE;
+  reg_errcode_t ret;
+
+  char *buf;
+  tre_tnfa_transition_t *trans_i;
+  tre_tnfa_reach_t *reach, *reach_next, *reach_i, *reach_next_i;
+  tre_reach_pos_t *reach_pos;
+  int *tag_i;
+  int num_tags, i;
+
+  regoff_t match_eo = -1;	   /* end offset of match (-1 if no match found yet) */
+  int new_match = 0;
+  regoff_t *tmp_tags = NULL;
+  regoff_t *tmp_iptr;
+
+#ifdef TRE_MBSTATE
+  memset(&mbstate, '\0', sizeof(mbstate));
+#endif /* TRE_MBSTATE */
+
+  if (!match_tags)
+    num_tags = 0;
+  else
+    num_tags = tnfa->num_tags;
+
+  /* Allocate memory for temporary data required for matching.	This needs to
+     be done for every matching operation to be thread safe.  This allocates
+     everything in a single large block with calloc(). */
+  {
+    size_t tbytes, rbytes, pbytes, xbytes, total_bytes;
+    char *tmp_buf;
+
+    /* Ensure that tbytes and xbytes*num_states cannot overflow, and that
+     * they don't contribute more than 1/8 of SIZE_MAX to total_bytes. */
+    if (num_tags > SIZE_MAX/(8 * sizeof(regoff_t) * tnfa->num_states))
+      return REG_ESPACE;
+
+    /* Likewise check rbytes. */
+    if (tnfa->num_states+1 > SIZE_MAX/(8 * sizeof(*reach_next)))
+      return REG_ESPACE;
+
+    /* Likewise check pbytes. */
+    if (tnfa->num_states > SIZE_MAX/(8 * sizeof(*reach_pos)))
+      return REG_ESPACE;
+
+    /* Compute the length of the block we need. */
+    tbytes = sizeof(*tmp_tags) * num_tags;
+    rbytes = sizeof(*reach_next) * (tnfa->num_states + 1);
+    pbytes = sizeof(*reach_pos) * tnfa->num_states;
+    xbytes = sizeof(regoff_t) * num_tags;
+    total_bytes =
+      (sizeof(long) - 1) * 4 /* for alignment paddings */
+      + (rbytes + xbytes * tnfa->num_states) * 2 + tbytes + pbytes;
+
+    /* Allocate the memory. */
+    buf = calloc(total_bytes, 1);
+    if (buf == NULL)
+      return REG_ESPACE;
+
+    /* Get the various pointers within tmp_buf (properly aligned). */
+    tmp_tags = (void *)buf;
+    tmp_buf = buf + tbytes;
+    tmp_buf += ALIGN(tmp_buf, long);
+    reach_next = (void *)tmp_buf;
+    tmp_buf += rbytes;
+    tmp_buf += ALIGN(tmp_buf, long);
+    reach = (void *)tmp_buf;
+    tmp_buf += rbytes;
+    tmp_buf += ALIGN(tmp_buf, long);
+    reach_pos = (void *)tmp_buf;
+    tmp_buf += pbytes;
+    tmp_buf += ALIGN(tmp_buf, long);
+    for (i = 0; i < tnfa->num_states; i++)
+      {
+	reach[i].tags = (void *)tmp_buf;
+	tmp_buf += xbytes;
+	reach_next[i].tags = (void *)tmp_buf;
+	tmp_buf += xbytes;
+      }
+  }
+
+  for (i = 0; i < tnfa->num_states; i++)
+    reach_pos[i].pos = -1;
+
+  GET_NEXT_WCHAR();
+  pos = 0;
+
+  reach_next_i = reach_next;
+  while (1)
+    {
+      /* If no match found yet, add the initial states to `reach_next'. */
+      if (match_eo < 0)
+	{
+	  trans_i = tnfa->initial;
+	  while (trans_i->state != NULL)
+	    {
+	      if (reach_pos[trans_i->state_id].pos < pos)
+		{
+		  if (trans_i->assertions
+		      && CHECK_ASSERTIONS(trans_i->assertions))
+		    {
+		      trans_i++;
+		      continue;
+		    }
+
+		  reach_next_i->state = trans_i->state;
+		  for (i = 0; i < num_tags; i++)
+		    reach_next_i->tags[i] = -1;
+		  tag_i = trans_i->tags;
+		  if (tag_i)
+		    while (*tag_i >= 0)
+		      {
+			if (*tag_i < num_tags)
+			  reach_next_i->tags[*tag_i] = pos;
+			tag_i++;
+		      }
+		  if (reach_next_i->state == tnfa->final)
+		    {
+		      match_eo = pos;
+		      new_match = 1;
+		      for (i = 0; i < num_tags; i++)
+			match_tags[i] = reach_next_i->tags[i];
+		    }
+		  reach_pos[trans_i->state_id].pos = pos;
+		  reach_pos[trans_i->state_id].tags = &reach_next_i->tags;
+		  reach_next_i++;
+		}
+	      trans_i++;
+	    }
+	  reach_next_i->state = NULL;
+	}
+      else
+	{
+	  if (num_tags == 0 || reach_next_i == reach_next)
+	    /* We have found a match. */
+	    break;
+	}
+
+      /* Check for end of string. */
+      if (!next_c) break;
+
+      GET_NEXT_WCHAR();
+
+      /* Swap `reach' and `reach_next'. */
+      reach_i = reach;
+      reach = reach_next;
+      reach_next = reach_i;
+
+      /* For each state in `reach', weed out states that don't fulfill the
+	 minimal matching conditions. */
+      if (tnfa->num_minimals && new_match)
+	{
+	  new_match = 0;
+	  reach_next_i = reach_next;
+	  for (reach_i = reach; reach_i->state; reach_i++)
+	    {
+	      int skip = 0;
+	      for (i = 0; tnfa->minimal_tags[i] >= 0; i += 2)
+		{
+		  int end = tnfa->minimal_tags[i];
+		  int start = tnfa->minimal_tags[i + 1];
+		  if (end >= num_tags)
+		    {
+		      skip = 1;
+		      break;
+		    }
+		  else if (reach_i->tags[start] == match_tags[start]
+			   && reach_i->tags[end] < match_tags[end])
+		    {
+		      skip = 1;
+		      break;
+		    }
+		}
+	      if (!skip)
+		{
+		  reach_next_i->state = reach_i->state;
+		  tmp_iptr = reach_next_i->tags;
+		  reach_next_i->tags = reach_i->tags;
+		  reach_i->tags = tmp_iptr;
+		  reach_next_i++;
+		}
+	    }
+	  reach_next_i->state = NULL;
+
+	  /* Swap `reach' and `reach_next'. */
+	  reach_i = reach;
+	  reach = reach_next;
+	  reach_next = reach_i;
+	}
+
+      /* For each state in `reach' see if there is a transition leaving with
+	 the current input symbol to a state not yet in `reach_next', and
+	 add the destination states to `reach_next'. */
+      reach_next_i = reach_next;
+      for (reach_i = reach; reach_i->state; reach_i++)
+	{
+	  for (trans_i = reach_i->state; trans_i->state; trans_i++)
+	    {
+	      /* Does this transition match the input symbol? */
+	      if (trans_i->code_min <= (tre_cint_t)prev_c &&
+		  trans_i->code_max >= (tre_cint_t)prev_c)
+		{
+		  if (trans_i->assertions
+		      && (CHECK_ASSERTIONS(trans_i->assertions)
+			  || CHECK_CHAR_CLASSES(trans_i, tnfa, eflags)))
+		    {
+		      continue;
+		    }
+
+		  /* Compute the tags after this transition. */
+		  for (i = 0; i < num_tags; i++)
+		    tmp_tags[i] = reach_i->tags[i];
+		  tag_i = trans_i->tags;
+		  if (tag_i != NULL)
+		    while (*tag_i >= 0)
+		      {
+			if (*tag_i < num_tags)
+			  tmp_tags[*tag_i] = pos;
+			tag_i++;
+		      }
+
+		  if (reach_pos[trans_i->state_id].pos < pos)
+		    {
+		      /* Found an unvisited node. */
+		      reach_next_i->state = trans_i->state;
+		      tmp_iptr = reach_next_i->tags;
+		      reach_next_i->tags = tmp_tags;
+		      tmp_tags = tmp_iptr;
+		      reach_pos[trans_i->state_id].pos = pos;
+		      reach_pos[trans_i->state_id].tags = &reach_next_i->tags;
+
+		      if (reach_next_i->state == tnfa->final
+			  && (match_eo == -1
+			      || (num_tags > 0
+				  && reach_next_i->tags[0] <= match_tags[0])))
+			{
+			  match_eo = pos;
+			  new_match = 1;
+			  for (i = 0; i < num_tags; i++)
+			    match_tags[i] = reach_next_i->tags[i];
+			}
+		      reach_next_i++;
+
+		    }
+		  else
+		    {
+		      assert(reach_pos[trans_i->state_id].pos == pos);
+		      /* Another path has also reached this state.  We choose
+			 the winner by examining the tag values for both
+			 paths. */
+		      if (tre_tag_order(num_tags, tnfa->tag_directions,
+					tmp_tags,
+					*reach_pos[trans_i->state_id].tags))
+			{
+			  /* The new path wins. */
+			  tmp_iptr = *reach_pos[trans_i->state_id].tags;
+			  *reach_pos[trans_i->state_id].tags = tmp_tags;
+			  if (trans_i->state == tnfa->final)
+			    {
+			      match_eo = pos;
+			      new_match = 1;
+			      for (i = 0; i < num_tags; i++)
+				match_tags[i] = tmp_tags[i];
+			    }
+			  tmp_tags = tmp_iptr;
+			}
+		    }
+		}
+	    }
+	}
+      reach_next_i->state = NULL;
+    }
+
+  *match_end_ofs = match_eo;
+  ret = match_eo >= 0 ? REG_OK : REG_NOMATCH;
+error_exit:
+  xfree(buf);
+  return ret;
+}
+
+
+
+/***********************************************************************
+ from tre-match-backtrack.c
+***********************************************************************/
+
+/*
+  This matcher is for regexps that use back referencing.  Regexp matching
+  with back referencing is an NP-complete problem on the number of back
+  references.  The easiest way to match them is to use a backtracking
+  routine which basically goes through all possible paths in the TNFA
+  and chooses the one which results in the best (leftmost and longest)
+  match.  This can be spectacularly expensive and may run out of stack
+  space, but there really is no better known generic algorithm.	 Quoting
+  Henry Spencer from comp.compilers:
+  <URL: http://compilers.iecc.com/comparch/article/93-03-102>
+
+    POSIX.2 REs require longest match, which is really exciting to
+    implement since the obsolete ("basic") variant also includes
+    \<digit>.  I haven't found a better way of tackling this than doing
+    a preliminary match using a DFA (or simulation) on a modified RE
+    that just replicates subREs for \<digit>, and then doing a
+    backtracking match to determine whether the subRE matches were
+    right.  This can be rather slow, but I console myself with the
+    thought that people who use \<digit> deserve very slow execution.
+    (Pun unintentional but very appropriate.)
+
+*/
+
+typedef struct {
+  regoff_t pos;
+  const char *str_byte;
+  tre_tnfa_transition_t *state;
+  int state_id;
+  int next_c;
+  regoff_t *tags;
+#ifdef TRE_MBSTATE
+  mbstate_t mbstate;
+#endif /* TRE_MBSTATE */
+} tre_backtrack_item_t;
+
+typedef struct tre_backtrack_struct {
+  tre_backtrack_item_t item;
+  struct tre_backtrack_struct *prev;
+  struct tre_backtrack_struct *next;
+} *tre_backtrack_t;
+
+#ifdef TRE_MBSTATE
+#define BT_STACK_MBSTATE_IN  stack->item.mbstate = (mbstate)
+#define BT_STACK_MBSTATE_OUT (mbstate) = stack->item.mbstate
+#else /* !TRE_MBSTATE */
+#define BT_STACK_MBSTATE_IN
+#define BT_STACK_MBSTATE_OUT
+#endif /* !TRE_MBSTATE */
+
+#define tre_bt_mem_new		  tre_mem_new
+#define tre_bt_mem_alloc	  tre_mem_alloc
+#define tre_bt_mem_destroy	  tre_mem_destroy
+
+
+#define BT_STACK_PUSH(_pos, _str_byte, _str_wide, _state, _state_id, _next_c, _tags, _mbstate) \
+  do									      \
+    {									      \
+      int i;								      \
+      if (!stack->next)							      \
+	{								      \
+	  tre_backtrack_t s;						      \
+	  s = tre_bt_mem_alloc(mem, sizeof(*s));			      \
+	  if (!s)							      \
+	    {								      \
+	      tre_bt_mem_destroy(mem);					      \
+	      if (tags)							      \
+		xfree(tags);						      \
+	      if (pmatch)						      \
+		xfree(pmatch);						      \
+	      if (states_seen)						      \
+		xfree(states_seen);					      \
+	      return REG_ESPACE;					      \
+	    }								      \
+	  s->prev = stack;						      \
+	  s->next = NULL;						      \
+	  s->item.tags = tre_bt_mem_alloc(mem,				      \
+					  sizeof(*tags) * tnfa->num_tags);    \
+	  if (!s->item.tags)						      \
+	    {								      \
+	      tre_bt_mem_destroy(mem);					      \
+	      if (tags)							      \
+		xfree(tags);						      \
+	      if (pmatch)						      \
+		xfree(pmatch);						      \
+	      if (states_seen)						      \
+		xfree(states_seen);					      \
+	      return REG_ESPACE;					      \
+	    }								      \
+	  stack->next = s;						      \
+	  stack = s;							      \
+	}								      \
+      else								      \
+	stack = stack->next;						      \
+      stack->item.pos = (_pos);						      \
+      stack->item.str_byte = (_str_byte);				      \
+      stack->item.state = (_state);					      \
+      stack->item.state_id = (_state_id);				      \
+      stack->item.next_c = (_next_c);					      \
+      for (i = 0; i < tnfa->num_tags; i++)				      \
+	stack->item.tags[i] = (_tags)[i];				      \
+      BT_STACK_MBSTATE_IN;						      \
+    }									      \
+  while (0)
+
+#define BT_STACK_POP()							      \
+  do									      \
+    {									      \
+      int i;								      \
+      assert(stack->prev);						      \
+      pos = stack->item.pos;						      \
+      str_byte = stack->item.str_byte;					      \
+      state = stack->item.state;					      \
+      next_c = stack->item.next_c;					      \
+      for (i = 0; i < tnfa->num_tags; i++)				      \
+	tags[i] = stack->item.tags[i];					      \
+      BT_STACK_MBSTATE_OUT;						      \
+      stack = stack->prev;						      \
+    }									      \
+  while (0)
+
+#undef MIN
+#define MIN(a, b) ((a) <= (b) ? (a) : (b))
+
+static reg_errcode_t
+tre_tnfa_run_backtrack(const tre_tnfa_t *tnfa, const void *string,
+		       regoff_t *match_tags, int eflags, regoff_t *match_end_ofs)
+{
+  /* State variables required by GET_NEXT_WCHAR. */
+  tre_char_t prev_c = 0, next_c = 0;
+  const char *str_byte = string;
+  regoff_t pos = 0;
+  regoff_t pos_add_next = 1;
+#ifdef TRE_MBSTATE
+  mbstate_t mbstate;
+#endif /* TRE_MBSTATE */
+  int reg_notbol = eflags & REG_NOTBOL;
+  int reg_noteol = eflags & REG_NOTEOL;
+  int reg_newline = tnfa->cflags & REG_NEWLINE;
+
+  /* These are used to remember the necessary values of the above
+     variables to return to the position where the current search
+     started from. */
+  int next_c_start;
+  const char *str_byte_start;
+  regoff_t pos_start = -1;
+#ifdef TRE_MBSTATE
+  mbstate_t mbstate_start;
+#endif /* TRE_MBSTATE */
+
+  /* End offset of best match so far, or -1 if no match found yet. */
+  regoff_t match_eo = -1;
+  /* Tag arrays. */
+  int *next_tags;
+  regoff_t *tags = NULL;
+  /* Current TNFA state. */
+  tre_tnfa_transition_t *state;
+  int *states_seen = NULL;
+
+  /* Memory allocator to for allocating the backtracking stack. */
+  tre_mem_t mem = tre_bt_mem_new();
+
+  /* The backtracking stack. */
+  tre_backtrack_t stack;
+
+  tre_tnfa_transition_t *trans_i;
+  regmatch_t *pmatch = NULL;
+  int ret;
+
+#ifdef TRE_MBSTATE
+  memset(&mbstate, '\0', sizeof(mbstate));
+#endif /* TRE_MBSTATE */
+
+  if (!mem)
+    return REG_ESPACE;
+  stack = tre_bt_mem_alloc(mem, sizeof(*stack));
+  if (!stack)
+    {
+      ret = REG_ESPACE;
+      goto error_exit;
+    }
+  stack->prev = NULL;
+  stack->next = NULL;
+
+  if (tnfa->num_tags)
+    {
+      tags = xmalloc(sizeof(*tags) * tnfa->num_tags);
+      if (!tags)
+	{
+	  ret = REG_ESPACE;
+	  goto error_exit;
+	}
+    }
+  if (tnfa->num_submatches)
+    {
+      pmatch = xmalloc(sizeof(*pmatch) * tnfa->num_submatches);
+      if (!pmatch)
+	{
+	  ret = REG_ESPACE;
+	  goto error_exit;
+	}
+    }
+  if (tnfa->num_states)
+    {
+      states_seen = xmalloc(sizeof(*states_seen) * tnfa->num_states);
+      if (!states_seen)
+	{
+	  ret = REG_ESPACE;
+	  goto error_exit;
+	}
+    }
+
+ retry:
+  {
+    int i;
+    for (i = 0; i < tnfa->num_tags; i++)
+      {
+	tags[i] = -1;
+	if (match_tags)
+	  match_tags[i] = -1;
+      }
+    for (i = 0; i < tnfa->num_states; i++)
+      states_seen[i] = 0;
+  }
+
+  state = NULL;
+  pos = pos_start;
+  GET_NEXT_WCHAR();
+  pos_start = pos;
+  next_c_start = next_c;
+  str_byte_start = str_byte;
+#ifdef TRE_MBSTATE
+  mbstate_start = mbstate;
+#endif /* TRE_MBSTATE */
+
+  /* Handle initial states. */
+  next_tags = NULL;
+  for (trans_i = tnfa->initial; trans_i->state; trans_i++)
+    {
+      if (trans_i->assertions && CHECK_ASSERTIONS(trans_i->assertions))
+	{
+	  continue;
+	}
+      if (state == NULL)
+	{
+	  /* Start from this state. */
+	  state = trans_i->state;
+	  next_tags = trans_i->tags;
+	}
+      else
+	{
+	  /* Backtrack to this state. */
+	  BT_STACK_PUSH(pos, str_byte, 0, trans_i->state,
+			trans_i->state_id, next_c, tags, mbstate);
+	  {
+	    int *tmp = trans_i->tags;
+	    if (tmp)
+	      while (*tmp >= 0)
+		stack->item.tags[*tmp++] = pos;
+	  }
+	}
+    }
+
+  if (next_tags)
+    for (; *next_tags >= 0; next_tags++)
+      tags[*next_tags] = pos;
+
+
+  if (state == NULL)
+    goto backtrack;
+
+  while (1)
+    {
+      tre_tnfa_transition_t *next_state;
+      int empty_br_match;
+
+      if (state == tnfa->final)
+	{
+	  if (match_eo < pos
+	      || (match_eo == pos
+		  && match_tags
+		  && tre_tag_order(tnfa->num_tags, tnfa->tag_directions,
+				   tags, match_tags)))
+	    {
+	      int i;
+	      /* This match wins the previous match. */
+	      match_eo = pos;
+	      if (match_tags)
+		for (i = 0; i < tnfa->num_tags; i++)
+		  match_tags[i] = tags[i];
+	    }
+	  /* Our TNFAs never have transitions leaving from the final state,
+	     so we jump right to backtracking. */
+	  goto backtrack;
+	}
+
+      /* Go to the next character in the input string. */
+      empty_br_match = 0;
+      trans_i = state;
+      if (trans_i->state && trans_i->assertions & ASSERT_BACKREF)
+	{
+	  /* This is a back reference state.  All transitions leaving from
+	     this state have the same back reference "assertion".  Instead
+	     of reading the next character, we match the back reference. */
+	  regoff_t so, eo;
+	  int bt = trans_i->u.backref;
+	  regoff_t bt_len;
+	  int result;
+
+	  /* Get the substring we need to match against.  Remember to
+	     turn off REG_NOSUB temporarily. */
+	  tre_fill_pmatch(bt + 1, pmatch, tnfa->cflags & ~REG_NOSUB,
+			  tnfa, tags, pos);
+	  so = pmatch[bt].rm_so;
+	  eo = pmatch[bt].rm_eo;
+	  bt_len = eo - so;
+
+	  result = strncmp((const char*)string + so, str_byte - 1,
+				 (size_t)bt_len);
+
+	  if (result == 0)
+	    {
+	      /* Back reference matched.  Check for infinite loop. */
+	      if (bt_len == 0)
+		empty_br_match = 1;
+	      if (empty_br_match && states_seen[trans_i->state_id])
+		{
+		  goto backtrack;
+		}
+
+	      states_seen[trans_i->state_id] = empty_br_match;
+
+	      /* Advance in input string and resync `prev_c', `next_c'
+		 and pos. */
+	      str_byte += bt_len - 1;
+	      pos += bt_len - 1;
+	      GET_NEXT_WCHAR();
+	    }
+	  else
+	    {
+	      goto backtrack;
+	    }
+	}
+      else
+	{
+	  /* Check for end of string. */
+	  if (next_c == L'\0')
+		goto backtrack;
+
+	  /* Read the next character. */
+	  GET_NEXT_WCHAR();
+	}
+
+      next_state = NULL;
+      for (trans_i = state; trans_i->state; trans_i++)
+	{
+	  if (trans_i->code_min <= (tre_cint_t)prev_c
+	      && trans_i->code_max >= (tre_cint_t)prev_c)
+	    {
+	      if (trans_i->assertions
+		  && (CHECK_ASSERTIONS(trans_i->assertions)
+		      || CHECK_CHAR_CLASSES(trans_i, tnfa, eflags)))
+		{
+		  continue;
+		}
+
+	      if (next_state == NULL)
+		{
+		  /* First matching transition. */
+		  next_state = trans_i->state;
+		  next_tags = trans_i->tags;
+		}
+	      else
+		{
+		  /* Second matching transition.  We may need to backtrack here
+		     to take this transition instead of the first one, so we
+		     push this transition in the backtracking stack so we can
+		     jump back here if needed. */
+		  BT_STACK_PUSH(pos, str_byte, 0, trans_i->state,
+				trans_i->state_id, next_c, tags, mbstate);
+		  {
+		    int *tmp;
+		    for (tmp = trans_i->tags; tmp && *tmp >= 0; tmp++)
+		      stack->item.tags[*tmp] = pos;
+		  }
+#if 0 /* XXX - it's important not to look at all transitions here to keep
+	 the stack small! */
+		  break;
+#endif
+		}
+	    }
+	}
+
+      if (next_state != NULL)
+	{
+	  /* Matching transitions were found.  Take the first one. */
+	  state = next_state;
+
+	  /* Update the tag values. */
+	  if (next_tags)
+	    while (*next_tags >= 0)
+	      tags[*next_tags++] = pos;
+	}
+      else
+	{
+	backtrack:
+	  /* A matching transition was not found.  Try to backtrack. */
+	  if (stack->prev)
+	    {
+	      if (stack->item.state->assertions & ASSERT_BACKREF)
+		{
+		  states_seen[stack->item.state_id] = 0;
+		}
+
+	      BT_STACK_POP();
+	    }
+	  else if (match_eo < 0)
+	    {
+	      /* Try starting from a later position in the input string. */
+	      /* Check for end of string. */
+	      if (next_c == L'\0')
+		    {
+		      break;
+		    }
+	      next_c = next_c_start;
+#ifdef TRE_MBSTATE
+	      mbstate = mbstate_start;
+#endif /* TRE_MBSTATE */
+	      str_byte = str_byte_start;
+	      goto retry;
+	    }
+	  else
+	    {
+	      break;
+	    }
+	}
+    }
+
+  ret = match_eo >= 0 ? REG_OK : REG_NOMATCH;
+  *match_end_ofs = match_eo;
+
+ error_exit:
+  tre_bt_mem_destroy(mem);
+#ifndef TRE_USE_ALLOCA
+  if (tags)
+    xfree(tags);
+  if (pmatch)
+    xfree(pmatch);
+  if (states_seen)
+    xfree(states_seen);
+#endif /* !TRE_USE_ALLOCA */
+
+  return ret;
+}
+
+/***********************************************************************
+ from regexec.c
+***********************************************************************/
+
+/* Fills the POSIX.2 regmatch_t array according to the TNFA tag and match
+   endpoint values. */
+static void
+tre_fill_pmatch(size_t nmatch, regmatch_t pmatch[], int cflags,
+		const tre_tnfa_t *tnfa, regoff_t *tags, regoff_t match_eo)
+{
+  tre_submatch_data_t *submatch_data;
+  unsigned int i, j;
+  int *parents;
+
+  i = 0;
+  if (match_eo >= 0 && !(cflags & REG_NOSUB))
+    {
+      /* Construct submatch offsets from the tags. */
+      submatch_data = tnfa->submatch_data;
+      while (i < tnfa->num_submatches && i < nmatch)
+	{
+	  if (submatch_data[i].so_tag == tnfa->end_tag)
+	    pmatch[i].rm_so = match_eo;
+	  else
+	    pmatch[i].rm_so = tags[submatch_data[i].so_tag];
+
+	  if (submatch_data[i].eo_tag == tnfa->end_tag)
+	    pmatch[i].rm_eo = match_eo;
+	  else
+	    pmatch[i].rm_eo = tags[submatch_data[i].eo_tag];
+
+	  /* If either of the endpoints were not used, this submatch
+	     was not part of the match. */
+	  if (pmatch[i].rm_so == -1 || pmatch[i].rm_eo == -1)
+	    pmatch[i].rm_so = pmatch[i].rm_eo = -1;
+
+	  i++;
+	}
+      /* Reset all submatches that are not within all of their parent
+	 submatches. */
+      i = 0;
+      while (i < tnfa->num_submatches && i < nmatch)
+	{
+	  if (pmatch[i].rm_eo == -1)
+	    assert(pmatch[i].rm_so == -1);
+	  assert(pmatch[i].rm_so <= pmatch[i].rm_eo);
+
+	  parents = submatch_data[i].parents;
+	  if (parents != NULL)
+	    for (j = 0; parents[j] >= 0; j++)
+	      {
+		if (pmatch[i].rm_so < pmatch[parents[j]].rm_so
+		    || pmatch[i].rm_eo > pmatch[parents[j]].rm_eo)
+		  pmatch[i].rm_so = pmatch[i].rm_eo = -1;
+	      }
+	  i++;
+	}
+    }
+
+  while (i < nmatch)
+    {
+      pmatch[i].rm_so = -1;
+      pmatch[i].rm_eo = -1;
+      i++;
+    }
+}
+
+
+/*
+  Wrapper functions for POSIX compatible regexp matching.
+*/
+
+int
+regexec(const regex_t *restrict preg, const char *restrict string,
+	  size_t nmatch, regmatch_t pmatch[restrict], int eflags)
+{
+  tre_tnfa_t *tnfa = (void *)preg->TRE_REGEX_T_FIELD;
+  reg_errcode_t status;
+  regoff_t *tags = NULL, eo;
+  if (tnfa->cflags & REG_NOSUB) nmatch = 0;
+  if (tnfa->num_tags > 0 && nmatch > 0)
+    {
+      tags = xmalloc(sizeof(*tags) * tnfa->num_tags);
+      if (tags == NULL)
+	return REG_ESPACE;
+    }
+
+  /* Dispatch to the appropriate matcher. */
+  if (tnfa->have_backrefs)
+    {
+      /* The regex has back references, use the backtracking matcher. */
+      status = tre_tnfa_run_backtrack(tnfa, string, tags, eflags, &eo);
+    }
+  else
+    {
+      /* Exact matching, no back references, use the parallel matcher. */
+      status = tre_tnfa_run_parallel(tnfa, string, tags, eflags, &eo);
+    }
+
+  if (status == REG_OK)
+    /* A match was found, so fill the submatch registers. */
+    tre_fill_pmatch(nmatch, pmatch, tnfa->cflags, tnfa, tags, eo);
+  if (tags)
+    xfree(tags);
+  return status;
+}
libc/musl/src/regex/tre-mem.c
@@ -0,0 +1,158 @@
+/*
+  tre-mem.c - TRE memory allocator
+
+  Copyright (c) 2001-2009 Ville Laurikari <vl@iki.fi>
+  All rights reserved.
+
+  Redistribution and use in source and binary forms, with or without
+  modification, are permitted provided that the following conditions
+  are met:
+
+    1. Redistributions of source code must retain the above copyright
+       notice, this list of conditions and the following disclaimer.
+
+    2. Redistributions in binary form must reproduce the above copyright
+       notice, this list of conditions and the following disclaimer in the
+       documentation and/or other materials provided with the distribution.
+
+  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER AND CONTRIBUTORS
+  ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+  A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT
+  HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+*/
+
+/*
+  This memory allocator is for allocating small memory blocks efficiently
+  in terms of memory overhead and execution speed.  The allocated blocks
+  cannot be freed individually, only all at once.  There can be multiple
+  allocators, though.
+*/
+
+#include <stdlib.h>
+#include <string.h>
+
+#include "tre.h"
+
+/*
+  This memory allocator is for allocating small memory blocks efficiently
+  in terms of memory overhead and execution speed.  The allocated blocks
+  cannot be freed individually, only all at once.  There can be multiple
+  allocators, though.
+*/
+
+/* Returns a new memory allocator or NULL if out of memory. */
+tre_mem_t
+tre_mem_new_impl(int provided, void *provided_block)
+{
+  tre_mem_t mem;
+  if (provided)
+    {
+      mem = provided_block;
+      memset(mem, 0, sizeof(*mem));
+    }
+  else
+    mem = xcalloc(1, sizeof(*mem));
+  if (mem == NULL)
+    return NULL;
+  return mem;
+}
+
+
+/* Frees the memory allocator and all memory allocated with it. */
+void
+tre_mem_destroy(tre_mem_t mem)
+{
+  tre_list_t *tmp, *l = mem->blocks;
+
+  while (l != NULL)
+    {
+      xfree(l->data);
+      tmp = l->next;
+      xfree(l);
+      l = tmp;
+    }
+  xfree(mem);
+}
+
+
+/* Allocates a block of `size' bytes from `mem'.  Returns a pointer to the
+   allocated block or NULL if an underlying malloc() failed. */
+void *
+tre_mem_alloc_impl(tre_mem_t mem, int provided, void *provided_block,
+		   int zero, size_t size)
+{
+  void *ptr;
+
+  if (mem->failed)
+    {
+      return NULL;
+    }
+
+  if (mem->n < size)
+    {
+      /* We need more memory than is available in the current block.
+	 Allocate a new block. */
+      tre_list_t *l;
+      if (provided)
+	{
+	  if (provided_block == NULL)
+	    {
+	      mem->failed = 1;
+	      return NULL;
+	    }
+	  mem->ptr = provided_block;
+	  mem->n = TRE_MEM_BLOCK_SIZE;
+	}
+      else
+	{
+	  int block_size;
+	  if (size * 8 > TRE_MEM_BLOCK_SIZE)
+	    block_size = size * 8;
+	  else
+	    block_size = TRE_MEM_BLOCK_SIZE;
+	  l = xmalloc(sizeof(*l));
+	  if (l == NULL)
+	    {
+	      mem->failed = 1;
+	      return NULL;
+	    }
+	  l->data = xmalloc(block_size);
+	  if (l->data == NULL)
+	    {
+	      xfree(l);
+	      mem->failed = 1;
+	      return NULL;
+	    }
+	  l->next = NULL;
+	  if (mem->current != NULL)
+	    mem->current->next = l;
+	  if (mem->blocks == NULL)
+	    mem->blocks = l;
+	  mem->current = l;
+	  mem->ptr = l->data;
+	  mem->n = block_size;
+	}
+    }
+
+  /* Make sure the next pointer will be aligned. */
+  size += ALIGN(mem->ptr + size, long);
+
+  /* Allocate from current block. */
+  ptr = mem->ptr;
+  mem->ptr += size;
+  mem->n -= size;
+
+  /* Set to zero if needed. */
+  if (zero)
+    memset(ptr, 0, size);
+
+  return ptr;
+}
libc/musl/src/regex/tre.h
@@ -0,0 +1,231 @@
+/*
+  tre-internal.h - TRE internal definitions
+
+  Copyright (c) 2001-2009 Ville Laurikari <vl@iki.fi>
+  All rights reserved.
+
+  Redistribution and use in source and binary forms, with or without
+  modification, are permitted provided that the following conditions
+  are met:
+
+    1. Redistributions of source code must retain the above copyright
+       notice, this list of conditions and the following disclaimer.
+
+    2. Redistributions in binary form must reproduce the above copyright
+       notice, this list of conditions and the following disclaimer in the
+       documentation and/or other materials provided with the distribution.
+
+  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER AND CONTRIBUTORS
+  ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+  A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT
+  HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+*/
+
+#include <regex.h>
+#include <wchar.h>
+#include <wctype.h>
+
+#undef  TRE_MBSTATE
+
+#define NDEBUG
+
+#define TRE_REGEX_T_FIELD __opaque
+typedef int reg_errcode_t;
+
+typedef wchar_t tre_char_t;
+
+#define DPRINT(msg) do { } while(0)
+
+#define elementsof(x)	( sizeof(x) / sizeof(x[0]) )
+
+#define tre_mbrtowc(pwc, s, n, ps) (mbtowc((pwc), (s), (n)))
+
+/* Wide characters. */
+typedef wint_t tre_cint_t;
+#define TRE_CHAR_MAX 0x10ffff
+
+#define tre_isalnum iswalnum
+#define tre_isalpha iswalpha
+#define tre_isblank iswblank
+#define tre_iscntrl iswcntrl
+#define tre_isdigit iswdigit
+#define tre_isgraph iswgraph
+#define tre_islower iswlower
+#define tre_isprint iswprint
+#define tre_ispunct iswpunct
+#define tre_isspace iswspace
+#define tre_isupper iswupper
+#define tre_isxdigit iswxdigit
+
+#define tre_tolower towlower
+#define tre_toupper towupper
+#define tre_strlen  wcslen
+
+/* Use system provided iswctype() and wctype(). */
+typedef wctype_t tre_ctype_t;
+#define tre_isctype iswctype
+#define tre_ctype   wctype
+
+/* Returns number of bytes to add to (char *)ptr to make it
+   properly aligned for the type. */
+#define ALIGN(ptr, type) \
+  ((((long)ptr) % sizeof(type)) \
+   ? (sizeof(type) - (((long)ptr) % sizeof(type))) \
+   : 0)
+
+#undef MAX
+#undef MIN
+#define MAX(a, b) (((a) >= (b)) ? (a) : (b))
+#define MIN(a, b) (((a) <= (b)) ? (a) : (b))
+
+/* TNFA transition type. A TNFA state is an array of transitions,
+   the terminator is a transition with NULL `state'. */
+typedef struct tnfa_transition tre_tnfa_transition_t;
+
+struct tnfa_transition {
+  /* Range of accepted characters. */
+  tre_cint_t code_min;
+  tre_cint_t code_max;
+  /* Pointer to the destination state. */
+  tre_tnfa_transition_t *state;
+  /* ID number of the destination state. */
+  int state_id;
+  /* -1 terminated array of tags (or NULL). */
+  int *tags;
+  /* Assertion bitmap. */
+  int assertions;
+  /* Assertion parameters. */
+  union {
+    /* Character class assertion. */
+    tre_ctype_t class;
+    /* Back reference assertion. */
+    int backref;
+  } u;
+  /* Negative character class assertions. */
+  tre_ctype_t *neg_classes;
+};
+
+
+/* Assertions. */
+#define ASSERT_AT_BOL		  1   /* Beginning of line. */
+#define ASSERT_AT_EOL		  2   /* End of line. */
+#define ASSERT_CHAR_CLASS	  4   /* Character class in `class'. */
+#define ASSERT_CHAR_CLASS_NEG	  8   /* Character classes in `neg_classes'. */
+#define ASSERT_AT_BOW		 16   /* Beginning of word. */
+#define ASSERT_AT_EOW		 32   /* End of word. */
+#define ASSERT_AT_WB		 64   /* Word boundary. */
+#define ASSERT_AT_WB_NEG	128   /* Not a word boundary. */
+#define ASSERT_BACKREF		256   /* A back reference in `backref'. */
+#define ASSERT_LAST		256
+
+/* Tag directions. */
+typedef enum {
+  TRE_TAG_MINIMIZE = 0,
+  TRE_TAG_MAXIMIZE = 1
+} tre_tag_direction_t;
+
+/* Instructions to compute submatch register values from tag values
+   after a successful match.  */
+struct tre_submatch_data {
+  /* Tag that gives the value for rm_so (submatch start offset). */
+  int so_tag;
+  /* Tag that gives the value for rm_eo (submatch end offset). */
+  int eo_tag;
+  /* List of submatches this submatch is contained in. */
+  int *parents;
+};
+
+typedef struct tre_submatch_data tre_submatch_data_t;
+
+
+/* TNFA definition. */
+typedef struct tnfa tre_tnfa_t;
+
+struct tnfa {
+  tre_tnfa_transition_t *transitions;
+  unsigned int num_transitions;
+  tre_tnfa_transition_t *initial;
+  tre_tnfa_transition_t *final;
+  tre_submatch_data_t *submatch_data;
+  char *firstpos_chars;
+  int first_char;
+  unsigned int num_submatches;
+  tre_tag_direction_t *tag_directions;
+  int *minimal_tags;
+  int num_tags;
+  int num_minimals;
+  int end_tag;
+  int num_states;
+  int cflags;
+  int have_backrefs;
+  int have_approx;
+};
+
+/* from tre-mem.h: */
+
+#define TRE_MEM_BLOCK_SIZE 1024
+
+typedef struct tre_list {
+  void *data;
+  struct tre_list *next;
+} tre_list_t;
+
+typedef struct tre_mem_struct {
+  tre_list_t *blocks;
+  tre_list_t *current;
+  char *ptr;
+  size_t n;
+  int failed;
+  void **provided;
+} *tre_mem_t;
+
+#define tre_mem_new_impl   __tre_mem_new_impl
+#define tre_mem_alloc_impl __tre_mem_alloc_impl
+#define tre_mem_destroy    __tre_mem_destroy
+
+hidden tre_mem_t tre_mem_new_impl(int provided, void *provided_block);
+hidden void *tre_mem_alloc_impl(tre_mem_t mem, int provided, void *provided_block,
+                                int zero, size_t size);
+
+/* Returns a new memory allocator or NULL if out of memory. */
+#define tre_mem_new()  tre_mem_new_impl(0, NULL)
+
+/* Allocates a block of `size' bytes from `mem'.  Returns a pointer to the
+   allocated block or NULL if an underlying malloc() failed. */
+#define tre_mem_alloc(mem, size) tre_mem_alloc_impl(mem, 0, NULL, 0, size)
+
+/* Allocates a block of `size' bytes from `mem'.  Returns a pointer to the
+   allocated block or NULL if an underlying malloc() failed.  The memory
+   is set to zero. */
+#define tre_mem_calloc(mem, size) tre_mem_alloc_impl(mem, 0, NULL, 1, size)
+
+#ifdef TRE_USE_ALLOCA
+/* alloca() versions.  Like above, but memory is allocated with alloca()
+   instead of malloc(). */
+
+#define tre_mem_newa() \
+  tre_mem_new_impl(1, alloca(sizeof(struct tre_mem_struct)))
+
+#define tre_mem_alloca(mem, size)					      \
+  ((mem)->n >= (size)							      \
+   ? tre_mem_alloc_impl((mem), 1, NULL, 0, (size))			      \
+   : tre_mem_alloc_impl((mem), 1, alloca(TRE_MEM_BLOCK_SIZE), 0, (size)))
+#endif /* TRE_USE_ALLOCA */
+
+
+/* Frees the memory allocator and all memory allocated with it. */
+hidden void tre_mem_destroy(tre_mem_t mem);
+
+#define xmalloc malloc
+#define xcalloc calloc
+#define xfree free
+#define xrealloc realloc
+
libc/musl/src/sched/affinity.c
@@ -0,0 +1,33 @@
+#define _GNU_SOURCE
+#include <sched.h>
+#include <string.h>
+#include "pthread_impl.h"
+#include "syscall.h"
+
+int sched_setaffinity(pid_t tid, size_t size, const cpu_set_t *set)
+{
+	return syscall(SYS_sched_setaffinity, tid, size, set);
+}
+
+int pthread_setaffinity_np(pthread_t td, size_t size, const cpu_set_t *set)
+{
+	return -__syscall(SYS_sched_setaffinity, td->tid, size, set);
+}
+
+static int do_getaffinity(pid_t tid, size_t size, cpu_set_t *set)
+{
+	long ret = __syscall(SYS_sched_getaffinity, tid, size, set);
+	if (ret < 0) return ret;
+	if (ret < size) memset((char *)set+ret, 0, size-ret);
+	return 0;
+}
+
+int sched_getaffinity(pid_t tid, size_t size, cpu_set_t *set)
+{
+	return __syscall_ret(do_getaffinity(tid, size, set));
+}
+
+int pthread_getaffinity_np(pthread_t td, size_t size, cpu_set_t *set)
+{
+	return -do_getaffinity(td->tid, size, set);
+}
libc/musl/src/sched/sched_cpucount.c
@@ -0,0 +1,11 @@
+#define _GNU_SOURCE
+#include <sched.h>
+
+int __sched_cpucount(size_t size, const cpu_set_t *set)
+{
+	size_t i, j, cnt=0;
+	const unsigned char *p = (const void *)set;
+	for (i=0; i<size; i++) for (j=0; j<8; j++)
+		if (p[i] & (1<<j)) cnt++;
+	return cnt;
+}
libc/musl/src/sched/sched_get_priority_max.c
@@ -0,0 +1,12 @@
+#include <sched.h>
+#include "syscall.h"
+
+int sched_get_priority_max(int policy)
+{
+	return syscall(SYS_sched_get_priority_max, policy);
+}
+
+int sched_get_priority_min(int policy)
+{
+	return syscall(SYS_sched_get_priority_min, policy);
+}
libc/musl/src/sched/sched_getcpu.c
@@ -0,0 +1,42 @@
+#define _GNU_SOURCE
+#include <errno.h>
+#include <sched.h>
+#include "syscall.h"
+#include "atomic.h"
+
+#ifdef VDSO_GETCPU_SYM
+
+static void *volatile vdso_func;
+
+typedef long (*getcpu_f)(unsigned *, unsigned *, void *);
+
+static long getcpu_init(unsigned *cpu, unsigned *node, void *unused)
+{
+	void *p = __vdsosym(VDSO_GETCPU_VER, VDSO_GETCPU_SYM);
+	getcpu_f f = (getcpu_f)p;
+	a_cas_p(&vdso_func, (void *)getcpu_init, p);
+	return f ? f(cpu, node, unused) : -ENOSYS;
+}
+
+static void *volatile vdso_func = (void *)getcpu_init;
+
+#endif
+
+int sched_getcpu(void)
+{
+	int r;
+	unsigned cpu;
+
+#ifdef VDSO_GETCPU_SYM
+	getcpu_f f = (getcpu_f)vdso_func;
+	if (f) {
+		r = f(&cpu, 0, 0);
+		if (!r) return cpu;
+		if (r != -ENOSYS) return __syscall_ret(r);
+	}
+#endif
+
+	r = __syscall(SYS_getcpu, &cpu, 0, 0);
+	if (!r) return cpu;
+	return __syscall_ret(r);
+}
libc/musl/src/sched/sched_getparam.c
@@ -0,0 +1,8 @@
+#include <sched.h>
+#include <errno.h>
+#include "syscall.h"
+
+int sched_getparam(pid_t pid, struct sched_param *param)
+{
+	return __syscall_ret(-ENOSYS);
+}
libc/musl/src/sched/sched_getscheduler.c
@@ -0,0 +1,8 @@
+#include <sched.h>
+#include <errno.h>
+#include "syscall.h"
+
+int sched_getscheduler(pid_t pid)
+{
+	return __syscall_ret(-ENOSYS);
+}
libc/musl/src/sched/sched_rr_get_interval.c
@@ -0,0 +1,7 @@
+#include <sched.h>
+#include "syscall.h"
+
+int sched_rr_get_interval(pid_t pid, struct timespec *ts)
+{
+	return syscall(SYS_sched_rr_get_interval, pid, ts);
+}
libc/musl/src/sched/sched_setparam.c
@@ -0,0 +1,8 @@
+#include <sched.h>
+#include <errno.h>
+#include "syscall.h"
+
+int sched_setparam(pid_t pid, const struct sched_param *param)
+{
+	return __syscall_ret(-ENOSYS);
+}
libc/musl/src/sched/sched_setscheduler.c
@@ -0,0 +1,8 @@
+#include <sched.h>
+#include <errno.h>
+#include "syscall.h"
+
+int sched_setscheduler(pid_t pid, int sched, const struct sched_param *param)
+{
+	return __syscall_ret(-ENOSYS);
+}
libc/musl/src/sched/sched_yield.c
@@ -0,0 +1,7 @@
+#include <sched.h>
+#include "syscall.h"
+
+int sched_yield()
+{
+	return syscall(SYS_sched_yield);
+}
libc/musl/src/search/hsearch.c
@@ -0,0 +1,153 @@
+#define _GNU_SOURCE
+#include <stdlib.h>
+#include <string.h>
+#include <search.h>
+
+/*
+open addressing hash table with 2^n table size
+quadratic probing is used in case of hash collision
+tab indices and hash are size_t
+after resize fails with ENOMEM the state of tab is still usable
+
+with the posix api items cannot be iterated and length cannot be queried
+*/
+
+#define MINSIZE 8
+#define MAXSIZE ((size_t)-1/2 + 1)
+
+struct __tab {
+	ENTRY *entries;
+	size_t mask;
+	size_t used;
+};
+
+static struct hsearch_data htab;
+
+static int __hcreate_r(size_t, struct hsearch_data *);
+static void __hdestroy_r(struct hsearch_data *);
+static int __hsearch_r(ENTRY, ACTION, ENTRY **, struct hsearch_data *);
+
+static size_t keyhash(char *k)
+{
+	unsigned char *p = (void *)k;
+	size_t h = 0;
+
+	while (*p)
+		h = 31*h + *p++;
+	return h;
+}
+
+static int resize(size_t nel, struct hsearch_data *htab)
+{
+	size_t newsize;
+	size_t i, j;
+	ENTRY *e, *newe;
+	ENTRY *oldtab = htab->__tab->entries;
+	ENTRY *oldend = htab->__tab->entries + htab->__tab->mask + 1;
+
+	if (nel > MAXSIZE)
+		nel = MAXSIZE;
+	for (newsize = MINSIZE; newsize < nel; newsize *= 2);
+	htab->__tab->entries = calloc(newsize, sizeof *htab->__tab->entries);
+	if (!htab->__tab->entries) {
+		htab->__tab->entries = oldtab;
+		return 0;
+	}
+	htab->__tab->mask = newsize - 1;
+	if (!oldtab)
+		return 1;
+	for (e = oldtab; e < oldend; e++)
+		if (e->key) {
+			for (i=keyhash(e->key),j=1; ; i+=j++) {
+				newe = htab->__tab->entries + (i & htab->__tab->mask);
+				if (!newe->key)
+					break;
+			}
+			*newe = *e;
+		}
+	free(oldtab);
+	return 1;
+}
+
+int hcreate(size_t nel)
+{
+	return __hcreate_r(nel, &htab);
+}
+
+void hdestroy(void)
+{
+	__hdestroy_r(&htab);
+}
+
+static ENTRY *lookup(char *key, size_t hash, struct hsearch_data *htab)
+{
+	size_t i, j;
+	ENTRY *e;
+
+	for (i=hash,j=1; ; i+=j++) {
+		e = htab->__tab->entries + (i & htab->__tab->mask);
+		if (!e->key || strcmp(e->key, key) == 0)
+			break;
+	}
+	return e;
+}
+
+ENTRY *hsearch(ENTRY item, ACTION action)
+{
+	ENTRY *e;
+
+	__hsearch_r(item, action, &e, &htab);
+	return e;
+}
+
+static int __hcreate_r(size_t nel, struct hsearch_data *htab)
+{
+	int r;
+
+	htab->__tab = calloc(1, sizeof *htab->__tab);
+	if (!htab->__tab)
+		return 0;
+	r = resize(nel, htab);
+	if (r == 0) {
+		free(htab->__tab);
+		htab->__tab = 0;
+	}
+	return r;
+}
+weak_alias(__hcreate_r, hcreate_r);
+
+static void __hdestroy_r(struct hsearch_data *htab)
+{
+	if (htab->__tab) free(htab->__tab->entries);
+	free(htab->__tab);
+	htab->__tab = 0;
+}
+weak_alias(__hdestroy_r, hdestroy_r);
+
+static int __hsearch_r(ENTRY item, ACTION action, ENTRY **retval, struct hsearch_data *htab)
+{
+	size_t hash = keyhash(item.key);
+	ENTRY *e = lookup(item.key, hash, htab);
+
+	if (e->key) {
+		*retval = e;
+		return 1;
+	}
+	if (action == FIND) {
+		*retval = 0;
+		return 0;
+	}
+	*e = item;
+	if (++htab->__tab->used > htab->__tab->mask - htab->__tab->mask/4) {
+		if (!resize(2*htab->__tab->used, htab)) {
+			htab->__tab->used--;
+			e->key = 0;
+			*retval = 0;
+			return 0;
+		}
+		e = lookup(item.key, hash, htab);
+	}
+	*retval = e;
+	return 1;
+}
+weak_alias(__hsearch_r, hsearch_r);
libc/musl/src/search/insque.c
@@ -0,0 +1,32 @@
+#include <search.h>
+
+struct node {
+	struct node *next;
+	struct node *prev;
+};
+
+void insque(void *element, void *pred)
+{
+	struct node *e = element;
+	struct node *p = pred;
+
+	if (!p) {
+		e->next = e->prev = 0;
+		return;
+	}
+	e->next = p->next;
+	e->prev = p;
+	p->next = e;
+	if (e->next)
+		e->next->prev = e;
+}
+
+void remque(void *element)
+{
+	struct node *e = element;
+
+	if (e->next)
+		e->next->prev = e->prev;
+	if (e->prev)
+		e->prev->next = e->next;
+}
libc/musl/src/search/lsearch.c
@@ -0,0 +1,31 @@
+#include <search.h>
+#include <string.h>
+
+void *lsearch(const void *key, void *base, size_t *nelp, size_t width,
+	int (*compar)(const void *, const void *))
+{
+	char (*p)[width] = base;
+	size_t n = *nelp;
+	size_t i;
+
+	for (i = 0; i < n; i++)
+		if (compar(key, p[i]) == 0)
+			return p[i];
+	*nelp = n+1;
+	return memcpy(p[n], key, width);
+}
+
+void *lfind(const void *key, const void *base, size_t *nelp,
+	size_t width, int (*compar)(const void *, const void *))
+{
+	char (*p)[width] = (void *)base;
+	size_t n = *nelp;
+	size_t i;
+
+	for (i = 0; i < n; i++)
+		if (compar(key, p[i]) == 0)
+			return p[i];
+	return 0;
+}
+
+
libc/musl/src/search/tdelete.c
@@ -0,0 +1,49 @@
+#include <stdlib.h>
+#include <search.h>
+#include "tsearch.h"
+
+void *tdelete(const void *restrict key, void **restrict rootp,
+	int(*cmp)(const void *, const void *))
+{
+	if (!rootp)
+		return 0;
+
+	void **a[MAXH+1];
+	struct node *n = *rootp;
+	struct node *parent;
+	struct node *child;
+	int i=0;
+	/* *a[0] is an arbitrary non-null pointer that is returned when
+	   the root node is deleted.  */
+	a[i++] = rootp;
+	a[i++] = rootp;
+	for (;;) {
+		if (!n)
+			return 0;
+		int c = cmp(key, n->key);
+		if (!c)
+			break;
+		a[i++] = &n->a[c>0];
+		n = n->a[c>0];
+	}
+	parent = *a[i-2];
+	if (n->a[0]) {
+		/* free the preceding node instead of the deleted one.  */
+		struct node *deleted = n;
+		a[i++] = &n->a[0];
+		n = n->a[0];
+		while (n->a[1]) {
+			a[i++] = &n->a[1];
+			n = n->a[1];
+		}
+		deleted->key = n->key;
+		child = n->a[0];
+	} else {
+		child = n->a[1];
+	}
+	/* freed node has at most one child, move it up and rebalance.  */
+	free(n);
+	*a[--i] = child;
+	while (--i && __tsearch_balance(a[i]));
+	return parent;
+}
libc/musl/src/search/tdestroy.c
@@ -0,0 +1,16 @@
+#define _GNU_SOURCE
+#include <stdlib.h>
+#include <search.h>
+#include "tsearch.h"
+
+void tdestroy(void *root, void (*freekey)(void *))
+{
+	struct node *r = root;
+
+	if (r == 0)
+		return;
+	tdestroy(r->a[0], freekey);
+	tdestroy(r->a[1], freekey);
+	if (freekey) freekey((void *)r->key);
+	free(r);
+}
libc/musl/src/search/tfind.c
@@ -0,0 +1,20 @@
+#include <search.h>
+#include "tsearch.h"
+
+void *tfind(const void *key, void *const *rootp,
+	int(*cmp)(const void *, const void *))
+{
+	if (!rootp)
+		return 0;
+
+	struct node *n = *rootp;
+	for (;;) {
+		if (!n)
+			break;
+		int c = cmp(key, n->key);
+		if (!c)
+			break;
+		n = n->a[c>0];
+	}
+	return n;
+}
libc/musl/src/search/tsearch.c
@@ -0,0 +1,92 @@
+#include <stdlib.h>
+#include <search.h>
+#include "tsearch.h"
+
+static inline int height(struct node *n) { return n ? n->h : 0; }
+
+static int rot(void **p, struct node *x, int dir /* deeper side */)
+{
+	struct node *y = x->a[dir];
+	struct node *z = y->a[!dir];
+	int hx = x->h;
+	int hz = height(z);
+	if (hz > height(y->a[dir])) {
+		/*
+		 *   x
+		 *  / \ dir          z
+		 * A   y            / \
+		 *    / \   -->    x   y
+		 *   z   D        /|   |\
+		 *  / \          A B   C D
+		 * B   C
+		 */
+		x->a[dir] = z->a[!dir];
+		y->a[!dir] = z->a[dir];
+		z->a[!dir] = x;
+		z->a[dir] = y;
+		x->h = hz;
+		y->h = hz;
+		z->h = hz+1;
+	} else {
+		/*
+		 *   x               y
+		 *  / \             / \
+		 * A   y    -->    x   D
+		 *    / \         / \
+		 *   z   D       A   z
+		 */
+		x->a[dir] = z;
+		y->a[!dir] = x;
+		x->h = hz+1;
+		y->h = hz+2;
+		z = y;
+	}
+	*p = z;
+	return z->h - hx;
+}
+
+/* balance *p, return 0 if height is unchanged.  */
+int __tsearch_balance(void **p)
+{
+	struct node *n = *p;
+	int h0 = height(n->a[0]);
+	int h1 = height(n->a[1]);
+	if (h0 - h1 + 1u < 3u) {
+		int old = n->h;
+		n->h = h0<h1 ? h1+1 : h0+1;
+		return n->h - old;
+	}
+	return rot(p, n, h0<h1);
+}
+
+void *tsearch(const void *key, void **rootp,
+	int (*cmp)(const void *, const void *))
+{
+	if (!rootp)
+		return 0;
+
+	void **a[MAXH];
+	struct node *n = *rootp;
+	struct node *r;
+	int i=0;
+	a[i++] = rootp;
+	for (;;) {
+		if (!n)
+			break;
+		int c = cmp(key, n->key);
+		if (!c)
+			return n;
+		a[i++] = &n->a[c>0];
+		n = n->a[c>0];
+	}
+	r = malloc(sizeof *r);
+	if (!r)
+		return 0;
+	r->key = key;
+	r->a[0] = r->a[1] = 0;
+	r->h = 1;
+	/* insert new node, rebalance ancestors.  */
+	*a[--i] = r;
+	while (i && __tsearch_balance(a[--i]));
+	return r;
+}
libc/musl/src/search/tsearch.h
@@ -0,0 +1,13 @@
+#include <search.h>
+#include <features.h>
+
+/* AVL tree height < 1.44*log2(nodes+2)-0.3, MAXH is a safe upper bound.  */
+#define MAXH (sizeof(void*)*8*3/2)
+
+struct node {
+	const void *key;
+	void *a[2];
+	int h;
+};
+
+hidden int __tsearch_balance(void **);
libc/musl/src/search/twalk.c
@@ -0,0 +1,22 @@
+#include <search.h>
+#include "tsearch.h"
+
+static void walk(const struct node *r, void (*action)(const void *, VISIT, int), int d)
+{
+	if (!r)
+		return;
+	if (r->h == 1)
+		action(r, leaf, d);
+	else {
+		action(r, preorder, d);
+		walk(r->a[0], action, d+1);
+		action(r, postorder, d);
+		walk(r->a[1], action, d+1);
+		action(r, endorder, d);
+	}
+}
+
+void twalk(const void *root, void (*action)(const void *, VISIT, int))
+{
+	walk(root, action, 0);
+}
libc/musl/src/select/poll.c
@@ -0,0 +1,15 @@
+#include <poll.h>
+#include <time.h>
+#include <signal.h>
+#include "syscall.h"
+
+int poll(struct pollfd *fds, nfds_t n, int timeout)
+{
+#ifdef SYS_poll
+	return syscall_cp(SYS_poll, fds, n, timeout);
+#else
+	return syscall_cp(SYS_ppoll, fds, n, timeout>=0 ?
+		&((struct timespec){ .tv_sec = timeout/1000,
+		.tv_nsec = timeout%1000*1000000 }) : 0, 0, _NSIG/8);
+#endif
+}
libc/musl/src/select/pselect.c
@@ -0,0 +1,12 @@
+#include <sys/select.h>
+#include <signal.h>
+#include <stdint.h>
+#include "syscall.h"
+
+int pselect(int n, fd_set *restrict rfds, fd_set *restrict wfds, fd_set *restrict efds, const struct timespec *restrict ts, const sigset_t *restrict mask)
+{
+	syscall_arg_t data[2] = { (uintptr_t)mask, _NSIG/8 };
+	struct timespec ts_tmp;
+	if (ts) ts_tmp = *ts;
+	return syscall_cp(SYS_pselect6, n, rfds, wfds, efds, ts ? &ts_tmp : 0, data);
+}
libc/musl/src/select/select.c
@@ -0,0 +1,25 @@
+#include <sys/select.h>
+#include <signal.h>
+#include <stdint.h>
+#include <errno.h>
+#include "syscall.h"
+
+int select(int n, fd_set *restrict rfds, fd_set *restrict wfds, fd_set *restrict efds, struct timeval *restrict tv)
+{
+#ifdef SYS_select
+	return syscall_cp(SYS_select, n, rfds, wfds, efds, tv);
+#else
+	syscall_arg_t data[2] = { 0, _NSIG/8 };
+	struct timespec ts;
+	if (tv) {
+		if (tv->tv_sec < 0 || tv->tv_usec < 0)
+			return __syscall_ret(-EINVAL);
+		time_t extra_secs = tv->tv_usec / 1000000;
+		ts.tv_nsec = tv->tv_usec % 1000000 * 1000;
+		const time_t max_time = (1ULL<<8*sizeof(time_t)-1)-1;
+		ts.tv_sec = extra_secs > max_time - tv->tv_sec ?
+			max_time : tv->tv_sec + extra_secs;
+	}
+	return syscall_cp(SYS_pselect6, n, rfds, wfds, efds, tv ? &ts : 0, data);
+#endif
+}
libc/musl/src/setjmp/aarch64/longjmp.s
@@ -0,0 +1,24 @@
+.global _longjmp
+.global longjmp
+.type _longjmp,%function
+.type longjmp,%function
+_longjmp:
+longjmp:
+	// IHI0055B_aapcs64.pdf 5.1.1, 5.1.2 callee saved registers
+	ldp x19, x20, [x0,#0]
+	ldp x21, x22, [x0,#16]
+	ldp x23, x24, [x0,#32]
+	ldp x25, x26, [x0,#48]
+	ldp x27, x28, [x0,#64]
+	ldp x29, x30, [x0,#80]
+	ldr x2, [x0,#104]
+	mov sp, x2
+	ldp d8 , d9, [x0,#112]
+	ldp d10, d11, [x0,#128]
+	ldp d12, d13, [x0,#144]
+	ldp d14, d15, [x0,#160]
+
+	mov x0, x1
+	cbnz x1, 1f
+	mov x0, #1
+1:	br x30
libc/musl/src/setjmp/aarch64/setjmp.s
@@ -0,0 +1,24 @@
+.global __setjmp
+.global _setjmp
+.global setjmp
+.type __setjmp,@function
+.type _setjmp,@function
+.type setjmp,@function
+__setjmp:
+_setjmp:
+setjmp:
+	// IHI0055B_aapcs64.pdf 5.1.1, 5.1.2 callee saved registers
+	stp x19, x20, [x0,#0]
+	stp x21, x22, [x0,#16]
+	stp x23, x24, [x0,#32]
+	stp x25, x26, [x0,#48]
+	stp x27, x28, [x0,#64]
+	stp x29, x30, [x0,#80]
+	mov x2, sp
+	str x2, [x0,#104]
+	stp  d8,  d9, [x0,#112]
+	stp d10, d11, [x0,#128]
+	stp d12, d13, [x0,#144]
+	stp d14, d15, [x0,#160]
+	mov x0, #0
+	ret
libc/musl/src/setjmp/arm/longjmp.s
@@ -0,0 +1,43 @@
+.syntax unified
+.global _longjmp
+.global longjmp
+.type _longjmp,%function
+.type longjmp,%function
+_longjmp:
+longjmp:
+	mov ip,r0
+	movs r0,r1
+	moveq r0,#1
+	ldmia ip!, {v1,v2,v3,v4,v5,v6,sl,fp}
+	ldmia ip!, {r2,lr}
+	mov sp,r2
+
+	adr r1,1f
+	ldr r2,1f
+	ldr r1,[r1,r2]
+
+	tst r1,#0x260
+	beq 3f
+	tst r1,#0x20
+	beq 2f
+	ldc p2, cr4, [ip], #48
+2:	tst r1,#0x40
+	beq 2f
+	.fpu vfp
+	vldmia ip!, {d8-d15}
+	.fpu softvfp
+	.eabi_attribute 10, 0
+	.eabi_attribute 27, 0
+2:	tst r1,#0x200
+	beq 3f
+	ldcl p1, cr10, [ip], #8
+	ldcl p1, cr11, [ip], #8
+	ldcl p1, cr12, [ip], #8
+	ldcl p1, cr13, [ip], #8
+	ldcl p1, cr14, [ip], #8
+	ldcl p1, cr15, [ip], #8
+3:	bx lr
+
+.hidden __hwcap
+.align 2
+1:	.word __hwcap-1b
libc/musl/src/setjmp/arm/setjmp.s
@@ -0,0 +1,45 @@
+.syntax unified
+.global __setjmp
+.global _setjmp
+.global setjmp
+.type __setjmp,%function
+.type _setjmp,%function
+.type setjmp,%function
+__setjmp:
+_setjmp:
+setjmp:
+	mov ip,r0
+	stmia ip!,{v1,v2,v3,v4,v5,v6,sl,fp}
+	mov r2,sp
+	stmia ip!,{r2,lr}
+	mov r0,#0
+
+	adr r1,1f
+	ldr r2,1f
+	ldr r1,[r1,r2]
+
+	tst r1,#0x260
+	beq 3f
+	tst r1,#0x20
+	beq 2f
+	stc p2, cr4, [ip], #48
+2:	tst r1,#0x40
+	beq 2f
+	.fpu vfp
+	vstmia ip!, {d8-d15}
+	.fpu softvfp
+	.eabi_attribute 10, 0
+	.eabi_attribute 27, 0
+2:	tst r1,#0x200
+	beq 3f
+	stcl p1, cr10, [ip], #8
+	stcl p1, cr11, [ip], #8
+	stcl p1, cr12, [ip], #8
+	stcl p1, cr13, [ip], #8
+	stcl p1, cr14, [ip], #8
+	stcl p1, cr15, [ip], #8
+3:	bx lr
+
+.hidden __hwcap
+.align 2
+1:	.word __hwcap-1b
libc/musl/src/setjmp/i386/longjmp.s
@@ -0,0 +1,20 @@
+.global _longjmp
+.global longjmp
+.type _longjmp,@function
+.type longjmp,@function
+_longjmp:
+longjmp:
+	mov  4(%esp),%edx
+	mov  8(%esp),%eax
+	test    %eax,%eax
+	jnz 1f
+	inc     %eax
+1:
+	mov   (%edx),%ebx
+	mov  4(%edx),%esi
+	mov  8(%edx),%edi
+	mov 12(%edx),%ebp
+	mov 16(%edx),%ecx
+	mov     %ecx,%esp
+	mov 20(%edx),%ecx
+	jmp *%ecx
libc/musl/src/setjmp/i386/setjmp.s
@@ -0,0 +1,23 @@
+.global ___setjmp
+.hidden ___setjmp
+.global __setjmp
+.global _setjmp
+.global setjmp
+.type __setjmp,@function
+.type _setjmp,@function
+.type setjmp,@function
+___setjmp:
+__setjmp:
+_setjmp:
+setjmp:
+	mov 4(%esp), %eax
+	mov    %ebx, (%eax)
+	mov    %esi, 4(%eax)
+	mov    %edi, 8(%eax)
+	mov    %ebp, 12(%eax)
+	lea 4(%esp), %ecx
+	mov    %ecx, 16(%eax)
+	mov  (%esp), %ecx
+	mov    %ecx, 20(%eax)
+	xor    %eax, %eax
+	ret
libc/musl/src/setjmp/m68k/longjmp.s
@@ -0,0 +1,14 @@
+.global _longjmp
+.global longjmp
+.type _longjmp,@function
+.type longjmp,@function
+_longjmp:
+longjmp:
+	movea.l 4(%sp),%a0
+	move.l 8(%sp),%d0
+	bne 1f
+	move.l #1,%d0
+1:	movem.l (%a0),%d2-%d7/%a2-%a7
+	fmovem.x 52(%a0),%fp2-%fp7
+	move.l 48(%a0),(%sp)
+	rts
libc/musl/src/setjmp/m68k/setjmp.s
@@ -0,0 +1,18 @@
+.global ___setjmp
+.hidden ___setjmp
+.global __setjmp
+.global _setjmp
+.global setjmp
+.type __setjmp,@function
+.type _setjmp,@function
+.type setjmp,@function
+___setjmp:
+__setjmp:
+_setjmp:
+setjmp:
+	movea.l 4(%sp),%a0
+	movem.l %d2-%d7/%a2-%a7,(%a0)
+	move.l (%sp),48(%a0)
+	fmovem.x %fp2-%fp7,52(%a0)
+	clr.l %d0
+	rts
libc/musl/src/setjmp/microblaze/longjmp.s
@@ -0,0 +1,29 @@
+.global _longjmp
+.global longjmp
+.type   _longjmp,@function
+.type   longjmp,@function
+_longjmp:
+longjmp:
+	addi    r3, r6, 0
+	bnei    r3, 1f
+	addi    r3, r3, 1
+1:      lwi     r1,  r5, 0
+	lwi     r15, r5, 4
+	lwi     r2,  r5, 8
+	lwi     r13, r5, 12
+	lwi     r18, r5, 16
+	lwi     r19, r5, 20
+	lwi     r20, r5, 24
+	lwi     r21, r5, 28
+	lwi     r22, r5, 32
+	lwi     r23, r5, 36
+	lwi     r24, r5, 40
+	lwi     r25, r5, 44
+	lwi     r26, r5, 48
+	lwi     r27, r5, 52
+	lwi     r28, r5, 56
+	lwi     r29, r5, 60
+	lwi     r30, r5, 64
+	lwi     r31, r5, 68
+	rtsd    r15, 8
+	nop
libc/musl/src/setjmp/microblaze/setjmp.s
@@ -0,0 +1,32 @@
+.global ___setjmp
+.hidden ___setjmp
+.global __setjmp
+.global _setjmp
+.global setjmp
+.type __setjmp,@function
+.type _setjmp,@function
+.type setjmp,@function
+___setjmp:
+__setjmp:
+_setjmp:
+setjmp:
+	swi     r1,  r5, 0
+	swi     r15, r5, 4
+	swi     r2,  r5, 8
+	swi     r13, r5, 12
+	swi     r18, r5, 16
+	swi     r19, r5, 20
+	swi     r20, r5, 24
+	swi     r21, r5, 28
+	swi     r22, r5, 32
+	swi     r23, r5, 36
+	swi     r24, r5, 40
+	swi     r25, r5, 44
+	swi     r26, r5, 48
+	swi     r27, r5, 52
+	swi     r28, r5, 56
+	swi     r29, r5, 60
+	swi     r30, r5, 64
+	swi     r31, r5, 68
+	rtsd    r15, 8
+	ori     r3, r0, 0
libc/musl/src/setjmp/mips/longjmp.S
@@ -0,0 +1,40 @@
+.set noreorder
+
+.global _longjmp
+.global longjmp
+.type   _longjmp,@function
+.type   longjmp,@function
+_longjmp:
+longjmp:
+	move    $2, $5
+	bne     $2, $0, 1f
+	nop
+	addu    $2, $2, 1
+1:
+#ifndef __mips_soft_float
+	lwc1    $20, 56($4)
+	lwc1    $21, 60($4)
+	lwc1    $22, 64($4)
+	lwc1    $23, 68($4)
+	lwc1    $24, 72($4)
+	lwc1    $25, 76($4)
+	lwc1    $26, 80($4)
+	lwc1    $27, 84($4)
+	lwc1    $28, 88($4)
+	lwc1    $29, 92($4)
+	lwc1    $30, 96($4)
+	lwc1    $31, 100($4)
+#endif
+	lw      $ra,  0($4)
+	lw      $sp,  4($4)
+	lw      $16,  8($4)
+	lw      $17, 12($4)
+	lw      $18, 16($4)
+	lw      $19, 20($4)
+	lw      $20, 24($4)
+	lw      $21, 28($4)
+	lw      $22, 32($4)
+	lw      $23, 36($4)
+	lw      $30, 40($4)
+	jr      $ra
+	lw      $28, 44($4)
libc/musl/src/setjmp/mips/setjmp.S
@@ -0,0 +1,39 @@
+.set noreorder
+
+.global __setjmp
+.global _setjmp
+.global setjmp
+.type   __setjmp,@function
+.type   _setjmp,@function
+.type   setjmp,@function
+__setjmp:
+_setjmp:
+setjmp:
+	sw      $ra,  0($4)
+	sw      $sp,  4($4)
+	sw      $16,  8($4)
+	sw      $17, 12($4)
+	sw      $18, 16($4)
+	sw      $19, 20($4)
+	sw      $20, 24($4)
+	sw      $21, 28($4)
+	sw      $22, 32($4)
+	sw      $23, 36($4)
+	sw      $30, 40($4)
+	sw      $28, 44($4)
+#ifndef __mips_soft_float
+	swc1    $20, 56($4)
+	swc1    $21, 60($4)
+	swc1    $22, 64($4)
+	swc1    $23, 68($4)
+	swc1    $24, 72($4)
+	swc1    $25, 76($4)
+	swc1    $26, 80($4)
+	swc1    $27, 84($4)
+	swc1    $28, 88($4)
+	swc1    $29, 92($4)
+	swc1    $30, 96($4)
+	swc1    $31, 100($4)
+#endif
+	jr      $ra
+	li      $2, 0
libc/musl/src/setjmp/mips64/longjmp.S
@@ -0,0 +1,37 @@
+.set	noreorder
+.global	_longjmp
+.global	longjmp
+.type	_longjmp,@function
+.type	longjmp,@function
+_longjmp:
+longjmp:
+	move	$2, $5
+
+	bne	$2, $0, 1f
+	nop
+	daddu	$2, $2, 1
+1:
+#ifndef __mips_soft_float
+	ldc1	$24, 96($4)
+	ldc1	$25, 104($4)
+	ldc1	$26, 112($4)
+	ldc1	$27, 120($4)
+	ldc1	$28, 128($4)
+	ldc1	$29, 136($4)
+	ldc1	$30, 144($4)
+	ldc1	$31, 152($4)
+#endif
+	ld	$ra, 0($4)
+	ld	$sp, 8($4)
+	ld	$gp, 16($4)
+	ld	$16, 24($4)
+	ld	$17, 32($4)
+	ld	$18, 40($4)
+	ld	$19, 48($4)
+	ld	$20, 56($4)
+	ld	$21, 64($4)
+	ld	$22, 72($4)
+	ld	$23, 80($4)
+	ld	$30, 88($4)
+	jr	$ra
+	nop
libc/musl/src/setjmp/mips64/setjmp.S
@@ -0,0 +1,34 @@
+.set	noreorder
+.global	__setjmp
+.global	_setjmp
+.global	setjmp
+.type	__setjmp,@function
+.type	_setjmp,@function
+.type	setjmp,@function
+__setjmp:
+_setjmp:
+setjmp:
+	sd	$ra, 0($4)
+	sd	$sp, 8($4)
+	sd	$gp, 16($4)
+	sd	$16, 24($4)
+	sd	$17, 32($4)
+	sd	$18, 40($4)
+	sd	$19, 48($4)
+	sd	$20, 56($4)
+	sd	$21, 64($4)
+	sd	$22, 72($4)
+	sd	$23, 80($4)
+	sd	$30, 88($4)
+#ifndef __mips_soft_float
+	sdc1	$24, 96($4)
+	sdc1	$25, 104($4)
+	sdc1	$26, 112($4)
+	sdc1	$27, 120($4)
+	sdc1	$28, 128($4)
+	sdc1	$29, 136($4)
+	sdc1	$30, 144($4)
+	sdc1	$31, 152($4)
+#endif
+	jr	$ra
+	li	$2, 0
libc/musl/src/setjmp/mipsn32/longjmp.S
@@ -0,0 +1,36 @@
+.set	noreorder
+.global	_longjmp
+.global	longjmp
+.type	_longjmp,@function
+.type	longjmp,@function
+_longjmp:
+longjmp:
+	move	$2, $5
+	bne	$2, $0, 1f
+	nop
+	addu	$2, $2, 1
+1:
+#ifndef __mips_soft_float
+	ldc1	$24, 96($4)
+	ldc1	$25, 104($4)
+	ldc1	$26, 112($4)
+	ldc1	$27, 120($4)
+	ldc1	$28, 128($4)
+	ldc1	$29, 136($4)
+	ldc1	$30, 144($4)
+	ldc1	$31, 152($4)
+#endif
+	ld	$ra, 0($4)
+	ld	$sp, 8($4)
+	ld	$gp, 16($4)
+	ld	$16, 24($4)
+	ld	$17, 32($4)
+	ld	$18, 40($4)
+	ld	$19, 48($4)
+	ld	$20, 56($4)
+	ld	$21, 64($4)
+	ld	$22, 72($4)
+	ld	$23, 80($4)
+	ld	$30, 88($4)
+	jr	$ra
+	nop
libc/musl/src/setjmp/mipsn32/setjmp.S
@@ -0,0 +1,34 @@
+.set	noreorder
+.global	__setjmp
+.global	_setjmp
+.global	setjmp
+.type	__setjmp,@function
+.type	_setjmp,@function
+.type	setjmp,@function
+__setjmp:
+_setjmp:
+setjmp:
+	sd	$ra, 0($4)
+	sd	$sp, 8($4)
+	sd	$gp, 16($4)
+	sd	$16, 24($4)
+	sd	$17, 32($4)
+	sd	$18, 40($4)
+	sd	$19, 48($4)
+	sd	$20, 56($4)
+	sd	$21, 64($4)
+	sd	$22, 72($4)
+	sd	$23, 80($4)
+	sd	$30, 88($4)
+#ifndef __mips_soft_float
+	sdc1	$24, 96($4)
+	sdc1	$25, 104($4)
+	sdc1	$26, 112($4)
+	sdc1	$27, 120($4)
+	sdc1	$28, 128($4)
+	sdc1	$29, 136($4)
+	sdc1	$30, 144($4)
+	sdc1	$31, 152($4)
+#endif
+	jr	$ra
+	li	$2, 0
libc/musl/src/setjmp/or1k/longjmp.s
@@ -0,0 +1,25 @@
+.global _longjmp
+.global longjmp
+.type   _longjmp,@function
+.type   longjmp,@function
+_longjmp:
+longjmp:
+	l.sfeqi	r4, 0
+	l.bnf	1f
+	 l.addi	r11, r4,0
+	l.ori	r11, r0, 1
+1:	l.lwz	r1, 0(r3)
+	l.lwz	r2, 4(r3)
+	l.lwz	r9, 8(r3)
+	l.lwz	r10, 12(r3)
+	l.lwz	r14, 16(r3)
+	l.lwz	r16, 20(r3)
+	l.lwz	r18, 24(r3)
+	l.lwz	r20, 28(r3)
+	l.lwz	r22, 32(r3)
+	l.lwz	r24, 36(r3)
+	l.lwz	r26, 40(r3)
+	l.lwz	r28, 44(r3)
+	l.lwz	r30, 48(r3)
+	l.jr	r9
+	 l.nop
libc/musl/src/setjmp/or1k/setjmp.s
@@ -0,0 +1,27 @@
+.global ___setjmp
+.hidden ___setjmp
+.global __setjmp
+.global _setjmp
+.global setjmp
+.type __setjmp,@function
+.type _setjmp,@function
+.type setjmp,@function
+___setjmp:
+__setjmp:
+_setjmp:
+setjmp:
+	l.sw	0(r3), r1
+	l.sw	4(r3), r2
+	l.sw	8(r3), r9
+	l.sw	12(r3), r10
+	l.sw	16(r3), r14
+	l.sw	20(r3), r16
+	l.sw	24(r3), r18
+	l.sw	28(r3), r20
+	l.sw	32(r3), r22
+	l.sw	36(r3), r24
+	l.sw	40(r3), r26
+	l.sw	44(r3), r28
+	l.sw	48(r3), r30
+	l.jr	r9
+	 l.ori	r11,r0,0
libc/musl/src/setjmp/powerpc/longjmp.S
@@ -0,0 +1,69 @@
+	.global _longjmp
+	.global longjmp
+	.type   _longjmp,@function
+	.type   longjmp,@function
+_longjmp:
+longjmp:
+	/*
+	 * void longjmp(jmp_buf env, int val);
+	 * put val into return register and restore the env saved in setjmp
+	 * if val(r4) is 0, put 1 there.
+	 */
+	/* 0) move old return address into r0 */
+	lwz 0, 0(3)
+	/* 1) put it into link reg */
+	mtlr 0
+	/* 2 ) restore stack ptr */
+	lwz 1, 4(3)
+	/* 3) restore control reg */
+	lwz 0, 8(3)
+	mtcr 0
+	/* 4) restore r14-r31 */
+	lwz 14, 12(3)
+	lwz 15, 16(3)
+	lwz 16, 20(3)
+	lwz 17, 24(3)
+	lwz 18, 28(3)
+	lwz 19, 32(3)
+	lwz 20, 36(3)
+	lwz 21, 40(3)
+	lwz 22, 44(3)
+	lwz 23, 48(3)
+	lwz 24, 52(3)
+	lwz 25, 56(3)
+	lwz 26, 60(3)
+	lwz 27, 64(3)
+	lwz 28, 68(3)
+	lwz 29, 72(3)
+	lwz 30, 76(3)
+	lwz 31, 80(3)
+#ifndef _SOFT_FLOAT
+	lfd 14,88(3)
+	lfd 15,96(3)
+	lfd 16,104(3)
+	lfd 17,112(3)
+	lfd 18,120(3)
+	lfd 19,128(3)
+	lfd 20,136(3)
+	lfd 21,144(3)
+	lfd 22,152(3)
+	lfd 23,160(3)
+	lfd 24,168(3)
+	lfd 25,176(3)
+	lfd 26,184(3)
+	lfd 27,192(3)
+	lfd 28,200(3)
+	lfd 29,208(3)
+	lfd 30,216(3)
+	lfd 31,224(3)
+#endif
+	/* 5) put val into return reg r3 */
+	mr 3, 4
+
+	/* 6) check if return value is 0, make it 1 in that case */
+	cmpwi cr7, 4, 0
+	bne cr7, 1f
+	li 3, 1
+1:
+	blr
+
libc/musl/src/setjmp/powerpc/setjmp.S
@@ -0,0 +1,63 @@
+	.global ___setjmp
+	.hidden ___setjmp
+	.global __setjmp
+	.global _setjmp
+	.global setjmp
+	.type   __setjmp,@function
+	.type   _setjmp,@function
+	.type   setjmp,@function
+___setjmp:
+__setjmp:
+_setjmp:
+setjmp:
+	/* 0) store IP int 0, then into the jmpbuf pointed to by r3 (first arg) */
+	mflr 0
+	stw 0, 0(3)
+	/* 1) store reg1 (SP) */
+	stw 1, 4(3)
+	/* 2) store cr */
+	mfcr 0
+	stw 0, 8(3)
+	/* 3) store r14-31 */
+	stw 14, 12(3)
+	stw 15, 16(3)
+	stw 16, 20(3)
+	stw 17, 24(3)
+	stw 18, 28(3)
+	stw 19, 32(3)
+	stw 20, 36(3)
+	stw 21, 40(3)
+	stw 22, 44(3)
+	stw 23, 48(3)
+	stw 24, 52(3)
+	stw 25, 56(3)
+	stw 26, 60(3)
+	stw 27, 64(3)
+	stw 28, 68(3)
+	stw 29, 72(3)
+	stw 30, 76(3)
+	stw 31, 80(3)
+#ifndef _SOFT_FLOAT
+	stfd 14,88(3)
+	stfd 15,96(3)
+	stfd 16,104(3)
+	stfd 17,112(3)
+	stfd 18,120(3)
+	stfd 19,128(3)
+	stfd 20,136(3)
+	stfd 21,144(3)
+	stfd 22,152(3)
+	stfd 23,160(3)
+	stfd 24,168(3)
+	stfd 25,176(3)
+	stfd 26,184(3)
+	stfd 27,192(3)
+	stfd 28,200(3)
+	stfd 29,208(3)
+	stfd 30,216(3)
+	stfd 31,224(3)
+#endif
+	/* 4) set return value to 0 */
+	li 3, 0
+	/* 5) return */
+	blr
libc/musl/src/setjmp/powerpc64/longjmp.s
@@ -0,0 +1,81 @@
+	.global _longjmp
+	.global longjmp
+	.type   _longjmp,@function
+	.type   longjmp,@function
+_longjmp:
+longjmp:
+	# 0) move old return address into the link register
+	ld   0,  0*8(3)
+	mtlr 0
+	# 1) restore cr
+	ld   0,  1*8(3)
+	mtcr 0
+	# 2) restore SP
+	ld   1,  2*8(3)
+	# 3) restore TOC into both r2 and the caller's stack.
+	#    Which location is required depends on whether setjmp was called
+	#    locally or non-locally, but it's always safe to restore to both.
+	ld   2,  3*8(3)
+	std  2,   24(1)
+	# 4) restore r14-r31
+	ld  14,  4*8(3)
+	ld  15,  5*8(3)
+	ld  16,  6*8(3)
+	ld  17,  7*8(3)
+	ld  18,  8*8(3)
+	ld  19,  9*8(3)
+	ld  20, 10*8(3)
+	ld  21, 11*8(3)
+	ld  22, 12*8(3)
+	ld  23, 13*8(3)
+	ld  24, 14*8(3)
+	ld  25, 15*8(3)
+	ld  26, 16*8(3)
+	ld  27, 17*8(3)
+	ld  28, 18*8(3)
+	ld  29, 19*8(3)
+	ld  30, 20*8(3)
+	ld  31, 21*8(3)
+	# 5) restore floating point registers f14-f31
+	lfd 14, 22*8(3)
+	lfd 15, 23*8(3)
+	lfd 16, 24*8(3)
+	lfd 17, 25*8(3)
+	lfd 18, 26*8(3)
+	lfd 19, 27*8(3)
+	lfd 20, 28*8(3)
+	lfd 21, 29*8(3)
+	lfd 22, 30*8(3)
+	lfd 23, 31*8(3)
+	lfd 24, 32*8(3)
+	lfd 25, 33*8(3)
+	lfd 26, 34*8(3)
+	lfd 27, 35*8(3)
+	lfd 28, 36*8(3)
+	lfd 29, 37*8(3)
+	lfd 30, 38*8(3)
+	lfd 31, 39*8(3)
+
+	# 6) restore vector registers v20-v31
+	addi 3, 3, 40*8
+	lvx 20, 0, 3 ; addi 3, 3, 16
+	lvx 21, 0, 3 ; addi 3, 3, 16
+	lvx 22, 0, 3 ; addi 3, 3, 16
+	lvx 23, 0, 3 ; addi 3, 3, 16
+	lvx 24, 0, 3 ; addi 3, 3, 16
+	lvx 25, 0, 3 ; addi 3, 3, 16
+	lvx 26, 0, 3 ; addi 3, 3, 16
+	lvx 27, 0, 3 ; addi 3, 3, 16
+	lvx 28, 0, 3 ; addi 3, 3, 16
+	lvx 29, 0, 3 ; addi 3, 3, 16
+	lvx 30, 0, 3 ; addi 3, 3, 16
+	lvx 31, 0, 3
+
+	# 7) return r4 ? r4 : 1
+	mr    3,   4
+	cmpwi cr7, 4, 0
+	bne   cr7, 1f
+	li    3,   1
+1:
+	blr
+
libc/musl/src/setjmp/powerpc64/setjmp.s
@@ -0,0 +1,89 @@
+	.global __setjmp
+	.global _setjmp
+	.global setjmp
+	.type   __setjmp,@function
+	.type   _setjmp,@function
+	.type   setjmp,@function
+__setjmp:
+_setjmp:
+setjmp:
+	ld 5, 24(1)   # load from the TOC slot in the caller's stack frame
+	b __setjmp_toc
+
+	.localentry __setjmp,.-__setjmp
+	.localentry _setjmp,.-_setjmp
+	.localentry setjmp,.-setjmp
+	mr 5, 2
+
+	.global __setjmp_toc
+	.hidden __setjmp_toc
+	# same as normal setjmp, except TOC pointer to save is provided in r5.
+	# r4 would normally be the 2nd parameter, but we're using r5 to simplify calling from sigsetjmp.
+	# solves the problem of knowing whether to save the TOC pointer from r2 or the caller's stack frame.
+__setjmp_toc:
+	# 0) store IP into 0, then into the jmpbuf pointed to by r3 (first arg)
+	mflr  0
+	std   0,  0*8(3)
+	# 1) store cr
+	mfcr  0
+	std   0,  1*8(3)
+	# 2) store SP and TOC
+	std   1,  2*8(3)
+	std   5,  3*8(3)
+	# 3) store r14-31
+	std  14,  4*8(3)
+	std  15,  5*8(3)
+	std  16,  6*8(3)
+	std  17,  7*8(3)
+	std  18,  8*8(3)
+	std  19,  9*8(3)
+	std  20, 10*8(3)
+	std  21, 11*8(3)
+	std  22, 12*8(3)
+	std  23, 13*8(3)
+	std  24, 14*8(3)
+	std  25, 15*8(3)
+	std  26, 16*8(3)
+	std  27, 17*8(3)
+	std  28, 18*8(3)
+	std  29, 19*8(3)
+	std  30, 20*8(3)
+	std  31, 21*8(3)
+	# 4) store floating point registers f14-f31
+	stfd 14, 22*8(3)
+	stfd 15, 23*8(3)
+	stfd 16, 24*8(3)
+	stfd 17, 25*8(3)
+	stfd 18, 26*8(3)
+	stfd 19, 27*8(3)
+	stfd 20, 28*8(3)
+	stfd 21, 29*8(3)
+	stfd 22, 30*8(3)
+	stfd 23, 31*8(3)
+	stfd 24, 32*8(3)
+	stfd 25, 33*8(3)
+	stfd 26, 34*8(3)
+	stfd 27, 35*8(3)
+	stfd 28, 36*8(3)
+	stfd 29, 37*8(3)
+	stfd 30, 38*8(3)
+	stfd 31, 39*8(3)
+
+	# 5) store vector registers v20-v31
+	addi  3, 3, 40*8
+	stvx 20, 0, 3 ; addi 3, 3, 16
+	stvx 21, 0, 3 ; addi 3, 3, 16
+	stvx 22, 0, 3 ; addi 3, 3, 16
+	stvx 23, 0, 3 ; addi 3, 3, 16
+	stvx 24, 0, 3 ; addi 3, 3, 16
+	stvx 25, 0, 3 ; addi 3, 3, 16
+	stvx 26, 0, 3 ; addi 3, 3, 16
+	stvx 27, 0, 3 ; addi 3, 3, 16
+	stvx 28, 0, 3 ; addi 3, 3, 16
+	stvx 29, 0, 3 ; addi 3, 3, 16
+	stvx 30, 0, 3 ; addi 3, 3, 16
+	stvx 31, 0, 3
+
+	# 6) return 0
+	li 3, 0
+	blr
libc/musl/src/setjmp/s390x/longjmp.s
@@ -0,0 +1,23 @@
+	.global _longjmp
+	.global longjmp
+	.type   _longjmp,@function
+	.type   longjmp,@function
+_longjmp:
+longjmp:
+
+1:
+	lmg %r6, %r15, 0(%r2)
+
+	ld  %f8, 10*8(%r2)
+	ld  %f9, 11*8(%r2)
+	ld %f10, 12*8(%r2)
+	ld %f11, 13*8(%r2)
+	ld %f12, 14*8(%r2)
+	ld %f13, 15*8(%r2)
+	ld %f14, 16*8(%r2)
+	ld %f15, 17*8(%r2)
+
+	ltgr %r2, %r3
+	bnzr %r14
+	lhi  %r2, 1
+	br   %r14
libc/musl/src/setjmp/s390x/setjmp.s
@@ -0,0 +1,25 @@
+	.global ___setjmp
+	.hidden ___setjmp
+	.global __setjmp
+	.global _setjmp
+	.global setjmp
+	.type   __setjmp,@function
+	.type   _setjmp,@function
+	.type   setjmp,@function
+___setjmp:
+__setjmp:
+_setjmp:
+setjmp:
+	stmg %r6, %r15, 0(%r2)
+
+	std  %f8,  10*8(%r2)
+	std  %f9,  11*8(%r2)
+	std  %f10, 12*8(%r2)
+	std  %f11, 13*8(%r2)
+	std  %f12, 14*8(%r2)
+	std  %f13, 15*8(%r2)
+	std  %f14, 16*8(%r2)
+	std  %f15, 17*8(%r2)
+
+	lghi %r2, 0
+	br   %r14
libc/musl/src/setjmp/sh/longjmp.S
@@ -0,0 +1,28 @@
+.global _longjmp
+.global longjmp
+.type   _longjmp, @function
+.type   longjmp,  @function
+_longjmp:
+longjmp:
+	mov.l  @r4+, r8
+	mov.l  @r4+, r9
+	mov.l  @r4+, r10
+	mov.l  @r4+, r11
+	mov.l  @r4+, r12
+	mov.l  @r4+, r13
+	mov.l  @r4+, r14
+	mov.l  @r4+, r15
+	lds.l  @r4+, pr
+#if __SH_FPU_ANY__ || __SH4__
+	fmov.s @r4+, fr12
+	fmov.s @r4+, fr13
+	fmov.s @r4+, fr14
+	fmov.s @r4+, fr15
+#endif
+
+	tst  r5, r5
+	movt r0
+	add  r5, r0
+
+	rts
+	 nop
libc/musl/src/setjmp/sh/setjmp.S
@@ -0,0 +1,32 @@
+.global ___setjmp
+.hidden ___setjmp
+.global __setjmp
+.global _setjmp
+.global setjmp
+.type   __setjmp, @function
+.type   _setjmp,  @function
+.type   setjmp,   @function
+___setjmp:
+__setjmp:
+_setjmp:
+setjmp:
+#if __SH_FPU_ANY__ || __SH4__
+	add   #52, r4
+	fmov.s fr15, @-r4
+	fmov.s fr14, @-r4
+	fmov.s fr13, @-r4
+	fmov.s fr12, @-r4
+#else
+	add   #36, r4
+#endif
+	sts.l  pr,   @-r4
+	mov.l  r15,  @-r4
+	mov.l  r14,  @-r4
+	mov.l  r13,  @-r4
+	mov.l  r12,  @-r4
+	mov.l  r11,  @-r4
+	mov.l  r10,  @-r4
+	mov.l  r9,   @-r4
+	mov.l  r8,   @-r4
+	rts
+	 mov  #0, r0
libc/musl/src/setjmp/x32/longjmp.s
@@ -0,0 +1,22 @@
+/* Copyright 2011-2012 Nicholas J. Kain, licensed under standard MIT license */
+.global _longjmp
+.global longjmp
+.type _longjmp,@function
+.type longjmp,@function
+_longjmp:
+longjmp:
+	mov %rsi,%rax           /* val will be longjmp return */
+	test %rax,%rax
+	jnz 1f
+	inc %rax                /* if val==0, val=1 per longjmp semantics */
+1:
+	mov (%rdi),%rbx         /* rdi is the jmp_buf, restore regs from it */
+	mov 8(%rdi),%rbp
+	mov 16(%rdi),%r12
+	mov 24(%rdi),%r13
+	mov 32(%rdi),%r14
+	mov 40(%rdi),%r15
+	mov 48(%rdi),%rdx       /* this ends up being the stack pointer */
+	mov %rdx,%rsp
+	mov 56(%rdi),%rdx       /* this is the instruction pointer */
+	jmp *%rdx               /* goto saved address without altering rsp */
libc/musl/src/setjmp/x32/setjmp.s
@@ -0,0 +1,22 @@
+/* Copyright 2011-2012 Nicholas J. Kain, licensed under standard MIT license */
+.global __setjmp
+.global _setjmp
+.global setjmp
+.type __setjmp,@function
+.type _setjmp,@function
+.type setjmp,@function
+__setjmp:
+_setjmp:
+setjmp:
+	mov %rbx,(%rdi)         /* rdi is jmp_buf, move registers onto it */
+	mov %rbp,8(%rdi)
+	mov %r12,16(%rdi)
+	mov %r13,24(%rdi)
+	mov %r14,32(%rdi)
+	mov %r15,40(%rdi)
+	lea 8(%rsp),%rdx        /* this is our rsp WITHOUT current ret addr */
+	mov %rdx,48(%rdi)
+	mov (%rsp),%rdx         /* save return addr ptr for new rip */
+	mov %rdx,56(%rdi)
+	xor %rax,%rax           /* always return 0 */
+	ret
libc/musl/src/setjmp/x86_64/longjmp.s
@@ -0,0 +1,22 @@
+/* Copyright 2011-2012 Nicholas J. Kain, licensed under standard MIT license */
+.global _longjmp
+.global longjmp
+.type _longjmp,@function
+.type longjmp,@function
+_longjmp:
+longjmp:
+	mov %rsi,%rax           /* val will be longjmp return */
+	test %rax,%rax
+	jnz 1f
+	inc %rax                /* if val==0, val=1 per longjmp semantics */
+1:
+	mov (%rdi),%rbx         /* rdi is the jmp_buf, restore regs from it */
+	mov 8(%rdi),%rbp
+	mov 16(%rdi),%r12
+	mov 24(%rdi),%r13
+	mov 32(%rdi),%r14
+	mov 40(%rdi),%r15
+	mov 48(%rdi),%rdx       /* this ends up being the stack pointer */
+	mov %rdx,%rsp
+	mov 56(%rdi),%rdx       /* this is the instruction pointer */
+	jmp *%rdx               /* goto saved address without altering rsp */
libc/musl/src/setjmp/x86_64/setjmp.s
@@ -0,0 +1,22 @@
+/* Copyright 2011-2012 Nicholas J. Kain, licensed under standard MIT license */
+.global __setjmp
+.global _setjmp
+.global setjmp
+.type __setjmp,@function
+.type _setjmp,@function
+.type setjmp,@function
+__setjmp:
+_setjmp:
+setjmp:
+	mov %rbx,(%rdi)         /* rdi is jmp_buf, move registers onto it */
+	mov %rbp,8(%rdi)
+	mov %r12,16(%rdi)
+	mov %r13,24(%rdi)
+	mov %r14,32(%rdi)
+	mov %r15,40(%rdi)
+	lea 8(%rsp),%rdx        /* this is our rsp WITHOUT current ret addr */
+	mov %rdx,48(%rdi)
+	mov (%rsp),%rdx         /* save return addr ptr for new rip */
+	mov %rdx,56(%rdi)
+	xor %rax,%rax           /* always return 0 */
+	ret
libc/musl/src/setjmp/longjmp.c
libc/musl/src/setjmp/setjmp.c
libc/musl/src/signal/aarch64/restore.s
@@ -0,0 +1,10 @@
+.global __restore
+.hidden __restore
+.type __restore,%function
+__restore:
+.global __restore_rt
+.hidden __restore_rt
+.type __restore_rt,%function
+__restore_rt:
+	mov x8,#139 // SYS_rt_sigreturn
+	svc 0
libc/musl/src/signal/aarch64/sigsetjmp.s
@@ -0,0 +1,21 @@
+.global sigsetjmp
+.global __sigsetjmp
+.type sigsetjmp,%function
+.type __sigsetjmp,%function
+sigsetjmp:
+__sigsetjmp:
+	cbz x1,setjmp
+
+	str x30,[x0,#176]
+	str x19,[x0,#176+8+8]
+	mov x19,x0
+
+	bl setjmp
+
+	mov w1,w0
+	mov x0,x19
+	ldr x30,[x0,#176]
+	ldr x19,[x0,#176+8+8]
+
+.hidden __sigsetjmp_tail
+	b __sigsetjmp_tail
libc/musl/src/signal/arm/restore.s
@@ -0,0 +1,15 @@
+.syntax unified
+
+.global __restore
+.hidden __restore
+.type __restore,%function
+__restore:
+	mov r7,#119
+	swi 0x0
+
+.global __restore_rt
+.hidden __restore_rt
+.type __restore_rt,%function
+__restore_rt:
+	mov r7,#173
+	swi 0x0
libc/musl/src/signal/arm/sigsetjmp.s
@@ -0,0 +1,23 @@
+.syntax unified
+.global sigsetjmp
+.global __sigsetjmp
+.type sigsetjmp,%function
+.type __sigsetjmp,%function
+sigsetjmp:
+__sigsetjmp:
+	tst r1,r1
+	beq setjmp
+
+	str lr,[r0,#256]
+	str r4,[r0,#260+8]
+	mov r4,r0
+
+	bl setjmp
+
+	mov r1,r0
+	mov r0,r4
+	ldr lr,[r0,#256]
+	ldr r4,[r0,#260+8]
+
+.hidden __sigsetjmp_tail
+	b __sigsetjmp_tail
libc/musl/src/signal/i386/restore.s
@@ -0,0 +1,14 @@
+.global __restore
+.hidden __restore
+.type __restore,@function
+__restore:
+	popl %eax
+	movl $119, %eax
+	int $0x80
+
+.global __restore_rt
+.hidden __restore_rt
+.type __restore_rt,@function
+__restore_rt:
+	movl $173, %eax
+	int $0x80
libc/musl/src/signal/i386/sigsetjmp.s
@@ -0,0 +1,26 @@
+.global sigsetjmp
+.global __sigsetjmp
+.type sigsetjmp,@function
+.type __sigsetjmp,@function
+sigsetjmp:
+__sigsetjmp:
+	mov 8(%esp),%ecx
+	jecxz 1f
+
+	mov 4(%esp),%eax
+	popl 24(%eax)
+	mov %ebx,28+8(%eax)
+	mov %eax,%ebx
+
+.hidden ___setjmp
+	call ___setjmp
+
+	pushl 24(%ebx)
+	mov %ebx,4(%esp)
+	mov %eax,8(%esp)
+	mov 28+8(%ebx),%ebx
+
+.hidden __sigsetjmp_tail
+	jmp __sigsetjmp_tail
+
+1:	jmp ___setjmp
libc/musl/src/signal/m68k/sigsetjmp.s
@@ -0,0 +1,29 @@
+.global sigsetjmp
+.global __sigsetjmp
+.type sigsetjmp,@function
+.type __sigsetjmp,@function
+sigsetjmp:
+__sigsetjmp:
+	move.l 8(%sp),%d0
+	beq 1f
+
+	movea.l 4(%sp),%a1
+	move.l (%sp)+,156(%a1)
+	move.l %a2,156+4+8(%a1)
+	movea.l %a1,%a2
+
+.hidden ___setjmp
+	lea ___setjmp-.-8,%a1
+	jsr (%pc,%a1)
+
+	move.l 156(%a2),-(%sp)
+	move.l %a2,4(%sp)
+	move.l %d0,8(%sp)
+	movea.l 156+4+8(%a2),%a2
+
+.hidden __sigsetjmp_tail
+	lea __sigsetjmp_tail-.-8,%a1
+	jmp (%pc,%a1)
+
+1:	lea ___setjmp-.-8,%a1
+	jmp (%pc,%a1)
libc/musl/src/signal/microblaze/restore.s
@@ -0,0 +1,13 @@
+.global __restore
+.hidden __restore
+.type __restore,@function
+__restore:
+	ori     r12, r0, 119
+	brki    r14, 0x8
+
+.global __restore_rt
+.hidden __restore_rt
+.type __restore_rt,@function
+__restore_rt:
+	ori     r12, r0, 173
+	brki    r14, 0x8
libc/musl/src/signal/microblaze/sigsetjmp.s
@@ -0,0 +1,22 @@
+.global sigsetjmp
+.global __sigsetjmp
+.type sigsetjmp,@function
+.type __sigsetjmp,@function
+sigsetjmp:
+__sigsetjmp:
+.hidden ___setjmp
+	beqi r6, ___setjmp
+
+	swi r15,r5,72
+	swi r19,r5,72+4+8
+
+	brlid r15,___setjmp
+	 ori r19,r5,0
+
+	ori r6,r3,0
+	ori r5,r19,0
+	lwi r15,r5,72
+	lwi r19,r5,72+4+8
+
+.hidden __sigsetjmp_tail
+	bri __sigsetjmp_tail
libc/musl/src/signal/mips/restore.s
@@ -0,0 +1,15 @@
+.set noreorder
+
+.global __restore_rt
+.hidden __restore_rt
+.type   __restore_rt,@function
+__restore_rt:
+	li $2, 4193
+	syscall
+
+.global __restore
+.hidden __restore
+.type   __restore,@function
+__restore:
+	li $2, 4119
+	syscall
libc/musl/src/signal/mips/sigsetjmp.s
@@ -0,0 +1,33 @@
+.set noreorder
+
+.global sigsetjmp
+.global __sigsetjmp
+.type sigsetjmp,@function
+.type __sigsetjmp,@function
+sigsetjmp:
+__sigsetjmp:
+	lui $gp, %hi(_gp_disp)
+	addiu $gp, %lo(_gp_disp)
+	beq $5, $0, 1f
+	 addu $gp, $gp, $25
+
+	sw $ra, 104($4)
+	sw $16, 104+4+16($4)
+
+	lw $25, %call16(setjmp)($gp)
+	jalr $25
+	 move $16, $4
+
+	move $5,$2
+	move $4,$16
+	lw $ra, 104($4)
+	lw $16, 104+4+16($4)
+
+.hidden __sigsetjmp_tail
+	lw $25, %call16(__sigsetjmp_tail)($gp)
+	jr $25
+	 nop
+
+1:	lw $25, %call16(setjmp)($gp)
+	jr $25
+	 nop
libc/musl/src/signal/mips64/restore.s
@@ -0,0 +1,11 @@
+.set	noreorder
+.global	__restore_rt
+.global	__restore
+.hidden __restore_rt
+.hidden __restore
+.type	__restore_rt,@function
+.type	__restore,@function
+__restore_rt:
+__restore:
+	li	$2,5211
+	syscall
libc/musl/src/signal/mips64/sigsetjmp.s
@@ -0,0 +1,38 @@
+.set	noreorder
+.global	sigsetjmp
+.global	__sigsetjmp
+.type	sigsetjmp,@function
+.type	__sigsetjmp,@function
+sigsetjmp:
+__sigsetjmp:
+	lui	$3, %hi(%neg(%gp_rel(sigsetjmp)))
+	daddiu	$3, $3, %lo(%neg(%gp_rel(sigsetjmp)))
+
+	# comparing save mask with 0, if equals to 0 then
+	# sigsetjmp is equal to setjmp.
+	beq	$5, $0, 1f
+	daddu	$3, $3, $25
+	sd	$ra, 160($4)
+	sd	$16, 168($4)
+
+	# save base of got so that we can use it later
+	# once we return from 'longjmp'
+	sd	$3, 176($4)
+	ld	$25, %got_disp(setjmp)($3)
+	jalr	$25
+	move	$16, $4
+
+	move	$5, $2		# Return from 'setjmp' or 'longjmp'
+	move	$4, $16		# Restore the pointer-to-sigjmp_buf
+	ld	$ra, 160($4)	# Restore ra of sigsetjmp
+	ld	$16, 168($4)	# Restore $16 of sigsetjmp
+	ld	$3, 176($4)	# Restore base of got
+
+.hidden	__sigsetjmp_tail
+	ld	$25, %got_disp(__sigsetjmp_tail)($3)
+	jr	$25
+	nop
+1:
+	ld	$25, %got_disp(setjmp)($3)
+	jr	$25
+	nop
libc/musl/src/signal/mipsn32/restore.s
@@ -0,0 +1,11 @@
+.set	noreorder
+.global	__restore_rt
+.global	__restore
+.hidden __restore_rt
+.hidden __restore
+.type	__restore_rt,@function
+.type	__restore,@function
+__restore_rt:
+__restore:
+	li	$2,6211
+	syscall
libc/musl/src/signal/mipsn32/sigsetjmp.s
@@ -0,0 +1,38 @@
+.set	noreorder
+.global	sigsetjmp
+.global	__sigsetjmp
+.type	sigsetjmp,@function
+.type	__sigsetjmp,@function
+sigsetjmp:
+__sigsetjmp:
+	lui	$3, %hi(%neg(%gp_rel(sigsetjmp)))
+	addiu	$3, $3, %lo(%neg(%gp_rel(sigsetjmp)))
+
+	# comparing save mask with 0, if equals to 0 then
+	# sigsetjmp is equal to setjmp.
+	beq	$5, $0, 1f
+	addu	$3, $3, $25
+	sd	$ra, 160($4)
+	sd	$16, 168($4)
+
+	# save base of got so that we can use it later
+	# once we return from 'longjmp'
+	sd	$3, 176($4)
+	lw	$25, %got_disp(setjmp)($3)
+	jalr	$25
+	move	$16, $4
+
+	move	$5, $2		# Return from 'setjmp' or 'longjmp'
+	move	$4, $16		# Restore the pointer-to-sigjmp_buf
+	ld	$ra, 160($4)	# Restore ra of sigsetjmp
+	ld	$16, 168($4)	# Restore $16 of sigsetjmp
+	ld	$3, 176($4)	# Restore base of got
+
+.hidden	__sigsetjmp_tail
+	lw	$25, %got_disp(__sigsetjmp_tail)($3)
+	jr	$25
+	nop
+1:
+	lw	$25, %got_disp(setjmp)($3)
+	jr	$25
+	nop
libc/musl/src/signal/or1k/sigsetjmp.s
@@ -0,0 +1,24 @@
+.global sigsetjmp
+.global __sigsetjmp
+.type sigsetjmp,@function
+.type __sigsetjmp,@function
+sigsetjmp:
+__sigsetjmp:
+	l.sfeq	r4, r0
+.hidden ___setjmp
+	l.bf	___setjmp
+
+	l.sw    52(r3), r9
+	l.sw    52+4+8(r3), r20
+
+	l.jal	___setjmp
+	 l.ori   r20, r3, 0
+
+	l.ori r4, r11, 0
+	l.ori r3, r20, 0
+
+	l.lwz   r9, 52(r3)
+
+.hidden __sigsetjmp_tail
+	l.j	__sigsetjmp_tail
+	 l.lwz   r20, 52+4+8(r3)
libc/musl/src/signal/powerpc/restore.s
@@ -0,0 +1,13 @@
+	.global __restore
+	.hidden __restore
+	.type __restore,%function
+__restore:
+	li      0, 119 #__NR_sigreturn
+	sc
+
+	.global __restore_rt
+	.hidden __restore_rt
+	.type __restore_rt,%function
+__restore_rt:
+	li      0, 172 # __NR_rt_sigreturn
+	sc
libc/musl/src/signal/powerpc/sigsetjmp.s
@@ -0,0 +1,27 @@
+	.global sigsetjmp
+	.global __sigsetjmp
+	.type sigsetjmp,%function
+	.type __sigsetjmp,%function
+sigsetjmp:
+__sigsetjmp:
+	cmpwi cr7, 4, 0
+	beq- cr7, 1f
+
+	mflr 5
+	stw 5, 448(3)
+	stw 16, 448+4+8(3)
+	mr 16, 3
+
+.hidden ___setjmp
+	bl ___setjmp
+
+	mr 4, 3
+	mr 3, 16
+	lwz 5, 448(3)
+	mtlr 5
+	lwz 16, 448+4+8(3)
+
+.hidden __sigsetjmp_tail
+	b __sigsetjmp_tail
+
+1:	b ___setjmp
libc/musl/src/signal/powerpc64/restore.s
@@ -0,0 +1,13 @@
+	.global __restore
+	.hidden __restore
+	.type __restore,%function
+__restore:
+	li      0, 119 #__NR_sigreturn
+	sc
+
+	.global __restore_rt
+	.hidden __restore_rt
+	.type __restore_rt,%function
+__restore_rt:
+	li      0, 172 # __NR_rt_sigreturn
+	sc
libc/musl/src/signal/powerpc64/sigsetjmp.s
@@ -0,0 +1,37 @@
+	.global sigsetjmp
+	.global __sigsetjmp
+	.type sigsetjmp,%function
+	.type __sigsetjmp,%function
+	.hidden __setjmp_toc
+sigsetjmp:
+__sigsetjmp:
+	addis 2, 12, .TOC.-__sigsetjmp@ha
+	addi  2,  2, .TOC.-__sigsetjmp@l
+	ld    5, 24(1)   # load from the TOC slot in the caller's stack frame
+	b     1f
+
+	.localentry sigsetjmp,.-sigsetjmp
+	.localentry __sigsetjmp,.-__sigsetjmp
+	mr    5,  2
+
+1:
+	cmpwi cr7, 4, 0
+	beq-  cr7, __setjmp_toc
+
+	mflr  6
+	std   6, 512(3)
+	std   2, 512+16(3)
+	std  16, 512+24(3)
+	mr   16, 3
+
+	bl __setjmp_toc
+
+	mr   4,  3
+	mr   3, 16
+	ld   5, 512(3)
+	mtlr 5
+	ld   2, 512+16(3)
+	ld  16, 512+24(3)
+
+.hidden __sigsetjmp_tail
+	b __sigsetjmp_tail
libc/musl/src/signal/s390x/restore.s
@@ -0,0 +1,11 @@
+	.global __restore
+	.hidden __restore
+	.type __restore,%function
+__restore:
+	svc 119 #__NR_sigreturn
+
+	.global __restore_rt
+	.hidden __restore_rt
+	.type __restore_rt,%function
+__restore_rt:
+	svc 173 # __NR_rt_sigreturn
libc/musl/src/signal/s390x/sigsetjmp.s
@@ -0,0 +1,23 @@
+	.global sigsetjmp
+	.global __sigsetjmp
+	.type sigsetjmp,%function
+	.type __sigsetjmp,%function
+	.hidden ___setjmp
+sigsetjmp:
+__sigsetjmp:
+	ltgr  %r3, %r3
+	jz    ___setjmp
+
+	stg   %r14, 18*8(%r2)
+	stg   %r6,  20*8(%r2)
+	lgr   %r6,  %r2
+
+	brasl %r14, ___setjmp
+
+	lgr   %r3,  %r2
+	lgr   %r2,  %r6
+	lg    %r14, 18*8(%r2)
+	lg    %r6,  20*8(%r2)
+
+.hidden __sigsetjmp_tail
+	jg __sigsetjmp_tail
libc/musl/src/signal/sh/restore.s
@@ -0,0 +1,24 @@
+.global __restore
+.hidden __restore
+__restore:
+	mov   #119, r3  !__NR_sigreturn
+	trapa #31
+
+	or    r0, r0
+	or    r0, r0
+	or    r0, r0
+	or    r0, r0
+	or    r0, r0
+
+.global __restore_rt
+.hidden __restore_rt
+__restore_rt:
+	mov   #100, r3  !__NR_rt_sigreturn
+	add   #73, r3
+	trapa #31
+
+	or    r0, r0
+	or    r0, r0
+	or    r0, r0
+	or    r0, r0
+	or    r0, r0
libc/musl/src/signal/sh/sigsetjmp.s
@@ -0,0 +1,41 @@
+.global sigsetjmp
+.global __sigsetjmp
+.type sigsetjmp,@function
+.type __sigsetjmp,@function
+sigsetjmp:
+__sigsetjmp:
+	tst r5, r5
+	bt 9f
+
+	mov r4, r6
+	add #60, r6
+	sts pr, r0
+	mov.l r0, @r6
+	mov.l r8, @(4+8,r6)
+
+	mov.l 1f, r0
+2:	bsrf r0
+	 mov r4, r8
+
+	mov r0, r5
+	mov r8, r4
+	mov r4, r6
+	add #60, r6
+
+	mov.l @r6, r0
+	lds r0, pr
+
+	mov.l 3f, r0
+4:	braf r0
+	 mov.l @(4+8,r4), r8
+
+9:	mov.l 5f, r0
+6:	braf r0
+	 nop
+
+.align 2
+.hidden ___setjmp
+1:	.long ___setjmp@PLT-(2b+4-.)
+.hidden __sigsetjmp_tail
+3:	.long __sigsetjmp_tail@PLT-(4b+4-.)
+5:	.long ___setjmp@PLT-(6b+4-.)
libc/musl/src/signal/x32/restore.s
@@ -0,0 +1,8 @@
+	nop
+.global __restore_rt
+.hidden __restore_rt
+.type __restore_rt,@function
+__restore_rt:
+	mov $0x40000201, %rax /* SYS_rt_sigreturn */
+	syscall
+.size __restore_rt,.-__restore_rt
libc/musl/src/signal/x32/sigsetjmp.s
@@ -0,0 +1,25 @@
+.global sigsetjmp
+.global __sigsetjmp
+.type sigsetjmp,@function
+.type __sigsetjmp,@function
+sigsetjmp:
+__sigsetjmp:
+	test %esi,%esi
+	jz 1f
+
+	popq 64(%rdi)
+	mov %rbx,72+8(%rdi)
+	mov %rdi,%rbx
+
+	call setjmp@PLT
+
+	pushq 64(%rbx)
+	movl $0, 4(%rsp)
+	mov %rbx,%rdi
+	mov %eax,%esi
+	mov 72+8(%rbx),%rbx
+
+.hidden __sigsetjmp_tail
+	jmp __sigsetjmp_tail
+
+1:	jmp setjmp@PLT
libc/musl/src/signal/x86_64/restore.s
@@ -0,0 +1,8 @@
+	nop
+.global __restore_rt
+.hidden __restore_rt
+.type __restore_rt,@function
+__restore_rt:
+	mov $15, %rax
+	syscall
+.size __restore_rt,.-__restore_rt
libc/musl/src/signal/x86_64/sigsetjmp.s
@@ -0,0 +1,24 @@
+.global sigsetjmp
+.global __sigsetjmp
+.type sigsetjmp,@function
+.type __sigsetjmp,@function
+sigsetjmp:
+__sigsetjmp:
+	test %esi,%esi
+	jz 1f
+
+	popq 64(%rdi)
+	mov %rbx,72+8(%rdi)
+	mov %rdi,%rbx
+
+	call setjmp@PLT
+
+	pushq 64(%rbx)
+	mov %rbx,%rdi
+	mov %eax,%esi
+	mov 72+8(%rbx),%rbx
+
+.hidden __sigsetjmp_tail
+	jmp __sigsetjmp_tail
+
+1:	jmp setjmp@PLT
libc/musl/src/signal/block.c
@@ -0,0 +1,44 @@
+#include "pthread_impl.h"
+#include "syscall.h"
+#include <signal.h>
+
+static const unsigned long all_mask[] = {
+#if ULONG_MAX == 0xffffffff && _NSIG == 129
+	-1UL, -1UL, -1UL, -1UL
+#elif ULONG_MAX == 0xffffffff
+	-1UL, -1UL
+#else
+	-1UL
+#endif
+};
+
+static const unsigned long app_mask[] = {
+#if ULONG_MAX == 0xffffffff
+#if _NSIG == 65
+	0x7fffffff, 0xfffffffc
+#else
+	0x7fffffff, 0xfffffffc, -1UL, -1UL
+#endif
+#else
+#if _NSIG == 65
+	0xfffffffc7fffffff
+#else
+	0xfffffffc7fffffff, -1UL
+#endif
+#endif
+};
+
+void __block_all_sigs(void *set)
+{
+	__syscall(SYS_rt_sigprocmask, SIG_BLOCK, &all_mask, set, _NSIG/8);
+}
+
+void __block_app_sigs(void *set)
+{
+	__syscall(SYS_rt_sigprocmask, SIG_BLOCK, &app_mask, set, _NSIG/8);
+}
+
+void __restore_sigs(void *set)
+{
+	__syscall(SYS_rt_sigprocmask, SIG_SETMASK, set, 0, _NSIG/8);
+}
libc/musl/src/signal/getitimer.c
@@ -0,0 +1,7 @@
+#include <sys/time.h>
+#include "syscall.h"
+
+int getitimer(int which, struct itimerval *old)
+{
+	return syscall(SYS_getitimer, which, old);
+}
libc/musl/src/signal/kill.c
@@ -0,0 +1,7 @@
+#include <signal.h>
+#include "syscall.h"
+
+int kill(pid_t pid, int sig)
+{
+	return syscall(SYS_kill, pid, sig);
+}
libc/musl/src/signal/killpg.c
@@ -0,0 +1,11 @@
+#include <signal.h>
+#include <errno.h>
+
+int killpg(pid_t pgid, int sig)
+{
+	if (pgid < 0) {
+		errno = EINVAL;
+		return -1;
+	}
+	return kill(-pgid, sig);
+}
libc/musl/src/signal/psiginfo.c
@@ -0,0 +1,6 @@
+#include <signal.h>
+
+void psiginfo(const siginfo_t *si, const char *msg)
+{
+	psignal(si->si_signo, msg);
+}
libc/musl/src/signal/psignal.c
@@ -0,0 +1,27 @@
+#include "stdio_impl.h"
+#include <string.h>
+#include <signal.h>
+#include <errno.h>
+
+void psignal(int sig, const char *msg)
+{
+	FILE *f = stderr;
+	char *s = strsignal(sig);
+
+	FLOCK(f);
+
+	/* Save stderr's orientation and encoding rule, since psignal is not
+	 * permitted to change them. Save errno and restore it if there is no
+	 * error since fprintf might change it even on success but psignal is
+	 * not permitted to do so. */
+	void *old_locale = f->locale;
+	int old_mode = f->mode;
+	int old_errno = errno;
+
+	if (fprintf(f, "%s%s%s\n", msg?msg:"", msg?": ":"", s)>=0)
+		errno = old_errno;
+	f->mode = old_mode;
+	f->locale = old_locale;
+
+	FUNLOCK(f);
+}
libc/musl/src/signal/raise.c
@@ -0,0 +1,13 @@
+#include <signal.h>
+#include <stdint.h>
+#include "syscall.h"
+#include "pthread_impl.h"
+
+int raise(int sig)
+{
+	sigset_t set;
+	__block_app_sigs(&set);
+	int ret = syscall(SYS_tkill, __pthread_self()->tid, sig);
+	__restore_sigs(&set);
+	return ret;
+}
libc/musl/src/signal/restore.c
@@ -0,0 +1,12 @@
+#include <features.h>
+
+/* These functions will not work, but suffice for targets where the
+ * kernel sigaction structure does not actually use sa_restorer. */
+
+hidden void __restore()
+{
+}
+
+hidden void __restore_rt()
+{
+}
libc/musl/src/signal/setitimer.c
@@ -0,0 +1,7 @@
+#include <sys/time.h>
+#include "syscall.h"
+
+int setitimer(int which, const struct itimerval *restrict new, struct itimerval *restrict old)
+{
+	return syscall(SYS_setitimer, which, new, old);
+}
libc/musl/src/signal/sigaction.c
@@ -0,0 +1,88 @@
+#include <signal.h>
+#include <errno.h>
+#include <string.h>
+#include "syscall.h"
+#include "pthread_impl.h"
+#include "libc.h"
+#include "lock.h"
+#include "ksigaction.h"
+
+volatile int dummy_lock[1] = { 0 };
+
+extern hidden volatile int __abort_lock[1];
+
+weak_alias(dummy_lock, __abort_lock);
+
+static int unmask_done;
+static unsigned long handler_set[_NSIG/(8*sizeof(long))];
+
+void __get_handler_set(sigset_t *set)
+{
+	memcpy(set, handler_set, sizeof handler_set);
+}
+
+volatile int __eintr_valid_flag;
+
+int __libc_sigaction(int sig, const struct sigaction *restrict sa, struct sigaction *restrict old)
+{
+	struct k_sigaction ksa, ksa_old;
+	unsigned long set[_NSIG/(8*sizeof(long))];
+	if (sa) {
+		if ((uintptr_t)sa->sa_handler > 1UL) {
+			a_or_l(handler_set+(sig-1)/(8*sizeof(long)),
+				1UL<<(sig-1)%(8*sizeof(long)));
+
+			/* If pthread_create has not yet been called,
+			 * implementation-internal signals might not
+			 * yet have been unblocked. They must be
+			 * unblocked before any signal handler is
+			 * installed, so that an application cannot
+			 * receive an illegal sigset_t (with them
+			 * blocked) as part of the ucontext_t passed
+			 * to the signal handler. */
+			if (!libc.threaded && !unmask_done) {
+				__syscall(SYS_rt_sigprocmask, SIG_UNBLOCK,
+					SIGPT_SET, 0, _NSIG/8);
+				unmask_done = 1;
+			}
+
+			if (!(sa->sa_flags & SA_RESTART)) {
+				a_store(&__eintr_valid_flag, 1);
+			}
+		}
+		/* Changing the disposition of SIGABRT to anything but
+		 * SIG_DFL requires a lock, so that it cannot be changed
+		 * while abort is terminating the process after simply
+		 * calling raise(SIGABRT) failed to do so. */
+		if (sa->sa_handler != SIG_DFL && sig == SIGABRT) {
+			__block_all_sigs(&set);
+			LOCK(__abort_lock);
+		}
+		ksa.handler = sa->sa_handler;
+		ksa.flags = sa->sa_flags | SA_RESTORER;
+		ksa.restorer = (sa->sa_flags & SA_SIGINFO) ? __restore_rt : __restore;
+		memcpy(&ksa.mask, &sa->sa_mask, _NSIG/8);
+	}
+	int r = __syscall(SYS_rt_sigaction, sig, sa?&ksa:0, old?&ksa_old:0, _NSIG/8);
+	if (sig == SIGABRT && sa && sa->sa_handler != SIG_DFL) {
+		UNLOCK(__abort_lock);
+		__restore_sigs(&set);
+	}
+	if (old && !r) {
+		old->sa_handler = ksa_old.handler;
+		old->sa_flags = ksa_old.flags;
+		memcpy(&old->sa_mask, &ksa_old.mask, _NSIG/8);
+	}
+	return __syscall_ret(r);
+}
+
+int __sigaction(int sig, const struct sigaction *restrict sa, struct sigaction *restrict old)
+{
+	if (sig-32U < 3 || sig-1U >= _NSIG-1) {
+		errno = EINVAL;
+		return -1;
+	}
+	return __libc_sigaction(sig, sa, old);
+}
+
+weak_alias(__sigaction, sigaction);
libc/musl/src/signal/sigaddset.c
@@ -0,0 +1,13 @@
+#include <signal.h>
+#include <errno.h>
+
+int sigaddset(sigset_t *set, int sig)
+{
+	unsigned s = sig-1;
+	if (s >= _NSIG-1 || sig-32U < 3) {
+		errno = EINVAL;
+		return -1;
+	}
+	set->__bits[s/8/sizeof *set->__bits] |= 1UL<<(s&8*sizeof *set->__bits-1);
+	return 0;
+}
libc/musl/src/signal/sigaltstack.c
@@ -0,0 +1,18 @@
+#include <signal.h>
+#include <errno.h>
+#include "syscall.h"
+
+int sigaltstack(const stack_t *restrict ss, stack_t *restrict old)
+{
+	if (ss) {
+		if (ss->ss_size < MINSIGSTKSZ) {
+			errno = ENOMEM;
+			return -1;
+		}
+		if (ss->ss_flags & ~SS_DISABLE) {
+			errno = EINVAL;
+			return -1;
+		}
+	}
+	return syscall(SYS_sigaltstack, ss, old);
+}
libc/musl/src/signal/sigandset.c
@@ -0,0 +1,12 @@
+#define _GNU_SOURCE
+#include <signal.h>
+
+#define SST_SIZE (_NSIG/8/sizeof(long))
+
+int sigandset(sigset_t *dest, const sigset_t *left, const sigset_t *right)
+{
+	unsigned long i = 0, *d = (void*) dest, *l = (void*) left, *r = (void*) right;
+	for(; i < SST_SIZE; i++) d[i] = l[i] & r[i];
+	return 0;
+}
+
libc/musl/src/signal/sigdelset.c
@@ -0,0 +1,13 @@
+#include <signal.h>
+#include <errno.h>
+
+int sigdelset(sigset_t *set, int sig)
+{
+	unsigned s = sig-1;
+	if (s >= _NSIG-1 || sig-32U < 3) {
+		errno = EINVAL;
+		return -1;
+	}
+	set->__bits[s/8/sizeof *set->__bits] &=~(1UL<<(s&8*sizeof *set->__bits-1));
+	return 0;
+}
libc/musl/src/signal/sigemptyset.c
@@ -0,0 +1,13 @@
+#include <signal.h>
+#include <string.h>
+
+int sigemptyset(sigset_t *set)
+{
+	set->__bits[0] = 0;
+	if (sizeof(long)==4 || _NSIG > 65) set->__bits[1] = 0;
+	if (sizeof(long)==4 && _NSIG > 65) {
+		set->__bits[2] = 0;
+		set->__bits[3] = 0;
+	}
+	return 0;
+}
libc/musl/src/signal/sigfillset.c
@@ -0,0 +1,18 @@
+#include <signal.h>
+#include <limits.h>
+
+int sigfillset(sigset_t *set)
+{
+#if ULONG_MAX == 0xffffffff
+	set->__bits[0] = 0x7ffffffful;
+	set->__bits[1] = 0xfffffffcul;
+	if (_NSIG > 65) {
+		set->__bits[2] = 0xfffffffful;
+		set->__bits[3] = 0xfffffffful;
+	}
+#else
+	set->__bits[0] = 0xfffffffc7ffffffful;
+	if (_NSIG > 65) set->__bits[1] = 0xfffffffffffffffful;
+#endif
+	return 0;
+}
libc/musl/src/signal/sighold.c
@@ -0,0 +1,10 @@
+#include <signal.h>
+
+int sighold(int sig)
+{
+	sigset_t mask;
+
+	sigemptyset(&mask);
+	if (sigaddset(&mask, sig) < 0) return -1;
+	return sigprocmask(SIG_BLOCK, &mask, 0);
+}
libc/musl/src/signal/sigignore.c
@@ -0,0 +1,11 @@
+#include <signal.h>
+
+int sigignore(int sig)
+{
+	struct sigaction sa;
+
+	sigemptyset(&sa.sa_mask);
+	sa.sa_handler = SIG_IGN;
+	sa.sa_flags = 0;
+	return sigaction(sig, &sa, 0);
+}
libc/musl/src/signal/siginterrupt.c
@@ -0,0 +1,12 @@
+#include <signal.h>
+
+int siginterrupt(int sig, int flag)
+{
+	struct sigaction sa;
+
+	sigaction(sig, 0, &sa);
+	if (flag) sa.sa_flags &= ~SA_RESTART;
+	else sa.sa_flags |= SA_RESTART;
+
+	return sigaction(sig, &sa, 0);
+}
libc/musl/src/signal/sigisemptyset.c
@@ -0,0 +1,10 @@
+#define _GNU_SOURCE
+#include <signal.h>
+#include <string.h>
+
+int sigisemptyset(const sigset_t *set)
+{
+	for (size_t i=0; i<_NSIG/8/sizeof *set->__bits; i++)
+		if (set->__bits[i]) return 0;
+	return 1;
+}
libc/musl/src/signal/sigismember.c
@@ -0,0 +1,8 @@
+#include <signal.h>
+
+int sigismember(const sigset_t *set, int sig)
+{
+	unsigned s = sig-1;
+	if (s >= _NSIG-1) return 0;
+	return !!(set->__bits[s/8/sizeof *set->__bits] & 1UL<<(s&8*sizeof *set->__bits-1));
+}
libc/musl/src/signal/siglongjmp.c
@@ -0,0 +1,9 @@
+#include <setjmp.h>
+#include <signal.h>
+#include "syscall.h"
+#include "pthread_impl.h"
+
+_Noreturn void siglongjmp(sigjmp_buf buf, int ret)
+{
+	longjmp(buf, ret);
+}
libc/musl/src/signal/signal.c
@@ -0,0 +1,13 @@
+#include <signal.h>
+#include "syscall.h"
+
+void (*signal(int sig, void (*func)(int)))(int)
+{
+	struct sigaction sa_old, sa = { .sa_handler = func, .sa_flags = SA_RESTART };
+	if (__sigaction(sig, &sa, &sa_old) < 0)
+		return SIG_ERR;
+	return sa_old.sa_handler;
+}
+
+weak_alias(signal, bsd_signal);
+weak_alias(signal, __sysv_signal);
libc/musl/src/signal/sigorset.c
@@ -0,0 +1,12 @@
+#define _GNU_SOURCE
+#include <signal.h>
+
+#define SST_SIZE (_NSIG/8/sizeof(long))
+
+int sigorset(sigset_t *dest, const sigset_t *left, const sigset_t *right)
+{
+	unsigned long i = 0, *d = (void*) dest, *l = (void*) left, *r = (void*) right;
+	for(; i < SST_SIZE; i++) d[i] = l[i] | r[i];
+	return 0;
+}
+
libc/musl/src/signal/sigpause.c
@@ -0,0 +1,9 @@
+#include <signal.h>
+
+int sigpause(int sig)
+{
+	sigset_t mask;
+	sigprocmask(0, 0, &mask);
+	sigdelset(&mask, sig);
+	return sigsuspend(&mask);
+}
libc/musl/src/signal/sigpending.c
@@ -0,0 +1,7 @@
+#include <signal.h>
+#include "syscall.h"
+
+int sigpending(sigset_t *set)
+{
+	return syscall(SYS_rt_sigpending, set, _NSIG/8);
+}
libc/musl/src/signal/sigprocmask.c
@@ -0,0 +1,10 @@
+#include <signal.h>
+#include <errno.h>
+
+int sigprocmask(int how, const sigset_t *restrict set, sigset_t *restrict old)
+{
+	int r = pthread_sigmask(how, set, old);
+	if (!r) return r;
+	errno = r;
+	return -1;
+}
libc/musl/src/signal/sigqueue.c
@@ -0,0 +1,22 @@
+#include <signal.h>
+#include <string.h>
+#include <unistd.h>
+#include "syscall.h"
+#include "pthread_impl.h"
+
+int sigqueue(pid_t pid, int sig, const union sigval value)
+{
+	siginfo_t si;
+	sigset_t set;
+	int r;
+	memset(&si, 0, sizeof si);
+	si.si_signo = sig;
+	si.si_code = SI_QUEUE;
+	si.si_value = value;
+	si.si_uid = getuid();
+	__block_app_sigs(&set);
+	si.si_pid = getpid();
+	r = syscall(SYS_rt_sigqueueinfo, pid, sig, &si);
+	__restore_sigs(&set);
+	return r;
+}
libc/musl/src/signal/sigrelse.c
@@ -0,0 +1,10 @@
+#include <signal.h>
+
+int sigrelse(int sig)
+{
+	sigset_t mask;
+
+	sigemptyset(&mask);
+	if (sigaddset(&mask, sig) < 0) return -1;
+	return sigprocmask(SIG_UNBLOCK, &mask, 0);
+}
libc/musl/src/signal/sigrtmax.c
@@ -0,0 +1,6 @@
+#include <signal.h>
+
+int __libc_current_sigrtmax()
+{
+	return _NSIG-1;
+}
libc/musl/src/signal/sigrtmin.c
@@ -0,0 +1,6 @@
+#include <signal.h>
+
+int __libc_current_sigrtmin()
+{
+	return 35;
+}
libc/musl/src/signal/sigset.c
@@ -0,0 +1,27 @@
+#include <signal.h>
+
+void (*sigset(int sig, void (*handler)(int)))(int)
+{
+	struct sigaction sa, sa_old;
+	sigset_t mask;
+
+	sigemptyset(&mask);
+	if (sigaddset(&mask, sig) < 0)
+		return SIG_ERR;
+	
+	if (handler == SIG_HOLD) {
+		if (sigaction(sig, 0, &sa_old) < 0)
+			return SIG_ERR;
+		if (sigprocmask(SIG_BLOCK, &mask, &mask) < 0)
+			return SIG_ERR;
+	} else {
+		sa.sa_handler = handler;
+		sa.sa_flags = 0;
+		sigemptyset(&sa.sa_mask);
+		if (sigaction(sig, &sa, &sa_old) < 0)
+			return SIG_ERR;
+		if (sigprocmask(SIG_UNBLOCK, &mask, &mask) < 0)
+			return SIG_ERR;
+	}
+	return sigismember(&mask, sig) ? SIG_HOLD : sa_old.sa_handler;
+}
libc/musl/src/signal/sigsetjmp.c
libc/musl/src/signal/sigsetjmp_tail.c
@@ -0,0 +1,10 @@
+#include <setjmp.h>
+#include <signal.h>
+#include "syscall.h"
+
+hidden int __sigsetjmp_tail(sigjmp_buf jb, int ret)
+{
+	void *p = jb->__ss;
+	__syscall(SYS_rt_sigprocmask, SIG_SETMASK, ret?p:0, ret?0:p, _NSIG/8);
+	return ret;
+}
libc/musl/src/signal/sigsuspend.c
@@ -0,0 +1,7 @@
+#include <signal.h>
+#include "syscall.h"
+
+int sigsuspend(const sigset_t *mask)
+{
+	return syscall_cp(SYS_rt_sigsuspend, mask, _NSIG/8);
+}
libc/musl/src/signal/sigtimedwait.c
@@ -0,0 +1,12 @@
+#include <signal.h>
+#include <errno.h>
+#include "syscall.h"
+
+int sigtimedwait(const sigset_t *restrict mask, siginfo_t *restrict si, const struct timespec *restrict timeout)
+{
+	int ret;
+	do ret = syscall_cp(SYS_rt_sigtimedwait, mask,
+		si, timeout, _NSIG/8);
+	while (ret<0 && errno==EINTR);
+	return ret;
+}
libc/musl/src/signal/sigwait.c
@@ -0,0 +1,10 @@
+#include <signal.h>
+
+int sigwait(const sigset_t *restrict mask, int *restrict sig)
+{
+	siginfo_t si;
+	if (sigtimedwait(mask, &si, 0) < 0)
+		return -1;
+	*sig = si.si_signo;
+	return 0;
+}
libc/musl/src/signal/sigwaitinfo.c
@@ -0,0 +1,6 @@
+#include <signal.h>
+
+int sigwaitinfo(const sigset_t *restrict mask, siginfo_t *restrict si)
+{
+	return sigtimedwait(mask, si, 0);
+}
libc/musl/src/stat/__xstat.c
@@ -0,0 +1,36 @@
+#include <sys/stat.h>
+
+int __fxstat(int ver, int fd, struct stat *buf)
+{
+	return fstat(fd, buf);
+}
+
+int __fxstatat(int ver, int fd, const char *path, struct stat *buf, int flag)
+{
+	return fstatat(fd, path, buf, flag);
+}
+
+int __lxstat(int ver, const char *path, struct stat *buf)
+{
+	return lstat(path, buf);
+}
+
+int __xstat(int ver, const char *path, struct stat *buf)
+{
+	return stat(path, buf);
+}
+
+weak_alias(__fxstat, __fxstat64);
+weak_alias(__fxstatat, __fxstatat64);
+weak_alias(__lxstat, __lxstat64);
+weak_alias(__xstat, __xstat64);
+
+int __xmknod(int ver, const char *path, mode_t mode, dev_t *dev)
+{
+	return mknod(path, mode, *dev);
+}
+
+int __xmknodat(int ver, int fd, const char *path, mode_t mode, dev_t *dev)
+{
+	return mknodat(fd, path, mode, *dev);
+}
libc/musl/src/stat/chmod.c
@@ -0,0 +1,12 @@
+#include <sys/stat.h>
+#include <fcntl.h>
+#include "syscall.h"
+
+int chmod(const char *path, mode_t mode)
+{
+#ifdef SYS_chmod
+	return syscall(SYS_chmod, path, mode);
+#else
+	return syscall(SYS_fchmodat, AT_FDCWD, path, mode);
+#endif
+}
libc/musl/src/stat/fchmod.c
@@ -0,0 +1,19 @@
+#include <sys/stat.h>
+#include <errno.h>
+#include <fcntl.h>
+#include "syscall.h"
+
+int fchmod(int fd, mode_t mode)
+{
+	int ret = __syscall(SYS_fchmod, fd, mode);
+	if (ret != -EBADF || __syscall(SYS_fcntl, fd, F_GETFD) < 0)
+		return __syscall_ret(ret);
+
+	char buf[15+3*sizeof(int)];
+	__procfdname(buf, fd);
+#ifdef SYS_chmod
+	return syscall(SYS_chmod, buf, mode);
+#else
+	return syscall(SYS_fchmodat, AT_FDCWD, buf, mode);
+#endif
+}
libc/musl/src/stat/fchmodat.c
@@ -0,0 +1,37 @@
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <errno.h>
+#include "syscall.h"
+
+int fchmodat(int fd, const char *path, mode_t mode, int flag)
+{
+	if (!flag) return syscall(SYS_fchmodat, fd, path, mode, flag);
+
+	if (flag != AT_SYMLINK_NOFOLLOW)
+		return __syscall_ret(-EINVAL);
+
+	struct stat st;
+	int ret, fd2;
+	char proc[15+3*sizeof(int)];
+
+	if ((ret = __syscall(SYS_fstatat, fd, path, &st, flag)))
+		return __syscall_ret(ret);
+	if (S_ISLNK(st.st_mode))
+		return __syscall_ret(-EOPNOTSUPP);
+
+	if ((fd2 = __syscall(SYS_openat, fd, path, O_RDONLY|O_PATH|O_NOFOLLOW|O_NOCTTY|O_CLOEXEC)) < 0) {
+		if (fd2 == -ELOOP)
+			return __syscall_ret(-EOPNOTSUPP);
+		return __syscall_ret(fd2);
+	}
+
+	__procfdname(proc, fd2);
+	ret = __syscall(SYS_fstatat, AT_FDCWD, proc, &st, 0);
+	if (!ret) {
+		if (S_ISLNK(st.st_mode)) ret = -EOPNOTSUPP;
+		else ret = __syscall(SYS_fchmodat, AT_FDCWD, proc, mode);
+	}
+
+	__syscall(SYS_close, fd2);
+	return __syscall_ret(ret);
+}
libc/musl/src/stat/fstat.c
@@ -0,0 +1,21 @@
+#include <sys/stat.h>
+#include <errno.h>
+#include <fcntl.h>
+#include "syscall.h"
+
+int fstat(int fd, struct stat *st)
+{
+	int ret = __syscall(SYS_fstat, fd, st);
+	if (ret != -EBADF || __syscall(SYS_fcntl, fd, F_GETFD) < 0)
+		return __syscall_ret(ret);
+
+	char buf[15+3*sizeof(int)];
+	__procfdname(buf, fd);
+#ifdef SYS_stat
+	return syscall(SYS_stat, buf, st);
+#else
+	return syscall(SYS_fstatat, AT_FDCWD, buf, st, 0);
+#endif
+}
+
+weak_alias(fstat, fstat64);
libc/musl/src/stat/fstatat.c
@@ -0,0 +1,9 @@
+#include <sys/stat.h>
+#include "syscall.h"
+
+int fstatat(int fd, const char *restrict path, struct stat *restrict buf, int flag)
+{
+	return syscall(SYS_fstatat, fd, path, buf, flag);
+}
+
+weak_alias(fstatat, fstatat64);
libc/musl/src/stat/futimens.c
@@ -0,0 +1,6 @@
+#include <sys/stat.h>
+
+int futimens(int fd, const struct timespec times[2])
+{
+	return utimensat(fd, 0, times, 0);
+}
libc/musl/src/stat/futimesat.c
@@ -0,0 +1,22 @@
+#define _GNU_SOURCE
+#include <sys/time.h>
+#include <sys/stat.h>
+#include <errno.h>
+#include "syscall.h"
+
+int __futimesat(int dirfd, const char *pathname, const struct timeval times[2])
+{
+	struct timespec ts[2];
+	if (times) {
+		int i;
+		for (i=0; i<2; i++) {
+			if (times[i].tv_usec >= 1000000ULL)
+				return __syscall_ret(-EINVAL);
+			ts[i].tv_sec = times[i].tv_sec;
+			ts[i].tv_nsec = times[i].tv_usec * 1000;
+		}
+	}
+	return utimensat(dirfd, pathname, times ? ts : 0, 0);
+}
+
+weak_alias(__futimesat, futimesat);
libc/musl/src/stat/lchmod.c
@@ -0,0 +1,8 @@
+#define _GNU_SOURCE
+#include <sys/stat.h>
+#include <fcntl.h>
+
+int lchmod(const char *path, mode_t mode)
+{
+	return fchmodat(AT_FDCWD, path, mode, AT_SYMLINK_NOFOLLOW);
+}
libc/musl/src/stat/lstat.c
@@ -0,0 +1,14 @@
+#include <sys/stat.h>
+#include <fcntl.h>
+#include "syscall.h"
+
+int lstat(const char *restrict path, struct stat *restrict buf)
+{
+#ifdef SYS_lstat
+	return syscall(SYS_lstat, path, buf);
+#else
+	return syscall(SYS_fstatat, AT_FDCWD, path, buf, AT_SYMLINK_NOFOLLOW);
+#endif
+}
+
+weak_alias(lstat, lstat64);
libc/musl/src/stat/mkdir.c
@@ -0,0 +1,12 @@
+#include <sys/stat.h>
+#include <fcntl.h>
+#include "syscall.h"
+
+int mkdir(const char *path, mode_t mode)
+{
+#ifdef SYS_mkdir
+	return syscall(SYS_mkdir, path, mode);
+#else
+	return syscall(SYS_mkdirat, AT_FDCWD, path, mode);
+#endif
+}
libc/musl/src/stat/mkdirat.c
@@ -0,0 +1,7 @@
+#include <sys/stat.h>
+#include "syscall.h"
+
+int mkdirat(int fd, const char *path, mode_t mode)
+{
+	return syscall(SYS_mkdirat, fd, path, mode);
+}
libc/musl/src/stat/mkfifo.c
@@ -0,0 +1,6 @@
+#include <sys/stat.h>
+
+int mkfifo(const char *path, mode_t mode)
+{
+	return mknod(path, mode | S_IFIFO, 0);
+}
libc/musl/src/stat/mkfifoat.c
@@ -0,0 +1,6 @@
+#include <sys/stat.h>
+
+int mkfifoat(int fd, const char *path, mode_t mode)
+{
+	return mknodat(fd, path, mode | S_IFIFO, 0);
+}
libc/musl/src/stat/mknod.c
@@ -0,0 +1,12 @@
+#include <sys/stat.h>
+#include <fcntl.h>
+#include "syscall.h"
+
+int mknod(const char *path, mode_t mode, dev_t dev)
+{
+#ifdef SYS_mknod
+	return syscall(SYS_mknod, path, mode, dev);
+#else
+	return syscall(SYS_mknodat, AT_FDCWD, path, mode, dev);
+#endif
+}
libc/musl/src/stat/mknodat.c
@@ -0,0 +1,7 @@
+#include <sys/stat.h>
+#include "syscall.h"
+
+int mknodat(int fd, const char *path, mode_t mode, dev_t dev)
+{
+	return syscall(SYS_mknodat, fd, path, mode, dev);
+}
libc/musl/src/stat/stat.c
@@ -0,0 +1,14 @@
+#include <sys/stat.h>
+#include <fcntl.h>
+#include "syscall.h"
+
+int stat(const char *restrict path, struct stat *restrict buf)
+{
+#ifdef SYS_stat
+	return syscall(SYS_stat, path, buf);
+#else
+	return syscall(SYS_fstatat, AT_FDCWD, path, buf, 0);
+#endif
+}
+
+weak_alias(stat, stat64);
libc/musl/src/stat/statvfs.c
@@ -0,0 +1,63 @@
+#include <sys/statvfs.h>
+#include <sys/statfs.h>
+#include "syscall.h"
+
+static int __statfs(const char *path, struct statfs *buf)
+{
+	*buf = (struct statfs){0};
+#ifdef SYS_statfs64
+	return syscall(SYS_statfs64, path, sizeof *buf, buf);
+#else
+	return syscall(SYS_statfs, path, buf);
+#endif
+}
+
+static int __fstatfs(int fd, struct statfs *buf)
+{
+	*buf = (struct statfs){0};
+#ifdef SYS_fstatfs64
+	return syscall(SYS_fstatfs64, fd, sizeof *buf, buf);
+#else
+	return syscall(SYS_fstatfs, fd, buf);
+#endif
+}
+
+weak_alias(__statfs, statfs);
+weak_alias(__fstatfs, fstatfs);
+
+static void fixup(struct statvfs *out, const struct statfs *in)
+{
+	*out = (struct statvfs){0};
+	out->f_bsize = in->f_bsize;
+	out->f_frsize = in->f_frsize ? in->f_frsize : in->f_bsize;
+	out->f_blocks = in->f_blocks;
+	out->f_bfree = in->f_bfree;
+	out->f_bavail = in->f_bavail;
+	out->f_files = in->f_files;
+	out->f_ffree = in->f_ffree;
+	out->f_favail = in->f_ffree;
+	out->f_fsid = in->f_fsid.__val[0];
+	out->f_flag = in->f_flags;
+	out->f_namemax = in->f_namelen;
+}
+
+int statvfs(const char *restrict path, struct statvfs *restrict buf)
+{
+	struct statfs kbuf;
+	if (__statfs(path, &kbuf)<0) return -1;
+	fixup(buf, &kbuf);
+	return 0;
+}
+
+int fstatvfs(int fd, struct statvfs *buf)
+{
+	struct statfs kbuf;
+	if (__fstatfs(fd, &kbuf)<0) return -1;
+	fixup(buf, &kbuf);
+	return 0;
+}
+
+weak_alias(statvfs, statvfs64);
+weak_alias(statfs, statfs64);
+weak_alias(fstatvfs, fstatvfs64);
+weak_alias(fstatfs, fstatfs64);
libc/musl/src/stat/umask.c
@@ -0,0 +1,7 @@
+#include <sys/stat.h>
+#include "syscall.h"
+
+mode_t umask(mode_t mode)
+{
+	return syscall(SYS_umask, mode);
+}
libc/musl/src/stat/utimensat.c
@@ -0,0 +1,37 @@
+#include <sys/stat.h>
+#include <sys/time.h>
+#include <fcntl.h>
+#include <errno.h>
+#include "syscall.h"
+
+int utimensat(int fd, const char *path, const struct timespec times[2], int flags)
+{
+	int r = __syscall(SYS_utimensat, fd, path, times, flags);
+#ifdef SYS_futimesat
+	if (r != -ENOSYS || flags) return __syscall_ret(r);
+	struct timeval *tv = 0, tmp[2];
+	if (times) {
+		int i;
+		tv = tmp;
+		for (i=0; i<2; i++) {
+			if (times[i].tv_nsec >= 1000000000ULL) {
+				if (times[i].tv_nsec == UTIME_NOW &&
+				    times[1-i].tv_nsec == UTIME_NOW) {
+					tv = 0;
+					break;
+				}
+				if (times[i].tv_nsec == UTIME_OMIT)
+					return __syscall_ret(-ENOSYS);
+				return __syscall_ret(-EINVAL);
+			}
+			tmp[i].tv_sec = times[i].tv_sec;
+			tmp[i].tv_usec = times[i].tv_nsec / 1000;
+		}
+	}
+
+	r = __syscall(SYS_futimesat, fd, path, tv);
+	if (r != -ENOSYS || fd != AT_FDCWD) return __syscall_ret(r);
+	r = __syscall(SYS_utimes, path, tv);
+#endif
+	return __syscall_ret(r);
+}
libc/musl/src/stdio/__fclose_ca.c
@@ -0,0 +1,6 @@
+#include "stdio_impl.h"
+
+int __fclose_ca(FILE *f)
+{
+	return f->close(f);
+}
libc/musl/src/stdio/__fdopen.c
@@ -0,0 +1,61 @@
+#include "stdio_impl.h"
+#include <stdlib.h>
+#include <sys/ioctl.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <string.h>
+#include "libc.h"
+
+FILE *__fdopen(int fd, const char *mode)
+{
+	FILE *f;
+	struct winsize wsz;
+
+	/* Check for valid initial mode character */
+	if (!strchr("rwa", *mode)) {
+		errno = EINVAL;
+		return 0;
+	}
+
+	/* Allocate FILE+buffer or fail */
+	if (!(f=malloc(sizeof *f + UNGET + BUFSIZ))) return 0;
+
+	/* Zero-fill only the struct, not the buffer */
+	memset(f, 0, sizeof *f);
+
+	/* Impose mode restrictions */
+	if (!strchr(mode, '+')) f->flags = (*mode == 'r') ? F_NOWR : F_NORD;
+
+	/* Apply close-on-exec flag */
+	if (strchr(mode, 'e')) __syscall(SYS_fcntl, fd, F_SETFD, FD_CLOEXEC);
+
+	/* Set append mode on fd if opened for append */
+	if (*mode == 'a') {
+		int flags = __syscall(SYS_fcntl, fd, F_GETFL);
+		if (!(flags & O_APPEND))
+			__syscall(SYS_fcntl, fd, F_SETFL, flags | O_APPEND);
+		f->flags |= F_APP;
+	}
+
+	f->fd = fd;
+	f->buf = (unsigned char *)f + sizeof *f + UNGET;
+	f->buf_size = BUFSIZ;
+
+	/* Activate line buffered mode for terminals */
+	f->lbf = EOF;
+	if (!(f->flags & F_NOWR) && !__syscall(SYS_ioctl, fd, TIOCGWINSZ, &wsz))
+		f->lbf = '\n';
+
+	/* Initialize op ptrs. No problem if some are unneeded. */
+	f->read = __stdio_read;
+	f->write = __stdio_write;
+	f->seek = __stdio_seek;
+	f->close = __stdio_close;
+
+	if (!libc.threaded) f->lock = -1;
+
+	/* Add new FILE to open file list */
+	return __ofl_add(f);
+}
+
+weak_alias(__fdopen, fdopen);
libc/musl/src/stdio/__fmodeflags.c
@@ -0,0 +1,16 @@
+#include <fcntl.h>
+#include <string.h>
+
+int __fmodeflags(const char *mode)
+{
+	int flags;
+	if (strchr(mode, '+')) flags = O_RDWR;
+	else if (*mode == 'r') flags = O_RDONLY;
+	else flags = O_WRONLY;
+	if (strchr(mode, 'x')) flags |= O_EXCL;
+	if (strchr(mode, 'e')) flags |= O_CLOEXEC;
+	if (*mode != 'r') flags |= O_CREAT;
+	if (*mode == 'w') flags |= O_TRUNC;
+	if (*mode == 'a') flags |= O_APPEND;
+	return flags;
+}
libc/musl/src/stdio/__fopen_rb_ca.c
@@ -0,0 +1,22 @@
+#include "stdio_impl.h"
+#include <fcntl.h>
+#include <string.h>
+
+FILE *__fopen_rb_ca(const char *filename, FILE *f, unsigned char *buf, size_t len)
+{
+	memset(f, 0, sizeof *f);
+
+	f->fd = sys_open(filename, O_RDONLY|O_CLOEXEC);
+	if (f->fd < 0) return 0;
+	__syscall(SYS_fcntl, f->fd, F_SETFD, FD_CLOEXEC);
+
+	f->flags = F_NOWR | F_PERM;
+	f->buf = buf + UNGET;
+	f->buf_size = len - UNGET;
+	f->read = __stdio_read;
+	f->seek = __stdio_seek;
+	f->close = __stdio_close;
+	f->lock = -1;
+
+	return f;
+}
libc/musl/src/stdio/__lockfile.c
@@ -0,0 +1,23 @@
+#include "stdio_impl.h"
+#include "pthread_impl.h"
+
+int __lockfile(FILE *f)
+{
+	int owner = f->lock, tid = __pthread_self()->tid;
+	if ((owner & ~MAYBE_WAITERS) == tid)
+		return 0;
+	owner = a_cas(&f->lock, 0, tid);
+	if (!owner) return 1;
+	while ((owner = a_cas(&f->lock, 0, tid|MAYBE_WAITERS))) {
+		if ((owner & MAYBE_WAITERS) ||
+		    a_cas(&f->lock, owner, owner|MAYBE_WAITERS)==owner)
+			__futexwait(&f->lock, owner|MAYBE_WAITERS, 1);
+	}
+	return 1;
+}
+
+void __unlockfile(FILE *f)
+{
+	if (a_swap(&f->lock, 0) & MAYBE_WAITERS)
+		__wake(&f->lock, 1, 1);
+}
libc/musl/src/stdio/__overflow.c
@@ -0,0 +1,10 @@
+#include "stdio_impl.h"
+
+int __overflow(FILE *f, int _c)
+{
+	unsigned char c = _c;
+	if (!f->wend && __towrite(f)) return EOF;
+	if (f->wpos != f->wend && c != f->lbf) return *f->wpos++ = c;
+	if (f->write(f, &c, 1)!=1) return EOF;
+	return c;
+}
libc/musl/src/stdio/__stdio_close.c
@@ -0,0 +1,13 @@
+#include "stdio_impl.h"
+
+static int dummy(int fd)
+{
+	return fd;
+}
+
+weak_alias(dummy, __aio_close);
+
+int __stdio_close(FILE *f)
+{
+	return syscall(SYS_close, __aio_close(f->fd));
+}
libc/musl/src/stdio/__stdio_exit.c
@@ -0,0 +1,25 @@
+#include "stdio_impl.h"
+
+static FILE *volatile dummy_file = 0;
+weak_alias(dummy_file, __stdin_used);
+weak_alias(dummy_file, __stdout_used);
+weak_alias(dummy_file, __stderr_used);
+
+static void close_file(FILE *f)
+{
+	if (!f) return;
+	FFINALLOCK(f);
+	if (f->wpos != f->wbase) f->write(f, 0, 0);
+	if (f->rpos != f->rend) f->seek(f, f->rpos-f->rend, SEEK_CUR);
+}
+
+void __stdio_exit(void)
+{
+	FILE *f;
+	for (f=*__ofl_lock(); f; f=f->next) close_file(f);
+	close_file(__stdin_used);
+	close_file(__stdout_used);
+	close_file(__stderr_used);
+}
+
+weak_alias(__stdio_exit, __stdio_exit_needed);
libc/musl/src/stdio/__stdio_read.c
@@ -0,0 +1,24 @@
+#include "stdio_impl.h"
+#include <sys/uio.h>
+
+size_t __stdio_read(FILE *f, unsigned char *buf, size_t len)
+{
+	struct iovec iov[2] = {
+		{ .iov_base = buf, .iov_len = len - !!f->buf_size },
+		{ .iov_base = f->buf, .iov_len = f->buf_size }
+	};
+	ssize_t cnt;
+
+	cnt = iov[0].iov_len ? syscall(SYS_readv, f->fd, iov, 2)
+		: syscall(SYS_read, f->fd, iov[1].iov_base, iov[1].iov_len);
+	if (cnt <= 0) {
+		f->flags |= cnt ? F_ERR : F_EOF;
+		return 0;
+	}
+	if (cnt <= iov[0].iov_len) return cnt;
+	cnt -= iov[0].iov_len;
+	f->rpos = f->buf;
+	f->rend = f->buf + cnt;
+	if (f->buf_size) buf[len-1] = *f->rpos++;
+	return len;
+}
libc/musl/src/stdio/__stdio_seek.c
@@ -0,0 +1,13 @@
+#include "stdio_impl.h"
+
+off_t __stdio_seek(FILE *f, off_t off, int whence)
+{
+	off_t ret;
+#ifdef SYS__llseek
+	if (syscall(SYS__llseek, f->fd, off>>32, off, &ret, whence)<0)
+		ret = -1;
+#else
+	ret = syscall(SYS_lseek, f->fd, off, whence);
+#endif
+	return ret;
+}
libc/musl/src/stdio/__stdio_write.c
@@ -0,0 +1,34 @@
+#include "stdio_impl.h"
+#include <sys/uio.h>
+
+size_t __stdio_write(FILE *f, const unsigned char *buf, size_t len)
+{
+	struct iovec iovs[2] = {
+		{ .iov_base = f->wbase, .iov_len = f->wpos-f->wbase },
+		{ .iov_base = (void *)buf, .iov_len = len }
+	};
+	struct iovec *iov = iovs;
+	size_t rem = iov[0].iov_len + iov[1].iov_len;
+	int iovcnt = 2;
+	ssize_t cnt;
+	for (;;) {
+		cnt = syscall(SYS_writev, f->fd, iov, iovcnt);
+		if (cnt == rem) {
+			f->wend = f->buf + f->buf_size;
+			f->wpos = f->wbase = f->buf;
+			return len;
+		}
+		if (cnt < 0) {
+			f->wpos = f->wbase = f->wend = 0;
+			f->flags |= F_ERR;
+			return iovcnt == 2 ? 0 : len-iov[0].iov_len;
+		}
+		rem -= cnt;
+		if (cnt > iov[0].iov_len) {
+			cnt -= iov[0].iov_len;
+			iov++; iovcnt--;
+		}
+		iov[0].iov_base = (char *)iov[0].iov_base + cnt;
+		iov[0].iov_len -= cnt;
+	}
+}
libc/musl/src/stdio/__stdout_write.c
@@ -0,0 +1,11 @@
+#include "stdio_impl.h"
+#include <sys/ioctl.h>
+
+size_t __stdout_write(FILE *f, const unsigned char *buf, size_t len)
+{
+	struct winsize wsz;
+	f->write = __stdio_write;
+	if (!(f->flags & F_SVB) && __syscall(SYS_ioctl, f->fd, TIOCGWINSZ, &wsz))
+		f->lbf = -1;
+	return __stdio_write(f, buf, len);
+}
libc/musl/src/stdio/__string_read.c
@@ -0,0 +1,16 @@
+#include "stdio_impl.h"
+#include <string.h>
+
+size_t __string_read(FILE *f, unsigned char *buf, size_t len)
+{
+	char *src = f->cookie;
+	size_t k = len+256;
+	char *end = memchr(src, 0, k);
+	if (end) k = end-src;
+	if (k < len) len = k;
+	memcpy(buf, src, len);
+	f->rpos = (void *)(src+len);
+	f->rend = (void *)(src+k);
+	f->cookie = src+k;
+	return len;
+}
libc/musl/src/stdio/__toread.c
@@ -0,0 +1,19 @@
+#include <stdio_impl.h>
+
+int __toread(FILE *f)
+{
+	f->mode |= f->mode-1;
+	if (f->wpos != f->wbase) f->write(f, 0, 0);
+	f->wpos = f->wbase = f->wend = 0;
+	if (f->flags & F_NORD) {
+		f->flags |= F_ERR;
+		return EOF;
+	}
+	f->rpos = f->rend = f->buf + f->buf_size;
+	return (f->flags & F_EOF) ? EOF : 0;
+}
+
+hidden void __toread_needs_stdio_exit()
+{
+	__stdio_exit_needed();
+}
libc/musl/src/stdio/__towrite.c
@@ -0,0 +1,23 @@
+#include "stdio_impl.h"
+
+int __towrite(FILE *f)
+{
+	f->mode |= f->mode-1;
+	if (f->flags & F_NOWR) {
+		f->flags |= F_ERR;
+		return EOF;
+	}
+	/* Clear read buffer (easier than summoning nasal demons) */
+	f->rpos = f->rend = 0;
+
+	/* Activate write through the buffer. */
+	f->wpos = f->wbase = f->buf;
+	f->wend = f->buf + f->buf_size;
+
+	return 0;
+}
+
+hidden void __towrite_needs_stdio_exit()
+{
+	__stdio_exit_needed();
+}
libc/musl/src/stdio/__uflow.c
@@ -0,0 +1,11 @@
+#include "stdio_impl.h"
+
+/* This function assumes it will never be called if there is already
+ * data buffered for reading. */
+
+int __uflow(FILE *f)
+{
+	unsigned char c;
+	if (!__toread(f) && f->read(f, &c, 1)==1) return c;
+	return EOF;
+}
libc/musl/src/stdio/asprintf.c
@@ -0,0 +1,13 @@
+#define _GNU_SOURCE
+#include <stdio.h>
+#include <stdarg.h>
+
+int asprintf(char **s, const char *fmt, ...)
+{
+	int ret;
+	va_list ap;
+	va_start(ap, fmt);
+	ret = vasprintf(s, fmt, ap);
+	va_end(ap);
+	return ret;
+}
libc/musl/src/stdio/clearerr.c
@@ -0,0 +1,10 @@
+#include "stdio_impl.h"
+
+void clearerr(FILE *f)
+{
+	FLOCK(f);
+	f->flags &= ~(F_EOF|F_ERR);
+	FUNLOCK(f);
+}
+
+weak_alias(clearerr, clearerr_unlocked);
libc/musl/src/stdio/dprintf.c
@@ -0,0 +1,12 @@
+#include <stdio.h>
+#include <stdarg.h>
+
+int dprintf(int fd, const char *restrict fmt, ...)
+{
+	int ret;
+	va_list ap;
+	va_start(ap, fmt);
+	ret = vdprintf(fd, fmt, ap);
+	va_end(ap);
+	return ret;
+}
libc/musl/src/stdio/ext.c
@@ -0,0 +1,57 @@
+#define _GNU_SOURCE
+#include "stdio_impl.h"
+#include <stdio_ext.h>
+
+void _flushlbf(void)
+{
+	fflush(0);
+}
+
+int __fsetlocking(FILE *f, int type)
+{
+	return 0;
+}
+
+int __fwriting(FILE *f)
+{
+	return (f->flags & F_NORD) || f->wend;
+}
+
+int __freading(FILE *f)
+{
+	return (f->flags & F_NOWR) || f->rend;
+}
+
+int __freadable(FILE *f)
+{
+	return !(f->flags & F_NORD);
+}
+
+int __fwritable(FILE *f)
+{
+	return !(f->flags & F_NOWR);
+}
+
+int __flbf(FILE *f)
+{
+	return f->lbf >= 0;
+}
+
+size_t __fbufsize(FILE *f)
+{
+	return f->buf_size;
+}
+
+size_t __fpending(FILE *f)
+{
+	return f->wend ? f->wpos - f->wbase : 0;
+}
+
+int __fpurge(FILE *f)
+{
+	f->wpos = f->wbase = f->wend = 0;
+	f->rpos = f->rend = 0;
+	return 0;
+}
+
+weak_alias(__fpurge, fpurge);
libc/musl/src/stdio/ext2.c
@@ -0,0 +1,24 @@
+#include "stdio_impl.h"
+#include <stdio_ext.h>
+
+size_t __freadahead(FILE *f)
+{
+	return f->rend ? f->rend - f->rpos : 0;
+}
+
+const char *__freadptr(FILE *f, size_t *sizep)
+{
+	if (f->rpos == f->rend) return 0;
+	*sizep = f->rend - f->rpos;
+	return (const char *)f->rpos;
+}
+
+void __freadptrinc(FILE *f, size_t inc)
+{
+	f->rpos += inc;
+}
+
+void __fseterr(FILE *f)
+{
+	f->flags |= F_ERR;
+}
libc/musl/src/stdio/fclose.c
@@ -0,0 +1,38 @@
+#include "stdio_impl.h"
+#include <stdlib.h>
+
+static void dummy(FILE *f) { }
+weak_alias(dummy, __unlist_locked_file);
+
+int fclose(FILE *f)
+{
+	int r;
+	
+	FLOCK(f);
+	r = fflush(f);
+	r |= f->close(f);
+	FUNLOCK(f);
+
+	/* Past this point, f is closed and any further explict access
+	 * to it is undefined. However, it still exists as an entry in
+	 * the open file list and possibly in the thread's locked files
+	 * list, if it was closed while explicitly locked. Functions
+	 * which process these lists must tolerate dead FILE objects
+	 * (which necessarily have inactive buffer pointers) without
+	 * producing any side effects. */
+
+	if (f->flags & F_PERM) return r;
+
+	__unlist_locked_file(f);
+
+	FILE **head = __ofl_lock();
+	if (f->prev) f->prev->next = f->next;
+	if (f->next) f->next->prev = f->prev;
+	if (*head == f) *head = f->next;
+	__ofl_unlock();
+
+	free(f->getln_buf);
+	free(f);
+
+	return r;
+}
libc/musl/src/stdio/feof.c
@@ -0,0 +1,14 @@
+#include "stdio_impl.h"
+
+#undef feof
+
+int feof(FILE *f)
+{
+	FLOCK(f);
+	int ret = !!(f->flags & F_EOF);
+	FUNLOCK(f);
+	return ret;
+}
+
+weak_alias(feof, feof_unlocked);
+weak_alias(feof, _IO_feof_unlocked);
libc/musl/src/stdio/ferror.c
@@ -0,0 +1,14 @@
+#include "stdio_impl.h"
+
+#undef ferror
+
+int ferror(FILE *f)
+{
+	FLOCK(f);
+	int ret = !!(f->flags & F_ERR);
+	FUNLOCK(f);
+	return ret;
+}
+
+weak_alias(ferror, ferror_unlocked);
+weak_alias(ferror, _IO_ferror_unlocked);
libc/musl/src/stdio/fflush.c
@@ -0,0 +1,47 @@
+#include "stdio_impl.h"
+
+/* stdout.c will override this if linked */
+static FILE *volatile dummy = 0;
+weak_alias(dummy, __stdout_used);
+weak_alias(dummy, __stderr_used);
+
+int fflush(FILE *f)
+{
+	if (!f) {
+		int r = 0;
+		if (__stdout_used) r |= fflush(__stdout_used);
+		if (__stderr_used) r |= fflush(__stderr_used);
+
+		for (f=*__ofl_lock(); f; f=f->next) {
+			FLOCK(f);
+			if (f->wpos != f->wbase) r |= fflush(f);
+			FUNLOCK(f);
+		}
+		__ofl_unlock();
+
+		return r;
+	}
+
+	FLOCK(f);
+
+	/* If writing, flush output */
+	if (f->wpos != f->wbase) {
+		f->write(f, 0, 0);
+		if (!f->wpos) {
+			FUNLOCK(f);
+			return EOF;
+		}
+	}
+
+	/* If reading, sync position, per POSIX */
+	if (f->rpos != f->rend) f->seek(f, f->rpos-f->rend, SEEK_CUR);
+
+	/* Clear read and write modes */
+	f->wpos = f->wbase = f->wend = 0;
+	f->rpos = f->rend = 0;
+
+	FUNLOCK(f);
+	return 0;
+}
+
+weak_alias(fflush, fflush_unlocked);
libc/musl/src/stdio/fgetc.c
@@ -0,0 +1,7 @@
+#include <stdio.h>
+#include "getc.h"
+
+int fgetc(FILE *f)
+{
+	return do_getc(f);
+}
libc/musl/src/stdio/fgetln.c
@@ -0,0 +1,21 @@
+#define _GNU_SOURCE
+#include "stdio_impl.h"
+#include <string.h>
+
+char *fgetln(FILE *f, size_t *plen)
+{
+	char *ret = 0, *z;
+	ssize_t l;
+	FLOCK(f);
+	ungetc(getc_unlocked(f), f);
+	if (f->rend && (z=memchr(f->rpos, '\n', f->rend - f->rpos))) {
+		ret = (char *)f->rpos;
+		*plen = ++z - ret;
+		f->rpos = (void *)z;
+	} else if ((l = getline(&f->getln_buf, (size_t[]){0}, f)) > 0) {
+		*plen = l;
+		ret = f->getln_buf;
+	}
+	FUNLOCK(f);
+	return ret;
+}
libc/musl/src/stdio/fgetpos.c
@@ -0,0 +1,11 @@
+#include "stdio_impl.h"
+
+int fgetpos(FILE *restrict f, fpos_t *restrict pos)
+{
+	off_t off = __ftello(f);
+	if (off < 0) return -1;
+	*(long long *)pos = off;
+	return 0;
+}
+
+weak_alias(fgetpos, fgetpos64);
libc/musl/src/stdio/fgets.c
@@ -0,0 +1,48 @@
+#include "stdio_impl.h"
+#include <string.h>
+
+#define MIN(a,b) ((a)<(b) ? (a) : (b))
+
+char *fgets(char *restrict s, int n, FILE *restrict f)
+{
+	char *p = s;
+	unsigned char *z;
+	size_t k;
+	int c;
+
+	FLOCK(f);
+
+	if (n--<=1) {
+		f->mode |= f->mode-1;
+		FUNLOCK(f);
+		if (n) return 0;
+		*s = 0;
+		return s;
+	}
+
+	while (n) {
+		if (f->rpos != f->rend) {
+			z = memchr(f->rpos, '\n', f->rend - f->rpos);
+			k = z ? z - f->rpos + 1 : f->rend - f->rpos;
+			k = MIN(k, n);
+			memcpy(p, f->rpos, k);
+			f->rpos += k;
+			p += k;
+			n -= k;
+			if (z || !n) break;
+		}
+		if ((c = getc_unlocked(f)) < 0) {
+			if (p==s || !feof(f)) s = 0;
+			break;
+		}
+		n--;
+		if ((*p++ = c) == '\n') break;
+	}
+	if (s) *p = 0;
+
+	FUNLOCK(f);
+
+	return s;
+}
+
+weak_alias(fgets, fgets_unlocked);
libc/musl/src/stdio/fgetwc.c
@@ -0,0 +1,62 @@
+#include "stdio_impl.h"
+#include "locale_impl.h"
+#include <wchar.h>
+#include <errno.h>
+
+static wint_t __fgetwc_unlocked_internal(FILE *f)
+{
+	wchar_t wc;
+	int c;
+	size_t l;
+
+	/* Convert character from buffer if possible */
+	if (f->rpos != f->rend) {
+		l = mbtowc(&wc, (void *)f->rpos, f->rend - f->rpos);
+		if (l+1 >= 1) {
+			f->rpos += l + !l; /* l==0 means 1 byte, null */
+			return wc;
+		}
+	}
+
+	/* Convert character byte-by-byte */
+	mbstate_t st = { 0 };
+	unsigned char b;
+	int first = 1;
+	do {
+		b = c = getc_unlocked(f);
+		if (c < 0) {
+			if (!first) errno = EILSEQ;
+			return WEOF;
+		}
+		l = mbrtowc(&wc, (void *)&b, 1, &st);
+		if (l == -1) {
+			if (!first) ungetc(b, f);
+			return WEOF;
+		}
+		first = 0;
+	} while (l == -2);
+
+	return wc;
+}
+
+wint_t __fgetwc_unlocked(FILE *f)
+{
+	locale_t *ploc = &CURRENT_LOCALE, loc = *ploc;
+	if (f->mode <= 0) fwide(f, 1);
+	*ploc = f->locale;
+	wchar_t wc = __fgetwc_unlocked_internal(f);
+	*ploc = loc;
+	return wc;
+}
+
+wint_t fgetwc(FILE *f)
+{
+	wint_t c;
+	FLOCK(f);
+	c = __fgetwc_unlocked(f);
+	FUNLOCK(f);
+	return c;
+}
+
+weak_alias(__fgetwc_unlocked, fgetwc_unlocked);
+weak_alias(__fgetwc_unlocked, getwc_unlocked);
libc/musl/src/stdio/fgetws.c
@@ -0,0 +1,33 @@
+#include "stdio_impl.h"
+#include <wchar.h>
+#include <errno.h>
+
+wint_t __fgetwc_unlocked(FILE *);
+
+wchar_t *fgetws(wchar_t *restrict s, int n, FILE *restrict f)
+{
+	wchar_t *p = s;
+
+	if (!n--) return s;
+
+	FLOCK(f);
+
+	/* Setup a dummy errno so we can detect EILSEQ. This is
+	 * the only way to catch encoding errors in the form of a
+	 * partial character just before EOF. */
+	errno = EAGAIN;
+	for (; n; n--) {
+		wint_t c = __fgetwc_unlocked(f);
+		if (c == WEOF) break;
+		*p++ = c;
+		if (c == '\n') break;
+	}
+	*p = 0;
+	if (ferror(f) || errno==EILSEQ) p = s;
+
+	FUNLOCK(f);
+
+	return (p == s) ? NULL : s;
+}
+
+weak_alias(fgetws, fgetws_unlocked);
libc/musl/src/stdio/fileno.c
@@ -0,0 +1,16 @@
+#include "stdio_impl.h"
+#include <errno.h>
+
+int fileno(FILE *f)
+{
+	FLOCK(f);
+	int fd = f->fd;
+	FUNLOCK(f);
+	if (fd < 0) {
+		errno = EBADF;
+		return -1;
+	}
+	return fd;
+}
+
+weak_alias(fileno, fileno_unlocked);
libc/musl/src/stdio/flockfile.c
@@ -0,0 +1,9 @@
+#include "stdio_impl.h"
+#include "pthread_impl.h"
+
+void flockfile(FILE *f)
+{
+	if (!ftrylockfile(f)) return;
+	__lockfile(f);
+	__register_locked_file(f, __pthread_self());
+}
libc/musl/src/stdio/fmemopen.c
@@ -0,0 +1,127 @@
+#include "stdio_impl.h"
+#include <errno.h>
+#include <string.h>
+#include <stdlib.h>
+#include <inttypes.h>
+#include "libc.h"
+
+struct cookie {
+	size_t pos, len, size;
+	unsigned char *buf;
+	int mode;
+};
+
+struct mem_FILE {
+	FILE f;
+	struct cookie c;
+	unsigned char buf[UNGET+BUFSIZ], buf2[];
+};
+
+static off_t mseek(FILE *f, off_t off, int whence)
+{
+	ssize_t base;
+	struct cookie *c = f->cookie;
+	if (whence>2U) {
+fail:
+		errno = EINVAL;
+		return -1;
+	}
+	base = (size_t [3]){0, c->pos, c->len}[whence];
+	if (off < -base || off > (ssize_t)c->size-base) goto fail;
+	return c->pos = base+off;
+}
+
+static size_t mread(FILE *f, unsigned char *buf, size_t len)
+{
+	struct cookie *c = f->cookie;
+	size_t rem = c->len - c->pos;
+	if (c->pos > c->len) rem = 0;
+	if (len > rem) {
+		len = rem;
+		f->flags |= F_EOF;
+	}
+	memcpy(buf, c->buf+c->pos, len);
+	c->pos += len;
+	rem -= len;
+	if (rem > f->buf_size) rem = f->buf_size;
+	f->rpos = f->buf;
+	f->rend = f->buf + rem;
+	memcpy(f->rpos, c->buf+c->pos, rem);
+	c->pos += rem;
+	return len;
+}
+
+static size_t mwrite(FILE *f, const unsigned char *buf, size_t len)
+{
+	struct cookie *c = f->cookie;
+	size_t rem;
+	size_t len2 = f->wpos - f->wbase;
+	if (len2) {
+		f->wpos = f->wbase;
+		if (mwrite(f, f->wpos, len2) < len2) return 0;
+	}
+	if (c->mode == 'a') c->pos = c->len;
+	rem = c->size - c->pos;
+	if (len > rem) len = rem;
+	memcpy(c->buf+c->pos, buf, len);
+	c->pos += len;
+	if (c->pos > c->len) {
+		c->len = c->pos;
+		if (c->len < c->size) c->buf[c->len] = 0;
+		else if ((f->flags&F_NORD) && c->size) c->buf[c->size-1] = 0;
+	}
+	return len;
+}
+
+static int mclose(FILE *m)
+{
+	return 0;
+}
+
+FILE *fmemopen(void *restrict buf, size_t size, const char *restrict mode)
+{
+	struct mem_FILE *f;
+	int plus = !!strchr(mode, '+');
+	
+	if (!size || !strchr("rwa", *mode)) {
+		errno = EINVAL;
+		return 0;
+	}
+
+	if (!buf && size > PTRDIFF_MAX) {
+		errno = ENOMEM;
+		return 0;
+	}
+
+	f = malloc(sizeof *f + (buf?0:size));
+	if (!f) return 0;
+	memset(&f->f, 0, sizeof f->f);
+	f->f.cookie = &f->c;
+	f->f.fd = -1;
+	f->f.lbf = EOF;
+	f->f.buf = f->buf + UNGET;
+	f->f.buf_size = sizeof f->buf - UNGET;
+	if (!buf) {
+		buf = f->buf2;;
+		memset(buf, 0, size);
+	}
+
+	memset(&f->c, 0, sizeof f->c);
+	f->c.buf = buf;
+	f->c.size = size;
+	f->c.mode = *mode;
+	
+	if (!plus) f->f.flags = (*mode == 'r') ? F_NOWR : F_NORD;
+	if (*mode == 'r') f->c.len = size;
+	else if (*mode == 'a') f->c.len = f->c.pos = strnlen(buf, size);
+	else if (plus) *f->c.buf = 0;
+
+	f->f.read = mread;
+	f->f.write = mwrite;
+	f->f.seek = mseek;
+	f->f.close = mclose;
+
+	if (!libc.threaded) f->f.lock = -1;
+
+	return __ofl_add(&f->f);
+}
libc/musl/src/stdio/fopen.c
@@ -0,0 +1,33 @@
+#include "stdio_impl.h"
+#include <fcntl.h>
+#include <string.h>
+#include <errno.h>
+
+FILE *fopen(const char *restrict filename, const char *restrict mode)
+{
+	FILE *f;
+	int fd;
+	int flags;
+
+	/* Check for valid initial mode character */
+	if (!strchr("rwa", *mode)) {
+		errno = EINVAL;
+		return 0;
+	}
+
+	/* Compute the flags to pass to open() */
+	flags = __fmodeflags(mode);
+
+	fd = sys_open(filename, flags, 0666);
+	if (fd < 0) return 0;
+	if (flags & O_CLOEXEC)
+		__syscall(SYS_fcntl, fd, F_SETFD, FD_CLOEXEC);
+
+	f = __fdopen(fd, mode);
+	if (f) return f;
+
+	__syscall(SYS_close, fd);
+	return 0;
+}
+
+weak_alias(fopen, fopen64);
libc/musl/src/stdio/fopencookie.c
@@ -0,0 +1,135 @@
+#define _GNU_SOURCE
+#include "stdio_impl.h"
+#include <stdlib.h>
+#include <sys/ioctl.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <string.h>
+
+struct fcookie {
+	void *cookie;
+	cookie_io_functions_t iofuncs;
+};
+
+struct cookie_FILE {
+	FILE f;
+	struct fcookie fc;
+	unsigned char buf[UNGET+BUFSIZ];
+};
+
+static size_t cookieread(FILE *f, unsigned char *buf, size_t len)
+{
+	struct fcookie *fc = f->cookie;
+	ssize_t ret = -1;
+	size_t remain = len, readlen = 0;
+	size_t len2 = len - !!f->buf_size;
+
+	if (!fc->iofuncs.read) goto bail;
+
+	if (len2) {
+		ret = fc->iofuncs.read(fc->cookie, (char *) buf, len2);
+		if (ret <= 0) goto bail;
+
+		readlen += ret;
+		remain -= ret;
+	}
+
+	if (!f->buf_size || remain > !!f->buf_size) return readlen;
+
+	f->rpos = f->buf;
+	ret = fc->iofuncs.read(fc->cookie, (char *) f->rpos, f->buf_size);
+	if (ret <= 0) goto bail;
+	f->rend = f->rpos + ret;
+
+	buf[readlen++] = *f->rpos++;
+
+	return readlen;
+
+bail:
+	f->flags |= ret == 0 ? F_EOF : F_ERR;
+	f->rpos = f->rend = f->buf;
+	return readlen;
+}
+
+static size_t cookiewrite(FILE *f, const unsigned char *buf, size_t len)
+{
+	struct fcookie *fc = f->cookie;
+	ssize_t ret;
+	size_t len2 = f->wpos - f->wbase;
+	if (!fc->iofuncs.write) return len;
+	if (len2) {
+		f->wpos = f->wbase;
+		if (cookiewrite(f, f->wpos, len2) < len2) return 0;
+	}
+	ret = fc->iofuncs.write(fc->cookie, (const char *) buf, len);
+	if (ret < 0) {
+		f->wpos = f->wbase = f->wend = 0;
+		f->flags |= F_ERR;
+		return 0;
+	}
+	return ret;
+}
+
+static off_t cookieseek(FILE *f, off_t off, int whence)
+{
+	struct fcookie *fc = f->cookie;
+	int res;
+	if (whence > 2U) {
+		errno = EINVAL;
+		return -1;
+	}
+	if (!fc->iofuncs.seek) {
+		errno = ENOTSUP;
+		return -1;
+	}
+	res = fc->iofuncs.seek(fc->cookie, &off, whence);
+	if (res < 0)
+		return res;
+	return off;
+}
+
+static int cookieclose(FILE *f)
+{
+	struct fcookie *fc = f->cookie;
+	if (fc->iofuncs.close) return fc->iofuncs.close(fc->cookie);
+	return 0;
+}
+
+FILE *fopencookie(void *cookie, const char *mode, cookie_io_functions_t iofuncs)
+{
+	struct cookie_FILE *f;
+
+	/* Check for valid initial mode character */
+	if (!strchr("rwa", *mode)) {
+		errno = EINVAL;
+		return 0;
+	}
+
+	/* Allocate FILE+fcookie+buffer or fail */
+	if (!(f=malloc(sizeof *f))) return 0;
+
+	/* Zero-fill only the struct, not the buffer */
+	memset(&f->f, 0, sizeof f->f);
+
+	/* Impose mode restrictions */
+	if (!strchr(mode, '+')) f->f.flags = (*mode == 'r') ? F_NOWR : F_NORD;
+
+	/* Set up our fcookie */
+	f->fc.cookie = cookie;
+	f->fc.iofuncs = iofuncs;
+
+	f->f.fd = -1;
+	f->f.cookie = &f->fc;
+	f->f.buf = f->buf + UNGET;
+	f->f.buf_size = sizeof f->buf - UNGET;
+	f->f.lbf = EOF;
+
+	/* Initialize op ptrs. No problem if some are unneeded. */
+	f->f.read = cookieread;
+	f->f.write = cookiewrite;
+	f->f.seek = cookieseek;
+	f->f.close = cookieclose;
+
+	/* Add new FILE to open file list */
+	return __ofl_add(&f->f);
+}
libc/musl/src/stdio/fprintf.c
@@ -0,0 +1,12 @@
+#include <stdio.h>
+#include <stdarg.h>
+
+int fprintf(FILE *restrict f, const char *restrict fmt, ...)
+{
+	int ret;
+	va_list ap;
+	va_start(ap, fmt);
+	ret = vfprintf(f, fmt, ap);
+	va_end(ap);
+	return ret;
+}
libc/musl/src/stdio/fputc.c
@@ -0,0 +1,7 @@
+#include <stdio.h>
+#include "putc.h"
+
+int fputc(int c, FILE *f)
+{
+	return do_putc(c, f);
+}
libc/musl/src/stdio/fputs.c
@@ -0,0 +1,10 @@
+#include "stdio_impl.h"
+#include <string.h>
+
+int fputs(const char *restrict s, FILE *restrict f)
+{
+	size_t l = strlen(s);
+	return (fwrite(s, 1, l, f)==l) - 1;
+}
+
+weak_alias(fputs, fputs_unlocked);
libc/musl/src/stdio/fputwc.c
@@ -0,0 +1,40 @@
+#include "stdio_impl.h"
+#include "locale_impl.h"
+#include <wchar.h>
+#include <limits.h>
+#include <ctype.h>
+
+wint_t __fputwc_unlocked(wchar_t c, FILE *f)
+{
+	char mbc[MB_LEN_MAX];
+	int l;
+	locale_t *ploc = &CURRENT_LOCALE, loc = *ploc;
+
+	if (f->mode <= 0) fwide(f, 1);
+	*ploc = f->locale;
+
+	if (isascii(c)) {
+		c = putc_unlocked(c, f);
+	} else if (f->wpos + MB_LEN_MAX < f->wend) {
+		l = wctomb((void *)f->wpos, c);
+		if (l < 0) c = WEOF;
+		else f->wpos += l;
+	} else {
+		l = wctomb(mbc, c);
+		if (l < 0 || __fwritex((void *)mbc, l, f) < l) c = WEOF;
+	}
+	if (c==WEOF) f->flags |= F_ERR;
+	*ploc = loc;
+	return c;
+}
+
+wint_t fputwc(wchar_t c, FILE *f)
+{
+	FLOCK(f);
+	c = __fputwc_unlocked(c, f);
+	FUNLOCK(f);
+	return c;
+}
+
+weak_alias(__fputwc_unlocked, fputwc_unlocked);
+weak_alias(__fputwc_unlocked, putwc_unlocked);
libc/musl/src/stdio/fputws.c
@@ -0,0 +1,29 @@
+#include "stdio_impl.h"
+#include "locale_impl.h"
+#include <wchar.h>
+
+int fputws(const wchar_t *restrict ws, FILE *restrict f)
+{
+	unsigned char buf[BUFSIZ];
+	size_t l=0;
+	locale_t *ploc = &CURRENT_LOCALE, loc = *ploc;
+
+	FLOCK(f);
+
+	fwide(f, 1);
+	*ploc = f->locale;
+
+	while (ws && (l = wcsrtombs((void *)buf, (void*)&ws, sizeof buf, 0))+1 > 1)
+		if (__fwritex(buf, l, f) < l) {
+			FUNLOCK(f);
+			*ploc = loc;
+			return -1;
+		}
+
+	FUNLOCK(f);
+
+	*ploc = loc;
+	return l; /* 0 or -1 */
+}
+
+weak_alias(fputws, fputws_unlocked);
libc/musl/src/stdio/fread.c
@@ -0,0 +1,38 @@
+#include "stdio_impl.h"
+#include <string.h>
+
+#define MIN(a,b) ((a)<(b) ? (a) : (b))
+
+size_t fread(void *restrict destv, size_t size, size_t nmemb, FILE *restrict f)
+{
+	unsigned char *dest = destv;
+	size_t len = size*nmemb, l = len, k;
+	if (!size) nmemb = 0;
+
+	FLOCK(f);
+
+	f->mode |= f->mode-1;
+
+	if (f->rpos != f->rend) {
+		/* First exhaust the buffer. */
+		k = MIN(f->rend - f->rpos, l);
+		memcpy(dest, f->rpos, k);
+		f->rpos += k;
+		dest += k;
+		l -= k;
+	}
+	
+	/* Read the remainder directly */
+	for (; l; l-=k, dest+=k) {
+		k = __toread(f) ? 0 : f->read(f, dest, l);
+		if (!k) {
+			FUNLOCK(f);
+			return (len-l)/size;
+		}
+	}
+
+	FUNLOCK(f);
+	return nmemb;
+}
+
+weak_alias(fread, fread_unlocked);
libc/musl/src/stdio/freopen.c
@@ -0,0 +1,53 @@
+#include "stdio_impl.h"
+#include <fcntl.h>
+#include <unistd.h>
+
+/* The basic idea of this implementation is to open a new FILE,
+ * hack the necessary parts of the new FILE into the old one, then
+ * close the new FILE. */
+
+/* Locking IS necessary because another thread may provably hold the
+ * lock, via flockfile or otherwise, when freopen is called, and in that
+ * case, freopen cannot act until the lock is released. */
+
+FILE *freopen(const char *restrict filename, const char *restrict mode, FILE *restrict f)
+{
+	int fl = __fmodeflags(mode);
+	FILE *f2;
+
+	FLOCK(f);
+
+	fflush(f);
+
+	if (!filename) {
+		if (fl&O_CLOEXEC)
+			__syscall(SYS_fcntl, f->fd, F_SETFD, FD_CLOEXEC);
+		fl &= ~(O_CREAT|O_EXCL|O_CLOEXEC);
+		if (syscall(SYS_fcntl, f->fd, F_SETFL, fl) < 0)
+			goto fail;
+	} else {
+		f2 = fopen(filename, mode);
+		if (!f2) goto fail;
+		if (f2->fd == f->fd) f2->fd = -1; /* avoid closing in fclose */
+		else if (__dup3(f2->fd, f->fd, fl&O_CLOEXEC)<0) goto fail2;
+
+		f->flags = (f->flags & F_PERM) | f2->flags;
+		f->read = f2->read;
+		f->write = f2->write;
+		f->seek = f2->seek;
+		f->close = f2->close;
+
+		fclose(f2);
+	}
+
+	FUNLOCK(f);
+	return f;
+
+fail2:
+	fclose(f2);
+fail:
+	fclose(f);
+	return NULL;
+}
+
+weak_alias(freopen, freopen64);
libc/musl/src/stdio/fscanf.c
@@ -0,0 +1,14 @@
+#include <stdio.h>
+#include <stdarg.h>
+
+int fscanf(FILE *restrict f, const char *restrict fmt, ...)
+{
+	int ret;
+	va_list ap;
+	va_start(ap, fmt);
+	ret = vfscanf(f, fmt, ap);
+	va_end(ap);
+	return ret;
+}
+
+weak_alias(fscanf, __isoc99_fscanf);
libc/musl/src/stdio/fseek.c
@@ -0,0 +1,43 @@
+#include "stdio_impl.h"
+
+int __fseeko_unlocked(FILE *f, off_t off, int whence)
+{
+	/* Adjust relative offset for unread data in buffer, if any. */
+	if (whence == SEEK_CUR && f->rend) off -= f->rend - f->rpos;
+
+	/* Flush write buffer, and report error on failure. */
+	if (f->wpos != f->wbase) {
+		f->write(f, 0, 0);
+		if (!f->wpos) return -1;
+	}
+
+	/* Leave writing mode */
+	f->wpos = f->wbase = f->wend = 0;
+
+	/* Perform the underlying seek. */
+	if (f->seek(f, off, whence) < 0) return -1;
+
+	/* If seek succeeded, file is seekable and we discard read buffer. */
+	f->rpos = f->rend = 0;
+	f->flags &= ~F_EOF;
+	
+	return 0;
+}
+
+int __fseeko(FILE *f, off_t off, int whence)
+{
+	int result;
+	FLOCK(f);
+	result = __fseeko_unlocked(f, off, whence);
+	FUNLOCK(f);
+	return result;
+}
+
+int fseek(FILE *f, long off, int whence)
+{
+	return __fseeko(f, off, whence);
+}
+
+weak_alias(__fseeko, fseeko);
+
+weak_alias(fseeko, fseeko64);
libc/musl/src/stdio/fsetpos.c
@@ -0,0 +1,8 @@
+#include "stdio_impl.h"
+
+int fsetpos(FILE *f, const fpos_t *pos)
+{
+	return __fseeko(f, *(const long long *)pos, SEEK_SET);
+}
+
+weak_alias(fsetpos, fsetpos64);
libc/musl/src/stdio/ftell.c
@@ -0,0 +1,41 @@
+#include "stdio_impl.h"
+#include <limits.h>
+#include <errno.h>
+
+off_t __ftello_unlocked(FILE *f)
+{
+	off_t pos = f->seek(f, 0,
+		(f->flags & F_APP) && f->wpos != f->wbase
+		? SEEK_END : SEEK_CUR);
+	if (pos < 0) return pos;
+
+	/* Adjust for data in buffer. */
+	if (f->rend)
+		pos += f->rpos - f->rend;
+	else if (f->wbase)
+		pos += f->wpos - f->wbase;
+	return pos;
+}
+
+off_t __ftello(FILE *f)
+{
+	off_t pos;
+	FLOCK(f);
+	pos = __ftello_unlocked(f);
+	FUNLOCK(f);
+	return pos;
+}
+
+long ftell(FILE *f)
+{
+	off_t pos = __ftello(f);
+	if (pos > LONG_MAX) {
+		errno = EOVERFLOW;
+		return -1;
+	}
+	return pos;
+}
+
+weak_alias(__ftello, ftello);
+
+weak_alias(ftello, ftello64);
libc/musl/src/stdio/ftrylockfile.c
@@ -0,0 +1,46 @@
+#include "stdio_impl.h"
+#include "pthread_impl.h"
+#include <limits.h>
+
+void __do_orphaned_stdio_locks()
+{
+	FILE *f;
+	for (f=__pthread_self()->stdio_locks; f; f=f->next_locked)
+		a_store(&f->lock, 0x40000000);
+}
+
+void __unlist_locked_file(FILE *f)
+{
+	if (f->lockcount) {
+		if (f->next_locked) f->next_locked->prev_locked = f->prev_locked;
+		if (f->prev_locked) f->prev_locked->next_locked = f->next_locked;
+		else __pthread_self()->stdio_locks = f->next_locked;
+	}
+}
+
+void __register_locked_file(FILE *f, pthread_t self)
+{
+	f->lockcount = 1;
+	f->prev_locked = 0;
+	f->next_locked = self->stdio_locks;
+	if (f->next_locked) f->next_locked->prev_locked = f;
+	self->stdio_locks = f;
+}
+
+int ftrylockfile(FILE *f)
+{
+	pthread_t self = __pthread_self();
+	int tid = self->tid;
+	int owner = f->lock;
+	if ((owner & ~MAYBE_WAITERS) == tid) {
+		if (f->lockcount == LONG_MAX)
+			return -1;
+		f->lockcount++;
+		return 0;
+	}
+	if (owner < 0) f->lock = owner = 0;
+	if (owner || a_cas(&f->lock, 0, tid))
+		return -1;
+	__register_locked_file(f, self);
+	return 0;
+}
libc/musl/src/stdio/funlockfile.c
@@ -0,0 +1,13 @@
+#include "stdio_impl.h"
+#include "pthread_impl.h"
+
+void funlockfile(FILE *f)
+{
+	if (f->lockcount == 1) {
+		__unlist_locked_file(f);
+		f->lockcount = 0;
+		__unlockfile(f);
+	} else {
+		f->lockcount--;
+	}
+}
libc/musl/src/stdio/fwide.c
@@ -0,0 +1,16 @@
+#include <wchar.h>
+#include "stdio_impl.h"
+#include "locale_impl.h"
+
+int fwide(FILE *f, int mode)
+{
+	FLOCK(f);
+	if (mode) {
+		if (!f->locale) f->locale = MB_CUR_MAX==1
+			? C_LOCALE : UTF8_LOCALE;
+		if (!f->mode) f->mode = mode>0 ? 1 : -1;
+	}
+	mode = f->mode;
+	FUNLOCK(f);
+	return mode;
+}
libc/musl/src/stdio/fwprintf.c
@@ -0,0 +1,13 @@
+#include <stdio.h>
+#include <stdarg.h>
+#include <wchar.h>
+
+int fwprintf(FILE *restrict f, const wchar_t *restrict fmt, ...)
+{
+	int ret;
+	va_list ap;
+	va_start(ap, fmt);
+	ret = vfwprintf(f, fmt, ap);
+	va_end(ap);
+	return ret;
+}
libc/musl/src/stdio/fwrite.c
@@ -0,0 +1,38 @@
+#include "stdio_impl.h"
+#include <string.h>
+
+size_t __fwritex(const unsigned char *restrict s, size_t l, FILE *restrict f)
+{
+	size_t i=0;
+
+	if (!f->wend && __towrite(f)) return 0;
+
+	if (l > f->wend - f->wpos) return f->write(f, s, l);
+
+	if (f->lbf >= 0) {
+		/* Match /^(.*\n|)/ */
+		for (i=l; i && s[i-1] != '\n'; i--);
+		if (i) {
+			size_t n = f->write(f, s, i);
+			if (n < i) return n;
+			s += i;
+			l -= i;
+		}
+	}
+
+	memcpy(f->wpos, s, l);
+	f->wpos += l;
+	return l+i;
+}
+
+size_t fwrite(const void *restrict src, size_t size, size_t nmemb, FILE *restrict f)
+{
+	size_t k, l = size*nmemb;
+	if (!size) nmemb = 0;
+	FLOCK(f);
+	k = __fwritex(src, l, f);
+	FUNLOCK(f);
+	return k==l ? nmemb : k/size;
+}
+
+weak_alias(fwrite, fwrite_unlocked);
libc/musl/src/stdio/fwscanf.c
@@ -0,0 +1,15 @@
+#include <stdio.h>
+#include <stdarg.h>
+#include <wchar.h>
+
+int fwscanf(FILE *restrict f, const wchar_t *restrict fmt, ...)
+{
+	int ret;
+	va_list ap;
+	va_start(ap, fmt);
+	ret = vfwscanf(f, fmt, ap);
+	va_end(ap);
+	return ret;
+}
+
+weak_alias(fwscanf,__isoc99_fwscanf);
libc/musl/src/stdio/getc.c
@@ -0,0 +1,9 @@
+#include <stdio.h>
+#include "getc.h"
+
+int getc(FILE *f)
+{
+	return do_getc(f);
+}
+
+weak_alias(getc, _IO_getc);
libc/musl/src/stdio/getc.h
@@ -0,0 +1,22 @@
+#include "stdio_impl.h"
+#include "pthread_impl.h"
+
+#ifdef __GNUC__
+__attribute__((__noinline__))
+#endif
+static int locking_getc(FILE *f)
+{
+	if (a_cas(&f->lock, 0, MAYBE_WAITERS-1)) __lockfile(f);
+	int c = getc_unlocked(f);
+	if (a_swap(&f->lock, 0) & MAYBE_WAITERS)
+		__wake(&f->lock, 1, 1);
+	return c;
+}
+
+static inline int do_getc(FILE *f)
+{
+	int l = f->lock;
+	if (l < 0 || l && (l & ~MAYBE_WAITERS) == __pthread_self()->tid)
+		return getc_unlocked(f);
+	return locking_getc(f);
+}
libc/musl/src/stdio/getc_unlocked.c
@@ -0,0 +1,9 @@
+#include "stdio_impl.h"
+
+int (getc_unlocked)(FILE *f)
+{
+	return getc_unlocked(f);
+}
+
+weak_alias (getc_unlocked, fgetc_unlocked);
+weak_alias (getc_unlocked, _IO_getc_unlocked);
libc/musl/src/stdio/getchar.c
@@ -0,0 +1,7 @@
+#include <stdio.h>
+#include "getc.h"
+
+int getchar(void)
+{
+	return do_getc(stdin);
+}
libc/musl/src/stdio/getchar_unlocked.c
@@ -0,0 +1,6 @@
+#include "stdio_impl.h"
+
+int getchar_unlocked(void)
+{
+	return getc_unlocked(stdin);
+}
libc/musl/src/stdio/getdelim.c
@@ -0,0 +1,81 @@
+#include "stdio_impl.h"
+#include <string.h>
+#include <stdlib.h>
+#include <inttypes.h>
+#include <errno.h>
+
+ssize_t getdelim(char **restrict s, size_t *restrict n, int delim, FILE *restrict f)
+{
+	char *tmp;
+	unsigned char *z;
+	size_t k;
+	size_t i=0;
+	int c;
+
+	FLOCK(f);
+
+	if (!n || !s) {
+		f->mode |= f->mode-1;
+		f->flags |= F_ERR;
+		FUNLOCK(f);
+		errno = EINVAL;
+		return -1;
+	}
+
+	if (!*s) *n=0;
+
+	for (;;) {
+		if (f->rpos != f->rend) {
+			z = memchr(f->rpos, delim, f->rend - f->rpos);
+			k = z ? z - f->rpos + 1 : f->rend - f->rpos;
+		} else {
+			z = 0;
+			k = 0;
+		}
+		if (i+k >= *n) {
+			size_t m = i+k+2;
+			if (!z && m < SIZE_MAX/4) m += m/2;
+			tmp = realloc(*s, m);
+			if (!tmp) {
+				m = i+k+2;
+				tmp = realloc(*s, m);
+				if (!tmp) {
+					/* Copy as much as fits and ensure no
+					 * pushback remains in the FILE buf. */
+					k = *n-i;
+					memcpy(*s+i, f->rpos, k);
+					f->rpos += k;
+					f->mode |= f->mode-1;
+					f->flags |= F_ERR;
+					FUNLOCK(f);
+					errno = ENOMEM;
+					return -1;
+				}
+			}
+			*s = tmp;
+			*n = m;
+		}
+		memcpy(*s+i, f->rpos, k);
+		f->rpos += k;
+		i += k;
+		if (z) break;
+		if ((c = getc_unlocked(f)) == EOF) {
+			if (!i || !feof(f)) {
+				FUNLOCK(f);
+				return -1;
+			}
+			break;
+		}
+		/* If the byte read by getc won't fit without growing the
+		 * output buffer, push it back for next iteration. */
+		if (i+1 >= *n) *--f->rpos = c;
+		else if (((*s)[i++] = c) == delim) break;
+	}
+	(*s)[i] = 0;
+
+	FUNLOCK(f);
+
+	return i;
+}
+
+weak_alias(getdelim, __getdelim);
libc/musl/src/stdio/getline.c
@@ -0,0 +1,6 @@
+#include <stdio.h>
+
+ssize_t getline(char **restrict s, size_t *restrict n, FILE *restrict f)
+{
+	return getdelim(s, n, '\n', f);
+}
libc/musl/src/stdio/gets.c
@@ -0,0 +1,10 @@
+#include "stdio_impl.h"
+#include <limits.h>
+#include <string.h>
+
+char *gets(char *s)
+{
+	char *ret = fgets(s, INT_MAX, stdin);
+	if (ret && s[strlen(s)-1] == '\n') s[strlen(s)-1] = 0;
+	return ret;
+}
libc/musl/src/stdio/getw.c
@@ -0,0 +1,8 @@
+#define _GNU_SOURCE
+#include <stdio.h>
+
+int getw(FILE *f)
+{
+	int x;
+	return fread(&x, sizeof x, 1, f) ? x : EOF;
+}
libc/musl/src/stdio/getwc.c
@@ -0,0 +1,7 @@
+#include "stdio_impl.h"
+#include <wchar.h>
+
+wint_t getwc(FILE *f)
+{
+	return fgetwc(f);
+}
libc/musl/src/stdio/getwchar.c
@@ -0,0 +1,9 @@
+#include "stdio_impl.h"
+#include <wchar.h>
+
+wint_t getwchar(void)
+{
+	return fgetwc(stdin);
+}
+
+weak_alias(getwchar, getwchar_unlocked);
libc/musl/src/stdio/ofl.c
@@ -0,0 +1,16 @@
+#include "stdio_impl.h"
+#include "lock.h"
+
+static FILE *ofl_head;
+static volatile int ofl_lock[1];
+
+FILE **__ofl_lock()
+{
+	LOCK(ofl_lock);
+	return &ofl_head;
+}
+
+void __ofl_unlock()
+{
+	UNLOCK(ofl_lock);
+}
libc/musl/src/stdio/ofl_add.c
@@ -0,0 +1,11 @@
+#include "stdio_impl.h"
+
+FILE *__ofl_add(FILE *f)
+{
+	FILE **head = __ofl_lock();
+	f->next = *head;
+	if (*head) (*head)->prev = f;
+	*head = f;
+	__ofl_unlock();
+	return f;
+}
libc/musl/src/stdio/open_memstream.c
@@ -0,0 +1,99 @@
+#include "stdio_impl.h"
+#include <errno.h>
+#include <limits.h>
+#include <string.h>
+#include <stdlib.h>
+#include "libc.h"
+
+struct cookie {
+	char **bufp;
+	size_t *sizep;
+	size_t pos;
+	char *buf;
+	size_t len;
+	size_t space;
+};
+
+struct ms_FILE {
+	FILE f;
+	struct cookie c;
+	unsigned char buf[BUFSIZ];
+};
+
+static off_t ms_seek(FILE *f, off_t off, int whence)
+{
+	ssize_t base;
+	struct cookie *c = f->cookie;
+	if (whence>2U) {
+fail:
+		errno = EINVAL;
+		return -1;
+	}
+	base = (size_t [3]){0, c->pos, c->len}[whence];
+	if (off < -base || off > SSIZE_MAX-base) goto fail;
+	return c->pos = base+off;
+}
+
+static size_t ms_write(FILE *f, const unsigned char *buf, size_t len)
+{
+	struct cookie *c = f->cookie;
+	size_t len2 = f->wpos - f->wbase;
+	char *newbuf;
+	if (len2) {
+		f->wpos = f->wbase;
+		if (ms_write(f, f->wbase, len2) < len2) return 0;
+	}
+	if (len + c->pos >= c->space) {
+		len2 = 2*c->space+1 | c->pos+len+1;
+		newbuf = realloc(c->buf, len2);
+		if (!newbuf) return 0;
+		*c->bufp = c->buf = newbuf;
+		memset(c->buf + c->space, 0, len2 - c->space);
+		c->space = len2;
+	}
+	memcpy(c->buf+c->pos, buf, len);
+	c->pos += len;
+	if (c->pos >= c->len) c->len = c->pos;
+	*c->sizep = c->pos;
+	return len;
+}
+
+static int ms_close(FILE *f)
+{
+	return 0;
+}
+
+FILE *open_memstream(char **bufp, size_t *sizep)
+{
+	struct ms_FILE *f;
+	char *buf;
+
+	if (!(f=malloc(sizeof *f))) return 0;
+	if (!(buf=malloc(sizeof *buf))) {
+		free(f);
+		return 0;
+	}
+	memset(&f->f, 0, sizeof f->f);
+	memset(&f->c, 0, sizeof f->c);
+	f->f.cookie = &f->c;
+
+	f->c.bufp = bufp;
+	f->c.sizep = sizep;
+	f->c.pos = f->c.len = f->c.space = *sizep = 0;
+	f->c.buf = *bufp = buf;
+	*buf = 0;
+
+	f->f.flags = F_NORD;
+	f->f.fd = -1;
+	f->f.buf = f->buf;
+	f->f.buf_size = sizeof f->buf;
+	f->f.lbf = EOF;
+	f->f.write = ms_write;
+	f->f.seek = ms_seek;
+	f->f.close = ms_close;
+	f->f.mode = -1;
+
+	if (!libc.threaded) f->f.lock = -1;
+
+	return __ofl_add(&f->f);
+}
libc/musl/src/stdio/open_wmemstream.c
@@ -0,0 +1,102 @@
+#include "stdio_impl.h"
+#include <wchar.h>
+#include <errno.h>
+#include <limits.h>
+#include <string.h>
+#include <stdlib.h>
+#include "libc.h"
+
+struct cookie {
+	wchar_t **bufp;
+	size_t *sizep;
+	size_t pos;
+	wchar_t *buf;
+	size_t len;
+	size_t space;
+	mbstate_t mbs;
+};
+
+struct wms_FILE {
+	FILE f;
+	struct cookie c;
+	unsigned char buf[1];
+};
+
+static off_t wms_seek(FILE *f, off_t off, int whence)
+{
+	ssize_t base;
+	struct cookie *c = f->cookie;
+	if (whence>2U) {
+fail:
+		errno = EINVAL;
+		return -1;
+	}
+	base = (size_t [3]){0, c->pos, c->len}[whence];
+	if (off < -base || off > SSIZE_MAX/4-base) goto fail;
+	memset(&c->mbs, 0, sizeof c->mbs);
+	return c->pos = base+off;
+}
+
+static size_t wms_write(FILE *f, const unsigned char *buf, size_t len)
+{
+	struct cookie *c = f->cookie;
+	size_t len2;
+	wchar_t *newbuf;
+	if (len + c->pos >= c->space) {
+		len2 = 2*c->space+1 | c->pos+len+1;
+		if (len2 > SSIZE_MAX/4) return 0;
+		newbuf = realloc(c->buf, len2*4);
+		if (!newbuf) return 0;
+		*c->bufp = c->buf = newbuf;
+		memset(c->buf + c->space, 0, 4*(len2 - c->space));
+		c->space = len2;
+	}
+	
+	len2 = mbsnrtowcs(c->buf+c->pos, (void *)&buf, len, c->space-c->pos, &c->mbs);
+	if (len2 == -1) return 0;
+	c->pos += len2;
+	if (c->pos >= c->len) c->len = c->pos;
+	*c->sizep = c->pos;
+	return len;
+}
+
+static int wms_close(FILE *f)
+{
+	return 0;
+}
+
+FILE *open_wmemstream(wchar_t **bufp, size_t *sizep)
+{
+	struct wms_FILE *f;
+	wchar_t *buf;
+
+	if (!(f=malloc(sizeof *f))) return 0;
+	if (!(buf=malloc(sizeof *buf))) {
+		free(f);
+		return 0;
+	}
+	memset(&f->f, 0, sizeof f->f);
+	memset(&f->c, 0, sizeof f->c);
+	f->f.cookie = &f->c;
+
+	f->c.bufp = bufp;
+	f->c.sizep = sizep;
+	f->c.pos = f->c.len = f->c.space = *sizep = 0;
+	f->c.buf = *bufp = buf;
+	*buf = 0;
+
+	f->f.flags = F_NORD;
+	f->f.fd = -1;
+	f->f.buf = f->buf;
+	f->f.buf_size = 0;
+	f->f.lbf = EOF;
+	f->f.write = wms_write;
+	f->f.seek = wms_seek;
+	f->f.close = wms_close;
+
+	if (!libc.threaded) f->f.lock = -1;
+
+	fwide(&f->f, 1);
+
+	return __ofl_add(&f->f);
+}
libc/musl/src/stdio/pclose.c
@@ -0,0 +1,13 @@
+#include "stdio_impl.h"
+#include <errno.h>
+#include <unistd.h>
+
+int pclose(FILE *f)
+{
+	int status, r;
+	pid_t pid = f->pipe_pid;
+	fclose(f);
+	while ((r=__syscall(SYS_wait4, pid, &status, 0, 0)) == -EINTR);
+	if (r<0) return __syscall_ret(r);
+	return status;
+}
libc/musl/src/stdio/perror.c
@@ -0,0 +1,30 @@
+#include <stdio.h>
+#include <string.h>
+#include <errno.h>
+#include "stdio_impl.h"
+
+void perror(const char *msg)
+{
+	FILE *f = stderr;
+	char *errstr = strerror(errno);
+
+	FLOCK(f);
+
+	/* Save stderr's orientation and encoding rule, since perror is not
+	 * permitted to change them. */
+	void *old_locale = f->locale;
+	int old_mode = f->mode;
+	
+	if (msg && *msg) {
+		fwrite(msg, strlen(msg), 1, f);
+		fputc(':', f);
+		fputc(' ', f);
+	}
+	fwrite(errstr, strlen(errstr), 1, f);
+	fputc('\n', f);
+
+	f->mode = old_mode;
+	f->locale = old_locale;
+
+	FUNLOCK(f);
+}
libc/musl/src/stdio/popen.c
@@ -0,0 +1,73 @@
+#include <fcntl.h>
+#include <unistd.h>
+#include <errno.h>
+#include <string.h>
+#include <spawn.h>
+#include "stdio_impl.h"
+#include "syscall.h"
+
+extern char **__environ;
+
+FILE *popen(const char *cmd, const char *mode)
+{
+	int p[2], op, e;
+	pid_t pid;
+	FILE *f;
+	posix_spawn_file_actions_t fa;
+
+	if (*mode == 'r') {
+		op = 0;
+	} else if (*mode == 'w') {
+		op = 1;
+	} else {
+		errno = EINVAL;
+		return 0;
+	}
+	
+	if (pipe2(p, O_CLOEXEC)) return NULL;
+	f = fdopen(p[op], mode);
+	if (!f) {
+		__syscall(SYS_close, p[0]);
+		__syscall(SYS_close, p[1]);
+		return NULL;
+	}
+	FLOCK(f);
+
+	/* If the child's end of the pipe happens to already be on the final
+	 * fd number to which it will be assigned (either 0 or 1), it must
+	 * be moved to a different fd. Otherwise, there is no safe way to
+	 * remove the close-on-exec flag in the child without also creating
+	 * a file descriptor leak race condition in the parent. */
+	if (p[1-op] == 1-op) {
+		int tmp = fcntl(1-op, F_DUPFD_CLOEXEC, 0);
+		if (tmp < 0) {
+			e = errno;
+			goto fail;
+		}
+		__syscall(SYS_close, p[1-op]);
+		p[1-op] = tmp;
+	}
+
+	e = ENOMEM;
+	if (!posix_spawn_file_actions_init(&fa)) {
+		if (!posix_spawn_file_actions_adddup2(&fa, p[1-op], 1-op)) {
+			if (!(e = posix_spawn(&pid, "/bin/sh", &fa, 0,
+			    (char *[]){ "sh", "-c", (char *)cmd, 0 }, __environ))) {
+				posix_spawn_file_actions_destroy(&fa);
+				f->pipe_pid = pid;
+				if (!strchr(mode, 'e'))
+					fcntl(p[op], F_SETFD, 0);
+				__syscall(SYS_close, p[1-op]);
+				FUNLOCK(f);
+				return f;
+			}
+		}
+		posix_spawn_file_actions_destroy(&fa);
+	}
+fail:
+	fclose(f);
+	__syscall(SYS_close, p[1-op]);
+
+	errno = e;
+	return 0;
+}
libc/musl/src/stdio/printf.c
@@ -0,0 +1,12 @@
+#include <stdio.h>
+#include <stdarg.h>
+
+int printf(const char *restrict fmt, ...)
+{
+	int ret;
+	va_list ap;
+	va_start(ap, fmt);
+	ret = vfprintf(stdout, fmt, ap);
+	va_end(ap);
+	return ret;
+}
libc/musl/src/stdio/putc.c
@@ -0,0 +1,9 @@
+#include <stdio.h>
+#include "putc.h"
+
+int putc(int c, FILE *f)
+{
+	return do_putc(c, f);
+}
+
+weak_alias(putc, _IO_putc);
libc/musl/src/stdio/putc.h
@@ -0,0 +1,22 @@
+#include "stdio_impl.h"
+#include "pthread_impl.h"
+
+#ifdef __GNUC__
+__attribute__((__noinline__))
+#endif
+static int locking_putc(int c, FILE *f)
+{
+	if (a_cas(&f->lock, 0, MAYBE_WAITERS-1)) __lockfile(f);
+	c = putc_unlocked(c, f);
+	if (a_swap(&f->lock, 0) & MAYBE_WAITERS)
+		__wake(&f->lock, 1, 1);
+	return c;
+}
+
+static inline int do_putc(int c, FILE *f)
+{
+	int l = f->lock;
+	if (l < 0 || l && (l & ~MAYBE_WAITERS) == __pthread_self()->tid)
+		return putc_unlocked(c, f);
+	return locking_putc(c, f);
+}
libc/musl/src/stdio/putc_unlocked.c
@@ -0,0 +1,9 @@
+#include "stdio_impl.h"
+
+int (putc_unlocked)(int c, FILE *f)
+{
+	return putc_unlocked(c, f);
+}
+
+weak_alias(putc_unlocked, fputc_unlocked);
+weak_alias(putc_unlocked, _IO_putc_unlocked);
libc/musl/src/stdio/putchar.c
@@ -0,0 +1,7 @@
+#include <stdio.h>
+#include "putc.h"
+
+int putchar(int c)
+{
+	return do_putc(c, stdout);
+}
libc/musl/src/stdio/putchar_unlocked.c
@@ -0,0 +1,6 @@
+#include "stdio_impl.h"
+
+int putchar_unlocked(int c)
+{
+	return putc_unlocked(c, stdout);
+}
libc/musl/src/stdio/puts.c
@@ -0,0 +1,10 @@
+#include "stdio_impl.h"
+
+int puts(const char *s)
+{
+	int r;
+	FLOCK(stdout);
+	r = -(fputs(s, stdout) < 0 || putc_unlocked('\n', stdout) < 0);
+	FUNLOCK(stdout);
+	return r;
+}
libc/musl/src/stdio/putw.c
@@ -0,0 +1,7 @@
+#define _GNU_SOURCE
+#include <stdio.h>
+
+int putw(int x, FILE *f)
+{
+	return (int)fwrite(&x, sizeof x, 1, f)-1;
+}
libc/musl/src/stdio/putwc.c
@@ -0,0 +1,7 @@
+#include "stdio_impl.h"
+#include <wchar.h>
+
+wint_t putwc(wchar_t c, FILE *f)
+{
+	return fputwc(c, f);
+}
libc/musl/src/stdio/putwchar.c
@@ -0,0 +1,9 @@
+#include "stdio_impl.h"
+#include <wchar.h>
+
+wint_t putwchar(wchar_t c)
+{
+	return fputwc(c, stdout);
+}
+
+weak_alias(putwchar, putwchar_unlocked);
libc/musl/src/stdio/remove.c
@@ -0,0 +1,19 @@
+#include <stdio.h>
+#include <errno.h>
+#include <fcntl.h>
+#include "syscall.h"
+
+int remove(const char *path)
+{
+#ifdef SYS_unlink
+	int r = __syscall(SYS_unlink, path);
+#else
+	int r = __syscall(SYS_unlinkat, AT_FDCWD, path, 0);
+#endif
+#ifdef SYS_rmdir
+	if (r==-EISDIR) r = __syscall(SYS_rmdir, path);
+#else
+	if (r==-EISDIR) r = __syscall(SYS_unlinkat, AT_FDCWD, path, AT_REMOVEDIR);
+#endif
+	return __syscall_ret(r);
+}
libc/musl/src/stdio/rename.c
@@ -0,0 +1,12 @@
+#include <stdio.h>
+#include <fcntl.h>
+#include "syscall.h"
+
+int rename(const char *old, const char *new)
+{
+#ifdef SYS_rename
+	return syscall(SYS_rename, old, new);
+#else
+	return syscall(SYS_renameat, AT_FDCWD, old, AT_FDCWD, new);
+#endif
+}
libc/musl/src/stdio/rewind.c
@@ -0,0 +1,9 @@
+#include "stdio_impl.h"
+
+void rewind(FILE *f)
+{
+	FLOCK(f);
+	__fseeko_unlocked(f, 0, SEEK_SET);
+	f->flags &= ~F_ERR;
+	FUNLOCK(f);
+}
libc/musl/src/stdio/scanf.c
@@ -0,0 +1,14 @@
+#include <stdio.h>
+#include <stdarg.h>
+
+int scanf(const char *restrict fmt, ...)
+{
+	int ret;
+	va_list ap;
+	va_start(ap, fmt);
+	ret = vscanf(fmt, ap);
+	va_end(ap);
+	return ret;
+}
+
+weak_alias(scanf,__isoc99_scanf);
libc/musl/src/stdio/setbuf.c
@@ -0,0 +1,6 @@
+#include <stdio.h>
+
+void setbuf(FILE *restrict f, char *restrict buf)
+{
+	setvbuf(f, buf, buf ? _IOFBF : _IONBF, BUFSIZ);
+}
libc/musl/src/stdio/setbuffer.c
@@ -0,0 +1,7 @@
+#define _GNU_SOURCE
+#include <stdio.h>
+
+void setbuffer(FILE *f, char *buf, size_t size)
+{
+	setvbuf(f, buf, buf ? _IOFBF : _IONBF, size);
+}
libc/musl/src/stdio/setlinebuf.c
@@ -0,0 +1,7 @@
+#define _GNU_SOURCE
+#include <stdio.h>
+
+void setlinebuf(FILE *f)
+{
+	setvbuf(f, 0, _IOLBF, 0);
+}
libc/musl/src/stdio/setvbuf.c
@@ -0,0 +1,27 @@
+#include "stdio_impl.h"
+
+/* The behavior of this function is undefined except when it is the first
+ * operation on the stream, so the presence or absence of locking is not
+ * observable in a program whose behavior is defined. Thus no locking is
+ * performed here. No allocation of buffers is performed, but a buffer
+ * provided by the caller is used as long as it is suitably sized. */
+
+int setvbuf(FILE *restrict f, char *restrict buf, int type, size_t size)
+{
+	f->lbf = EOF;
+
+	if (type == _IONBF) {
+		f->buf_size = 0;
+	} else {
+		if (buf && size >= UNGET) {
+			f->buf = (void *)(buf + UNGET);
+			f->buf_size = size - UNGET;
+		}
+		if (type == _IOLBF && f->buf_size)
+			f->lbf = '\n';
+	}
+
+	f->flags |= F_SVB;
+
+	return 0;
+}
libc/musl/src/stdio/snprintf.c
@@ -0,0 +1,13 @@
+#include <stdio.h>
+#include <stdarg.h>
+
+int snprintf(char *restrict s, size_t n, const char *restrict fmt, ...)
+{
+	int ret;
+	va_list ap;
+	va_start(ap, fmt);
+	ret = vsnprintf(s, n, fmt, ap);
+	va_end(ap);
+	return ret;
+}
+
libc/musl/src/stdio/sprintf.c
@@ -0,0 +1,12 @@
+#include <stdio.h>
+#include <stdarg.h>
+
+int sprintf(char *restrict s, const char *restrict fmt, ...)
+{
+	int ret;
+	va_list ap;
+	va_start(ap, fmt);
+	ret = vsprintf(s, fmt, ap);
+	va_end(ap);
+	return ret;
+}
libc/musl/src/stdio/sscanf.c
@@ -0,0 +1,14 @@
+#include <stdio.h>
+#include <stdarg.h>
+
+int sscanf(const char *restrict s, const char *restrict fmt, ...)
+{
+	int ret;
+	va_list ap;
+	va_start(ap, fmt);
+	ret = vsscanf(s, fmt, ap);
+	va_end(ap);
+	return ret;
+}
+
+weak_alias(sscanf,__isoc99_sscanf);
libc/musl/src/stdio/stderr.c
@@ -0,0 +1,18 @@
+#include "stdio_impl.h"
+
+#undef stderr
+
+static unsigned char buf[UNGET];
+hidden FILE __stderr_FILE = {
+	.buf = buf+UNGET,
+	.buf_size = 0,
+	.fd = 2,
+	.flags = F_PERM | F_NORD,
+	.lbf = -1,
+	.write = __stdio_write,
+	.seek = __stdio_seek,
+	.close = __stdio_close,
+	.lock = -1,
+};
+FILE *const stderr = &__stderr_FILE;
+FILE *volatile __stderr_used = &__stderr_FILE;
libc/musl/src/stdio/stdin.c
@@ -0,0 +1,17 @@
+#include "stdio_impl.h"
+
+#undef stdin
+
+static unsigned char buf[BUFSIZ+UNGET];
+hidden FILE __stdin_FILE = {
+	.buf = buf+UNGET,
+	.buf_size = sizeof buf-UNGET,
+	.fd = 0,
+	.flags = F_PERM | F_NOWR,
+	.read = __stdio_read,
+	.seek = __stdio_seek,
+	.close = __stdio_close,
+	.lock = -1,
+};
+FILE *const stdin = &__stdin_FILE;
+FILE *volatile __stdin_used = &__stdin_FILE;
libc/musl/src/stdio/stdout.c
@@ -0,0 +1,18 @@
+#include "stdio_impl.h"
+
+#undef stdout
+
+static unsigned char buf[BUFSIZ+UNGET];
+hidden FILE __stdout_FILE = {
+	.buf = buf+UNGET,
+	.buf_size = sizeof buf-UNGET,
+	.fd = 1,
+	.flags = F_PERM | F_NORD,
+	.lbf = '\n',
+	.write = __stdout_write,
+	.seek = __stdio_seek,
+	.close = __stdio_close,
+	.lock = -1,
+};
+FILE *const stdout = &__stdout_FILE;
+FILE *volatile __stdout_used = &__stdout_FILE;
libc/musl/src/stdio/swprintf.c
@@ -0,0 +1,13 @@
+#include <stdarg.h>
+#include <wchar.h>
+
+int swprintf(wchar_t *restrict s, size_t n, const wchar_t *restrict fmt, ...)
+{
+	int ret;
+	va_list ap;
+	va_start(ap, fmt);
+	ret = vswprintf(s, n, fmt, ap);
+	va_end(ap);
+	return ret;
+}
+
libc/musl/src/stdio/swscanf.c
@@ -0,0 +1,14 @@
+#include <stdarg.h>
+#include <wchar.h>
+
+int swscanf(const wchar_t *restrict s, const wchar_t *restrict fmt, ...)
+{
+	int ret;
+	va_list ap;
+	va_start(ap, fmt);
+	ret = vswscanf(s, fmt, ap);
+	va_end(ap);
+	return ret;
+}
+
+weak_alias(swscanf,__isoc99_swscanf);
libc/musl/src/stdio/tempnam.c
@@ -0,0 +1,48 @@
+#include <stdio.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <sys/stat.h>
+#include <limits.h>
+#include <string.h>
+#include <stdlib.h>
+#include "syscall.h"
+
+#define MAXTRIES 100
+
+char *tempnam(const char *dir, const char *pfx)
+{
+	char s[PATH_MAX];
+	size_t l, dl, pl;
+	int try;
+	int r;
+
+	if (!dir) dir = P_tmpdir;
+	if (!pfx) pfx = "temp";
+
+	dl = strlen(dir);
+	pl = strlen(pfx);
+	l = dl + 1 + pl + 1 + 6;
+
+	if (l >= PATH_MAX) {
+		errno = ENAMETOOLONG;
+		return 0;
+	}
+
+	memcpy(s, dir, dl);
+	s[dl] = '/';
+	memcpy(s+dl+1, pfx, pl);
+	s[dl+1+pl] = '_';
+	s[l] = 0;
+
+	for (try=0; try<MAXTRIES; try++) {
+		__randname(s+l-6);
+#ifdef SYS_lstat
+		r = __syscall(SYS_lstat, s, &(struct stat){0});
+#else
+		r = __syscall(SYS_fstatat, AT_FDCWD, s,
+			&(struct stat){0}, AT_SYMLINK_NOFOLLOW);
+#endif
+		if (r == -ENOENT) return strdup(s);
+	}
+	return 0;
+}
libc/musl/src/stdio/tmpfile.c
@@ -0,0 +1,31 @@
+#include <stdio.h>
+#include <fcntl.h>
+#include <stdlib.h>
+#include "stdio_impl.h"
+
+#define MAXTRIES 100
+
+FILE *tmpfile(void)
+{
+	char s[] = "/tmp/tmpfile_XXXXXX";
+	int fd;
+	FILE *f;
+	int try;
+	for (try=0; try<MAXTRIES; try++) {
+		__randname(s+13);
+		fd = sys_open(s, O_RDWR|O_CREAT|O_EXCL, 0600);
+		if (fd >= 0) {
+#ifdef SYS_unlink
+			__syscall(SYS_unlink, s);
+#else
+			__syscall(SYS_unlinkat, AT_FDCWD, s, 0);
+#endif
+			f = __fdopen(fd, "w+");
+			if (!f) __syscall(SYS_close, fd);
+			return f;
+		}
+	}
+	return 0;
+}
+
+weak_alias(tmpfile, tmpfile64);
libc/musl/src/stdio/tmpnam.c
@@ -0,0 +1,28 @@
+#include <stdio.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <sys/stat.h>
+#include <string.h>
+#include <stdlib.h>
+#include "syscall.h"
+
+#define MAXTRIES 100
+
+char *tmpnam(char *buf)
+{
+	static char internal[L_tmpnam];
+	char s[] = "/tmp/tmpnam_XXXXXX";
+	int try;
+	int r;
+	for (try=0; try<MAXTRIES; try++) {
+		__randname(s+12);
+#ifdef SYS_lstat
+		r = __syscall(SYS_lstat, s, &(struct stat){0});
+#else
+		r = __syscall(SYS_fstatat, AT_FDCWD, s,
+			&(struct stat){0}, AT_SYMLINK_NOFOLLOW);
+#endif
+		if (r == -ENOENT) return strcpy(buf ? buf : internal, s);
+	}
+	return 0;
+}
libc/musl/src/stdio/ungetc.c
@@ -0,0 +1,20 @@
+#include "stdio_impl.h"
+
+int ungetc(int c, FILE *f)
+{
+	if (c == EOF) return c;
+
+	FLOCK(f);
+
+	if (!f->rpos) __toread(f);
+	if (!f->rpos || f->rpos <= f->buf - UNGET) {
+		FUNLOCK(f);
+		return EOF;
+	}
+
+	*--f->rpos = c;
+	f->flags &= ~F_EOF;
+
+	FUNLOCK(f);
+	return c;
+}
libc/musl/src/stdio/ungetwc.c
@@ -0,0 +1,35 @@
+#include "stdio_impl.h"
+#include "locale_impl.h"
+#include <wchar.h>
+#include <limits.h>
+#include <ctype.h>
+#include <string.h>
+
+wint_t ungetwc(wint_t c, FILE *f)
+{
+	unsigned char mbc[MB_LEN_MAX];
+	int l;
+	locale_t *ploc = &CURRENT_LOCALE, loc = *ploc;
+
+	FLOCK(f);
+
+	if (f->mode <= 0) fwide(f, 1);
+	*ploc = f->locale;
+
+	if (!f->rpos) __toread(f);
+	if (!f->rpos || c == WEOF || (l = wcrtomb((void *)mbc, c, 0)) < 0 ||
+	    f->rpos < f->buf - UNGET + l) {
+		FUNLOCK(f);
+		*ploc = loc;
+		return WEOF;
+	}
+
+	if (isascii(c)) *--f->rpos = c;
+	else memcpy(f->rpos -= l, mbc, l);
+
+	f->flags &= ~F_EOF;
+
+	FUNLOCK(f);
+	*ploc = loc;
+	return c;
+}
libc/musl/src/stdio/vasprintf.c
@@ -0,0 +1,15 @@
+#define _GNU_SOURCE
+#include <stdio.h>
+#include <stdarg.h>
+#include <stdlib.h>
+
+int vasprintf(char **s, const char *fmt, va_list ap)
+{
+	va_list ap2;
+	va_copy(ap2, ap);
+	int l = vsnprintf(0, 0, fmt, ap2);
+	va_end(ap2);
+
+	if (l<0 || !(*s=malloc(l+1U))) return -1;
+	return vsnprintf(*s, l+1U, fmt, ap);
+}
libc/musl/src/stdio/vdprintf.c
@@ -0,0 +1,16 @@
+#include "stdio_impl.h"
+
+static size_t wrap_write(FILE *f, const unsigned char *buf, size_t len)
+{
+	return __stdio_write(f, buf, len);
+}
+
+int vdprintf(int fd, const char *restrict fmt, va_list ap)
+{
+	FILE f = {
+		.fd = fd, .lbf = EOF, .write = wrap_write,
+		.buf = (void *)fmt, .buf_size = 0,
+		.lock = -1
+	};
+	return vfprintf(&f, fmt, ap);
+}
libc/musl/src/stdio/vfprintf.c
@@ -0,0 +1,696 @@
+#include "stdio_impl.h"
+#include <errno.h>
+#include <ctype.h>
+#include <limits.h>
+#include <string.h>
+#include <stdarg.h>
+#include <stddef.h>
+#include <stdlib.h>
+#include <wchar.h>
+#include <inttypes.h>
+#include <math.h>
+#include <float.h>
+
+/* Some useful macros */
+
+#define MAX(a,b) ((a)>(b) ? (a) : (b))
+#define MIN(a,b) ((a)<(b) ? (a) : (b))
+
+/* Convenient bit representation for modifier flags, which all fall
+ * within 31 codepoints of the space character. */
+
+#define ALT_FORM   (1U<<'#'-' ')
+#define ZERO_PAD   (1U<<'0'-' ')
+#define LEFT_ADJ   (1U<<'-'-' ')
+#define PAD_POS    (1U<<' '-' ')
+#define MARK_POS   (1U<<'+'-' ')
+#define GROUPED    (1U<<'\''-' ')
+
+#define FLAGMASK (ALT_FORM|ZERO_PAD|LEFT_ADJ|PAD_POS|MARK_POS|GROUPED)
+
+/* State machine to accept length modifiers + conversion specifiers.
+ * Result is 0 on failure, or an argument type to pop on success. */
+
+enum {
+	BARE, LPRE, LLPRE, HPRE, HHPRE, BIGLPRE,
+	ZTPRE, JPRE,
+	STOP,
+	PTR, INT, UINT, ULLONG,
+	LONG, ULONG,
+	SHORT, USHORT, CHAR, UCHAR,
+	LLONG, SIZET, IMAX, UMAX, PDIFF, UIPTR,
+	DBL, LDBL,
+	NOARG,
+	MAXSTATE
+};
+
+#define S(x) [(x)-'A']
+
+static const unsigned char states[]['z'-'A'+1] = {
+	{ /* 0: bare types */
+		S('d') = INT, S('i') = INT,
+		S('o') = UINT, S('u') = UINT, S('x') = UINT, S('X') = UINT,
+		S('e') = DBL, S('f') = DBL, S('g') = DBL, S('a') = DBL,
+		S('E') = DBL, S('F') = DBL, S('G') = DBL, S('A') = DBL,
+		S('c') = CHAR, S('C') = INT,
+		S('s') = PTR, S('S') = PTR, S('p') = UIPTR, S('n') = PTR,
+		S('m') = NOARG,
+		S('l') = LPRE, S('h') = HPRE, S('L') = BIGLPRE,
+		S('z') = ZTPRE, S('j') = JPRE, S('t') = ZTPRE,
+	}, { /* 1: l-prefixed */
+		S('d') = LONG, S('i') = LONG,
+		S('o') = ULONG, S('u') = ULONG, S('x') = ULONG, S('X') = ULONG,
+		S('e') = DBL, S('f') = DBL, S('g') = DBL, S('a') = DBL,
+		S('E') = DBL, S('F') = DBL, S('G') = DBL, S('A') = DBL,
+		S('c') = INT, S('s') = PTR, S('n') = PTR,
+		S('l') = LLPRE,
+	}, { /* 2: ll-prefixed */
+		S('d') = LLONG, S('i') = LLONG,
+		S('o') = ULLONG, S('u') = ULLONG,
+		S('x') = ULLONG, S('X') = ULLONG,
+		S('n') = PTR,
+	}, { /* 3: h-prefixed */
+		S('d') = SHORT, S('i') = SHORT,
+		S('o') = USHORT, S('u') = USHORT,
+		S('x') = USHORT, S('X') = USHORT,
+		S('n') = PTR,
+		S('h') = HHPRE,
+	}, { /* 4: hh-prefixed */
+		S('d') = CHAR, S('i') = CHAR,
+		S('o') = UCHAR, S('u') = UCHAR,
+		S('x') = UCHAR, S('X') = UCHAR,
+		S('n') = PTR,
+	}, { /* 5: L-prefixed */
+		S('e') = LDBL, S('f') = LDBL, S('g') = LDBL, S('a') = LDBL,
+		S('E') = LDBL, S('F') = LDBL, S('G') = LDBL, S('A') = LDBL,
+		S('n') = PTR,
+	}, { /* 6: z- or t-prefixed (assumed to be same size) */
+		S('d') = PDIFF, S('i') = PDIFF,
+		S('o') = SIZET, S('u') = SIZET,
+		S('x') = SIZET, S('X') = SIZET,
+		S('n') = PTR,
+	}, { /* 7: j-prefixed */
+		S('d') = IMAX, S('i') = IMAX,
+		S('o') = UMAX, S('u') = UMAX,
+		S('x') = UMAX, S('X') = UMAX,
+		S('n') = PTR,
+	}
+};
+
+#define OOB(x) ((unsigned)(x)-'A' > 'z'-'A')
+
+union arg
+{
+	uintmax_t i;
+	long double f;
+	void *p;
+};
+
+static void pop_arg(union arg *arg, int type, va_list *ap)
+{
+	switch (type) {
+	       case PTR:	arg->p = va_arg(*ap, void *);
+	break; case INT:	arg->i = va_arg(*ap, int);
+	break; case UINT:	arg->i = va_arg(*ap, unsigned int);
+	break; case LONG:	arg->i = va_arg(*ap, long);
+	break; case ULONG:	arg->i = va_arg(*ap, unsigned long);
+	break; case ULLONG:	arg->i = va_arg(*ap, unsigned long long);
+	break; case SHORT:	arg->i = (short)va_arg(*ap, int);
+	break; case USHORT:	arg->i = (unsigned short)va_arg(*ap, int);
+	break; case CHAR:	arg->i = (signed char)va_arg(*ap, int);
+	break; case UCHAR:	arg->i = (unsigned char)va_arg(*ap, int);
+	break; case LLONG:	arg->i = va_arg(*ap, long long);
+	break; case SIZET:	arg->i = va_arg(*ap, size_t);
+	break; case IMAX:	arg->i = va_arg(*ap, intmax_t);
+	break; case UMAX:	arg->i = va_arg(*ap, uintmax_t);
+	break; case PDIFF:	arg->i = va_arg(*ap, ptrdiff_t);
+	break; case UIPTR:	arg->i = (uintptr_t)va_arg(*ap, void *);
+	break; case DBL:	arg->f = va_arg(*ap, double);
+	break; case LDBL:	arg->f = va_arg(*ap, long double);
+	}
+}
+
+static void out(FILE *f, const char *s, size_t l)
+{
+	if (!(f->flags & F_ERR)) __fwritex((void *)s, l, f);
+}
+
+static void pad(FILE *f, char c, int w, int l, int fl)
+{
+	char pad[256];
+	if (fl & (LEFT_ADJ | ZERO_PAD) || l >= w) return;
+	l = w - l;
+	memset(pad, c, l>sizeof pad ? sizeof pad : l);
+	for (; l >= sizeof pad; l -= sizeof pad)
+		out(f, pad, sizeof pad);
+	out(f, pad, l);
+}
+
+static const char xdigits[16] = {
+	"0123456789ABCDEF"
+};
+
+static char *fmt_x(uintmax_t x, char *s, int lower)
+{
+	for (; x; x>>=4) *--s = xdigits[(x&15)]|lower;
+	return s;
+}
+
+static char *fmt_o(uintmax_t x, char *s)
+{
+	for (; x; x>>=3) *--s = '0' + (x&7);
+	return s;
+}
+
+static char *fmt_u(uintmax_t x, char *s)
+{
+	unsigned long y;
+	for (   ; x>ULONG_MAX; x/=10) *--s = '0' + x%10;
+	for (y=x;           y; y/=10) *--s = '0' + y%10;
+	return s;
+}
+
+/* Do not override this check. The floating point printing code below
+ * depends on the float.h constants being right. If they are wrong, it
+ * may overflow the stack. */
+#if LDBL_MANT_DIG == 53
+typedef char compiler_defines_long_double_incorrectly[9-(int)sizeof(long double)];
+#endif
+
+static int fmt_fp(FILE *f, long double y, int w, int p, int fl, int t)
+{
+	uint32_t big[(LDBL_MANT_DIG+28)/29 + 1          // mantissa expansion
+		+ (LDBL_MAX_EXP+LDBL_MANT_DIG+28+8)/9]; // exponent expansion
+	uint32_t *a, *d, *r, *z;
+	int e2=0, e, i, j, l;
+	char buf[9+LDBL_MANT_DIG/4], *s;
+	const char *prefix="-0X+0X 0X-0x+0x 0x";
+	int pl;
+	char ebuf0[3*sizeof(int)], *ebuf=&ebuf0[3*sizeof(int)], *estr;
+
+	pl=1;
+	if (signbit(y)) {
+		y=-y;
+	} else if (fl & MARK_POS) {
+		prefix+=3;
+	} else if (fl & PAD_POS) {
+		prefix+=6;
+	} else prefix++, pl=0;
+
+	if (!isfinite(y)) {
+		char *s = (t&32)?"inf":"INF";
+		if (y!=y) s=(t&32)?"nan":"NAN";
+		pad(f, ' ', w, 3+pl, fl&~ZERO_PAD);
+		out(f, prefix, pl);
+		out(f, s, 3);
+		pad(f, ' ', w, 3+pl, fl^LEFT_ADJ);
+		return MAX(w, 3+pl);
+	}
+
+	y = frexpl(y, &e2) * 2;
+	if (y) e2--;
+
+	if ((t|32)=='a') {
+		long double round = 8.0;
+		int re;
+
+		if (t&32) prefix += 9;
+		pl += 2;
+
+		if (p<0 || p>=LDBL_MANT_DIG/4-1) re=0;
+		else re=LDBL_MANT_DIG/4-1-p;
+
+		if (re) {
+			round *= 1<<(LDBL_MANT_DIG%4);
+			while (re--) round*=16;
+			if (*prefix=='-') {
+				y=-y;
+				y-=round;
+				y+=round;
+				y=-y;
+			} else {
+				y+=round;
+				y-=round;
+			}
+		}
+
+		estr=fmt_u(e2<0 ? -e2 : e2, ebuf);
+		if (estr==ebuf) *--estr='0';
+		*--estr = (e2<0 ? '-' : '+');
+		*--estr = t+('p'-'a');
+
+		s=buf;
+		do {
+			int x=y;
+			*s++=xdigits[x]|(t&32);
+			y=16*(y-x);
+			if (s-buf==1 && (y||p>0||(fl&ALT_FORM))) *s++='.';
+		} while (y);
+
+		if (p > INT_MAX-2-(ebuf-estr)-pl)
+			return -1;
+		if (p && s-buf-2 < p)
+			l = (p+2) + (ebuf-estr);
+		else
+			l = (s-buf) + (ebuf-estr);
+
+		pad(f, ' ', w, pl+l, fl);
+		out(f, prefix, pl);
+		pad(f, '0', w, pl+l, fl^ZERO_PAD);
+		out(f, buf, s-buf);
+		pad(f, '0', l-(ebuf-estr)-(s-buf), 0, 0);
+		out(f, estr, ebuf-estr);
+		pad(f, ' ', w, pl+l, fl^LEFT_ADJ);
+		return MAX(w, pl+l);
+	}
+	if (p<0) p=6;
+
+	if (y) y *= 0x1p28, e2-=28;
+
+	if (e2<0) a=r=z=big;
+	else a=r=z=big+sizeof(big)/sizeof(*big) - LDBL_MANT_DIG - 1;
+
+	do {
+		*z = y;
+		y = 1000000000*(y-*z++);
+	} while (y);
+
+	while (e2>0) {
+		uint32_t carry=0;
+		int sh=MIN(29,e2);
+		for (d=z-1; d>=a; d--) {
+			uint64_t x = ((uint64_t)*d<<sh)+carry;
+			*d = x % 1000000000;
+			carry = x / 1000000000;
+		}
+		if (carry) *--a = carry;
+		while (z>a && !z[-1]) z--;
+		e2-=sh;
+	}
+	while (e2<0) {
+		uint32_t carry=0, *b;
+		int sh=MIN(9,-e2), need=1+(p+LDBL_MANT_DIG/3U+8)/9;
+		for (d=a; d<z; d++) {
+			uint32_t rm = *d & (1<<sh)-1;
+			*d = (*d>>sh) + carry;
+			carry = (1000000000>>sh) * rm;
+		}
+		if (!*a) a++;
+		if (carry) *z++ = carry;
+		/* Avoid (slow!) computation past requested precision */
+		b = (t|32)=='f' ? r : a;
+		if (z-b > need) z = b+need;
+		e2+=sh;
+	}
+
+	if (a<z) for (i=10, e=9*(r-a); *a>=i; i*=10, e++);
+	else e=0;
+
+	/* Perform rounding: j is precision after the radix (possibly neg) */
+	j = p - ((t|32)!='f')*e - ((t|32)=='g' && p);
+	if (j < 9*(z-r-1)) {
+		uint32_t x;
+		/* We avoid C's broken division of negative numbers */
+		d = r + 1 + ((j+9*LDBL_MAX_EXP)/9 - LDBL_MAX_EXP);
+		j += 9*LDBL_MAX_EXP;
+		j %= 9;
+		for (i=10, j++; j<9; i*=10, j++);
+		x = *d % i;
+		/* Are there any significant digits past j? */
+		if (x || d+1!=z) {
+			long double round = 2/LDBL_EPSILON;
+			long double small;
+			if ((*d/i & 1) || (i==1000000000 && d>a && (d[-1]&1)))
+				round += 2;
+			if (x<i/2) small=0x0.8p0;
+			else if (x==i/2 && d+1==z) small=0x1.0p0;
+			else small=0x1.8p0;
+			if (pl && *prefix=='-') round*=-1, small*=-1;
+			*d -= x;
+			/* Decide whether to round by probing round+small */
+			if (round+small != round) {
+				*d = *d + i;
+				while (*d > 999999999) {
+					*d--=0;
+					if (d<a) *--a=0;
+					(*d)++;
+				}
+				for (i=10, e=9*(r-a); *a>=i; i*=10, e++);
+			}
+		}
+		if (z>d+1) z=d+1;
+	}
+	for (; z>a && !z[-1]; z--);
+	
+	if ((t|32)=='g') {
+		if (!p) p++;
+		if (p>e && e>=-4) {
+			t--;
+			p-=e+1;
+		} else {
+			t-=2;
+			p--;
+		}
+		if (!(fl&ALT_FORM)) {
+			/* Count trailing zeros in last place */
+			if (z>a && z[-1]) for (i=10, j=0; z[-1]%i==0; i*=10, j++);
+			else j=9;
+			if ((t|32)=='f')
+				p = MIN(p,MAX(0,9*(z-r-1)-j));
+			else
+				p = MIN(p,MAX(0,9*(z-r-1)+e-j));
+		}
+	}
+	if (p > INT_MAX-1-(p || (fl&ALT_FORM)))
+		return -1;
+	l = 1 + p + (p || (fl&ALT_FORM));
+	if ((t|32)=='f') {
+		if (e > INT_MAX-l) return -1;
+		if (e>0) l+=e;
+	} else {
+		estr=fmt_u(e<0 ? -e : e, ebuf);
+		while(ebuf-estr<2) *--estr='0';
+		*--estr = (e<0 ? '-' : '+');
+		*--estr = t;
+		if (ebuf-estr > INT_MAX-l) return -1;
+		l += ebuf-estr;
+	}
+
+	if (l > INT_MAX-pl) return -1;
+	pad(f, ' ', w, pl+l, fl);
+	out(f, prefix, pl);
+	pad(f, '0', w, pl+l, fl^ZERO_PAD);
+
+	if ((t|32)=='f') {
+		if (a>r) a=r;
+		for (d=a; d<=r; d++) {
+			char *s = fmt_u(*d, buf+9);
+			if (d!=a) while (s>buf) *--s='0';
+			else if (s==buf+9) *--s='0';
+			out(f, s, buf+9-s);
+		}
+		if (p || (fl&ALT_FORM)) out(f, ".", 1);
+		for (; d<z && p>0; d++, p-=9) {
+			char *s = fmt_u(*d, buf+9);
+			while (s>buf) *--s='0';
+			out(f, s, MIN(9,p));
+		}
+		pad(f, '0', p+9, 9, 0);
+	} else {
+		if (z<=a) z=a+1;
+		for (d=a; d<z && p>=0; d++) {
+			char *s = fmt_u(*d, buf+9);
+			if (s==buf+9) *--s='0';
+			if (d!=a) while (s>buf) *--s='0';
+			else {
+				out(f, s++, 1);
+				if (p>0||(fl&ALT_FORM)) out(f, ".", 1);
+			}
+			out(f, s, MIN(buf+9-s, p));
+			p -= buf+9-s;
+		}
+		pad(f, '0', p+18, 18, 0);
+		out(f, estr, ebuf-estr);
+	}
+
+	pad(f, ' ', w, pl+l, fl^LEFT_ADJ);
+
+	return MAX(w, pl+l);
+}
+
+static int getint(char **s) {
+	int i;
+	for (i=0; isdigit(**s); (*s)++) {
+		if (i > INT_MAX/10U || **s-'0' > INT_MAX-10*i) i = -1;
+		else i = 10*i + (**s-'0');
+	}
+	return i;
+}
+
+static int printf_core(FILE *f, const char *fmt, va_list *ap, union arg *nl_arg, int *nl_type)
+{
+	char *a, *z, *s=(char *)fmt;
+	unsigned l10n=0, fl;
+	int w, p, xp;
+	union arg arg;
+	int argpos;
+	unsigned st, ps;
+	int cnt=0, l=0;
+	size_t i;
+	char buf[sizeof(uintmax_t)*3+3+LDBL_MANT_DIG/4];
+	const char *prefix;
+	int t, pl;
+	wchar_t wc[2], *ws;
+	char mb[4];
+
+	for (;;) {
+		/* This error is only specified for snprintf, but since it's
+		 * unspecified for other forms, do the same. Stop immediately
+		 * on overflow; otherwise %n could produce wrong results. */
+		if (l > INT_MAX - cnt) goto overflow;
+
+		/* Update output count, end loop when fmt is exhausted */
+		cnt += l;
+		if (!*s) break;
+
+		/* Handle literal text and %% format specifiers */
+		for (a=s; *s && *s!='%'; s++);
+		for (z=s; s[0]=='%' && s[1]=='%'; z++, s+=2);
+		if (z-a > INT_MAX-cnt) goto overflow;
+		l = z-a;
+		if (f) out(f, a, l);
+		if (l) continue;
+
+		if (isdigit(s[1]) && s[2]=='$') {
+			l10n=1;
+			argpos = s[1]-'0';
+			s+=3;
+		} else {
+			argpos = -1;
+			s++;
+		}
+
+		/* Read modifier flags */
+		for (fl=0; (unsigned)*s-' '<32 && (FLAGMASK&(1U<<*s-' ')); s++)
+			fl |= 1U<<*s-' ';
+
+		/* Read field width */
+		if (*s=='*') {
+			if (isdigit(s[1]) && s[2]=='$') {
+				l10n=1;
+				nl_type[s[1]-'0'] = INT;
+				w = nl_arg[s[1]-'0'].i;
+				s+=3;
+			} else if (!l10n) {
+				w = f ? va_arg(*ap, int) : 0;
+				s++;
+			} else goto inval;
+			if (w<0) fl|=LEFT_ADJ, w=-w;
+		} else if ((w=getint(&s))<0) goto overflow;
+
+		/* Read precision */
+		if (*s=='.' && s[1]=='*') {
+			if (isdigit(s[2]) && s[3]=='$') {
+				nl_type[s[2]-'0'] = INT;
+				p = nl_arg[s[2]-'0'].i;
+				s+=4;
+			} else if (!l10n) {
+				p = f ? va_arg(*ap, int) : 0;
+				s+=2;
+			} else goto inval;
+			xp = (p>=0);
+		} else if (*s=='.') {
+			s++;
+			p = getint(&s);
+			xp = 1;
+		} else {
+			p = -1;
+			xp = 0;
+		}
+
+		/* Format specifier state machine */
+		st=0;
+		do {
+			if (OOB(*s)) goto inval;
+			ps=st;
+			st=states[st]S(*s++);
+		} while (st-1<STOP);
+		if (!st) goto inval;
+
+		/* Check validity of argument type (nl/normal) */
+		if (st==NOARG) {
+			if (argpos>=0) goto inval;
+		} else {
+			if (argpos>=0) nl_type[argpos]=st, arg=nl_arg[argpos];
+			else if (f) pop_arg(&arg, st, ap);
+			else return 0;
+		}
+
+		if (!f) continue;
+
+		z = buf + sizeof(buf);
+		prefix = "-+   0X0x";
+		pl = 0;
+		t = s[-1];
+
+		/* Transform ls,lc -> S,C */
+		if (ps && (t&15)==3) t&=~32;
+
+		/* - and 0 flags are mutually exclusive */
+		if (fl & LEFT_ADJ) fl &= ~ZERO_PAD;
+
+		switch(t) {
+		case 'n':
+			switch(ps) {
+			case BARE: *(int *)arg.p = cnt; break;
+			case LPRE: *(long *)arg.p = cnt; break;
+			case LLPRE: *(long long *)arg.p = cnt; break;
+			case HPRE: *(unsigned short *)arg.p = cnt; break;
+			case HHPRE: *(unsigned char *)arg.p = cnt; break;
+			case ZTPRE: *(size_t *)arg.p = cnt; break;
+			case JPRE: *(uintmax_t *)arg.p = cnt; break;
+			}
+			continue;
+		case 'p':
+			p = MAX(p, 2*sizeof(void*));
+			t = 'x';
+			fl |= ALT_FORM;
+		case 'x': case 'X':
+			a = fmt_x(arg.i, z, t&32);
+			if (arg.i && (fl & ALT_FORM)) prefix+=(t>>4), pl=2;
+			if (0) {
+		case 'o':
+			a = fmt_o(arg.i, z);
+			if ((fl&ALT_FORM) && p<z-a+1) p=z-a+1;
+			} if (0) {
+		case 'd': case 'i':
+			pl=1;
+			if (arg.i>INTMAX_MAX) {
+				arg.i=-arg.i;
+			} else if (fl & MARK_POS) {
+				prefix++;
+			} else if (fl & PAD_POS) {
+				prefix+=2;
+			} else pl=0;
+		case 'u':
+			a = fmt_u(arg.i, z);
+			}
+			if (xp && p<0) goto overflow;
+			if (xp) fl &= ~ZERO_PAD;
+			if (!arg.i && !p) {
+				a=z;
+				break;
+			}
+			p = MAX(p, z-a + !arg.i);
+			break;
+		case 'c':
+			*(a=z-(p=1))=arg.i;
+			fl &= ~ZERO_PAD;
+			break;
+		case 'm':
+			if (1) a = strerror(errno); else
+		case 's':
+			a = arg.p ? arg.p : "(null)";
+			z = a + strnlen(a, p<0 ? INT_MAX : p);
+			if (p<0 && *z) goto overflow;
+			p = z-a;
+			fl &= ~ZERO_PAD;
+			break;
+		case 'C':
+			wc[0] = arg.i;
+			wc[1] = 0;
+			arg.p = wc;
+			p = -1;
+		case 'S':
+			ws = arg.p;
+			for (i=l=0; i<p && *ws && (l=wctomb(mb, *ws++))>=0 && l<=p-i; i+=l);
+			if (l<0) return -1;
+			if (i > INT_MAX) goto overflow;
+			p = i;
+			pad(f, ' ', w, p, fl);
+			ws = arg.p;
+			for (i=0; i<0U+p && *ws && i+(l=wctomb(mb, *ws++))<=p; i+=l)
+				out(f, mb, l);
+			pad(f, ' ', w, p, fl^LEFT_ADJ);
+			l = w>p ? w : p;
+			continue;
+		case 'e': case 'f': case 'g': case 'a':
+		case 'E': case 'F': case 'G': case 'A':
+			if (xp && p<0) goto overflow;
+			l = fmt_fp(f, arg.f, w, p, fl, t);
+			if (l<0) goto overflow;
+			continue;
+		}
+
+		if (p < z-a) p = z-a;
+		if (p > INT_MAX-pl) goto overflow;
+		if (w < pl+p) w = pl+p;
+		if (w > INT_MAX-cnt) goto overflow;
+
+		pad(f, ' ', w, pl+p, fl);
+		out(f, prefix, pl);
+		pad(f, '0', w, pl+p, fl^ZERO_PAD);
+		pad(f, '0', p, z-a, 0);
+		out(f, a, z-a);
+		pad(f, ' ', w, pl+p, fl^LEFT_ADJ);
+
+		l = w;
+	}
+
+	if (f) return cnt;
+	if (!l10n) return 0;
+
+	for (i=1; i<=NL_ARGMAX && nl_type[i]; i++)
+		pop_arg(nl_arg+i, nl_type[i], ap);
+	for (; i<=NL_ARGMAX && !nl_type[i]; i++);
+	if (i<=NL_ARGMAX) goto inval;
+	return 1;
+
+inval:
+	errno = EINVAL;
+	return -1;
+overflow:
+	errno = EOVERFLOW;
+	return -1;
+}
+
+int vfprintf(FILE *restrict f, const char *restrict fmt, va_list ap)
+{
+	va_list ap2;
+	int nl_type[NL_ARGMAX+1] = {0};
+	union arg nl_arg[NL_ARGMAX+1];
+	unsigned char internal_buf[80], *saved_buf = 0;
+	int olderr;
+	int ret;
+
+	/* the copy allows passing va_list* even if va_list is an array */
+	va_copy(ap2, ap);
+	if (printf_core(0, fmt, &ap2, nl_arg, nl_type) < 0) {
+		va_end(ap2);
+		return -1;
+	}
+
+	FLOCK(f);
+	olderr = f->flags & F_ERR;
+	if (f->mode < 1) f->flags &= ~F_ERR;
+	if (!f->buf_size) {
+		saved_buf = f->buf;
+		f->buf = internal_buf;
+		f->buf_size = sizeof internal_buf;
+		f->wpos = f->wbase = f->wend = 0;
+	}
+	if (!f->wend && __towrite(f)) ret = -1;
+	else ret = printf_core(f, fmt, &ap2, nl_arg, nl_type);
+	if (saved_buf) {
+		f->write(f, 0, 0);
+		if (!f->wpos) ret = -1;
+		f->buf = saved_buf;
+		f->buf_size = 0;
+		f->wpos = f->wbase = f->wend = 0;
+	}
+	if (f->flags & F_ERR) ret = -1;
+	f->flags |= olderr;
+	FUNLOCK(f);
+	va_end(ap2);
+	return ret;
+}
libc/musl/src/stdio/vfscanf.c
@@ -0,0 +1,336 @@
+#include <stdlib.h>
+#include <stdarg.h>
+#include <ctype.h>
+#include <wchar.h>
+#include <wctype.h>
+#include <limits.h>
+#include <string.h>
+#include <stdint.h>
+
+#include "stdio_impl.h"
+#include "shgetc.h"
+#include "intscan.h"
+#include "floatscan.h"
+
+#define SIZE_hh -2
+#define SIZE_h  -1
+#define SIZE_def 0
+#define SIZE_l   1
+#define SIZE_L   2
+#define SIZE_ll  3
+
+static void store_int(void *dest, int size, unsigned long long i)
+{
+	if (!dest) return;
+	switch (size) {
+	case SIZE_hh:
+		*(char *)dest = i;
+		break;
+	case SIZE_h:
+		*(short *)dest = i;
+		break;
+	case SIZE_def:
+		*(int *)dest = i;
+		break;
+	case SIZE_l:
+		*(long *)dest = i;
+		break;
+	case SIZE_ll:
+		*(long long *)dest = i;
+		break;
+	}
+}
+
+static void *arg_n(va_list ap, unsigned int n)
+{
+	void *p;
+	unsigned int i;
+	va_list ap2;
+	va_copy(ap2, ap);
+	for (i=n; i>1; i--) va_arg(ap2, void *);
+	p = va_arg(ap2, void *);
+	va_end(ap2);
+	return p;
+}
+
+int vfscanf(FILE *restrict f, const char *restrict fmt, va_list ap)
+{
+	int width;
+	int size;
+	int alloc;
+	int base;
+	const unsigned char *p;
+	int c, t;
+	char *s;
+	wchar_t *wcs;
+	mbstate_t st;
+	void *dest=NULL;
+	int invert;
+	int matches=0;
+	unsigned long long x;
+	long double y;
+	off_t pos = 0;
+	unsigned char scanset[257];
+	size_t i, k;
+	wchar_t wc;
+
+	FLOCK(f);
+
+	for (p=(const unsigned char *)fmt; *p; p++) {
+
+		alloc = 0;
+
+		if (isspace(*p)) {
+			while (isspace(p[1])) p++;
+			shlim(f, 0);
+			while (isspace(shgetc(f)));
+			shunget(f);
+			pos += shcnt(f);
+			continue;
+		}
+		if (*p != '%' || p[1] == '%') {
+			shlim(f, 0);
+			if (*p == '%') {
+				p++;
+				while (isspace((c=shgetc(f))));
+			} else {
+				c = shgetc(f);
+			}
+			if (c!=*p) {
+				shunget(f);
+				if (c<0) goto input_fail;
+				goto match_fail;
+			}
+			pos += shcnt(f);
+			continue;
+		}
+
+		p++;
+		if (*p=='*') {
+			dest = 0; p++;
+		} else if (isdigit(*p) && p[1]=='$') {
+			dest = arg_n(ap, *p-'0'); p+=2;
+		} else {
+			dest = va_arg(ap, void *);
+		}
+
+		for (width=0; isdigit(*p); p++) {
+			width = 10*width + *p - '0';
+		}
+
+		if (*p=='m') {
+			wcs = 0;
+			s = 0;
+			alloc = !!dest;
+			p++;
+		} else {
+			alloc = 0;
+		}
+
+		size = SIZE_def;
+		switch (*p++) {
+		case 'h':
+			if (*p == 'h') p++, size = SIZE_hh;
+			else size = SIZE_h;
+			break;
+		case 'l':
+			if (*p == 'l') p++, size = SIZE_ll;
+			else size = SIZE_l;
+			break;
+		case 'j':
+			size = SIZE_ll;
+			break;
+		case 'z':
+		case 't':
+			size = SIZE_l;
+			break;
+		case 'L':
+			size = SIZE_L;
+			break;
+		case 'd': case 'i': case 'o': case 'u': case 'x':
+		case 'a': case 'e': case 'f': case 'g':
+		case 'A': case 'E': case 'F': case 'G': case 'X':
+		case 's': case 'c': case '[':
+		case 'S': case 'C':
+		case 'p': case 'n':
+			p--;
+			break;
+		default:
+			goto fmt_fail;
+		}
+
+		t = *p;
+
+		/* C or S */
+		if ((t&0x2f) == 3) {
+			t |= 32;
+			size = SIZE_l;
+		}
+
+		switch (t) {
+		case 'c':
+			if (width < 1) width = 1;
+		case '[':
+			break;
+		case 'n':
+			store_int(dest, size, pos);
+			/* do not increment match count, etc! */
+			continue;
+		default:
+			shlim(f, 0);
+			while (isspace(shgetc(f)));
+			shunget(f);
+			pos += shcnt(f);
+		}
+
+		shlim(f, width);
+		if (shgetc(f) < 0) goto input_fail;
+		shunget(f);
+
+		switch (t) {
+		case 's':
+		case 'c':
+		case '[':
+			if (t == 'c' || t == 's') {
+				memset(scanset, -1, sizeof scanset);
+				scanset[0] = 0;
+				if (t == 's') {
+					scanset[1+'\t'] = 0;
+					scanset[1+'\n'] = 0;
+					scanset[1+'\v'] = 0;
+					scanset[1+'\f'] = 0;
+					scanset[1+'\r'] = 0;
+					scanset[1+' '] = 0;
+				}
+			} else {
+				if (*++p == '^') p++, invert = 1;
+				else invert = 0;
+				memset(scanset, invert, sizeof scanset);
+				scanset[0] = 0;
+				if (*p == '-') p++, scanset[1+'-'] = 1-invert;
+				else if (*p == ']') p++, scanset[1+']'] = 1-invert;
+				for (; *p != ']'; p++) {
+					if (!*p) goto fmt_fail;
+					if (*p=='-' && p[1] && p[1] != ']')
+						for (c=p++[-1]; c<*p; c++)
+							scanset[1+c] = 1-invert;
+					scanset[1+*p] = 1-invert;
+				}
+			}
+			wcs = 0;
+			s = 0;
+			i = 0;
+			k = t=='c' ? width+1U : 31;
+			if (size == SIZE_l) {
+				if (alloc) {
+					wcs = malloc(k*sizeof(wchar_t));
+					if (!wcs) goto alloc_fail;
+				} else {
+					wcs = dest;
+				}
+				st = (mbstate_t){0};
+				while (scanset[(c=shgetc(f))+1]) {
+					switch (mbrtowc(&wc, &(char){c}, 1, &st)) {
+					case -1:
+						goto input_fail;
+					case -2:
+						continue;
+					}
+					if (wcs) wcs[i++] = wc;
+					if (alloc && i==k) {
+						k+=k+1;
+						wchar_t *tmp = realloc(wcs, k*sizeof(wchar_t));
+						if (!tmp) goto alloc_fail;
+						wcs = tmp;
+					}
+				}
+				if (!mbsinit(&st)) goto input_fail;
+			} else if (alloc) {
+				s = malloc(k);
+				if (!s) goto alloc_fail;
+				while (scanset[(c=shgetc(f))+1]) {
+					s[i++] = c;
+					if (i==k) {
+						k+=k+1;
+						char *tmp = realloc(s, k);
+						if (!tmp) goto alloc_fail;
+						s = tmp;
+					}
+				}
+			} else if ((s = dest)) {
+				while (scanset[(c=shgetc(f))+1])
+					s[i++] = c;
+			} else {
+				while (scanset[(c=shgetc(f))+1]);
+			}
+			shunget(f);
+			if (!shcnt(f)) goto match_fail;
+			if (t == 'c' && shcnt(f) != width) goto match_fail;
+			if (alloc) {
+				if (size == SIZE_l) *(wchar_t **)dest = wcs;
+				else *(char **)dest = s;
+			}
+			if (t != 'c') {
+				if (wcs) wcs[i] = 0;
+				if (s) s[i] = 0;
+			}
+			break;
+		case 'p':
+		case 'X':
+		case 'x':
+			base = 16;
+			goto int_common;
+		case 'o':
+			base = 8;
+			goto int_common;
+		case 'd':
+		case 'u':
+			base = 10;
+			goto int_common;
+		case 'i':
+			base = 0;
+		int_common:
+			x = __intscan(f, base, 0, ULLONG_MAX);
+			if (!shcnt(f)) goto match_fail;
+			if (t=='p' && dest) *(void **)dest = (void *)(uintptr_t)x;
+			else store_int(dest, size, x);
+			break;
+		case 'a': case 'A':
+		case 'e': case 'E':
+		case 'f': case 'F':
+		case 'g': case 'G':
+			y = __floatscan(f, size, 0);
+			if (!shcnt(f)) goto match_fail;
+			if (dest) switch (size) {
+			case SIZE_def:
+				*(float *)dest = y;
+				break;
+			case SIZE_l:
+				*(double *)dest = y;
+				break;
+			case SIZE_L:
+				*(long double *)dest = y;
+				break;
+			}
+			break;
+		}
+
+		pos += shcnt(f);
+		if (dest) matches++;
+	}
+	if (0) {
+fmt_fail:
+alloc_fail:
+input_fail:
+		if (!matches) matches--;
+match_fail:
+		if (alloc) {
+			free(s);
+			free(wcs);
+		}
+	}
+	FUNLOCK(f);
+	return matches;
+}
+
+weak_alias(vfscanf,__isoc99_vfscanf);
libc/musl/src/stdio/vfwprintf.c
@@ -0,0 +1,363 @@
+#include "stdio_impl.h"
+#include <errno.h>
+#include <ctype.h>
+#include <limits.h>
+#include <string.h>
+#include <stdarg.h>
+#include <stddef.h>
+#include <stdlib.h>
+#include <wchar.h>
+#include <inttypes.h>
+
+/* Convenient bit representation for modifier flags, which all fall
+ * within 31 codepoints of the space character. */
+
+#define ALT_FORM   (1U<<'#'-' ')
+#define ZERO_PAD   (1U<<'0'-' ')
+#define LEFT_ADJ   (1U<<'-'-' ')
+#define PAD_POS    (1U<<' '-' ')
+#define MARK_POS   (1U<<'+'-' ')
+#define GROUPED    (1U<<'\''-' ')
+
+#define FLAGMASK (ALT_FORM|ZERO_PAD|LEFT_ADJ|PAD_POS|MARK_POS|GROUPED)
+
+/* State machine to accept length modifiers + conversion specifiers.
+ * Result is 0 on failure, or an argument type to pop on success. */
+
+enum {
+	BARE, LPRE, LLPRE, HPRE, HHPRE, BIGLPRE,
+	ZTPRE, JPRE,
+	STOP,
+	PTR, INT, UINT, ULLONG,
+	LONG, ULONG,
+	SHORT, USHORT, CHAR, UCHAR,
+	LLONG, SIZET, IMAX, UMAX, PDIFF, UIPTR,
+	DBL, LDBL,
+	NOARG,
+	MAXSTATE
+};
+
+#define S(x) [(x)-'A']
+
+static const unsigned char states[]['z'-'A'+1] = {
+	{ /* 0: bare types */
+		S('d') = INT, S('i') = INT,
+		S('o') = UINT, S('u') = UINT, S('x') = UINT, S('X') = UINT,
+		S('e') = DBL, S('f') = DBL, S('g') = DBL, S('a') = DBL,
+		S('E') = DBL, S('F') = DBL, S('G') = DBL, S('A') = DBL,
+		S('c') = CHAR, S('C') = INT,
+		S('s') = PTR, S('S') = PTR, S('p') = UIPTR, S('n') = PTR,
+		S('m') = NOARG,
+		S('l') = LPRE, S('h') = HPRE, S('L') = BIGLPRE,
+		S('z') = ZTPRE, S('j') = JPRE, S('t') = ZTPRE,
+	}, { /* 1: l-prefixed */
+		S('d') = LONG, S('i') = LONG,
+		S('o') = ULONG, S('u') = ULONG, S('x') = ULONG, S('X') = ULONG,
+		S('c') = INT, S('s') = PTR, S('n') = PTR,
+		S('l') = LLPRE,
+	}, { /* 2: ll-prefixed */
+		S('d') = LLONG, S('i') = LLONG,
+		S('o') = ULLONG, S('u') = ULLONG,
+		S('x') = ULLONG, S('X') = ULLONG,
+		S('n') = PTR,
+	}, { /* 3: h-prefixed */
+		S('d') = SHORT, S('i') = SHORT,
+		S('o') = USHORT, S('u') = USHORT,
+		S('x') = USHORT, S('X') = USHORT,
+		S('n') = PTR,
+		S('h') = HHPRE,
+	}, { /* 4: hh-prefixed */
+		S('d') = CHAR, S('i') = CHAR,
+		S('o') = UCHAR, S('u') = UCHAR,
+		S('x') = UCHAR, S('X') = UCHAR,
+		S('n') = PTR,
+	}, { /* 5: L-prefixed */
+		S('e') = LDBL, S('f') = LDBL, S('g') = LDBL, S('a') = LDBL,
+		S('E') = LDBL, S('F') = LDBL, S('G') = LDBL, S('A') = LDBL,
+		S('n') = PTR,
+	}, { /* 6: z- or t-prefixed (assumed to be same size) */
+		S('d') = PDIFF, S('i') = PDIFF,
+		S('o') = SIZET, S('u') = SIZET,
+		S('x') = SIZET, S('X') = SIZET,
+		S('n') = PTR,
+	}, { /* 7: j-prefixed */
+		S('d') = IMAX, S('i') = IMAX,
+		S('o') = UMAX, S('u') = UMAX,
+		S('x') = UMAX, S('X') = UMAX,
+		S('n') = PTR,
+	}
+};
+
+#define OOB(x) ((unsigned)(x)-'A' > 'z'-'A')
+
+union arg
+{
+	uintmax_t i;
+	long double f;
+	void *p;
+};
+
+static void pop_arg(union arg *arg, int type, va_list *ap)
+{
+	switch (type) {
+	       case PTR:	arg->p = va_arg(*ap, void *);
+	break; case INT:	arg->i = va_arg(*ap, int);
+	break; case UINT:	arg->i = va_arg(*ap, unsigned int);
+	break; case LONG:	arg->i = va_arg(*ap, long);
+	break; case ULONG:	arg->i = va_arg(*ap, unsigned long);
+	break; case ULLONG:	arg->i = va_arg(*ap, unsigned long long);
+	break; case SHORT:	arg->i = (short)va_arg(*ap, int);
+	break; case USHORT:	arg->i = (unsigned short)va_arg(*ap, int);
+	break; case CHAR:	arg->i = (signed char)va_arg(*ap, int);
+	break; case UCHAR:	arg->i = (unsigned char)va_arg(*ap, int);
+	break; case LLONG:	arg->i = va_arg(*ap, long long);
+	break; case SIZET:	arg->i = va_arg(*ap, size_t);
+	break; case IMAX:	arg->i = va_arg(*ap, intmax_t);
+	break; case UMAX:	arg->i = va_arg(*ap, uintmax_t);
+	break; case PDIFF:	arg->i = va_arg(*ap, ptrdiff_t);
+	break; case UIPTR:	arg->i = (uintptr_t)va_arg(*ap, void *);
+	break; case DBL:	arg->f = va_arg(*ap, double);
+	break; case LDBL:	arg->f = va_arg(*ap, long double);
+	}
+}
+
+static void out(FILE *f, const wchar_t *s, size_t l)
+{
+	while (l-- && !(f->flags & F_ERR)) fputwc(*s++, f);
+}
+
+static int getint(wchar_t **s) {
+	int i;
+	for (i=0; iswdigit(**s); (*s)++) {
+		if (i > INT_MAX/10U || **s-'0' > INT_MAX-10*i) i = -1;
+		else i = 10*i + (**s-'0');
+	}
+	return i;
+}
+
+static const char sizeprefix['y'-'a'] = {
+['a'-'a']='L', ['e'-'a']='L', ['f'-'a']='L', ['g'-'a']='L',
+['d'-'a']='j', ['i'-'a']='j', ['o'-'a']='j', ['u'-'a']='j', ['x'-'a']='j',
+['p'-'a']='j'
+};
+
+static int wprintf_core(FILE *f, const wchar_t *fmt, va_list *ap, union arg *nl_arg, int *nl_type)
+{
+	wchar_t *a, *z, *s=(wchar_t *)fmt;
+	unsigned l10n=0, fl;
+	int w, p, xp;
+	union arg arg;
+	int argpos;
+	unsigned st, ps;
+	int cnt=0, l=0;
+	int i;
+	int t;
+	char *bs;
+	char charfmt[16];
+	wchar_t wc;
+
+	for (;;) {
+		/* This error is only specified for snprintf, but since it's
+		 * unspecified for other forms, do the same. Stop immediately
+		 * on overflow; otherwise %n could produce wrong results. */
+		if (l > INT_MAX - cnt) goto overflow;
+
+		/* Update output count, end loop when fmt is exhausted */
+		cnt += l;
+		if (!*s) break;
+
+		/* Handle literal text and %% format specifiers */
+		for (a=s; *s && *s!='%'; s++);
+		for (z=s; s[0]=='%' && s[1]=='%'; z++, s+=2);
+		if (z-a > INT_MAX-cnt) goto overflow;
+		l = z-a;
+		if (f) out(f, a, l);
+		if (l) continue;
+
+		if (iswdigit(s[1]) && s[2]=='$') {
+			l10n=1;
+			argpos = s[1]-'0';
+			s+=3;
+		} else {
+			argpos = -1;
+			s++;
+		}
+
+		/* Read modifier flags */
+		for (fl=0; (unsigned)*s-' '<32 && (FLAGMASK&(1U<<*s-' ')); s++)
+			fl |= 1U<<*s-' ';
+
+		/* Read field width */
+		if (*s=='*') {
+			if (iswdigit(s[1]) && s[2]=='$') {
+				l10n=1;
+				nl_type[s[1]-'0'] = INT;
+				w = nl_arg[s[1]-'0'].i;
+				s+=3;
+			} else if (!l10n) {
+				w = f ? va_arg(*ap, int) : 0;
+				s++;
+			} else goto inval;
+			if (w<0) fl|=LEFT_ADJ, w=-w;
+		} else if ((w=getint(&s))<0) goto overflow;
+
+		/* Read precision */
+		if (*s=='.' && s[1]=='*') {
+			if (isdigit(s[2]) && s[3]=='$') {
+				nl_type[s[2]-'0'] = INT;
+				p = nl_arg[s[2]-'0'].i;
+				s+=4;
+			} else if (!l10n) {
+				p = f ? va_arg(*ap, int) : 0;
+				s+=2;
+			} else goto inval;
+			xp = (p>=0);
+		} else if (*s=='.') {
+			s++;
+			p = getint(&s);
+			xp = 1;
+		} else {
+			p = -1;
+			xp = 0;
+		}
+
+		/* Format specifier state machine */
+		st=0;
+		do {
+			if (OOB(*s)) goto inval;
+			ps=st;
+			st=states[st]S(*s++);
+		} while (st-1<STOP);
+		if (!st) goto inval;
+
+		/* Check validity of argument type (nl/normal) */
+		if (st==NOARG) {
+			if (argpos>=0) goto inval;
+		} else {
+			if (argpos>=0) nl_type[argpos]=st, arg=nl_arg[argpos];
+			else if (f) pop_arg(&arg, st, ap);
+			else return 0;
+		}
+
+		if (!f) continue;
+		t = s[-1];
+		if (ps && (t&15)==3) t&=~32;
+
+		switch (t) {
+		case 'n':
+			switch(ps) {
+			case BARE: *(int *)arg.p = cnt; break;
+			case LPRE: *(long *)arg.p = cnt; break;
+			case LLPRE: *(long long *)arg.p = cnt; break;
+			case HPRE: *(unsigned short *)arg.p = cnt; break;
+			case HHPRE: *(unsigned char *)arg.p = cnt; break;
+			case ZTPRE: *(size_t *)arg.p = cnt; break;
+			case JPRE: *(uintmax_t *)arg.p = cnt; break;
+			}
+			continue;
+		case 'c':
+			if (w<1) w=1;
+			if (w>1 && !(fl&LEFT_ADJ)) fprintf(f, "%*s", w-1, "");
+			fputwc(btowc(arg.i), f);
+			if (w>1 && (fl&LEFT_ADJ)) fprintf(f, "%*s", w-1, "");
+			l = w;
+			continue;
+		case 'C':
+			fputwc(arg.i, f);
+			l = 1;
+			continue;
+		case 'S':
+			a = arg.p;
+			z = a + wcsnlen(a, p<0 ? INT_MAX : p);
+			if (p<0 && *z) goto overflow;
+			p = z-a;
+			if (w<p) w=p;
+			if (!(fl&LEFT_ADJ)) fprintf(f, "%*s", w-p, "");
+			out(f, a, p);
+			if ((fl&LEFT_ADJ)) fprintf(f, "%*s", w-p, "");
+			l=w;
+			continue;
+		case 'm':
+			arg.p = strerror(errno);
+		case 's':
+			if (!arg.p) arg.p = "(null)";
+			bs = arg.p;
+			for (i=l=0; l<(p<0?INT_MAX:p) && (i=mbtowc(&wc, bs, MB_LEN_MAX))>0; bs+=i, l++);
+			if (i<0) return -1;
+			if (p<0 && *bs) goto overflow;
+			p=l;
+			if (w<p) w=p;
+			if (!(fl&LEFT_ADJ)) fprintf(f, "%*s", w-p, "");
+			bs = arg.p;
+			while (l--) {
+				i=mbtowc(&wc, bs, MB_LEN_MAX);
+				bs+=i;
+				fputwc(wc, f);
+			}
+			if ((fl&LEFT_ADJ)) fprintf(f, "%*s", w-p, "");
+			l=w;
+			continue;
+		}
+
+		if (xp && p<0) goto overflow;
+		snprintf(charfmt, sizeof charfmt, "%%%s%s%s%s%s*.*%c%c",
+			"#"+!(fl & ALT_FORM),
+			"+"+!(fl & MARK_POS),
+			"-"+!(fl & LEFT_ADJ),
+			" "+!(fl & PAD_POS),
+			"0"+!(fl & ZERO_PAD),
+			sizeprefix[(t|32)-'a'], t);
+
+		switch (t|32) {
+		case 'a': case 'e': case 'f': case 'g':
+			l = fprintf(f, charfmt, w, p, arg.f);
+			break;
+		case 'd': case 'i': case 'o': case 'u': case 'x': case 'p':
+			l = fprintf(f, charfmt, w, p, arg.i);
+			break;
+		}
+	}
+
+	if (f) return cnt;
+	if (!l10n) return 0;
+
+	for (i=1; i<=NL_ARGMAX && nl_type[i]; i++)
+		pop_arg(nl_arg+i, nl_type[i], ap);
+	for (; i<=NL_ARGMAX && !nl_type[i]; i++);
+	if (i<=NL_ARGMAX) return -1;
+	return 1;
+
+inval:
+	errno = EINVAL;
+	return -1;
+overflow:
+	errno = EOVERFLOW;
+	return -1;
+}
+
+int vfwprintf(FILE *restrict f, const wchar_t *restrict fmt, va_list ap)
+{
+	va_list ap2;
+	int nl_type[NL_ARGMAX] = {0};
+	union arg nl_arg[NL_ARGMAX];
+	int olderr;
+	int ret;
+
+	/* the copy allows passing va_list* even if va_list is an array */
+	va_copy(ap2, ap);
+	if (wprintf_core(0, fmt, &ap2, nl_arg, nl_type) < 0) {
+		va_end(ap2);
+		return -1;
+	}
+
+	FLOCK(f);
+	fwide(f, 1);
+	olderr = f->flags & F_ERR;
+	f->flags &= ~F_ERR;
+	ret = wprintf_core(f, fmt, &ap2, nl_arg, nl_type);
+	if (f->flags & F_ERR) ret = -1;
+	f->flags |= olderr;
+	FUNLOCK(f);
+	va_end(ap2);
+	return ret;
+}
libc/musl/src/stdio/vfwscanf.c
@@ -0,0 +1,332 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdarg.h>
+#include <ctype.h>
+#include <wchar.h>
+#include <wctype.h>
+#include <limits.h>
+#include <string.h>
+
+#include "stdio_impl.h"
+#include "shgetc.h"
+#include "intscan.h"
+#include "floatscan.h"
+
+#define SIZE_hh -2
+#define SIZE_h  -1
+#define SIZE_def 0
+#define SIZE_l   1
+#define SIZE_L   2
+#define SIZE_ll  3
+
+static void store_int(void *dest, int size, unsigned long long i)
+{
+	if (!dest) return;
+	switch (size) {
+	case SIZE_hh:
+		*(char *)dest = i;
+		break;
+	case SIZE_h:
+		*(short *)dest = i;
+		break;
+	case SIZE_def:
+		*(int *)dest = i;
+		break;
+	case SIZE_l:
+		*(long *)dest = i;
+		break;
+	case SIZE_ll:
+		*(long long *)dest = i;
+		break;
+	}
+}
+
+static void *arg_n(va_list ap, unsigned int n)
+{
+	void *p;
+	unsigned int i;
+	va_list ap2;
+	va_copy(ap2, ap);
+	for (i=n; i>1; i--) va_arg(ap2, void *);
+	p = va_arg(ap2, void *);
+	va_end(ap2);
+	return p;
+}
+
+static int in_set(const wchar_t *set, int c)
+{
+	int j;
+	const wchar_t *p = set;
+	if (*p == '-') {
+		if (c=='-') return 1;
+		p++;
+	} else if (*p == ']') {
+		if (c==']') return 1;
+		p++;
+	}
+	for (; *p && *p != ']'; p++) {
+		if (*p=='-' && p[1] && p[1] != ']')
+			for (j=p++[-1]; j<*p; j++)
+				if (c==j) return 1;
+		if (c==*p) return 1;
+	}
+	return 0;
+}
+
+#if 1
+#undef getwc
+#define getwc(f) \
+	((f)->rpos != (f)->rend && *(f)->rpos < 128 ? *(f)->rpos++ : (getwc)(f))
+
+#undef ungetwc
+#define ungetwc(c,f) \
+	((f)->rend && (c)<128U ? *--(f)->rpos : ungetwc((c),(f)))
+#endif
+
+int vfwscanf(FILE *restrict f, const wchar_t *restrict fmt, va_list ap)
+{
+	int width;
+	int size;
+	int alloc;
+	const wchar_t *p;
+	int c, t;
+	char *s;
+	wchar_t *wcs;
+	void *dest=NULL;
+	int invert;
+	int matches=0;
+	off_t pos = 0, cnt;
+	static const char size_pfx[][3] = { "hh", "h", "", "l", "L", "ll" };
+	char tmp[3*sizeof(int)+10];
+	const wchar_t *set;
+	size_t i, k;
+
+	FLOCK(f);
+
+	fwide(f, 1);
+
+	for (p=fmt; *p; p++) {
+
+		alloc = 0;
+
+		if (iswspace(*p)) {
+			while (iswspace(p[1])) p++;
+			while (iswspace((c=getwc(f)))) pos++;
+			ungetwc(c, f);
+			continue;
+		}
+		if (*p != '%' || p[1] == '%') {
+			if (*p == '%') {
+				p++;
+				while (iswspace((c=getwc(f)))) pos++;
+			} else {
+				c = getwc(f);
+			}
+			if (c!=*p) {
+				ungetwc(c, f);
+				if (c<0) goto input_fail;
+				goto match_fail;
+			}
+			pos++;
+			continue;
+		}
+
+		p++;
+		if (*p=='*') {
+			dest = 0; p++;
+		} else if (iswdigit(*p) && p[1]=='$') {
+			dest = arg_n(ap, *p-'0'); p+=2;
+		} else {
+			dest = va_arg(ap, void *);
+		}
+
+		for (width=0; iswdigit(*p); p++) {
+			width = 10*width + *p - '0';
+		}
+
+		if (*p=='m') {
+			wcs = 0;
+			s = 0;
+			alloc = !!dest;
+			p++;
+		} else {
+			alloc = 0;
+		}
+
+		size = SIZE_def;
+		switch (*p++) {
+		case 'h':
+			if (*p == 'h') p++, size = SIZE_hh;
+			else size = SIZE_h;
+			break;
+		case 'l':
+			if (*p == 'l') p++, size = SIZE_ll;
+			else size = SIZE_l;
+			break;
+		case 'j':
+			size = SIZE_ll;
+			break;
+		case 'z':
+		case 't':
+			size = SIZE_l;
+			break;
+		case 'L':
+			size = SIZE_L;
+			break;
+		case 'd': case 'i': case 'o': case 'u': case 'x':
+		case 'a': case 'e': case 'f': case 'g':
+		case 'A': case 'E': case 'F': case 'G': case 'X':
+		case 's': case 'c': case '[':
+		case 'S': case 'C':
+		case 'p': case 'n':
+			p--;
+			break;
+		default:
+			goto fmt_fail;
+		}
+
+		t = *p;
+
+		/* Transform S,C -> ls,lc */
+		if ((t&0x2f)==3) {
+			size = SIZE_l;
+			t |= 32;
+		}
+
+		if (t != 'n') {
+			if (t != '[' && (t|32) != 'c')
+				while (iswspace((c=getwc(f)))) pos++;
+			else
+				c=getwc(f);
+			if (c < 0) goto input_fail;
+			ungetwc(c, f);
+		}
+
+		switch (t) {
+		case 'n':
+			store_int(dest, size, pos);
+			/* do not increment match count, etc! */
+			continue;
+
+		case 's':
+		case 'c':
+		case '[':
+			if (t == 'c') {
+				if (width<1) width = 1;
+				invert = 1;
+				set = L"";
+			} else if (t == 's') {
+				invert = 1;
+				static const wchar_t spaces[] = {
+					' ', '\t', '\n', '\r', 11, 12,  0x0085,
+					0x2000, 0x2001, 0x2002, 0x2003, 0x2004, 0x2005,
+					0x2006, 0x2008, 0x2009, 0x200a,
+					0x2028, 0x2029, 0x205f, 0x3000, 0 };
+				set = spaces;
+			} else {
+				if (*++p == '^') p++, invert = 1;
+				else invert = 0;
+				set = p;
+				if (*p==']') p++;
+				while (*p!=']') {
+					if (!*p) goto fmt_fail;
+					p++;
+				}
+			}
+
+			s = (size == SIZE_def) ? dest : 0;
+			wcs = (size == SIZE_l) ? dest : 0;
+
+			int gotmatch = 0;
+
+			if (width < 1) width = -1;
+
+			i = 0;
+			if (alloc) {
+				k = t=='c' ? width+1U : 31;
+				if (size == SIZE_l) {
+					wcs = malloc(k*sizeof(wchar_t));
+					if (!wcs) goto alloc_fail;
+				} else {
+					s = malloc(k);
+					if (!s) goto alloc_fail;
+				}
+			}
+			while (width) {
+				if ((c=getwc(f))<0) break;
+				if (in_set(set, c) == invert)
+					break;
+				if (wcs) {
+					wcs[i++] = c;
+					if (alloc && i==k) {
+						k += k+1;
+						wchar_t *tmp = realloc(wcs, k*sizeof(wchar_t));
+						if (!tmp) goto alloc_fail;
+						wcs = tmp;
+					}
+				} else if (size != SIZE_l) {
+					int l = wctomb(s?s+i:tmp, c);
+					if (l<0) goto input_fail;
+					i += l;
+					if (alloc && i > k-4) {
+						k += k+1;
+						char *tmp = realloc(s, k);
+						if (!tmp) goto alloc_fail;
+						s = tmp;
+					}
+				}
+				pos++;
+				width-=(width>0);
+				gotmatch=1;
+			}
+			if (width) {
+				ungetwc(c, f);
+				if (t == 'c' || !gotmatch) goto match_fail;
+			}
+
+			if (alloc) {
+				if (size == SIZE_l) *(wchar_t **)dest = wcs;
+				else *(char **)dest = s;
+			}
+			if (t != 'c') {
+				if (wcs) wcs[i] = 0;
+				if (s) s[i] = 0;
+			}
+			break;
+
+		case 'd': case 'i': case 'o': case 'u': case 'x':
+		case 'a': case 'e': case 'f': case 'g':
+		case 'A': case 'E': case 'F': case 'G': case 'X':
+		case 'p':
+			if (width < 1) width = 0;
+			snprintf(tmp, sizeof tmp, "%.*s%.0d%s%c%%lln",
+				1+!dest, "%*", width, size_pfx[size+2], t);
+			cnt = 0;
+			if (fscanf(f, tmp, dest?dest:&cnt, &cnt) == -1)
+				goto input_fail;
+			else if (!cnt)
+				goto match_fail;
+			pos += cnt;
+			break;
+		default:
+			goto fmt_fail;
+		}
+
+		if (dest) matches++;
+	}
+	if (0) {
+fmt_fail:
+alloc_fail:
+input_fail:
+		if (!matches) matches--;
+match_fail:
+		if (alloc) {
+			free(s);
+			free(wcs);
+		}
+	}
+	FUNLOCK(f);
+	return matches;
+}
+
+weak_alias(vfwscanf,__isoc99_vfwscanf);
libc/musl/src/stdio/vprintf.c
@@ -0,0 +1,6 @@
+#include <stdio.h>
+
+int vprintf(const char *restrict fmt, va_list ap)
+{
+	return vfprintf(stdout, fmt, ap);
+}
libc/musl/src/stdio/vscanf.c
@@ -0,0 +1,9 @@
+#include <stdio.h>
+#include <stdarg.h>
+
+int vscanf(const char *restrict fmt, va_list ap)
+{
+	return vfscanf(stdin, fmt, ap);
+}
+
+weak_alias(vscanf,__isoc99_vscanf);
libc/musl/src/stdio/vsnprintf.c
@@ -0,0 +1,55 @@
+#include "stdio_impl.h"
+#include <limits.h>
+#include <string.h>
+#include <errno.h>
+#include <stdint.h>
+
+struct cookie {
+	char *s;
+	size_t n;
+};
+
+#define MIN(a, b) ((a) < (b) ? (a) : (b))
+
+static size_t sn_write(FILE *f, const unsigned char *s, size_t l)
+{
+	struct cookie *c = f->cookie;
+	size_t k = MIN(c->n, f->wpos - f->wbase);
+	if (k) {
+		memcpy(c->s, f->wbase, k);
+		c->s += k;
+		c->n -= k;
+	}
+	k = MIN(c->n, l);
+	if (k) {
+		memcpy(c->s, s, k);
+		c->s += k;
+		c->n -= k;
+	}
+	*c->s = 0;
+	f->wpos = f->wbase = f->buf;
+	/* pretend to succeed, even if we discarded extra data */
+	return l;
+}
+
+int vsnprintf(char *restrict s, size_t n, const char *restrict fmt, va_list ap)
+{
+	unsigned char buf[1];
+	char dummy[1];
+	struct cookie c = { .s = n ? s : dummy, .n = n ? n-1 : 0 };
+	FILE f = {
+		.lbf = EOF,
+		.write = sn_write,
+		.lock = -1,
+		.buf = buf,
+		.cookie = &c,
+	};
+
+	if (n > INT_MAX) {
+		errno = EOVERFLOW;
+		return -1;
+	}
+
+	*c.s = 0;
+	return vfprintf(&f, fmt, ap);
+}
libc/musl/src/stdio/vsprintf.c
@@ -0,0 +1,7 @@
+#include <stdio.h>
+#include <limits.h>
+
+int vsprintf(char *restrict s, const char *restrict fmt, va_list ap)
+{
+	return vsnprintf(s, INT_MAX, fmt, ap);
+}
libc/musl/src/stdio/vsscanf.c
@@ -0,0 +1,17 @@
+#include "stdio_impl.h"
+
+static size_t do_read(FILE *f, unsigned char *buf, size_t len)
+{
+	return __string_read(f, buf, len);
+}
+
+int vsscanf(const char *restrict s, const char *restrict fmt, va_list ap)
+{
+	FILE f = {
+		.buf = (void *)s, .cookie = (void *)s,
+		.read = do_read, .lock = -1
+	};
+	return vfscanf(&f, fmt, ap);
+}
+
+weak_alias(vsscanf,__isoc99_vsscanf);
libc/musl/src/stdio/vswprintf.c
@@ -0,0 +1,60 @@
+#include "stdio_impl.h"
+#include <limits.h>
+#include <errno.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <wchar.h>
+
+struct cookie {
+	wchar_t *ws;
+	size_t l;
+};
+
+static size_t sw_write(FILE *f, const unsigned char *s, size_t l)
+{
+	size_t l0 = l;
+	int i = 0;
+	struct cookie *c = f->cookie;
+	if (s!=f->wbase && sw_write(f, f->wbase, f->wpos-f->wbase)==-1)
+		return -1;
+	while (c->l && l && (i=mbtowc(c->ws, (void *)s, l))>=0) {
+		s+=i;
+		l-=i;
+		c->l--;
+		c->ws++;
+	}
+	*c->ws = 0;
+	if (i < 0) {
+		f->wpos = f->wbase = f->wend = 0;
+		f->flags |= F_ERR;
+		return i;
+	}
+	f->wend = f->buf + f->buf_size;
+	f->wpos = f->wbase = f->buf;
+	return l0;
+}
+
+int vswprintf(wchar_t *restrict s, size_t n, const wchar_t *restrict fmt, va_list ap)
+{
+	int r;
+	unsigned char buf[256];
+	struct cookie c = { s, n-1 };
+	FILE f = {
+		.lbf = EOF,
+		.write = sw_write,
+		.lock = -1,
+		.buf = buf,
+		.buf_size = sizeof buf,
+		.cookie = &c,
+	};
+
+	if (!n) {
+		return -1;
+	} else if (n > INT_MAX) {
+		errno = EOVERFLOW;
+		return -1;
+	}
+	r = vfwprintf(&f, fmt, ap);
+	sw_write(&f, 0, 0);
+	return r>=n ? -1 : r;
+}
libc/musl/src/stdio/vswscanf.c
@@ -0,0 +1,38 @@
+#include "stdio_impl.h"
+#include <wchar.h>
+
+static size_t wstring_read(FILE *f, unsigned char *buf, size_t len)
+{
+	const wchar_t *src = f->cookie;
+	size_t k;
+
+	if (!src) return 0;
+
+	k = wcsrtombs((void *)f->buf, &src, f->buf_size, 0);
+	if (k==(size_t)-1) {
+		f->rpos = f->rend = 0;
+		return 0;
+	}
+
+	f->rpos = f->buf;
+	f->rend = f->buf + k;
+	f->cookie = (void *)src;
+
+	if (!len || !k) return 0;
+
+	*buf = *f->rpos++;
+	return 1;
+}
+
+int vswscanf(const wchar_t *restrict s, const wchar_t *restrict fmt, va_list ap)
+{
+	unsigned char buf[256];
+	FILE f = {
+		.buf = buf, .buf_size = sizeof buf,
+		.cookie = (void *)s,
+		.read = wstring_read, .lock = -1
+	};
+	return vfwscanf(&f, fmt, ap);
+}
+
+weak_alias(vswscanf,__isoc99_vswscanf);
libc/musl/src/stdio/vwprintf.c
@@ -0,0 +1,7 @@
+#include <stdio.h>
+#include <wchar.h>
+
+int vwprintf(const wchar_t *restrict fmt, va_list ap)
+{
+	return vfwprintf(stdout, fmt, ap);
+}
libc/musl/src/stdio/vwscanf.c
@@ -0,0 +1,10 @@
+#include <stdio.h>
+#include <stdarg.h>
+#include <wchar.h>
+
+int vwscanf(const wchar_t *restrict fmt, va_list ap)
+{
+	return vfwscanf(stdin, fmt, ap);
+}
+
+weak_alias(vwscanf,__isoc99_vwscanf);
libc/musl/src/stdio/wprintf.c
@@ -0,0 +1,13 @@
+#include <stdio.h>
+#include <stdarg.h>
+#include <wchar.h>
+
+int wprintf(const wchar_t *restrict fmt, ...)
+{
+	int ret;
+	va_list ap;
+	va_start(ap, fmt);
+	ret = vwprintf(fmt, ap);
+	va_end(ap);
+	return ret;
+}
libc/musl/src/stdio/wscanf.c
@@ -0,0 +1,15 @@
+#include <stdio.h>
+#include <stdarg.h>
+#include <wchar.h>
+
+int wscanf(const wchar_t *restrict fmt, ...)
+{
+	int ret;
+	va_list ap;
+	va_start(ap, fmt);
+	ret = vwscanf(fmt, ap);
+	va_end(ap);
+	return ret;
+}
+
+weak_alias(wscanf,__isoc99_wscanf);
libc/musl/src/stdlib/abs.c
@@ -0,0 +1,6 @@
+#include <stdlib.h>
+
+int abs(int a)
+{
+	return a>0 ? a : -a;
+}
libc/musl/src/stdlib/atof.c
@@ -0,0 +1,6 @@
+#include <stdlib.h>
+
+double atof(const char *s)
+{
+	return strtod(s, 0);
+}
libc/musl/src/stdlib/atoi.c
@@ -0,0 +1,16 @@
+#include <stdlib.h>
+#include <ctype.h>
+
+int atoi(const char *s)
+{
+	int n=0, neg=0;
+	while (isspace(*s)) s++;
+	switch (*s) {
+	case '-': neg=1;
+	case '+': s++;
+	}
+	/* Compute n as a negative number to avoid overflow on INT_MIN */
+	while (isdigit(*s))
+		n = 10*n - (*s++ - '0');
+	return neg ? n : -n;
+}
libc/musl/src/stdlib/atol.c
@@ -0,0 +1,17 @@
+#include <stdlib.h>
+#include <ctype.h>
+
+long atol(const char *s)
+{
+	long n=0;
+	int neg=0;
+	while (isspace(*s)) s++;
+	switch (*s) {
+	case '-': neg=1;
+	case '+': s++;
+	}
+	/* Compute n as a negative number to avoid overflow on LONG_MIN */
+	while (isdigit(*s))
+		n = 10*n - (*s++ - '0');
+	return neg ? n : -n;
+}
libc/musl/src/stdlib/atoll.c
@@ -0,0 +1,17 @@
+#include <stdlib.h>
+#include <ctype.h>
+
+long long atoll(const char *s)
+{
+	long long n=0;
+	int neg=0;
+	while (isspace(*s)) s++;
+	switch (*s) {
+	case '-': neg=1;
+	case '+': s++;
+	}
+	/* Compute n as a negative number to avoid overflow on LLONG_MIN */
+	while (isdigit(*s))
+		n = 10*n - (*s++ - '0');
+	return neg ? n : -n;
+}
libc/musl/src/stdlib/bsearch.c
@@ -0,0 +1,20 @@
+#include <stdlib.h>
+
+void *bsearch(const void *key, const void *base, size_t nel, size_t width, int (*cmp)(const void *, const void *))
+{
+	void *try;
+	int sign;
+	while (nel > 0) {
+		try = (char *)base + width*(nel/2);
+		sign = cmp(key, try);
+		if (sign < 0) {
+			nel /= 2;
+		} else if (sign > 0) {
+			base = (char *)try + width;
+			nel -= nel/2+1;
+		} else {
+			return try;
+		}
+	}
+	return NULL;
+}
libc/musl/src/stdlib/div.c
@@ -0,0 +1,6 @@
+#include <stdlib.h>
+
+div_t div(int num, int den)
+{
+	return (div_t){ num/den, num%den };
+}
libc/musl/src/stdlib/ecvt.c
@@ -0,0 +1,20 @@
+#define _GNU_SOURCE
+#include <stdlib.h>
+#include <stdio.h>
+
+char *ecvt(double x, int n, int *dp, int *sign)
+{
+	static char buf[16];
+	char tmp[32];
+	int i, j;
+
+	if (n-1U > 15) n = 15;
+	sprintf(tmp, "%.*e", n-1, x);
+	i = *sign = (tmp[0]=='-');
+	for (j=0; tmp[i]!='e'; j+=(tmp[i++]!='.'))
+		buf[j] = tmp[i];
+	buf[j] = 0;
+	*dp = atoi(tmp+i+1)+1;
+
+	return buf;
+}
libc/musl/src/stdlib/fcvt.c
@@ -0,0 +1,25 @@
+#define _GNU_SOURCE
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+char *fcvt(double x, int n, int *dp, int *sign)
+{
+	char tmp[1500];
+	int i, lz;
+
+	if (n > 1400U) n = 1400;
+	sprintf(tmp, "%.*f", n, x);
+	i = (tmp[0] == '-');
+	if (tmp[i] == '0') lz = strspn(tmp+i+2, "0");
+	else lz = -(int)strcspn(tmp+i, ".");
+
+	if (n<=lz) {
+		*sign = i;
+		*dp = 1;
+		if (n>14U) n = 14;
+		return "000000000000000"+14-n;
+	}
+
+	return ecvt(x, n-lz, dp, sign);
+}
libc/musl/src/stdlib/gcvt.c
@@ -0,0 +1,9 @@
+#define _GNU_SOURCE
+#include <stdlib.h>
+#include <stdio.h>
+
+char *gcvt(double x, int n, char *b)
+{
+	sprintf(b, "%.*g", n, x);
+	return b;
+}
libc/musl/src/stdlib/imaxabs.c
@@ -0,0 +1,6 @@
+#include <inttypes.h>
+
+intmax_t imaxabs(intmax_t a)
+{
+	return a>0 ? a : -a;
+}
libc/musl/src/stdlib/imaxdiv.c
@@ -0,0 +1,6 @@
+#include <inttypes.h>
+
+imaxdiv_t imaxdiv(intmax_t num, intmax_t den)
+{
+	return (imaxdiv_t){ num/den, num%den };
+}
libc/musl/src/stdlib/labs.c
@@ -0,0 +1,6 @@
+#include <stdlib.h>
+
+long labs(long a)
+{
+	return a>0 ? a : -a;
+}
libc/musl/src/stdlib/ldiv.c
@@ -0,0 +1,6 @@
+#include <stdlib.h>
+
+ldiv_t ldiv(long num, long den)
+{
+	return (ldiv_t){ num/den, num%den };
+}
libc/musl/src/stdlib/llabs.c
@@ -0,0 +1,6 @@
+#include <stdlib.h>
+
+long long llabs(long long a)
+{
+	return a>0 ? a : -a;
+}
libc/musl/src/stdlib/lldiv.c
@@ -0,0 +1,6 @@
+#include <stdlib.h>
+
+lldiv_t lldiv(long long num, long long den)
+{
+	return (lldiv_t){ num/den, num%den };
+}
libc/musl/src/stdlib/qsort.c
@@ -0,0 +1,218 @@
+/* Copyright (C) 2011 by Valentin Ochs
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ */
+
+/* Minor changes by Rich Felker for integration in musl, 2011-04-27. */
+
+/* Smoothsort, an adaptive variant of Heapsort.  Memory usage: O(1).
+   Run time: Worst case O(n log n), close to O(n) in the mostly-sorted case. */
+
+#include <stdint.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "atomic.h"
+#define ntz(x) a_ctz_l((x))
+
+typedef int (*cmpfun)(const void *, const void *);
+
+static inline int pntz(size_t p[2]) {
+	int r = ntz(p[0] - 1);
+	if(r != 0 || (r = 8*sizeof(size_t) + ntz(p[1])) != 8*sizeof(size_t)) {
+		return r;
+	}
+	return 0;
+}
+
+static void cycle(size_t width, unsigned char* ar[], int n)
+{
+	unsigned char tmp[256];
+	size_t l;
+	int i;
+
+	if(n < 2) {
+		return;
+	}
+
+	ar[n] = tmp;
+	while(width) {
+		l = sizeof(tmp) < width ? sizeof(tmp) : width;
+		memcpy(ar[n], ar[0], l);
+		for(i = 0; i < n; i++) {
+			memcpy(ar[i], ar[i + 1], l);
+			ar[i] += l;
+		}
+		width -= l;
+	}
+}
+
+/* shl() and shr() need n > 0 */
+static inline void shl(size_t p[2], int n)
+{
+	if(n >= 8 * sizeof(size_t)) {
+		n -= 8 * sizeof(size_t);
+		p[1] = p[0];
+		p[0] = 0;
+	}
+	p[1] <<= n;
+	p[1] |= p[0] >> (sizeof(size_t) * 8 - n);
+	p[0] <<= n;
+}
+
+static inline void shr(size_t p[2], int n)
+{
+	if(n >= 8 * sizeof(size_t)) {
+		n -= 8 * sizeof(size_t);
+		p[0] = p[1];
+		p[1] = 0;
+	}
+	p[0] >>= n;
+	p[0] |= p[1] << (sizeof(size_t) * 8 - n);
+	p[1] >>= n;
+}
+
+static void sift(unsigned char *head, size_t width, cmpfun cmp, int pshift, size_t lp[])
+{
+	unsigned char *rt, *lf;
+	unsigned char *ar[14 * sizeof(size_t) + 1];
+	int i = 1;
+
+	ar[0] = head;
+	while(pshift > 1) {
+		rt = head - width;
+		lf = head - width - lp[pshift - 2];
+
+		if((*cmp)(ar[0], lf) >= 0 && (*cmp)(ar[0], rt) >= 0) {
+			break;
+		}
+		if((*cmp)(lf, rt) >= 0) {
+			ar[i++] = lf;
+			head = lf;
+			pshift -= 1;
+		} else {
+			ar[i++] = rt;
+			head = rt;
+			pshift -= 2;
+		}
+	}
+	cycle(width, ar, i);
+}
+
+static void trinkle(unsigned char *head, size_t width, cmpfun cmp, size_t pp[2], int pshift, int trusty, size_t lp[])
+{
+	unsigned char *stepson,
+	              *rt, *lf;
+	size_t p[2];
+	unsigned char *ar[14 * sizeof(size_t) + 1];
+	int i = 1;
+	int trail;
+
+	p[0] = pp[0];
+	p[1] = pp[1];
+
+	ar[0] = head;
+	while(p[0] != 1 || p[1] != 0) {
+		stepson = head - lp[pshift];
+		if((*cmp)(stepson, ar[0]) <= 0) {
+			break;
+		}
+		if(!trusty && pshift > 1) {
+			rt = head - width;
+			lf = head - width - lp[pshift - 2];
+			if((*cmp)(rt, stepson) >= 0 || (*cmp)(lf, stepson) >= 0) {
+				break;
+			}
+		}
+
+		ar[i++] = stepson;
+		head = stepson;
+		trail = pntz(p);
+		shr(p, trail);
+		pshift += trail;
+		trusty = 0;
+	}
+	if(!trusty) {
+		cycle(width, ar, i);
+		sift(head, width, cmp, pshift, lp);
+	}
+}
+
+void qsort(void *base, size_t nel, size_t width, cmpfun cmp)
+{
+	size_t lp[12*sizeof(size_t)];
+	size_t i, size = width * nel;
+	unsigned char *head, *high;
+	size_t p[2] = {1, 0};
+	int pshift = 1;
+	int trail;
+
+	if (!size) return;
+
+	head = base;
+	high = head + size - width;
+
+	/* Precompute Leonardo numbers, scaled by element width */
+	for(lp[0]=lp[1]=width, i=2; (lp[i]=lp[i-2]+lp[i-1]+width) < size; i++);
+
+	while(head < high) {
+		if((p[0] & 3) == 3) {
+			sift(head, width, cmp, pshift, lp);
+			shr(p, 2);
+			pshift += 2;
+		} else {
+			if(lp[pshift - 1] >= high - head) {
+				trinkle(head, width, cmp, p, pshift, 0, lp);
+			} else {
+				sift(head, width, cmp, pshift, lp);
+			}
+			
+			if(pshift == 1) {
+				shl(p, 1);
+				pshift = 0;
+			} else {
+				shl(p, pshift - 1);
+				pshift = 1;
+			}
+		}
+		
+		p[0] |= 1;
+		head += width;
+	}
+
+	trinkle(head, width, cmp, p, pshift, 0, lp);
+
+	while(pshift != 1 || p[0] != 1 || p[1] != 0) {
+		if(pshift <= 1) {
+			trail = pntz(p);
+			shr(p, trail);
+			pshift += trail;
+		} else {
+			shl(p, 2);
+			pshift -= 2;
+			p[0] ^= 7;
+			shr(p, 1);
+			trinkle(head - lp[pshift] - width, width, cmp, p, pshift + 1, 1, lp);
+			shl(p, 1);
+			p[0] |= 1;
+			trinkle(head - width, width, cmp, p, pshift, 1, lp);
+		}
+		head -= width;
+	}
+}
libc/musl/src/stdlib/strtod.c
@@ -0,0 +1,37 @@
+#include <stdlib.h>
+#include "shgetc.h"
+#include "floatscan.h"
+#include "stdio_impl.h"
+
+static long double strtox(const char *s, char **p, int prec)
+{
+	FILE f;
+	sh_fromstring(&f, s);
+	shlim(&f, 0);
+	long double y = __floatscan(&f, prec, 1);
+	off_t cnt = shcnt(&f);
+	if (p) *p = cnt ? (char *)s + cnt : (char *)s;
+	return y;
+}
+
+float strtof(const char *restrict s, char **restrict p)
+{
+	return strtox(s, p, 0);
+}
+
+double strtod(const char *restrict s, char **restrict p)
+{
+	return strtox(s, p, 1);
+}
+
+long double strtold(const char *restrict s, char **restrict p)
+{
+	return strtox(s, p, 2);
+}
+
+weak_alias(strtof, strtof_l);
+weak_alias(strtod, strtod_l);
+weak_alias(strtold, strtold_l);
+weak_alias(strtof, __strtof_l);
+weak_alias(strtod, __strtod_l);
+weak_alias(strtold, __strtold_l);
libc/musl/src/stdlib/strtol.c
@@ -0,0 +1,56 @@
+#include "stdio_impl.h"
+#include "intscan.h"
+#include "shgetc.h"
+#include <inttypes.h>
+#include <limits.h>
+#include <ctype.h>
+
+static unsigned long long strtox(const char *s, char **p, int base, unsigned long long lim)
+{
+	FILE f;
+	sh_fromstring(&f, s);
+	shlim(&f, 0);
+	unsigned long long y = __intscan(&f, base, 1, lim);
+	if (p) {
+		size_t cnt = shcnt(&f);
+		*p = (char *)s + cnt;
+	}
+	return y;
+}
+
+unsigned long long strtoull(const char *restrict s, char **restrict p, int base)
+{
+	return strtox(s, p, base, ULLONG_MAX);
+}
+
+long long strtoll(const char *restrict s, char **restrict p, int base)
+{
+	return strtox(s, p, base, LLONG_MIN);
+}
+
+unsigned long strtoul(const char *restrict s, char **restrict p, int base)
+{
+	return strtox(s, p, base, ULONG_MAX);
+}
+
+long strtol(const char *restrict s, char **restrict p, int base)
+{
+	return strtox(s, p, base, 0UL+LONG_MIN);
+}
+
+intmax_t strtoimax(const char *restrict s, char **restrict p, int base)
+{
+	return strtoll(s, p, base);
+}
+
+uintmax_t strtoumax(const char *restrict s, char **restrict p, int base)
+{
+	return strtoull(s, p, base);
+}
+
+weak_alias(strtol, __strtol_internal);
+weak_alias(strtoul, __strtoul_internal);
+weak_alias(strtoll, __strtoll_internal);
+weak_alias(strtoull, __strtoull_internal);
+weak_alias(strtoimax, __strtoimax_internal);
+weak_alias(strtoumax, __strtoumax_internal);
libc/musl/src/stdlib/wcstod.c
@@ -0,0 +1,65 @@
+#include "shgetc.h"
+#include "floatscan.h"
+#include "stdio_impl.h"
+#include <wchar.h>
+#include <wctype.h>
+
+/* This read function heavily cheats. It knows:
+ *  (1) len will always be 1
+ *  (2) non-ascii characters don't matter */
+
+static size_t do_read(FILE *f, unsigned char *buf, size_t len)
+{
+	size_t i;
+	const wchar_t *wcs = f->cookie;
+
+	if (!wcs[0]) wcs=L"@";
+	for (i=0; i<f->buf_size && wcs[i]; i++)
+		f->buf[i] = wcs[i] < 128 ? wcs[i] : '@';
+	f->rpos = f->buf;
+	f->rend = f->buf + i;
+	f->cookie = (void *)(wcs+i);
+
+	if (i && len) {
+		*buf = *f->rpos++;
+		return 1;
+	}
+	return 0;
+}
+
+static long double wcstox(const wchar_t *s, wchar_t **p, int prec)
+{
+	wchar_t *t = (wchar_t *)s;
+	unsigned char buf[64];
+	FILE f = {0};
+	f.flags = 0;
+	f.rpos = f.rend = 0;
+	f.buf = buf + 4;
+	f.buf_size = sizeof buf - 4;
+	f.lock = -1;
+	f.read = do_read;
+	while (iswspace(*t)) t++;
+	f.cookie = (void *)t;
+	shlim(&f, 0);
+	long double y = __floatscan(&f, prec, 1);
+	if (p) {
+		size_t cnt = shcnt(&f);
+		*p = cnt ? t + cnt : (wchar_t *)s;
+	}
+	return y;
+}
+
+float wcstof(const wchar_t *restrict s, wchar_t **restrict p)
+{
+	return wcstox(s, p, 0);
+}
+
+double wcstod(const wchar_t *restrict s, wchar_t **restrict p)
+{
+	return wcstox(s, p, 1);
+}
+
+long double wcstold(const wchar_t *restrict s, wchar_t **restrict p)
+{
+	return wcstox(s, p, 2);
+}
libc/musl/src/stdlib/wcstol.c
@@ -0,0 +1,82 @@
+#include "stdio_impl.h"
+#include "intscan.h"
+#include "shgetc.h"
+#include <inttypes.h>
+#include <limits.h>
+#include <wctype.h>
+#include <wchar.h>
+
+/* This read function heavily cheats. It knows:
+ *  (1) len will always be 1
+ *  (2) non-ascii characters don't matter */
+
+static size_t do_read(FILE *f, unsigned char *buf, size_t len)
+{
+	size_t i;
+	const wchar_t *wcs = f->cookie;
+
+	if (!wcs[0]) wcs=L"@";
+	for (i=0; i<f->buf_size && wcs[i]; i++)
+		f->buf[i] = wcs[i] < 128 ? wcs[i] : '@';
+	f->rpos = f->buf;
+	f->rend = f->buf + i;
+	f->cookie = (void *)(wcs+i);
+
+	if (i && len) {
+		*buf = *f->rpos++;
+		return 1;
+	}
+	return 0;
+}
+
+static unsigned long long wcstox(const wchar_t *s, wchar_t **p, int base, unsigned long long lim)
+{
+	wchar_t *t = (wchar_t *)s;
+	unsigned char buf[64];
+	FILE f = {0};
+	f.flags = 0;
+	f.rpos = f.rend = 0;
+	f.buf = buf + 4;
+	f.buf_size = sizeof buf - 4;
+	f.lock = -1;
+	f.read = do_read;
+	while (iswspace(*t)) t++;
+	f.cookie = (void *)t;
+	shlim(&f, 0);
+	unsigned long long y = __intscan(&f, base, 1, lim);
+	if (p) {
+		size_t cnt = shcnt(&f);
+		*p = cnt ? t + cnt : (wchar_t *)s;
+	}
+	return y;
+}
+
+unsigned long long wcstoull(const wchar_t *restrict s, wchar_t **restrict p, int base)
+{
+	return wcstox(s, p, base, ULLONG_MAX);
+}
+
+long long wcstoll(const wchar_t *restrict s, wchar_t **restrict p, int base)
+{
+	return wcstox(s, p, base, LLONG_MIN);
+}
+
+unsigned long wcstoul(const wchar_t *restrict s, wchar_t **restrict p, int base)
+{
+	return wcstox(s, p, base, ULONG_MAX);
+}
+
+long wcstol(const wchar_t *restrict s, wchar_t **restrict p, int base)
+{
+	return wcstox(s, p, base, 0UL+LONG_MIN);
+}
+
+intmax_t wcstoimax(const wchar_t *restrict s, wchar_t **restrict p, int base)
+{
+	return wcstoll(s, p, base);
+}
+
+uintmax_t wcstoumax(const wchar_t *restrict s, wchar_t **restrict p, int base)
+{
+	return wcstoull(s, p, base);
+}
libc/musl/src/string/arm/__aeabi_memcpy.s
@@ -0,0 +1,45 @@
+.syntax unified
+
+.global __aeabi_memcpy8
+.global __aeabi_memcpy4
+.global __aeabi_memcpy
+.global __aeabi_memmove8
+.global __aeabi_memmove4
+.global __aeabi_memmove
+
+.type __aeabi_memcpy8,%function
+.type __aeabi_memcpy4,%function
+.type __aeabi_memcpy,%function
+.type __aeabi_memmove8,%function
+.type __aeabi_memmove4,%function
+.type __aeabi_memmove,%function
+
+__aeabi_memmove8:
+__aeabi_memmove4:
+__aeabi_memmove:
+	cmp   r0, r1
+	bls   3f
+	cmp   r2, #0
+	beq   2f
+	adds  r0, r0, r2
+	adds  r2, r1, r2
+1:	subs  r2, r2, #1
+	ldrb  r3, [r2]
+	subs  r0, r0, #1
+	strb  r3, [r0]
+	cmp   r1, r2
+	bne   1b
+2:	bx    lr
+__aeabi_memcpy8:
+__aeabi_memcpy4:
+__aeabi_memcpy:
+3:	cmp   r2, #0
+	beq   2f
+	adds  r2, r1, r2
+1:	ldrb  r3, [r1]
+	adds  r1, r1, #1
+	strb  r3, [r0]
+	adds  r0, r0, #1
+	cmp   r1, r2
+	bne   1b
+2:	bx    lr
libc/musl/src/string/arm/__aeabi_memset.s
@@ -0,0 +1,31 @@
+.syntax unified
+
+.global __aeabi_memclr8
+.global __aeabi_memclr4
+.global __aeabi_memclr
+.global __aeabi_memset8
+.global __aeabi_memset4
+.global __aeabi_memset
+
+.type __aeabi_memclr8,%function
+.type __aeabi_memclr4,%function
+.type __aeabi_memclr,%function
+.type __aeabi_memset8,%function
+.type __aeabi_memset4,%function
+.type __aeabi_memset,%function
+
+__aeabi_memclr8:
+__aeabi_memclr4:
+__aeabi_memclr:
+	movs  r2, #0
+__aeabi_memset8:
+__aeabi_memset4:
+__aeabi_memset:
+	cmp   r1, #0
+	beq   2f
+	adds  r1, r0, r1
+1:	strb  r2, [r0]
+	adds  r0, r0, #1
+	cmp   r1, r0
+	bne   1b
+2:	bx    lr
libc/musl/src/string/arm/memcpy.c
@@ -0,0 +1,3 @@
+#if __ARMEB__ || __thumb__
+#include "../memcpy.c"
+#endif
libc/musl/src/string/arm/memcpy_le.S
@@ -0,0 +1,383 @@
+#if !__ARMEB__ && !__thumb__
+
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ * All rights reserved.
+ *
+ * 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER 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.
+ */
+
+
+/*
+ * Optimized memcpy() for ARM.
+ *
+ * note that memcpy() always returns the destination pointer,
+ * so we have to preserve R0.
+  */
+
+/*
+ * This file has been modified from the original for use in musl libc.
+ * The main changes are: addition of .type memcpy,%function to make the
+ * code safely callable from thumb mode, adjusting the return
+ * instructions to be compatible with pre-thumb ARM cpus, and removal
+ * of prefetch code that is not compatible with older cpus.
+ */
+
+.syntax unified
+
+.global memcpy
+.type memcpy,%function
+memcpy:
+	/* The stack must always be 64-bits aligned to be compliant with the
+	 * ARM ABI. Since we have to save R0, we might as well save R4
+	 * which we can use for better pipelining of the reads below
+	 */
+	.fnstart
+	.save       {r0, r4, lr}
+	stmfd       sp!, {r0, r4, lr}
+	/* Making room for r5-r11 which will be spilled later */
+	.pad        #28
+	sub         sp, sp, #28
+
+	/* it simplifies things to take care of len<4 early */
+	cmp     r2, #4
+	blo     copy_last_3_and_return
+
+	/* compute the offset to align the source
+	 * offset = (4-(src&3))&3 = -src & 3
+	 */
+	rsb     r3, r1, #0
+	ands    r3, r3, #3
+	beq     src_aligned
+
+	/* align source to 32 bits. We need to insert 2 instructions between
+	 * a ldr[b|h] and str[b|h] because byte and half-word instructions
+	 * stall 2 cycles.
+	 */
+	movs    r12, r3, lsl #31
+	sub     r2, r2, r3              /* we know that r3 <= r2 because r2 >= 4 */
+	ldrbmi r3, [r1], #1
+	ldrbcs r4, [r1], #1
+	ldrbcs r12,[r1], #1
+	strbmi r3, [r0], #1
+	strbcs r4, [r0], #1
+	strbcs r12,[r0], #1
+
+src_aligned:
+
+	/* see if src and dst are aligned together (congruent) */
+	eor     r12, r0, r1
+	tst     r12, #3
+	bne     non_congruent
+
+	/* Use post-incriment mode for stm to spill r5-r11 to reserved stack
+	 * frame. Don't update sp.
+	 */
+	stmea   sp, {r5-r11}
+
+	/* align the destination to a cache-line */
+	rsb     r3, r0, #0
+	ands    r3, r3, #0x1C
+	beq     congruent_aligned32
+	cmp     r3, r2
+	andhi   r3, r2, #0x1C
+
+	/* conditionnaly copies 0 to 7 words (length in r3) */
+	movs    r12, r3, lsl #28
+	ldmcs   r1!, {r4, r5, r6, r7}           /* 16 bytes */
+	ldmmi   r1!, {r8, r9}                   /*  8 bytes */
+	stmcs   r0!, {r4, r5, r6, r7}
+	stmmi   r0!, {r8, r9}
+	tst     r3, #0x4
+	ldrne   r10,[r1], #4                    /*  4 bytes */
+	strne   r10,[r0], #4
+	sub     r2, r2, r3
+
+congruent_aligned32:
+	/*
+	 * here source is aligned to 32 bytes.
+	 */
+
+cached_aligned32:
+	subs    r2, r2, #32
+	blo     less_than_32_left
+
+	/*
+	 * We preload a cache-line up to 64 bytes ahead. On the 926, this will
+	 * stall only until the requested world is fetched, but the linefill
+	 * continues in the the background.
+	 * While the linefill is going, we write our previous cache-line
+	 * into the write-buffer (which should have some free space).
+	 * When the linefill is done, the writebuffer will
+	 * start dumping its content into memory
+	 *
+	 * While all this is going, we then load a full cache line into
+	 * 8 registers, this cache line should be in the cache by now
+	 * (or partly in the cache).
+	 *
+	 * This code should work well regardless of the source/dest alignment.
+	 *
+	 */
+
+	/* Align the preload register to a cache-line because the cpu does
+	 * "critical word first" (the first word requested is loaded first).
+	 */
+	@ bic           r12, r1, #0x1F
+	@ add           r12, r12, #64
+
+1:      ldmia   r1!, { r4-r11 }
+	subs    r2, r2, #32
+
+	/* 
+	 * NOTE: if r12 is more than 64 ahead of r1, the following ldrhi
+	 * for ARM9 preload will not be safely guarded by the preceding subs.
+	 * When it is safely guarded the only possibility to have SIGSEGV here
+	 * is because the caller overstates the length.
+	 */
+	@ ldrhi         r3, [r12], #32      /* cheap ARM9 preload */
+	stmia   r0!, { r4-r11 }
+	bhs     1b
+
+	add     r2, r2, #32
+
+less_than_32_left:
+	/*
+	 * less than 32 bytes left at this point (length in r2)
+	 */
+
+	/* skip all this if there is nothing to do, which should
+	 * be a common case (if not executed the code below takes
+	 * about 16 cycles)
+	 */
+	tst     r2, #0x1F
+	beq     1f
+
+	/* conditionnaly copies 0 to 31 bytes */
+	movs    r12, r2, lsl #28
+	ldmcs   r1!, {r4, r5, r6, r7}           /* 16 bytes */
+	ldmmi   r1!, {r8, r9}                   /*  8 bytes */
+	stmcs   r0!, {r4, r5, r6, r7}
+	stmmi   r0!, {r8, r9}
+	movs    r12, r2, lsl #30
+	ldrcs   r3, [r1], #4                    /*  4 bytes */
+	ldrhmi r4, [r1], #2                     /*  2 bytes */
+	strcs   r3, [r0], #4
+	strhmi r4, [r0], #2
+	tst     r2, #0x1
+	ldrbne r3, [r1]                         /*  last byte  */
+	strbne r3, [r0]
+
+	/* we're done! restore everything and return */
+1:      ldmfd   sp!, {r5-r11}
+	ldmfd   sp!, {r0, r4, lr}
+	bx      lr
+
+	/********************************************************************/
+
+non_congruent:
+	/*
+	 * here source is aligned to 4 bytes
+	 * but destination is not.
+	 *
+	 * in the code below r2 is the number of bytes read
+	 * (the number of bytes written is always smaller, because we have
+	 * partial words in the shift queue)
+	 */
+	cmp     r2, #4
+	blo     copy_last_3_and_return
+
+	/* Use post-incriment mode for stm to spill r5-r11 to reserved stack
+	 * frame. Don't update sp.
+	 */
+	stmea   sp, {r5-r11}
+
+	/* compute shifts needed to align src to dest */
+	rsb     r5, r0, #0
+	and     r5, r5, #3                      /* r5 = # bytes in partial words */
+	mov     r12, r5, lsl #3         /* r12 = right */
+	rsb     lr, r12, #32            /* lr = left  */
+
+	/* read the first word */
+	ldr     r3, [r1], #4
+	sub     r2, r2, #4
+
+	/* write a partial word (0 to 3 bytes), such that destination
+	 * becomes aligned to 32 bits (r5 = nb of words to copy for alignment)
+	 */
+	movs    r5, r5, lsl #31
+	strbmi r3, [r0], #1
+	movmi   r3, r3, lsr #8
+	strbcs r3, [r0], #1
+	movcs   r3, r3, lsr #8
+	strbcs r3, [r0], #1
+	movcs   r3, r3, lsr #8
+
+	cmp     r2, #4
+	blo     partial_word_tail
+
+	/* Align destination to 32 bytes (cache line boundary) */
+1:      tst     r0, #0x1c
+	beq     2f
+	ldr     r5, [r1], #4
+	sub     r2, r2, #4
+	orr     r4, r3, r5,             lsl lr
+	mov     r3, r5,                 lsr r12
+	str     r4, [r0], #4
+	cmp     r2, #4
+	bhs     1b
+	blo     partial_word_tail
+
+	/* copy 32 bytes at a time */
+2:      subs    r2, r2, #32
+	blo     less_than_thirtytwo
+
+	/* Use immediate mode for the shifts, because there is an extra cycle
+	 * for register shifts, which could account for up to 50% of
+	 * performance hit.
+	 */
+
+	cmp     r12, #24
+	beq     loop24
+	cmp     r12, #8
+	beq     loop8
+
+loop16:
+	ldr     r12, [r1], #4
+1:      mov     r4, r12
+	ldmia   r1!, {   r5,r6,r7,  r8,r9,r10,r11}
+	subs    r2, r2, #32
+	ldrhs   r12, [r1], #4
+	orr     r3, r3, r4, lsl #16
+	mov     r4, r4, lsr #16
+	orr     r4, r4, r5, lsl #16
+	mov     r5, r5, lsr #16
+	orr     r5, r5, r6, lsl #16
+	mov     r6, r6, lsr #16
+	orr     r6, r6, r7, lsl #16
+	mov     r7, r7, lsr #16
+	orr     r7, r7, r8, lsl #16
+	mov     r8, r8, lsr #16
+	orr     r8, r8, r9, lsl #16
+	mov     r9, r9, lsr #16
+	orr     r9, r9, r10, lsl #16
+	mov     r10, r10,               lsr #16
+	orr     r10, r10, r11, lsl #16
+	stmia   r0!, {r3,r4,r5,r6, r7,r8,r9,r10}
+	mov     r3, r11, lsr #16
+	bhs     1b
+	b       less_than_thirtytwo
+
+loop8:
+	ldr     r12, [r1], #4
+1:      mov     r4, r12
+	ldmia   r1!, {   r5,r6,r7,  r8,r9,r10,r11}
+	subs    r2, r2, #32
+	ldrhs   r12, [r1], #4
+	orr     r3, r3, r4, lsl #24
+	mov     r4, r4, lsr #8
+	orr     r4, r4, r5, lsl #24
+	mov     r5, r5, lsr #8
+	orr     r5, r5, r6, lsl #24
+	mov     r6, r6,  lsr #8
+	orr     r6, r6, r7, lsl #24
+	mov     r7, r7,  lsr #8
+	orr     r7, r7, r8,             lsl #24
+	mov     r8, r8,  lsr #8
+	orr     r8, r8, r9,             lsl #24
+	mov     r9, r9,  lsr #8
+	orr     r9, r9, r10,    lsl #24
+	mov     r10, r10, lsr #8
+	orr     r10, r10, r11,  lsl #24
+	stmia   r0!, {r3,r4,r5,r6, r7,r8,r9,r10}
+	mov     r3, r11, lsr #8
+	bhs     1b
+	b       less_than_thirtytwo
+
+loop24:
+	ldr     r12, [r1], #4
+1:      mov     r4, r12
+	ldmia   r1!, {   r5,r6,r7,  r8,r9,r10,r11}
+	subs    r2, r2, #32
+	ldrhs   r12, [r1], #4
+	orr     r3, r3, r4, lsl #8
+	mov     r4, r4, lsr #24
+	orr     r4, r4, r5, lsl #8
+	mov     r5, r5, lsr #24
+	orr     r5, r5, r6, lsl #8
+	mov     r6, r6, lsr #24
+	orr     r6, r6, r7, lsl #8
+	mov     r7, r7, lsr #24
+	orr     r7, r7, r8, lsl #8
+	mov     r8, r8, lsr #24
+	orr     r8, r8, r9, lsl #8
+	mov     r9, r9, lsr #24
+	orr     r9, r9, r10, lsl #8
+	mov     r10, r10, lsr #24
+	orr     r10, r10, r11, lsl #8
+	stmia   r0!, {r3,r4,r5,r6, r7,r8,r9,r10}
+	mov     r3, r11, lsr #24
+	bhs     1b
+
+less_than_thirtytwo:
+	/* copy the last 0 to 31 bytes of the source */
+	rsb     r12, lr, #32            /* we corrupted r12, recompute it  */
+	add     r2, r2, #32
+	cmp     r2, #4
+	blo     partial_word_tail
+
+1:      ldr     r5, [r1], #4
+	sub     r2, r2, #4
+	orr     r4, r3, r5,             lsl lr
+	mov     r3,     r5,                     lsr r12
+	str     r4, [r0], #4
+	cmp     r2, #4
+	bhs     1b
+
+partial_word_tail:
+	/* we have a partial word in the input buffer */
+	movs    r5, lr, lsl #(31-3)
+	strbmi r3, [r0], #1
+	movmi   r3, r3, lsr #8
+	strbcs r3, [r0], #1
+	movcs   r3, r3, lsr #8
+	strbcs r3, [r0], #1
+
+	/* Refill spilled registers from the stack. Don't update sp. */
+	ldmfd   sp, {r5-r11}
+
+copy_last_3_and_return:
+	movs    r2, r2, lsl #31 /* copy remaining 0, 1, 2 or 3 bytes */
+	ldrbmi r2, [r1], #1
+	ldrbcs r3, [r1], #1
+	ldrbcs r12,[r1]
+	strbmi r2, [r0], #1
+	strbcs r3, [r0], #1
+	strbcs r12,[r0]
+
+	/* we're done! restore sp and spilled registers and return */
+	add     sp,  sp, #28
+	ldmfd   sp!, {r0, r4, lr}
+	bx      lr
+
+#endif
libc/musl/src/string/i386/memcpy.s
@@ -0,0 +1,32 @@
+.global memcpy
+.global __memcpy_fwd
+.hidden __memcpy_fwd
+.type memcpy,@function
+memcpy:
+__memcpy_fwd:
+	push %esi
+	push %edi
+	mov 12(%esp),%edi
+	mov 16(%esp),%esi
+	mov 20(%esp),%ecx
+	mov %edi,%eax
+	cmp $4,%ecx
+	jc 1f
+	test $3,%edi
+	jz 1f
+2:	movsb
+	dec %ecx
+	test $3,%edi
+	jnz 2b
+1:	mov %ecx,%edx
+	shr $2,%ecx
+	rep
+	movsl
+	and $3,%edx
+	jz 1f
+2:	movsb
+	dec %edx
+	jnz 2b
+1:	pop %edi
+	pop %esi
+	ret
libc/musl/src/string/i386/memmove.s
@@ -0,0 +1,22 @@
+.global memmove
+.type memmove,@function
+memmove:
+	mov 4(%esp),%eax
+	sub 8(%esp),%eax
+	cmp 12(%esp),%eax
+.hidden __memcpy_fwd
+	jae __memcpy_fwd
+	push %esi
+	push %edi
+	mov 12(%esp),%edi
+	mov 16(%esp),%esi
+	mov 20(%esp),%ecx
+	lea -1(%edi,%ecx),%edi
+	lea -1(%esi,%ecx),%esi
+	std
+	rep movsb
+	cld
+	lea 1(%edi),%eax
+	pop %edi
+	pop %esi
+	ret
libc/musl/src/string/i386/memset.s
@@ -0,0 +1,76 @@
+.global memset
+.type memset,@function
+memset:
+	mov 12(%esp),%ecx
+	cmp $62,%ecx
+	ja 2f
+
+	mov 8(%esp),%dl
+	mov 4(%esp),%eax
+	test %ecx,%ecx
+	jz 1f
+
+	mov %dl,%dh
+
+	mov %dl,(%eax)
+	mov %dl,-1(%eax,%ecx)
+	cmp $2,%ecx
+	jbe 1f
+
+	mov %dx,1(%eax)
+	mov %dx,(-1-2)(%eax,%ecx)
+	cmp $6,%ecx
+	jbe 1f
+
+	shl $16,%edx
+	mov 8(%esp),%dl
+	mov 8(%esp),%dh
+
+	mov %edx,(1+2)(%eax)
+	mov %edx,(-1-2-4)(%eax,%ecx)
+	cmp $14,%ecx
+	jbe 1f
+
+	mov %edx,(1+2+4)(%eax)
+	mov %edx,(1+2+4+4)(%eax)
+	mov %edx,(-1-2-4-8)(%eax,%ecx)
+	mov %edx,(-1-2-4-4)(%eax,%ecx)
+	cmp $30,%ecx
+	jbe 1f
+
+	mov %edx,(1+2+4+8)(%eax)
+	mov %edx,(1+2+4+8+4)(%eax)
+	mov %edx,(1+2+4+8+8)(%eax)
+	mov %edx,(1+2+4+8+12)(%eax)
+	mov %edx,(-1-2-4-8-16)(%eax,%ecx)
+	mov %edx,(-1-2-4-8-12)(%eax,%ecx)
+	mov %edx,(-1-2-4-8-8)(%eax,%ecx)
+	mov %edx,(-1-2-4-8-4)(%eax,%ecx)
+
+1:	ret 	
+
+2:	movzbl 8(%esp),%eax
+	mov %edi,12(%esp)
+	imul $0x1010101,%eax
+	mov 4(%esp),%edi
+	test $15,%edi
+	mov %eax,-4(%edi,%ecx)
+	jnz 2f
+
+1:	shr $2, %ecx
+	rep
+	stosl
+	mov 4(%esp),%eax
+	mov 12(%esp),%edi
+	ret
+	
+2:	xor %edx,%edx
+	sub %edi,%edx
+	and $15,%edx
+	mov %eax,(%edi)
+	mov %eax,4(%edi)
+	mov %eax,8(%edi)
+	mov %eax,12(%edi)
+	sub %edx,%ecx
+	add %edx,%edi
+	jmp 1b
libc/musl/src/string/x86_64/memcpy.s
@@ -0,0 +1,25 @@
+.global memcpy
+.global __memcpy_fwd
+.hidden __memcpy_fwd
+.type memcpy,@function
+memcpy:
+__memcpy_fwd:
+	mov %rdi,%rax
+	cmp $8,%rdx
+	jc 1f
+	test $7,%edi
+	jz 1f
+2:	movsb
+	dec %rdx
+	test $7,%edi
+	jnz 2b
+1:	mov %rdx,%rcx
+	shr $3,%rcx
+	rep
+	movsq
+	and $7,%edx
+	jz 1f
+2:	movsb
+	dec %edx
+	jnz 2b
+1:	ret
libc/musl/src/string/x86_64/memmove.s
@@ -0,0 +1,16 @@
+.global memmove
+.type memmove,@function
+memmove:
+	mov %rdi,%rax
+	sub %rsi,%rax
+	cmp %rdx,%rax
+.hidden __memcpy_fwd
+	jae __memcpy_fwd
+	mov %rdx,%rcx
+	lea -1(%rdi,%rdx),%rdi
+	lea -1(%rsi,%rdx),%rsi
+	std
+	rep movsb
+	cld
+	lea 1(%rdi),%rax
+	ret
libc/musl/src/string/x86_64/memset.s
@@ -0,0 +1,72 @@
+.global memset
+.type memset,@function
+memset:
+	movzbq %sil,%rax
+	mov $0x101010101010101,%r8
+	imul %r8,%rax
+
+	cmp $126,%rdx
+	ja 2f
+
+	test %edx,%edx
+	jz 1f
+
+	mov %sil,(%rdi)
+	mov %sil,-1(%rdi,%rdx)
+	cmp $2,%edx
+	jbe 1f
+
+	mov %ax,1(%rdi)
+	mov %ax,(-1-2)(%rdi,%rdx)
+	cmp $6,%edx
+	jbe 1f
+
+	mov %eax,(1+2)(%rdi)
+	mov %eax,(-1-2-4)(%rdi,%rdx)
+	cmp $14,%edx
+	jbe 1f
+
+	mov %rax,(1+2+4)(%rdi)
+	mov %rax,(-1-2-4-8)(%rdi,%rdx)
+	cmp $30,%edx
+	jbe 1f
+
+	mov %rax,(1+2+4+8)(%rdi)
+	mov %rax,(1+2+4+8+8)(%rdi)
+	mov %rax,(-1-2-4-8-16)(%rdi,%rdx)
+	mov %rax,(-1-2-4-8-8)(%rdi,%rdx)
+	cmp $62,%edx
+	jbe 1f
+
+	mov %rax,(1+2+4+8+16)(%rdi)
+	mov %rax,(1+2+4+8+16+8)(%rdi)
+	mov %rax,(1+2+4+8+16+16)(%rdi)
+	mov %rax,(1+2+4+8+16+24)(%rdi)
+	mov %rax,(-1-2-4-8-16-32)(%rdi,%rdx)
+	mov %rax,(-1-2-4-8-16-24)(%rdi,%rdx)
+	mov %rax,(-1-2-4-8-16-16)(%rdi,%rdx)
+	mov %rax,(-1-2-4-8-16-8)(%rdi,%rdx)
+
+1:	mov %rdi,%rax
+	ret
+
+2:	test $15,%edi
+	mov %rdi,%r8
+	mov %rax,-8(%rdi,%rdx)
+	mov %rdx,%rcx
+	jnz 2f
+
+1:	shr $3,%rcx
+	rep
+	stosq
+	mov %r8,%rax
+	ret
+
+2:	xor %edx,%edx
+	sub %edi,%edx
+	and $15,%edx
+	mov %rax,(%rdi)
+	mov %rax,8(%rdi)
+	sub %rdx,%rcx
+	add %rdx,%rdi
+	jmp 1b
libc/musl/src/string/bcmp.c
@@ -0,0 +1,8 @@
+#define _BSD_SOURCE
+#include <string.h>
+#include <strings.h>
+
+int bcmp(const void *s1, const void *s2, size_t n)
+{
+	return memcmp(s1, s2, n);
+}
libc/musl/src/string/bcopy.c
@@ -0,0 +1,8 @@
+#define _BSD_SOURCE
+#include <string.h>
+#include <strings.h>
+
+void bcopy(const void *s1, void *s2, size_t n)
+{
+	memmove(s2, s1, n);
+}
libc/musl/src/string/bzero.c
@@ -0,0 +1,8 @@
+#define _BSD_SOURCE
+#include <string.h>
+#include <strings.h>
+
+void bzero(void *s, size_t n)
+{
+	memset(s, 0, n);
+}
libc/musl/src/string/explicit_bzero.c
@@ -0,0 +1,8 @@
+#define _BSD_SOURCE
+#include <string.h>
+
+void explicit_bzero(void *d, size_t n)
+{
+	d = memset(d, 0, n);
+	__asm__ __volatile__ ("" : : "r"(d) : "memory");
+}
libc/musl/src/string/index.c
@@ -0,0 +1,8 @@
+#define _BSD_SOURCE
+#include <string.h>
+#include <strings.h>
+
+char *index(const char *s, int c)
+{
+	return strchr(s, c);
+}
libc/musl/src/string/memccpy.c
@@ -0,0 +1,34 @@
+#include <string.h>
+#include <stdint.h>
+#include <limits.h>
+
+#define ALIGN (sizeof(size_t)-1)
+#define ONES ((size_t)-1/UCHAR_MAX)
+#define HIGHS (ONES * (UCHAR_MAX/2+1))
+#define HASZERO(x) ((x)-ONES & ~(x) & HIGHS)
+
+void *memccpy(void *restrict dest, const void *restrict src, int c, size_t n)
+{
+	unsigned char *d = dest;
+	const unsigned char *s = src;
+
+	c = (unsigned char)c;
+#ifdef __GNUC__
+	typedef size_t __attribute__((__may_alias__)) word;
+	word *wd;
+	const word *ws;
+	if (((uintptr_t)s & ALIGN) == ((uintptr_t)d & ALIGN)) {
+		for (; ((uintptr_t)s & ALIGN) && n && (*d=*s)!=c; n--, s++, d++);
+		if ((uintptr_t)s & ALIGN) goto tail;
+		size_t k = ONES * c;
+		wd=(void *)d; ws=(const void *)s;
+		for (; n>=sizeof(size_t) && !HASZERO(*ws^k);
+		       n-=sizeof(size_t), ws++, wd++) *wd = *ws;
+		d=(void *)wd; s=(const void *)ws;
+	}
+#endif
+	for (; n && (*d=*s)!=c; n--, s++, d++);
+tail:
+	if (n && *s==c) return d+1;
+	return 0;
+}
libc/musl/src/string/memchr.c
@@ -0,0 +1,27 @@
+#include <string.h>
+#include <stdint.h>
+#include <limits.h>
+
+#define SS (sizeof(size_t))
+#define ALIGN (sizeof(size_t)-1)
+#define ONES ((size_t)-1/UCHAR_MAX)
+#define HIGHS (ONES * (UCHAR_MAX/2+1))
+#define HASZERO(x) ((x)-ONES & ~(x) & HIGHS)
+
+void *memchr(const void *src, int c, size_t n)
+{
+	const unsigned char *s = src;
+	c = (unsigned char)c;
+#ifdef __GNUC__
+	for (; ((uintptr_t)s & ALIGN) && n && *s != c; s++, n--);
+	if (n && *s != c) {
+		typedef size_t __attribute__((__may_alias__)) word;
+		const word *w;
+		size_t k = ONES * c;
+		for (w = (const void *)s; n>=SS && !HASZERO(*w^k); w++, n-=SS);
+		s = (const void *)w;
+	}
+#endif
+	for (; n && *s != c; s++, n--);
+	return n ? (void *)s : 0;
+}
libc/musl/src/string/memcmp.c
@@ -0,0 +1,8 @@
+#include <string.h>
+
+int memcmp(const void *vl, const void *vr, size_t n)
+{
+	const unsigned char *l=vl, *r=vr;
+	for (; n && *l == *r; n--, l++, r++);
+	return n ? *l-*r : 0;
+}
libc/musl/src/string/memcpy.c
@@ -0,0 +1,124 @@
+#include <string.h>
+#include <stdint.h>
+#include <endian.h>
+
+void *memcpy(void *restrict dest, const void *restrict src, size_t n)
+{
+	unsigned char *d = dest;
+	const unsigned char *s = src;
+
+#ifdef __GNUC__
+
+#if __BYTE_ORDER == __LITTLE_ENDIAN
+#define LS >>
+#define RS <<
+#else
+#define LS <<
+#define RS >>
+#endif
+
+	typedef uint32_t __attribute__((__may_alias__)) u32;
+	uint32_t w, x;
+
+	for (; (uintptr_t)s % 4 && n; n--) *d++ = *s++;
+
+	if ((uintptr_t)d % 4 == 0) {
+		for (; n>=16; s+=16, d+=16, n-=16) {
+			*(u32 *)(d+0) = *(u32 *)(s+0);
+			*(u32 *)(d+4) = *(u32 *)(s+4);
+			*(u32 *)(d+8) = *(u32 *)(s+8);
+			*(u32 *)(d+12) = *(u32 *)(s+12);
+		}
+		if (n&8) {
+			*(u32 *)(d+0) = *(u32 *)(s+0);
+			*(u32 *)(d+4) = *(u32 *)(s+4);
+			d += 8; s += 8;
+		}
+		if (n&4) {
+			*(u32 *)(d+0) = *(u32 *)(s+0);
+			d += 4; s += 4;
+		}
+		if (n&2) {
+			*d++ = *s++; *d++ = *s++;
+		}
+		if (n&1) {
+			*d = *s;
+		}
+		return dest;
+	}
+
+	if (n >= 32) switch ((uintptr_t)d % 4) {
+	case 1:
+		w = *(u32 *)s;
+		*d++ = *s++;
+		*d++ = *s++;
+		*d++ = *s++;
+		n -= 3;
+		for (; n>=17; s+=16, d+=16, n-=16) {
+			x = *(u32 *)(s+1);
+			*(u32 *)(d+0) = (w LS 24) | (x RS 8);
+			w = *(u32 *)(s+5);
+			*(u32 *)(d+4) = (x LS 24) | (w RS 8);
+			x = *(u32 *)(s+9);
+			*(u32 *)(d+8) = (w LS 24) | (x RS 8);
+			w = *(u32 *)(s+13);
+			*(u32 *)(d+12) = (x LS 24) | (w RS 8);
+		}
+		break;
+	case 2:
+		w = *(u32 *)s;
+		*d++ = *s++;
+		*d++ = *s++;
+		n -= 2;
+		for (; n>=18; s+=16, d+=16, n-=16) {
+			x = *(u32 *)(s+2);
+			*(u32 *)(d+0) = (w LS 16) | (x RS 16);
+			w = *(u32 *)(s+6);
+			*(u32 *)(d+4) = (x LS 16) | (w RS 16);
+			x = *(u32 *)(s+10);
+			*(u32 *)(d+8) = (w LS 16) | (x RS 16);
+			w = *(u32 *)(s+14);
+			*(u32 *)(d+12) = (x LS 16) | (w RS 16);
+		}
+		break;
+	case 3:
+		w = *(u32 *)s;
+		*d++ = *s++;
+		n -= 1;
+		for (; n>=19; s+=16, d+=16, n-=16) {
+			x = *(u32 *)(s+3);
+			*(u32 *)(d+0) = (w LS 8) | (x RS 24);
+			w = *(u32 *)(s+7);
+			*(u32 *)(d+4) = (x LS 8) | (w RS 24);
+			x = *(u32 *)(s+11);
+			*(u32 *)(d+8) = (w LS 8) | (x RS 24);
+			w = *(u32 *)(s+15);
+			*(u32 *)(d+12) = (x LS 8) | (w RS 24);
+		}
+		break;
+	}
+	if (n&16) {
+		*d++ = *s++; *d++ = *s++; *d++ = *s++; *d++ = *s++;
+		*d++ = *s++; *d++ = *s++; *d++ = *s++; *d++ = *s++;
+		*d++ = *s++; *d++ = *s++; *d++ = *s++; *d++ = *s++;
+		*d++ = *s++; *d++ = *s++; *d++ = *s++; *d++ = *s++;
+	}
+	if (n&8) {
+		*d++ = *s++; *d++ = *s++; *d++ = *s++; *d++ = *s++;
+		*d++ = *s++; *d++ = *s++; *d++ = *s++; *d++ = *s++;
+	}
+	if (n&4) {
+		*d++ = *s++; *d++ = *s++; *d++ = *s++; *d++ = *s++;
+	}
+	if (n&2) {
+		*d++ = *s++; *d++ = *s++;
+	}
+	if (n&1) {
+		*d = *s;
+	}
+	return dest;
+#endif
+
+	for (; n; n--) *d++ = *s++;
+	return dest;
+}
libc/musl/src/string/memmem.c
@@ -0,0 +1,149 @@
+#define _GNU_SOURCE
+#include <string.h>
+#include <stdint.h>
+
+static char *twobyte_memmem(const unsigned char *h, size_t k, const unsigned char *n)
+{
+	uint16_t nw = n[0]<<8 | n[1], hw = h[0]<<8 | h[1];
+	for (h+=2, k-=2; k; k--, hw = hw<<8 | *h++)
+		if (hw == nw) return (char *)h-2;
+	return hw == nw ? (char *)h-2 : 0;
+}
+
+static char *threebyte_memmem(const unsigned char *h, size_t k, const unsigned char *n)
+{
+	uint32_t nw = n[0]<<24 | n[1]<<16 | n[2]<<8;
+	uint32_t hw = h[0]<<24 | h[1]<<16 | h[2]<<8;
+	for (h+=3, k-=3; k; k--, hw = (hw|*h++)<<8)
+		if (hw == nw) return (char *)h-3;
+	return hw == nw ? (char *)h-3 : 0;
+}
+
+static char *fourbyte_memmem(const unsigned char *h, size_t k, const unsigned char *n)
+{
+	uint32_t nw = n[0]<<24 | n[1]<<16 | n[2]<<8 | n[3];
+	uint32_t hw = h[0]<<24 | h[1]<<16 | h[2]<<8 | h[3];
+	for (h+=4, k-=4; k; k--, hw = hw<<8 | *h++)
+		if (hw == nw) return (char *)h-4;
+	return hw == nw ? (char *)h-4 : 0;
+}
+
+#define MAX(a,b) ((a)>(b)?(a):(b))
+#define MIN(a,b) ((a)<(b)?(a):(b))
+
+#define BITOP(a,b,op) \
+ ((a)[(size_t)(b)/(8*sizeof *(a))] op (size_t)1<<((size_t)(b)%(8*sizeof *(a))))
+
+static char *twoway_memmem(const unsigned char *h, const unsigned char *z, const unsigned char *n, size_t l)
+{
+	size_t i, ip, jp, k, p, ms, p0, mem, mem0;
+	size_t byteset[32 / sizeof(size_t)] = { 0 };
+	size_t shift[256];
+
+	/* Computing length of needle and fill shift table */
+	for (i=0; i<l; i++)
+		BITOP(byteset, n[i], |=), shift[n[i]] = i+1;
+
+	/* Compute maximal suffix */
+	ip = -1; jp = 0; k = p = 1;
+	while (jp+k<l) {
+		if (n[ip+k] == n[jp+k]) {
+			if (k == p) {
+				jp += p;
+				k = 1;
+			} else k++;
+		} else if (n[ip+k] > n[jp+k]) {
+			jp += k;
+			k = 1;
+			p = jp - ip;
+		} else {
+			ip = jp++;
+			k = p = 1;
+		}
+	}
+	ms = ip;
+	p0 = p;
+
+	/* And with the opposite comparison */
+	ip = -1; jp = 0; k = p = 1;
+	while (jp+k<l) {
+		if (n[ip+k] == n[jp+k]) {
+			if (k == p) {
+				jp += p;
+				k = 1;
+			} else k++;
+		} else if (n[ip+k] < n[jp+k]) {
+			jp += k;
+			k = 1;
+			p = jp - ip;
+		} else {
+			ip = jp++;
+			k = p = 1;
+		}
+	}
+	if (ip+1 > ms+1) ms = ip;
+	else p = p0;
+
+	/* Periodic needle? */
+	if (memcmp(n, n+p, ms+1)) {
+		mem0 = 0;
+		p = MAX(ms, l-ms-1) + 1;
+	} else mem0 = l-p;
+	mem = 0;
+
+	/* Search loop */
+	for (;;) {
+		/* If remainder of haystack is shorter than needle, done */
+		if (z-h < l) return 0;
+
+		/* Check last byte first; advance by shift on mismatch */
+		if (BITOP(byteset, h[l-1], &)) {
+			k = l-shift[h[l-1]];
+			if (k) {
+				if (k < mem) k = mem;
+				h += k;
+				mem = 0;
+				continue;
+			}
+		} else {
+			h += l;
+			mem = 0;
+			continue;
+		}
+
+		/* Compare right half */
+		for (k=MAX(ms+1,mem); k<l && n[k] == h[k]; k++);
+		if (k < l) {
+			h += k-ms;
+			mem = 0;
+			continue;
+		}
+		/* Compare left half */
+		for (k=ms+1; k>mem && n[k-1] == h[k-1]; k--);
+		if (k <= mem) return (char *)h;
+		h += p;
+		mem = mem0;
+	}
+}
+
+void *memmem(const void *h0, size_t k, const void *n0, size_t l)
+{
+	const unsigned char *h = h0, *n = n0;
+
+	/* Return immediately on empty needle */
+	if (!l) return (void *)h;
+
+	/* Return immediately when needle is longer than haystack */
+	if (k<l) return 0;
+
+	/* Use faster algorithms for short needles */
+	h = memchr(h0, *n, k);
+	if (!h || l==1) return (void *)h;
+	k -= h - (const unsigned char *)h0;
+	if (k<l) return 0;
+	if (l==2) return twobyte_memmem(h, k, n);
+	if (l==3) return threebyte_memmem(h, k, n);
+	if (l==4) return fourbyte_memmem(h, k, n);
+
+	return twoway_memmem(h, h+k, n, l);
+}
libc/musl/src/string/memmove.c
@@ -0,0 +1,42 @@
+#include <string.h>
+#include <stdint.h>
+
+#ifdef __GNUC__
+typedef __attribute__((__may_alias__)) size_t WT;
+#define WS (sizeof(WT))
+#endif
+
+void *memmove(void *dest, const void *src, size_t n)
+{
+	char *d = dest;
+	const char *s = src;
+
+	if (d==s) return d;
+	if ((uintptr_t)s-(uintptr_t)d-n <= -2*n) return memcpy(d, s, n);
+
+	if (d<s) {
+#ifdef __GNUC__
+		if ((uintptr_t)s % WS == (uintptr_t)d % WS) {
+			while ((uintptr_t)d % WS) {
+				if (!n--) return dest;
+				*d++ = *s++;
+			}
+			for (; n>=WS; n-=WS, d+=WS, s+=WS) *(WT *)d = *(WT *)s;
+		}
+#endif
+		for (; n; n--) *d++ = *s++;
+	} else {
+#ifdef __GNUC__
+		if ((uintptr_t)s % WS == (uintptr_t)d % WS) {
+			while ((uintptr_t)(d+n) % WS) {
+				if (!n--) return dest;
+				d[n] = s[n];
+			}
+			while (n>=WS) n-=WS, *(WT *)(d+n) = *(WT *)(s+n);
+		}
+#endif
+		while (n) n--, d[n] = s[n];
+	}
+
+	return dest;
+}
libc/musl/src/string/mempcpy.c
@@ -0,0 +1,7 @@
+#define _GNU_SOURCE
+#include <string.h>
+
+void *mempcpy(void *dest, const void *src, size_t n)
+{
+	return (char *)memcpy(dest, src, n) + n;
+}
libc/musl/src/string/memrchr.c
@@ -0,0 +1,11 @@
+#include <string.h>
+
+void *__memrchr(const void *m, int c, size_t n)
+{
+	const unsigned char *s = m;
+	c = (unsigned char)c;
+	while (n--) if (s[n]==c) return (void *)(s+n);
+	return 0;
+}
+
+weak_alias(__memrchr, memrchr);
libc/musl/src/string/memset.c
@@ -0,0 +1,90 @@
+#include <string.h>
+#include <stdint.h>
+
+void *memset(void *dest, int c, size_t n)
+{
+	unsigned char *s = dest;
+	size_t k;
+
+	/* Fill head and tail with minimal branching. Each
+	 * conditional ensures that all the subsequently used
+	 * offsets are well-defined and in the dest region. */
+
+	if (!n) return dest;
+	s[0] = c;
+	s[n-1] = c;
+	if (n <= 2) return dest;
+	s[1] = c;
+	s[2] = c;
+	s[n-2] = c;
+	s[n-3] = c;
+	if (n <= 6) return dest;
+	s[3] = c;
+	s[n-4] = c;
+	if (n <= 8) return dest;
+
+	/* Advance pointer to align it at a 4-byte boundary,
+	 * and truncate n to a multiple of 4. The previous code
+	 * already took care of any head/tail that get cut off
+	 * by the alignment. */
+
+	k = -(uintptr_t)s & 3;
+	s += k;
+	n -= k;
+	n &= -4;
+
+#ifdef __GNUC__
+	typedef uint32_t __attribute__((__may_alias__)) u32;
+	typedef uint64_t __attribute__((__may_alias__)) u64;
+
+	u32 c32 = ((u32)-1)/255 * (unsigned char)c;
+
+	/* In preparation to copy 32 bytes at a time, aligned on
+	 * an 8-byte bounary, fill head/tail up to 28 bytes each.
+	 * As in the initial byte-based head/tail fill, each
+	 * conditional below ensures that the subsequent offsets
+	 * are valid (e.g. !(n<=24) implies n>=28). */
+
+	*(u32 *)(s+0) = c32;
+	*(u32 *)(s+n-4) = c32;
+	if (n <= 8) return dest;
+	*(u32 *)(s+4) = c32;
+	*(u32 *)(s+8) = c32;
+	*(u32 *)(s+n-12) = c32;
+	*(u32 *)(s+n-8) = c32;
+	if (n <= 24) return dest;
+	*(u32 *)(s+12) = c32;
+	*(u32 *)(s+16) = c32;
+	*(u32 *)(s+20) = c32;
+	*(u32 *)(s+24) = c32;
+	*(u32 *)(s+n-28) = c32;
+	*(u32 *)(s+n-24) = c32;
+	*(u32 *)(s+n-20) = c32;
+	*(u32 *)(s+n-16) = c32;
+
+	/* Align to a multiple of 8 so we can fill 64 bits at a time,
+	 * and avoid writing the same bytes twice as much as is
+	 * practical without introducing additional branching. */
+
+	k = 24 + ((uintptr_t)s & 4);
+	s += k;
+	n -= k;
+
+	/* If this loop is reached, 28 tail bytes have already been
+	 * filled, so any remainder when n drops below 32 can be
+	 * safely ignored. */
+
+	u64 c64 = c32 | ((u64)c32 << 32);
+	for (; n >= 32; n-=32, s+=32) {
+		*(u64 *)(s+0) = c64;
+		*(u64 *)(s+8) = c64;
+		*(u64 *)(s+16) = c64;
+		*(u64 *)(s+24) = c64;
+	}
+#else
+	/* Pure C fallback with no aliasing violations. */
+	for (; n; n--, s++) *s = c;
+#endif
+
+	return dest;
+}
libc/musl/src/string/rindex.c
@@ -0,0 +1,8 @@
+#define _BSD_SOURCE
+#include <string.h>
+#include <strings.h>
+
+char *rindex(const char *s, int c)
+{
+	return strrchr(s, c);
+}
libc/musl/src/string/stpcpy.c
@@ -0,0 +1,29 @@
+#include <string.h>
+#include <stdint.h>
+#include <limits.h>
+
+#define ALIGN (sizeof(size_t))
+#define ONES ((size_t)-1/UCHAR_MAX)
+#define HIGHS (ONES * (UCHAR_MAX/2+1))
+#define HASZERO(x) ((x)-ONES & ~(x) & HIGHS)
+
+char *__stpcpy(char *restrict d, const char *restrict s)
+{
+#ifdef __GNUC__
+	typedef size_t __attribute__((__may_alias__)) word;
+	word *wd;
+	const word *ws;
+	if ((uintptr_t)s % ALIGN == (uintptr_t)d % ALIGN) {
+		for (; (uintptr_t)s % ALIGN; s++, d++)
+			if (!(*d=*s)) return d;
+		wd=(void *)d; ws=(const void *)s;
+		for (; !HASZERO(*ws); *wd++ = *ws++);
+		d=(void *)wd; s=(const void *)ws;
+	}
+#endif
+	for (; (*d=*s); s++, d++);
+
+	return d;
+}
+
+weak_alias(__stpcpy, stpcpy);
libc/musl/src/string/stpncpy.c
@@ -0,0 +1,32 @@
+#include <string.h>
+#include <stdint.h>
+#include <limits.h>
+
+#define ALIGN (sizeof(size_t)-1)
+#define ONES ((size_t)-1/UCHAR_MAX)
+#define HIGHS (ONES * (UCHAR_MAX/2+1))
+#define HASZERO(x) ((x)-ONES & ~(x) & HIGHS)
+
+char *__stpncpy(char *restrict d, const char *restrict s, size_t n)
+{
+#ifdef __GNUC__
+	typedef size_t __attribute__((__may_alias__)) word;
+	word *wd;
+	const word *ws;
+	if (((uintptr_t)s & ALIGN) == ((uintptr_t)d & ALIGN)) {
+		for (; ((uintptr_t)s & ALIGN) && n && (*d=*s); n--, s++, d++);
+		if (!n || !*s) goto tail;
+		wd=(void *)d; ws=(const void *)s;
+		for (; n>=sizeof(size_t) && !HASZERO(*ws);
+		       n-=sizeof(size_t), ws++, wd++) *wd = *ws;
+		d=(void *)wd; s=(const void *)ws;
+	}
+#endif
+	for (; n && (*d=*s); n--, s++, d++);
+tail:
+	memset(d, 0, n);
+	return d;
+}
+
+weak_alias(__stpncpy, stpncpy);
+
libc/musl/src/string/strcasecmp.c
@@ -0,0 +1,16 @@
+#include <strings.h>
+#include <ctype.h>
+
+int strcasecmp(const char *_l, const char *_r)
+{
+	const unsigned char *l=(void *)_l, *r=(void *)_r;
+	for (; *l && *r && (*l == *r || tolower(*l) == tolower(*r)); l++, r++);
+	return tolower(*l) - tolower(*r);
+}
+
+int __strcasecmp_l(const char *l, const char *r, locale_t loc)
+{
+	return strcasecmp(l, r);
+}
+
+weak_alias(__strcasecmp_l, strcasecmp_l);
libc/musl/src/string/strcasestr.c
@@ -0,0 +1,9 @@
+#define _GNU_SOURCE
+#include <string.h>
+
+char *strcasestr(const char *h, const char *n)
+{
+	size_t l = strlen(n);
+	for (; *h; h++) if (!strncasecmp(h, n, l)) return (char *)h;
+	return 0;
+}
libc/musl/src/string/strcat.c
@@ -0,0 +1,7 @@
+#include <string.h>
+
+char *strcat(char *restrict dest, const char *restrict src)
+{
+	strcpy(dest + strlen(dest), src);
+	return dest;
+}
libc/musl/src/string/strchr.c
@@ -0,0 +1,7 @@
+#include <string.h>
+
+char *strchr(const char *s, int c)
+{
+	char *r = __strchrnul(s, c);
+	return *(unsigned char *)r == (unsigned char)c ? r : 0;
+}
libc/musl/src/string/strchrnul.c
@@ -0,0 +1,28 @@
+#include <string.h>
+#include <stdint.h>
+#include <limits.h>
+
+#define ALIGN (sizeof(size_t))
+#define ONES ((size_t)-1/UCHAR_MAX)
+#define HIGHS (ONES * (UCHAR_MAX/2+1))
+#define HASZERO(x) ((x)-ONES & ~(x) & HIGHS)
+
+char *__strchrnul(const char *s, int c)
+{
+	c = (unsigned char)c;
+	if (!c) return (char *)s + strlen(s);
+
+#ifdef __GNUC__
+	typedef size_t __attribute__((__may_alias__)) word;
+	const word *w;
+	for (; (uintptr_t)s % ALIGN; s++)
+		if (!*s || *(unsigned char *)s == c) return (char *)s;
+	size_t k = ONES * c;
+	for (w = (void *)s; !HASZERO(*w) && !HASZERO(*w^k); w++);
+	s = (void *)w;
+#endif
+	for (; *s && *(unsigned char *)s != c; s++);
+	return (char *)s;
+}
+
+weak_alias(__strchrnul, strchrnul);
libc/musl/src/string/strcmp.c
@@ -0,0 +1,7 @@
+#include <string.h>
+
+int strcmp(const char *l, const char *r)
+{
+	for (; *l==*r && *l; l++, r++);
+	return *(unsigned char *)l - *(unsigned char *)r;
+}
libc/musl/src/string/strcpy.c
@@ -0,0 +1,7 @@
+#include <string.h>
+
+char *strcpy(char *restrict dest, const char *restrict src)
+{
+	__stpcpy(dest, src);
+	return dest;
+}
libc/musl/src/string/strcspn.c
@@ -0,0 +1,17 @@
+#include <string.h>
+
+#define BITOP(a,b,op) \
+ ((a)[(size_t)(b)/(8*sizeof *(a))] op (size_t)1<<((size_t)(b)%(8*sizeof *(a))))
+
+size_t strcspn(const char *s, const char *c)
+{
+	const char *a = s;
+	size_t byteset[32/sizeof(size_t)];
+
+	if (!c[0] || !c[1]) return __strchrnul(s, *c)-a;
+
+	memset(byteset, 0, sizeof byteset);
+	for (; *c && BITOP(byteset, *(unsigned char *)c, |=); c++);
+	for (; *s && !BITOP(byteset, *(unsigned char *)s, &); s++);
+	return s-a;
+}
libc/musl/src/string/strdup.c
@@ -0,0 +1,10 @@
+#include <stdlib.h>
+#include <string.h>
+
+char *strdup(const char *s)
+{
+	size_t l = strlen(s);
+	char *d = malloc(l+1);
+	if (!d) return NULL;
+	return memcpy(d, s, l+1);
+}
libc/musl/src/string/strerror_r.c
@@ -0,0 +1,19 @@
+#include <string.h>
+#include <errno.h>
+
+int strerror_r(int err, char *buf, size_t buflen)
+{
+	char *msg = strerror(err);
+	size_t l = strlen(msg);
+	if (l >= buflen) {
+		if (buflen) {
+			memcpy(buf, msg, buflen-1);
+			buf[buflen-1] = 0;
+		}
+		return ERANGE;
+	}
+	memcpy(buf, msg, l+1);
+	return 0;
+}
+
+weak_alias(strerror_r, __xpg_strerror_r);
libc/musl/src/string/strlcat.c
@@ -0,0 +1,9 @@
+#define _BSD_SOURCE
+#include <string.h>
+
+size_t strlcat(char *d, const char *s, size_t n)
+{
+	size_t l = strnlen(d, n);
+	if (l == n) return l + strlen(s);
+	return l + strlcpy(d+l, s, n-l);
+}
libc/musl/src/string/strlcpy.c
@@ -0,0 +1,34 @@
+#define _BSD_SOURCE
+#include <string.h>
+#include <stdint.h>
+#include <limits.h>
+
+#define ALIGN (sizeof(size_t)-1)
+#define ONES ((size_t)-1/UCHAR_MAX)
+#define HIGHS (ONES * (UCHAR_MAX/2+1))
+#define HASZERO(x) ((x)-ONES & ~(x) & HIGHS)
+
+size_t strlcpy(char *d, const char *s, size_t n)
+{
+	char *d0 = d;
+	size_t *wd;
+
+	if (!n--) goto finish;
+#ifdef __GNUC__
+	typedef size_t __attribute__((__may_alias__)) word;
+	const word *ws;
+	if (((uintptr_t)s & ALIGN) == ((uintptr_t)d & ALIGN)) {
+		for (; ((uintptr_t)s & ALIGN) && n && (*d=*s); n--, s++, d++);
+		if (n && *s) {
+			wd=(void *)d; ws=(const void *)s;
+			for (; n>=sizeof(size_t) && !HASZERO(*ws);
+			       n-=sizeof(size_t), ws++, wd++) *wd = *ws;
+			d=(void *)wd; s=(const void *)ws;
+		}
+	}
+#endif
+	for (; n && (*d=*s); n--, s++, d++);
+	*d = 0;
+finish:
+	return d-d0 + strlen(s);
+}
libc/musl/src/string/strlen.c
@@ -0,0 +1,22 @@
+#include <string.h>
+#include <stdint.h>
+#include <limits.h>
+
+#define ALIGN (sizeof(size_t))
+#define ONES ((size_t)-1/UCHAR_MAX)
+#define HIGHS (ONES * (UCHAR_MAX/2+1))
+#define HASZERO(x) ((x)-ONES & ~(x) & HIGHS)
+
+size_t strlen(const char *s)
+{
+	const char *a = s;
+#ifdef __GNUC__
+	typedef size_t __attribute__((__may_alias__)) word;
+	const word *w;
+	for (; (uintptr_t)s % ALIGN; s++) if (!*s) return s-a;
+	for (w = (const void *)s; !HASZERO(*w); w++);
+	s = (const void *)w;
+#endif
+	for (; *s; s++);
+	return s-a;
+}
libc/musl/src/string/strncasecmp.c
@@ -0,0 +1,17 @@
+#include <strings.h>
+#include <ctype.h>
+
+int strncasecmp(const char *_l, const char *_r, size_t n)
+{
+	const unsigned char *l=(void *)_l, *r=(void *)_r;
+	if (!n--) return 0;
+	for (; *l && *r && n && (*l == *r || tolower(*l) == tolower(*r)); l++, r++, n--);
+	return tolower(*l) - tolower(*r);
+}
+
+int __strncasecmp_l(const char *l, const char *r, size_t n, locale_t loc)
+{
+	return strncasecmp(l, r, n);
+}
+
+weak_alias(__strncasecmp_l, strncasecmp_l);
libc/musl/src/string/strncat.c
@@ -0,0 +1,10 @@
+#include <string.h>
+
+char *strncat(char *restrict d, const char *restrict s, size_t n)
+{
+	char *a = d;
+	d += strlen(d);
+	while (n && *s) n--, *d++ = *s++;
+	*d++ = 0;
+	return a;
+}
libc/musl/src/string/strncmp.c
@@ -0,0 +1,9 @@
+#include <string.h>
+
+int strncmp(const char *_l, const char *_r, size_t n)
+{
+	const unsigned char *l=(void *)_l, *r=(void *)_r;
+	if (!n--) return 0;
+	for (; *l && *r && n && *l == *r ; l++, r++, n--);
+	return *l - *r;
+}
libc/musl/src/string/strncpy.c
@@ -0,0 +1,7 @@
+#include <string.h>
+
+char *strncpy(char *restrict d, const char *restrict s, size_t n)
+{
+	__stpncpy(d, s, n);
+	return d;
+}
libc/musl/src/string/strndup.c
@@ -0,0 +1,12 @@
+#include <stdlib.h>
+#include <string.h>
+
+char *strndup(const char *s, size_t n)
+{
+	size_t l = strnlen(s, n);
+	char *d = malloc(l+1);
+	if (!d) return NULL;
+	memcpy(d, s, l);
+	d[l] = 0;
+	return d;
+}
libc/musl/src/string/strnlen.c
@@ -0,0 +1,7 @@
+#include <string.h>
+
+size_t strnlen(const char *s, size_t n)
+{
+	const char *p = memchr(s, 0, n);
+	return p ? p-s : n;
+}
libc/musl/src/string/strpbrk.c
@@ -0,0 +1,7 @@
+#include <string.h>
+
+char *strpbrk(const char *s, const char *b)
+{
+	s += strcspn(s, b);
+	return *s ? (char *)s : 0;
+}
libc/musl/src/string/strrchr.c
@@ -0,0 +1,6 @@
+#include <string.h>
+
+char *strrchr(const char *s, int c)
+{
+	return __memrchr(s, c, strlen(s) + 1);
+}
libc/musl/src/string/strsep.c
@@ -0,0 +1,13 @@
+#define _GNU_SOURCE
+#include <string.h>
+
+char *strsep(char **str, const char *sep)
+{
+	char *s = *str, *end;
+	if (!s) return NULL;
+	end = s + strcspn(s, sep);
+	if (*end) *end++ = 0;
+	else end = 0;
+	*str = end;
+	return s;
+}
libc/musl/src/string/strsignal.c
@@ -0,0 +1,116 @@
+#include <signal.h>
+#include <string.h>
+#include "locale_impl.h"
+
+#if (SIGHUP == 1) && (SIGINT == 2) && (SIGQUIT == 3) && (SIGILL == 4) \
+ && (SIGTRAP == 5) && (SIGABRT == 6) && (SIGBUS == 7) && (SIGFPE == 8) \
+ && (SIGKILL == 9) && (SIGUSR1 == 10) && (SIGSEGV == 11) && (SIGUSR2 == 12) \
+ && (SIGPIPE == 13) && (SIGALRM == 14) && (SIGTERM == 15) && (SIGSTKFLT == 16) \
+ && (SIGCHLD == 17) && (SIGCONT == 18) && (SIGSTOP == 19) && (SIGTSTP == 20) \
+ && (SIGTTIN == 21) && (SIGTTOU == 22) && (SIGURG == 23) && (SIGXCPU == 24) \
+ && (SIGXFSZ == 25) && (SIGVTALRM == 26) && (SIGPROF == 27) && (SIGWINCH == 28) \
+ && (SIGPOLL == 29) && (SIGPWR == 30) && (SIGSYS == 31)
+
+#define sigmap(x) x
+
+#else
+
+static const char map[] = {
+	[SIGHUP]    = 1,
+	[SIGINT]    = 2,
+	[SIGQUIT]   = 3,
+	[SIGILL]    = 4,
+	[SIGTRAP]   = 5,
+	[SIGABRT]   = 6,
+	[SIGBUS]    = 7,
+	[SIGFPE]    = 8,
+	[SIGKILL]   = 9,
+	[SIGUSR1]   = 10,
+	[SIGSEGV]   = 11,
+	[SIGUSR2]   = 12,
+	[SIGPIPE]   = 13,
+	[SIGALRM]   = 14,
+	[SIGTERM]   = 15,
+	[SIGSTKFLT] = 16,
+	[SIGCHLD]   = 17,
+	[SIGCONT]   = 18,
+	[SIGSTOP]   = 19,
+	[SIGTSTP]   = 20,
+	[SIGTTIN]   = 21,
+	[SIGTTOU]   = 22,
+	[SIGURG]    = 23,
+	[SIGXCPU]   = 24,
+	[SIGXFSZ]   = 25,
+	[SIGVTALRM] = 26,
+	[SIGPROF]   = 27,
+	[SIGWINCH]  = 28,
+	[SIGPOLL]   = 29,
+	[SIGPWR]    = 30,
+	[SIGSYS]    = 31
+};
+
+#define sigmap(x) ((x) >= sizeof map ? (x) : map[(x)])
+
+#endif
+
+static const char strings[] =
+	"Unknown signal\0"
+	"Hangup\0"
+	"Interrupt\0"
+	"Quit\0"
+	"Illegal instruction\0"
+	"Trace/breakpoint trap\0"
+	"Aborted\0"
+	"Bus error\0"
+	"Arithmetic exception\0"
+	"Killed\0"
+	"User defined signal 1\0"
+	"Segmentation fault\0"
+	"User defined signal 2\0"
+	"Broken pipe\0"
+	"Alarm clock\0"
+	"Terminated\0"
+	"Stack fault\0"
+	"Child process status\0"
+	"Continued\0"
+	"Stopped (signal)\0"
+	"Stopped\0"
+	"Stopped (tty input)\0"
+	"Stopped (tty output)\0"
+	"Urgent I/O condition\0"
+	"CPU time limit exceeded\0"
+	"File size limit exceeded\0"
+	"Virtual timer expired\0"
+	"Profiling timer expired\0"
+	"Window changed\0"
+	"I/O possible\0"
+	"Power failure\0"
+	"Bad system call\0"
+	"RT32"
+	"\0RT33\0RT34\0RT35\0RT36\0RT37\0RT38\0RT39\0RT40"
+	"\0RT41\0RT42\0RT43\0RT44\0RT45\0RT46\0RT47\0RT48"
+	"\0RT49\0RT50\0RT51\0RT52\0RT53\0RT54\0RT55\0RT56"
+	"\0RT57\0RT58\0RT59\0RT60\0RT61\0RT62\0RT63\0RT64"
+#if _NSIG > 65
+	"\0RT65\0RT66\0RT67\0RT68\0RT69\0RT70\0RT71\0RT72"
+	"\0RT73\0RT74\0RT75\0RT76\0RT77\0RT78\0RT79\0RT80"
+	"\0RT81\0RT82\0RT83\0RT84\0RT85\0RT86\0RT87\0RT88"
+	"\0RT89\0RT90\0RT91\0RT92\0RT93\0RT94\0RT95\0RT96"
+	"\0RT97\0RT98\0RT99\0RT100\0RT101\0RT102\0RT103\0RT104"
+	"\0RT105\0RT106\0RT107\0RT108\0RT109\0RT110\0RT111\0RT112"
+	"\0RT113\0RT114\0RT115\0RT116\0RT117\0RT118\0RT119\0RT120"
+	"\0RT121\0RT122\0RT123\0RT124\0RT125\0RT126\0RT127\0RT128"
+#endif
+	"";
+
+char *strsignal(int signum)
+{
+	const char *s = strings;
+
+	signum = sigmap(signum);
+	if (signum - 1U >= _NSIG-1) signum = 0;
+
+	for (; signum--; s++) for (; *s; s++);
+
+	return (char *)LCTRANS_CUR(s);
+}
libc/musl/src/string/strspn.c
@@ -0,0 +1,20 @@
+#include <string.h>
+
+#define BITOP(a,b,op) \
+ ((a)[(size_t)(b)/(8*sizeof *(a))] op (size_t)1<<((size_t)(b)%(8*sizeof *(a))))
+
+size_t strspn(const char *s, const char *c)
+{
+	const char *a = s;
+	size_t byteset[32/sizeof(size_t)] = { 0 };
+
+	if (!c[0]) return 0;
+	if (!c[1]) {
+		for (; *s == *c; s++);
+		return s-a;
+	}
+
+	for (; *c && BITOP(byteset, *(unsigned char *)c, |=); c++);
+	for (; *s && BITOP(byteset, *(unsigned char *)s, &); s++);
+	return s-a;
+}
libc/musl/src/string/strstr.c
@@ -0,0 +1,154 @@
+#include <string.h>
+#include <stdint.h>
+
+static char *twobyte_strstr(const unsigned char *h, const unsigned char *n)
+{
+	uint16_t nw = n[0]<<8 | n[1], hw = h[0]<<8 | h[1];
+	for (h++; *h && hw != nw; hw = hw<<8 | *++h);
+	return *h ? (char *)h-1 : 0;
+}
+
+static char *threebyte_strstr(const unsigned char *h, const unsigned char *n)
+{
+	uint32_t nw = n[0]<<24 | n[1]<<16 | n[2]<<8;
+	uint32_t hw = h[0]<<24 | h[1]<<16 | h[2]<<8;
+	for (h+=2; *h && hw != nw; hw = (hw|*++h)<<8);
+	return *h ? (char *)h-2 : 0;
+}
+
+static char *fourbyte_strstr(const unsigned char *h, const unsigned char *n)
+{
+	uint32_t nw = n[0]<<24 | n[1]<<16 | n[2]<<8 | n[3];
+	uint32_t hw = h[0]<<24 | h[1]<<16 | h[2]<<8 | h[3];
+	for (h+=3; *h && hw != nw; hw = hw<<8 | *++h);
+	return *h ? (char *)h-3 : 0;
+}
+
+#define MAX(a,b) ((a)>(b)?(a):(b))
+#define MIN(a,b) ((a)<(b)?(a):(b))
+
+#define BITOP(a,b,op) \
+ ((a)[(size_t)(b)/(8*sizeof *(a))] op (size_t)1<<((size_t)(b)%(8*sizeof *(a))))
+
+static char *twoway_strstr(const unsigned char *h, const unsigned char *n)
+{
+	const unsigned char *z;
+	size_t l, ip, jp, k, p, ms, p0, mem, mem0;
+	size_t byteset[32 / sizeof(size_t)] = { 0 };
+	size_t shift[256];
+
+	/* Computing length of needle and fill shift table */
+	for (l=0; n[l] && h[l]; l++)
+		BITOP(byteset, n[l], |=), shift[n[l]] = l+1;
+	if (n[l]) return 0; /* hit the end of h */
+
+	/* Compute maximal suffix */
+	ip = -1; jp = 0; k = p = 1;
+	while (jp+k<l) {
+		if (n[ip+k] == n[jp+k]) {
+			if (k == p) {
+				jp += p;
+				k = 1;
+			} else k++;
+		} else if (n[ip+k] > n[jp+k]) {
+			jp += k;
+			k = 1;
+			p = jp - ip;
+		} else {
+			ip = jp++;
+			k = p = 1;
+		}
+	}
+	ms = ip;
+	p0 = p;
+
+	/* And with the opposite comparison */
+	ip = -1; jp = 0; k = p = 1;
+	while (jp+k<l) {
+		if (n[ip+k] == n[jp+k]) {
+			if (k == p) {
+				jp += p;
+				k = 1;
+			} else k++;
+		} else if (n[ip+k] < n[jp+k]) {
+			jp += k;
+			k = 1;
+			p = jp - ip;
+		} else {
+			ip = jp++;
+			k = p = 1;
+		}
+	}
+	if (ip+1 > ms+1) ms = ip;
+	else p = p0;
+
+	/* Periodic needle? */
+	if (memcmp(n, n+p, ms+1)) {
+		mem0 = 0;
+		p = MAX(ms, l-ms-1) + 1;
+	} else mem0 = l-p;
+	mem = 0;
+
+	/* Initialize incremental end-of-haystack pointer */
+	z = h;
+
+	/* Search loop */
+	for (;;) {
+		/* Update incremental end-of-haystack pointer */
+		if (z-h < l) {
+			/* Fast estimate for MIN(l,63) */
+			size_t grow = l | 63;
+			const unsigned char *z2 = memchr(z, 0, grow);
+			if (z2) {
+				z = z2;
+				if (z-h < l) return 0;
+			} else z += grow;
+		}
+
+		/* Check last byte first; advance by shift on mismatch */
+		if (BITOP(byteset, h[l-1], &)) {
+			k = l-shift[h[l-1]];
+			if (k) {
+				if (k < mem) k = mem;
+				h += k;
+				mem = 0;
+				continue;
+			}
+		} else {
+			h += l;
+			mem = 0;
+			continue;
+		}
+
+		/* Compare right half */
+		for (k=MAX(ms+1,mem); n[k] && n[k] == h[k]; k++);
+		if (n[k]) {
+			h += k-ms;
+			mem = 0;
+			continue;
+		}
+		/* Compare left half */
+		for (k=ms+1; k>mem && n[k-1] == h[k-1]; k--);
+		if (k <= mem) return (char *)h;
+		h += p;
+		mem = mem0;
+	}
+}
+
+char *strstr(const char *h, const char *n)
+{
+	/* Return immediately on empty needle */
+	if (!n[0]) return (char *)h;
+
+	/* Use faster algorithms for short needles */
+	h = strchr(h, *n);
+	if (!h || !n[1]) return (char *)h;
+	if (!h[1]) return 0;
+	if (!n[2]) return twobyte_strstr((void *)h, (void *)n);
+	if (!h[2]) return 0;
+	if (!n[3]) return threebyte_strstr((void *)h, (void *)n);
+	if (!h[3]) return 0;
+	if (!n[4]) return fourbyte_strstr((void *)h, (void *)n);
+
+	return twoway_strstr((void *)h, (void *)n);
+}
libc/musl/src/string/strtok.c
@@ -0,0 +1,13 @@
+#include <string.h>
+
+char *strtok(char *restrict s, const char *restrict sep)
+{
+	static char *p;
+	if (!s && !(s = p)) return NULL;
+	s += strspn(s, sep);
+	if (!*s) return p = 0;
+	p = s + strcspn(s, sep);
+	if (*p) *p++ = 0;
+	else p = 0;
+	return s;
+}
libc/musl/src/string/strtok_r.c
@@ -0,0 +1,12 @@
+#include <string.h>
+
+char *strtok_r(char *restrict s, const char *restrict sep, char **restrict p)
+{
+	if (!s && !(s = *p)) return NULL;
+	s += strspn(s, sep);
+	if (!*s) return *p = 0;
+	*p = s + strcspn(s, sep);
+	if (**p) *(*p)++ = 0;
+	else *p = 0;
+	return s;
+}
libc/musl/src/string/strverscmp.c
@@ -0,0 +1,34 @@
+#define _GNU_SOURCE
+#include <ctype.h>
+#include <string.h>
+
+int strverscmp(const char *l0, const char *r0)
+{
+	const unsigned char *l = (const void *)l0;
+	const unsigned char *r = (const void *)r0;
+	size_t i, dp, j;
+	int z = 1;
+
+	/* Find maximal matching prefix and track its maximal digit
+	 * suffix and whether those digits are all zeros. */
+	for (dp=i=0; l[i]==r[i]; i++) {
+		int c = l[i];
+		if (!c) return 0;
+		if (!isdigit(c)) dp=i+1, z=1;
+		else if (c!='0') z=0;
+	}
+
+	if (l[dp]!='0' && r[dp]!='0') {
+		/* If we're not looking at a digit sequence that began
+		 * with a zero, longest digit string is greater. */
+		for (j=i; isdigit(l[j]); j++)
+			if (!isdigit(r[j])) return 1;
+		if (isdigit(r[j])) return -1;
+	} else if (z && dp<i && (isdigit(l[i]) || isdigit(r[i]))) {
+		/* Otherwise, if common prefix of digit sequence is
+		 * all zeros, digits order less than non-digits. */
+		return (unsigned char)(l[i]-'0') - (unsigned char)(r[i]-'0');
+	}
+
+	return l[i] - r[i];
+}
libc/musl/src/string/swab.c
@@ -0,0 +1,13 @@
+#include <unistd.h>
+
+void swab(const void *restrict _src, void *restrict _dest, ssize_t n)
+{
+	const char *src = _src;
+	char *dest = _dest;
+	for (; n>1; n-=2) {
+		dest[0] = src[1];
+		dest[1] = src[0];
+		dest += 2;
+		src += 2;
+	}
+}
libc/musl/src/string/wcpcpy.c
@@ -0,0 +1,6 @@
+#include <wchar.h>
+
+wchar_t *wcpcpy(wchar_t *restrict d, const wchar_t *restrict s)
+{
+	return wcscpy(d, s) + wcslen(s);
+}
libc/musl/src/string/wcpncpy.c
@@ -0,0 +1,6 @@
+#include <wchar.h>
+
+wchar_t *wcpncpy(wchar_t *restrict d, const wchar_t *restrict s, size_t n)
+{
+	return wcsncpy(d, s, n) + wcsnlen(s, n);
+}
libc/musl/src/string/wcscasecmp.c
@@ -0,0 +1,7 @@
+#include <wchar.h>
+#include <wctype.h>
+
+int wcscasecmp(const wchar_t *l, const wchar_t *r)
+{
+	return wcsncasecmp(l, r, -1);
+}
libc/musl/src/string/wcscasecmp_l.c
@@ -0,0 +1,6 @@
+#include <wchar.h>
+
+int wcscasecmp_l(const wchar_t *l, const wchar_t *r, locale_t locale)
+{
+	return wcscasecmp(l, r);
+}
libc/musl/src/string/wcscat.c
@@ -0,0 +1,7 @@
+#include <wchar.h>
+
+wchar_t *wcscat(wchar_t *restrict dest, const wchar_t *restrict src)
+{
+	wcscpy(dest + wcslen(dest), src);
+	return dest;
+}
libc/musl/src/string/wcschr.c
@@ -0,0 +1,8 @@
+#include <wchar.h>
+
+wchar_t *wcschr(const wchar_t *s, wchar_t c)
+{
+	if (!c) return (wchar_t *)s + wcslen(s);
+	for (; *s && *s != c; s++);
+	return *s ? (wchar_t *)s : 0;
+}
libc/musl/src/string/wcscmp.c
@@ -0,0 +1,7 @@
+#include <wchar.h>
+
+int wcscmp(const wchar_t *l, const wchar_t *r)
+{
+	for (; *l==*r && *l && *r; l++, r++);
+	return *l - *r;
+}
libc/musl/src/string/wcscpy.c
@@ -0,0 +1,8 @@
+#include <wchar.h>
+
+wchar_t *wcscpy(wchar_t *restrict d, const wchar_t *restrict s)
+{
+	wchar_t *a = d;
+	while ((*d++ = *s++));
+	return a;
+}
libc/musl/src/string/wcscspn.c
@@ -0,0 +1,10 @@
+#include <wchar.h>
+
+size_t wcscspn(const wchar_t *s, const wchar_t *c)
+{
+	const wchar_t *a;
+	if (!c[0]) return wcslen(s);
+	if (!c[1]) return (s=wcschr(a=s, *c)) ? s-a : wcslen(a);
+	for (a=s; *s && !wcschr(c, *s); s++);
+	return s-a;
+}
libc/musl/src/string/wcsdup.c
@@ -0,0 +1,10 @@
+#include <stdlib.h>
+#include <wchar.h>
+
+wchar_t *wcsdup(const wchar_t *s)
+{
+	size_t l = wcslen(s);
+	wchar_t *d = malloc((l+1)*sizeof(wchar_t));
+	if (!d) return NULL;
+	return wmemcpy(d, s, l+1);
+}
libc/musl/src/string/wcslen.c
@@ -0,0 +1,8 @@
+#include <wchar.h>
+
+size_t wcslen(const wchar_t *s)
+{
+	const wchar_t *a;
+	for (a=s; *s; s++);
+	return s-a;
+}
libc/musl/src/string/wcsncasecmp.c
@@ -0,0 +1,9 @@
+#include <wchar.h>
+#include <wctype.h>
+
+int wcsncasecmp(const wchar_t *l, const wchar_t *r, size_t n)
+{
+	if (!n--) return 0;
+	for (; *l && *r && n && (*l == *r || towlower(*l) == towlower(*r)); l++, r++, n--);
+	return towlower(*l) - towlower(*r);
+}
libc/musl/src/string/wcsncasecmp_l.c
@@ -0,0 +1,6 @@
+#include <wchar.h>
+
+int wcsncasecmp_l(const wchar_t *l, const wchar_t *r, size_t n, locale_t locale)
+{
+	return wcsncasecmp(l, r, n);
+}
libc/musl/src/string/wcsncat.c
@@ -0,0 +1,10 @@
+#include <wchar.h>
+
+wchar_t *wcsncat(wchar_t *restrict d, const wchar_t *restrict s, size_t n)
+{
+	wchar_t *a = d;
+	d += wcslen(d);
+	while (n && *s) n--, *d++ = *s++;
+	*d++ = 0;
+	return a;
+}
libc/musl/src/string/wcsncmp.c
@@ -0,0 +1,7 @@
+#include <wchar.h>
+
+int wcsncmp(const wchar_t *l, const wchar_t *r, size_t n)
+{
+	for (; n && *l==*r && *l && *r; n--, l++, r++);
+	return n ? *l - *r : 0;
+}
libc/musl/src/string/wcsncpy.c
@@ -0,0 +1,9 @@
+#include <wchar.h>
+
+wchar_t *wcsncpy(wchar_t *restrict d, const wchar_t *restrict s, size_t n)
+{
+	wchar_t *a = d;
+	while (n && *s) n--, *d++ = *s++;
+	wmemset(d, 0, n);
+	return a;
+}
libc/musl/src/string/wcsnlen.c
@@ -0,0 +1,8 @@
+#include <wchar.h>
+
+size_t wcsnlen(const wchar_t *s, size_t n)
+{
+	const wchar_t *z = wmemchr(s, 0, n);
+	if (z) n = z-s;
+	return n;
+}
libc/musl/src/string/wcspbrk.c
@@ -0,0 +1,7 @@
+#include <wchar.h>
+
+wchar_t *wcspbrk(const wchar_t *s, const wchar_t *b)
+{
+	s += wcscspn(s, b);
+	return *s ? (wchar_t *)s : NULL;
+}
libc/musl/src/string/wcsrchr.c
@@ -0,0 +1,8 @@
+#include <wchar.h>
+
+wchar_t *wcsrchr(const wchar_t *s, wchar_t c)
+{
+	const wchar_t *p;
+	for (p=s+wcslen(s); p>=s && *p!=c; p--);
+	return p>=s ? (wchar_t *)p : 0;
+}
libc/musl/src/string/wcsspn.c
@@ -0,0 +1,8 @@
+#include <wchar.h>
+
+size_t wcsspn(const wchar_t *s, const wchar_t *c)
+{
+	const wchar_t *a;
+	for (a=s; *s && wcschr(c, *s); s++);
+	return s-a;
+}
libc/musl/src/string/wcsstr.c
@@ -0,0 +1,105 @@
+#include <wchar.h>
+
+#define MAX(a,b) ((a)>(b)?(a):(b))
+#define MIN(a,b) ((a)<(b)?(a):(b))
+
+static wchar_t *twoway_wcsstr(const wchar_t *h, const wchar_t *n)
+{
+	const wchar_t *z;
+	size_t l, ip, jp, k, p, ms, p0, mem, mem0;
+
+	/* Computing length of needle */
+	for (l=0; n[l] && h[l]; l++);
+	if (n[l]) return 0; /* hit the end of h */
+
+	/* Compute maximal suffix */
+	ip = -1; jp = 0; k = p = 1;
+	while (jp+k<l) {
+		if (n[ip+k] == n[jp+k]) {
+			if (k == p) {
+				jp += p;
+				k = 1;
+			} else k++;
+		} else if (n[ip+k] > n[jp+k]) {
+			jp += k;
+			k = 1;
+			p = jp - ip;
+		} else {
+			ip = jp++;
+			k = p = 1;
+		}
+	}
+	ms = ip;
+	p0 = p;
+
+	/* And with the opposite comparison */
+	ip = -1; jp = 0; k = p = 1;
+	while (jp+k<l) {
+		if (n[ip+k] == n[jp+k]) {
+			if (k == p) {
+				jp += p;
+				k = 1;
+			} else k++;
+		} else if (n[ip+k] < n[jp+k]) {
+			jp += k;
+			k = 1;
+			p = jp - ip;
+		} else {
+			ip = jp++;
+			k = p = 1;
+		}
+	}
+	if (ip+1 > ms+1) ms = ip;
+	else p = p0;
+
+	/* Periodic needle? */
+	if (wmemcmp(n, n+p, ms+1)) {
+		mem0 = 0;
+		p = MAX(ms, l-ms-1) + 1;
+	} else mem0 = l-p;
+	mem = 0;
+
+	/* Initialize incremental end-of-haystack pointer */
+	z = h;
+
+	/* Search loop */
+	for (;;) {
+		/* Update incremental end-of-haystack pointer */
+		if (z-h < l) {
+			/* Fast estimate for MIN(l,63) */
+			size_t grow = l | 63;
+			const wchar_t *z2 = wmemchr(z, 0, grow);
+			if (z2) {
+				z = z2;
+				if (z-h < l) return 0;
+			} else z += grow;
+		}
+
+		/* Compare right half */
+		for (k=MAX(ms+1,mem); n[k] && n[k] == h[k]; k++);
+		if (n[k]) {
+			h += k-ms;
+			mem = 0;
+			continue;
+		}
+		/* Compare left half */
+		for (k=ms+1; k>mem && n[k-1] == h[k-1]; k--);
+		if (k <= mem) return (wchar_t *)h;
+		h += p;
+		mem = mem0;
+	}
+}
+
+wchar_t *wcsstr(const wchar_t *restrict h, const wchar_t *restrict n)
+{
+	/* Return immediately on empty needle or haystack */
+	if (!n[0]) return (wchar_t *)h;
+	if (!h[0]) return 0;
+
+	/* Use faster algorithms for short needles */
+	h = wcschr(h, *n);
+	if (!h || !n[1]) return (wchar_t *)h;
+	if (!h[1]) return 0;
+
+	return twoway_wcsstr(h, n);
+}
libc/musl/src/string/wcstok.c
@@ -0,0 +1,12 @@
+#include <wchar.h>
+
+wchar_t *wcstok(wchar_t *restrict s, const wchar_t *restrict sep, wchar_t **restrict p)
+{
+	if (!s && !(s = *p)) return NULL;
+	s += wcsspn(s, sep);
+	if (!*s) return *p = 0;
+	*p = s + wcscspn(s, sep);
+	if (**p) *(*p)++ = 0;
+	else *p = 0;
+	return s;
+}
libc/musl/src/string/wcswcs.c
@@ -0,0 +1,6 @@
+#include <wchar.h>
+
+wchar_t *wcswcs(const wchar_t *haystack, const wchar_t *needle)
+{
+	return wcsstr(haystack, needle);
+}
libc/musl/src/string/wmemchr.c
@@ -0,0 +1,7 @@
+#include <wchar.h>
+
+wchar_t *wmemchr(const wchar_t *s, wchar_t c, size_t n)
+{
+	for (; n && *s != c; n--, s++);
+	return n ? (wchar_t *)s : 0;
+}
libc/musl/src/string/wmemcmp.c
@@ -0,0 +1,7 @@
+#include <wchar.h>
+
+int wmemcmp(const wchar_t *l, const wchar_t *r, size_t n)
+{
+	for (; n && *l==*r; n--, l++, r++);
+	return n ? *l-*r : 0;
+}
libc/musl/src/string/wmemcpy.c
@@ -0,0 +1,8 @@
+#include <wchar.h>
+
+wchar_t *wmemcpy(wchar_t *restrict d, const wchar_t *restrict s, size_t n)
+{
+	wchar_t *a = d;
+	while (n--) *d++ = *s++;
+	return a;
+}
libc/musl/src/string/wmemmove.c
@@ -0,0 +1,13 @@
+#include <wchar.h>
+#include <stdint.h>
+
+wchar_t *wmemmove(wchar_t *d, const wchar_t *s, size_t n)
+{
+	wchar_t *d0 = d;
+	if (d == s) return d;
+	if ((uintptr_t)d-(uintptr_t)s < n * sizeof *d)
+		while (n--) d[n] = s[n];
+	else
+		while (n--) *d++ = *s++;
+	return d0;
+}
libc/musl/src/string/wmemset.c
@@ -0,0 +1,8 @@
+#include <wchar.h>
+
+wchar_t *wmemset(wchar_t *d, wchar_t c, size_t n)
+{
+	wchar_t *ret = d;
+	while (n--) *d++ = c;
+	return ret;
+}
libc/musl/src/temp/__randname.c
@@ -0,0 +1,18 @@
+#include <time.h>
+#include <stdint.h>
+
+/* This assumes that a check for the
+   template size has already been made */
+char *__randname(char *template)
+{
+	int i;
+	struct timespec ts;
+	unsigned long r;
+
+	__clock_gettime(CLOCK_REALTIME, &ts);
+	r = ts.tv_nsec*65537 ^ (uintptr_t)&ts / 16 + (uintptr_t)template;
+	for (i=0; i<6; i++, r>>=5)
+		template[i] = 'A'+(r&15)+(r&16)*2;
+
+	return template;
+}
libc/musl/src/temp/mkdtemp.c
@@ -0,0 +1,23 @@
+#include <string.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <sys/stat.h>
+
+char *mkdtemp(char *template)
+{
+	size_t l = strlen(template);
+	int retries = 100;
+
+	if (l<6 || memcmp(template+l-6, "XXXXXX", 6)) {
+		errno = EINVAL;
+		return 0;
+	}
+
+	do {
+		__randname(template+l-6);
+		if (!mkdir(template, 0700)) return template;
+	} while (--retries && errno == EEXIST);
+
+	memcpy(template+l-6, "XXXXXX", 6);
+	return 0;
+}
libc/musl/src/temp/mkostemp.c
@@ -0,0 +1,9 @@
+#define _BSD_SOURCE
+#include <stdlib.h>
+
+int mkostemp(char *template, int flags)
+{
+	return __mkostemps(template, 0, flags);
+}
+
+weak_alias(mkostemp, mkostemp64);
libc/musl/src/temp/mkostemps.c
@@ -0,0 +1,29 @@
+#define _BSD_SOURCE
+#include <stdlib.h>
+#include <string.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <errno.h>
+
+int __mkostemps(char *template, int len, int flags)
+{
+	size_t l = strlen(template);
+	if (l<6 || len>l-6 || memcmp(template+l-len-6, "XXXXXX", 6)) {
+		errno = EINVAL;
+		return -1;
+	}
+
+	flags -= flags & O_ACCMODE;
+	int fd, retries = 100;
+	do {
+		__randname(template+l-len-6);
+		if ((fd = open(template, flags | O_RDWR | O_CREAT | O_EXCL, 0600))>=0)
+			return fd;
+	} while (--retries && errno == EEXIST);
+
+	memcpy(template+l-len-6, "XXXXXX", 6);
+	return -1;
+}
+
+weak_alias(__mkostemps, mkostemps);
+weak_alias(__mkostemps, mkostemps64);
libc/musl/src/temp/mkstemp.c
@@ -0,0 +1,8 @@
+#include <stdlib.h>
+
+int mkstemp(char *template)
+{
+	return __mkostemps(template, 0, 0);
+}
+
+weak_alias(mkstemp, mkstemp64);
libc/musl/src/temp/mkstemps.c
@@ -0,0 +1,9 @@
+#define _BSD_SOURCE
+#include <stdlib.h>
+
+int mkstemps(char *template, int len)
+{
+	return __mkostemps(template, len, 0);
+}
+
+weak_alias(mkstemps, mkstemps64);
libc/musl/src/temp/mktemp.c
@@ -0,0 +1,30 @@
+#define _GNU_SOURCE
+#include <string.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <sys/stat.h>
+
+char *mktemp(char *template)
+{
+	size_t l = strlen(template);
+	int retries = 100;
+	struct stat st;
+
+	if (l < 6 || memcmp(template+l-6, "XXXXXX", 6)) {
+		errno = EINVAL;
+		*template = 0;
+		return template;
+	}
+
+	do {
+		__randname(template+l-6);
+		if (stat(template, &st)) {
+			if (errno != ENOENT) *template = 0;
+			return template;
+		}
+	} while (--retries);
+
+	*template = 0;
+	errno = EEXIST;
+	return template;
+}
libc/musl/src/termios/cfgetospeed.c
@@ -0,0 +1,13 @@
+#define _BSD_SOURCE
+#include <termios.h>
+#include <sys/ioctl.h>
+
+speed_t cfgetospeed(const struct termios *tio)
+{
+	return tio->c_cflag & CBAUD;
+}
+
+speed_t cfgetispeed(const struct termios *tio)
+{
+	return cfgetospeed(tio);
+}
libc/musl/src/termios/cfmakeraw.c
@@ -0,0 +1,13 @@
+#define _GNU_SOURCE
+#include <termios.h>
+
+void cfmakeraw(struct termios *t)
+{
+	t->c_iflag &= ~(IGNBRK|BRKINT|PARMRK|ISTRIP|INLCR|IGNCR|ICRNL|IXON);
+	t->c_oflag &= ~OPOST;
+	t->c_lflag &= ~(ECHO|ECHONL|ICANON|ISIG|IEXTEN);
+	t->c_cflag &= ~(CSIZE|PARENB);
+	t->c_cflag |= CS8;
+	t->c_cc[VMIN] = 1;
+	t->c_cc[VTIME] = 0;
+}
libc/musl/src/termios/cfsetospeed.c
@@ -0,0 +1,22 @@
+#define _BSD_SOURCE
+#include <termios.h>
+#include <sys/ioctl.h>
+#include <errno.h>
+
+int cfsetospeed(struct termios *tio, speed_t speed)
+{
+	if (speed & ~CBAUD) {
+		errno = EINVAL;
+		return -1;
+	}
+	tio->c_cflag &= ~CBAUD;
+	tio->c_cflag |= speed;
+	return 0;
+}
+
+int cfsetispeed(struct termios *tio, speed_t speed)
+{
+	return speed ? cfsetospeed(tio, speed) : 0;
+}
+
+weak_alias(cfsetospeed, cfsetspeed);
libc/musl/src/termios/tcdrain.c
@@ -0,0 +1,8 @@
+#include <termios.h>
+#include <sys/ioctl.h>
+#include "syscall.h"
+
+int tcdrain(int fd)
+{
+	return syscall_cp(SYS_ioctl, fd, TCSBRK, 1);
+}
libc/musl/src/termios/tcflow.c
@@ -0,0 +1,7 @@
+#include <termios.h>
+#include <sys/ioctl.h>
+
+int tcflow(int fd, int action)
+{
+	return ioctl(fd, TCXONC, action);
+}
libc/musl/src/termios/tcflush.c
@@ -0,0 +1,7 @@
+#include <termios.h>
+#include <sys/ioctl.h>
+
+int tcflush(int fd, int queue)
+{
+	return ioctl(fd, TCFLSH, queue);
+}
libc/musl/src/termios/tcgetattr.c
@@ -0,0 +1,9 @@
+#include <termios.h>
+#include <sys/ioctl.h>
+
+int tcgetattr(int fd, struct termios *tio)
+{
+	if (ioctl(fd, TCGETS, tio))
+		return -1;
+	return 0;
+}
libc/musl/src/termios/tcgetsid.c
@@ -0,0 +1,10 @@
+#include <termios.h>
+#include <sys/ioctl.h>
+
+pid_t tcgetsid(int fd)
+{
+	int sid;
+	if (ioctl(fd, TIOCGSID, &sid) < 0)
+		return -1;
+	return sid;
+}
libc/musl/src/termios/tcsendbreak.c
@@ -0,0 +1,8 @@
+#include <termios.h>
+#include <sys/ioctl.h>
+
+int tcsendbreak(int fd, int dur)
+{
+	/* nonzero duration is implementation-defined, so ignore it */
+	return ioctl(fd, TCSBRK, 0);
+}
libc/musl/src/termios/tcsetattr.c
@@ -0,0 +1,12 @@
+#include <termios.h>
+#include <sys/ioctl.h>
+#include <errno.h>
+
+int tcsetattr(int fd, int act, const struct termios *tio)
+{
+	if (act < 0 || act > 2) {
+		errno = EINVAL;
+		return -1;
+	}
+	return ioctl(fd, TCSETS+act, tio);
+}
libc/musl/src/thread/aarch64/__set_thread_area.s
@@ -0,0 +1,7 @@
+.global __set_thread_area
+.hidden __set_thread_area
+.type   __set_thread_area,@function
+__set_thread_area:
+	msr tpidr_el0,x0
+	mov w0,#0
+	ret
libc/musl/src/thread/aarch64/__unmapself.s
@@ -0,0 +1,7 @@
+.global __unmapself
+.type   __unmapself,%function
+__unmapself:
+	mov x8,#215 // SYS_munmap
+	svc 0
+	mov x8,#93 // SYS_exit
+	svc 0
libc/musl/src/thread/aarch64/clone.s
@@ -0,0 +1,30 @@
+// __clone(func, stack, flags, arg, ptid, tls, ctid)
+//         x0,   x1,    w2,    x3,  x4,   x5,  x6
+
+// syscall(SYS_clone, flags, stack, ptid, tls, ctid)
+//         x8,        x0,    x1,    x2,   x3,  x4
+
+.global __clone
+.hidden __clone
+.type   __clone,%function
+__clone:
+	// align stack and save func,arg
+	and x1,x1,#-16
+	stp x0,x3,[x1,#-16]!
+
+	// syscall
+	uxtw x0,w2
+	mov x2,x4
+	mov x3,x5
+	mov x4,x6
+	mov x8,#220 // SYS_clone
+	svc #0
+
+	cbz x0,1f
+	// parent
+	ret
+	// child
+1:	ldp x1,x0,[sp],#16
+	blr x1
+	mov x8,#93 // SYS_exit
+	svc #0
libc/musl/src/thread/aarch64/syscall_cp.s
@@ -0,0 +1,32 @@
+// __syscall_cp_asm(&self->cancel, nr, u, v, w, x, y, z)
+//                  x0             x1  x2 x3 x4 x5 x6 x7
+
+// syscall(nr, u, v, w, x, y, z)
+//         x8  x0 x1 x2 x3 x4 x5
+
+.global __cp_begin
+.hidden __cp_begin
+.global __cp_end
+.hidden __cp_end
+.global __cp_cancel
+.hidden __cp_cancel
+.hidden __cancel
+.global __syscall_cp_asm
+.hidden __syscall_cp_asm
+.type __syscall_cp_asm,%function
+__syscall_cp_asm:
+__cp_begin:
+	ldr w0,[x0]
+	cbnz w0,__cp_cancel
+	mov x8,x1
+	mov x0,x2
+	mov x1,x3
+	mov x2,x4
+	mov x3,x5
+	mov x4,x6
+	mov x5,x7
+	svc 0
+__cp_end:
+	ret
+__cp_cancel:
+	b __cancel
libc/musl/src/thread/arm/__aeabi_read_tp.s
@@ -0,0 +1,10 @@
+.syntax unified
+.global __aeabi_read_tp
+.type __aeabi_read_tp,%function
+__aeabi_read_tp:
+	ldr r0,1f
+	add r0,r0,pc
+	ldr r0,[r0]
+2:	bx r0
+	.align 2
+1:	.word __a_gettp_ptr - 2b
libc/musl/src/thread/arm/__set_thread_area.c
@@ -0,0 +1,52 @@
+#include <stdint.h>
+#include <elf.h>
+#include "pthread_impl.h"
+#include "libc.h"
+
+#define HWCAP_TLS (1 << 15)
+
+extern hidden const unsigned char
+	__a_barrier_oldkuser[], __a_barrier_v6[], __a_barrier_v7[],
+	__a_cas_v6[], __a_cas_v7[],
+	__a_gettp_cp15[];
+
+#define __a_barrier_kuser 0xffff0fa0
+#define __a_barrier_oldkuser (uintptr_t)__a_barrier_oldkuser
+#define __a_barrier_v6 (uintptr_t)__a_barrier_v6
+#define __a_barrier_v7 (uintptr_t)__a_barrier_v7
+
+#define __a_cas_kuser 0xffff0fc0
+#define __a_cas_v6 (uintptr_t)__a_cas_v6
+#define __a_cas_v7 (uintptr_t)__a_cas_v7
+
+#define __a_gettp_kuser 0xffff0fe0
+#define __a_gettp_cp15 (uintptr_t)__a_gettp_cp15
+
+extern hidden uintptr_t __a_barrier_ptr, __a_cas_ptr, __a_gettp_ptr;
+
+int __set_thread_area(void *p)
+{
+#if !__ARM_ARCH_7A__ && !__ARM_ARCH_7R__ && __ARM_ARCH < 7
+	if (__hwcap & HWCAP_TLS) {
+		size_t *aux;
+		__a_cas_ptr = __a_cas_v7;
+		__a_barrier_ptr = __a_barrier_v7;
+		for (aux=libc.auxv; *aux; aux+=2) {
+			if (*aux != AT_PLATFORM) continue;
+			const char *s = (void *)aux[1];
+			if (s[0]!='v' || s[1]!='6' || s[2]-'0'<10u) break;
+			__a_cas_ptr = __a_cas_v6;
+			__a_barrier_ptr = __a_barrier_v6;
+			break;
+		}
+	} else {
+		int ver = *(int *)0xffff0ffc;
+		__a_gettp_ptr = __a_gettp_kuser;
+		__a_cas_ptr = __a_cas_kuser;
+		__a_barrier_ptr = __a_barrier_kuser;
+		if (ver < 2) a_crash();
+		if (ver < 3) __a_barrier_ptr = __a_barrier_oldkuser;
+	}
+#endif
+	return __syscall(0xf0005, p);
+}
libc/musl/src/thread/arm/__unmapself.s
@@ -0,0 +1,9 @@
+.syntax unified
+.text
+.global __unmapself
+.type   __unmapself,%function
+__unmapself:
+	mov r7,#91
+	svc 0
+	mov r7,#1
+	svc 0
libc/musl/src/thread/arm/atomics.s
@@ -0,0 +1,106 @@
+.syntax unified
+.text
+
+.global __a_barrier_dummy
+.hidden __a_barrier_dummy
+.type __a_barrier_dummy,%function
+__a_barrier_dummy:
+	bx lr
+
+.global __a_barrier_oldkuser
+.hidden __a_barrier_oldkuser
+.type __a_barrier_oldkuser,%function
+__a_barrier_oldkuser:
+	push {r0,r1,r2,r3,ip,lr}
+	mov r1,r0
+	mov r2,sp
+	ldr ip,=0xffff0fc0
+	mov lr,pc
+	mov pc,ip
+	pop {r0,r1,r2,r3,ip,lr}
+	bx lr
+
+.global __a_barrier_v6
+.hidden __a_barrier_v6
+.type __a_barrier_v6,%function
+__a_barrier_v6:
+	.arch armv6t2
+	mcr p15,0,r0,c7,c10,5
+	bx lr
+
+.global __a_barrier_v7
+.hidden __a_barrier_v7
+.type __a_barrier_v7,%function
+__a_barrier_v7:
+	.arch armv7-a
+	dmb ish
+	bx lr
+
+.global __a_cas_dummy
+.hidden __a_cas_dummy
+.type __a_cas_dummy,%function
+__a_cas_dummy:
+	mov r3,r0
+	ldr r0,[r2]
+	subs r0,r3,r0
+	streq r1,[r2]
+	bx lr
+
+.global __a_cas_v6
+.hidden __a_cas_v6
+.type __a_cas_v6,%function
+__a_cas_v6:
+	.arch armv6t2
+	mov r3,r0
+	mcr p15,0,r0,c7,c10,5
+1:	ldrex r0,[r2]
+	subs r0,r3,r0
+	strexeq r0,r1,[r2]
+	teqeq r0,#1
+	beq 1b
+	mcr p15,0,r0,c7,c10,5
+	bx lr
+
+.global __a_cas_v7
+.hidden __a_cas_v7
+.type __a_cas_v7,%function
+__a_cas_v7:
+	.arch armv7-a
+	mov r3,r0
+	dmb ish
+1:	ldrex r0,[r2]
+	subs r0,r3,r0
+	strexeq r0,r1,[r2]
+	teqeq r0,#1
+	beq 1b
+	dmb ish
+	bx lr
+
+.global __a_gettp_cp15
+.hidden __a_gettp_cp15
+.type __a_gettp_cp15,%function
+__a_gettp_cp15:
+	mrc p15,0,r0,c13,c0,3
+	bx lr
+
+/* Tag this file with minimum ISA level so as not to affect linking. */
+.object_arch armv4t
+.eabi_attribute 6,2
+
+.data
+.align 2
+
+.global __a_barrier_ptr
+.hidden __a_barrier_ptr
+__a_barrier_ptr:
+	.word __a_barrier_dummy
+
+.global __a_cas_ptr
+.hidden __a_cas_ptr
+__a_cas_ptr:
+	.word __a_cas_dummy
+
+.global __a_gettp_ptr
+.hidden __a_gettp_ptr
+__a_gettp_ptr:
+	.word __a_gettp_cp15
libc/musl/src/thread/arm/clone.s
@@ -0,0 +1,32 @@
+.syntax unified
+.text
+.global __clone
+.hidden __clone
+.type   __clone,%function
+__clone:
+	stmfd sp!,{r4,r5,r6,r7}
+	mov r7,#120
+	mov r6,r3
+	mov r5,r0
+	mov r0,r2
+	and r1,r1,#-16
+	ldr r2,[sp,#16]
+	ldr r3,[sp,#20]
+	ldr r4,[sp,#24]
+	svc 0
+	tst r0,r0
+	beq 1f
+	ldmfd sp!,{r4,r5,r6,r7}
+	bx lr
+
+1:	mov r0,r6
+	tst r5,#1
+	bne 1f
+	mov lr,pc
+	mov pc,r5
+2:	mov r7,#1
+	svc 0
+
+1:	mov lr,pc
+	bx r5
+	b 2b
libc/musl/src/thread/arm/syscall_cp.s
@@ -0,0 +1,29 @@
+.syntax unified
+.global __cp_begin
+.hidden __cp_begin
+.global __cp_end
+.hidden __cp_end
+.global __cp_cancel
+.hidden __cp_cancel
+.hidden __cancel
+.global __syscall_cp_asm
+.hidden __syscall_cp_asm
+.type __syscall_cp_asm,%function
+__syscall_cp_asm:
+	mov ip,sp
+	stmfd sp!,{r4,r5,r6,r7,lr}
+__cp_begin:
+	ldr r0,[r0]
+	cmp r0,#0
+	blne __cp_cancel
+	mov r7,r1
+	mov r0,r2
+	mov r1,r3
+	ldmfd ip,{r2,r3,r4,r5,r6}
+	svc 0
+__cp_end:
+	ldmfd sp!,{r4,r5,r6,r7,lr}
+	bx lr
+__cp_cancel:
+	ldmfd sp!,{r4,r5,r6,r7,lr}
+	b __cancel
libc/musl/src/thread/i386/__set_thread_area.s
@@ -0,0 +1,46 @@
+.text
+.global __set_thread_area
+.hidden __set_thread_area
+.type   __set_thread_area,@function
+__set_thread_area:
+	push %ebx
+	push $0x51
+	push $0xfffff
+	push 16(%esp)
+	call 1f
+1:	addl $4f-1b,(%esp)
+	pop %ecx
+	mov (%ecx),%edx
+	push %edx
+	mov %esp,%ebx
+	xor %eax,%eax
+	mov $243,%al
+	int $128
+	testl %eax,%eax
+	jnz 2f
+	movl (%esp),%edx
+	movl %edx,(%ecx)
+	leal 3(,%edx,8),%edx
+3:	movw %dx,%gs
+1:
+	addl $16,%esp
+	popl %ebx
+	ret
+2:
+	mov %ebx,%ecx
+	xor %ebx,%ebx
+	xor %edx,%edx
+	mov %ebx,(%esp)
+	mov $1,%bl
+	mov $16,%dl
+	mov $123,%al
+	int $128
+	testl %eax,%eax
+	jnz 1b
+	mov $7,%dl
+	inc %al
+	jmp 3b
+
+.data
+	.align 4
+4:	.long -1
libc/musl/src/thread/i386/__unmapself.s
@@ -0,0 +1,11 @@
+.text
+.global __unmapself
+.type   __unmapself,@function
+__unmapself:
+	movl $91,%eax
+	movl 4(%esp),%ebx
+	movl 8(%esp),%ecx
+	int $128
+	xorl %ebx,%ebx
+	movl $1,%eax
+	int $128
libc/musl/src/thread/i386/clone.s
@@ -0,0 +1,49 @@
+.text
+.global __clone
+.hidden __clone
+.type   __clone,@function
+__clone:
+	push %ebp
+	mov %esp,%ebp
+	push %ebx
+	push %esi
+	push %edi
+
+	xor %eax,%eax
+	push $0x51
+	mov %gs,%ax
+	push $0xfffff
+	shr $3,%eax
+	push 28(%ebp)
+	push %eax
+	mov $120,%al
+
+	mov 12(%ebp),%ecx
+	mov 16(%ebp),%ebx
+	and $-16,%ecx
+	sub $16,%ecx
+	mov 20(%ebp),%edi
+	mov %edi,(%ecx)
+	mov 24(%ebp),%edx
+	mov %esp,%esi
+	mov 32(%ebp),%edi
+	mov 8(%ebp),%ebp
+	int $128
+	test %eax,%eax
+	jnz 1f
+
+	mov %ebp,%eax
+	xor %ebp,%ebp
+	call *%eax
+	mov %eax,%ebx
+	xor %eax,%eax
+	inc %eax
+	int $128
+	hlt
+
+1:	add $16,%esp
+	pop %edi
+	pop %esi
+	pop %ebx
+	pop %ebp
+	ret
libc/musl/src/thread/i386/syscall_cp.s
@@ -0,0 +1,41 @@
+.text
+.global __cp_begin
+.hidden __cp_begin
+.global __cp_end
+.hidden __cp_end
+.global __cp_cancel
+.hidden __cp_cancel
+.hidden __cancel
+.global __syscall_cp_asm
+.hidden __syscall_cp_asm
+.type   __syscall_cp_asm,@function
+__syscall_cp_asm:
+	mov 4(%esp),%ecx
+	pushl %ebx
+	pushl %esi
+	pushl %edi
+	pushl %ebp
+__cp_begin:
+	movl (%ecx),%eax
+	testl %eax,%eax
+	jnz __cp_cancel
+	movl 24(%esp),%eax
+	movl 28(%esp),%ebx
+	movl 32(%esp),%ecx
+	movl 36(%esp),%edx
+	movl 40(%esp),%esi
+	movl 44(%esp),%edi
+	movl 48(%esp),%ebp
+	int $128
+__cp_end:
+	popl %ebp
+	popl %edi
+	popl %esi
+	popl %ebx
+	ret
+__cp_cancel:
+	popl %ebp
+	popl %edi
+	popl %esi
+	popl %ebx
+	jmp __cancel
libc/musl/src/thread/i386/tls.s
@@ -0,0 +1,17 @@
+.text
+.global ___tls_get_addr
+.type ___tls_get_addr,@function
+___tls_get_addr:
+	mov %gs:4,%edx
+	mov (%eax),%ecx
+	cmp %ecx,(%edx)
+	jc 1f
+	mov 4(%eax),%eax
+	add (%edx,%ecx,4),%eax
+	ret
+1:	push %eax
+.weak __tls_get_new
+.hidden __tls_get_new
+	call __tls_get_new
+	pop %edx
+	ret
libc/musl/src/thread/m68k/__m68k_read_tp.s
@@ -0,0 +1,8 @@
+.text
+.global __m68k_read_tp
+.type   __m68k_read_tp,@function
+__m68k_read_tp:
+	move.l #333,%d0
+	trap #0
+	move.l %d0,%a0
+	rts
libc/musl/src/thread/m68k/clone.s
@@ -0,0 +1,25 @@
+.text
+.global __clone
+.hidden __clone
+.type   __clone,@function
+__clone:
+	movem.l %d2-%d5,-(%sp)
+	move.l #120,%d0
+	move.l 28(%sp),%d1
+	move.l 24(%sp),%d2
+	and.l #-16,%d2
+	move.l 36(%sp),%d3
+	move.l 44(%sp),%d4
+	move.l 40(%sp),%d5
+	move.l 20(%sp),%a0
+	move.l 32(%sp),%a1
+	trap #0
+	tst.l %d0
+	beq 1f
+	movem.l (%sp)+,%d2-%d5
+	rts
+1:	move.l %a1,-(%sp)
+	jsr (%a0)
+	move.l #1,%d0
+	trap #0
+	clr.b 0
libc/musl/src/thread/m68k/syscall_cp.s
@@ -0,0 +1,26 @@
+.text
+.global __cp_begin
+.hidden __cp_begin
+.global __cp_end
+.hidden __cp_end
+.global __cp_cancel
+.hidden __cp_cancel
+.hidden __cancel
+.global __syscall_cp_asm
+.hidden __syscall_cp_asm
+.type   __syscall_cp_asm,@function
+__syscall_cp_asm:
+	movem.l %d2-%d5,-(%sp)
+	movea.l 20(%sp),%a0
+__cp_begin:
+	move.l (%a0),%d0
+	bne __cp_cancel
+	movem.l 24(%sp),%d0-%d5/%a0
+	trap #0
+__cp_end:
+	movem.l (%sp)+,%d2-%d5
+	rts
+__cp_cancel:
+	movem.l (%sp)+,%d2-%d5
+	move.l __cancel-.-8,%a1
+	jmp (%pc,%a1)
libc/musl/src/thread/microblaze/__set_thread_area.s
@@ -0,0 +1,7 @@
+.global __set_thread_area
+.hidden __set_thread_area
+.type   __set_thread_area,@function
+__set_thread_area:
+	ori      r21, r5, 0
+	rtsd     r15, 8
+	ori      r3, r0, 0
libc/musl/src/thread/microblaze/__unmapself.s
@@ -0,0 +1,8 @@
+.global __unmapself
+.type   __unmapself,@function
+__unmapself:
+	ori     r12, r0, 91
+	brki    r14, 0x8
+	ori     r12, r0, 1
+	brki    r14, 0x8
+	nop
libc/musl/src/thread/microblaze/clone.s
@@ -0,0 +1,30 @@
+.global __clone
+.hidden __clone
+.type   __clone,@function
+
+# r5, r6, r7, r8, r9, r10, stack
+# fn, st, fl, ar, pt, tl, ct
+# fl, st, __, pt, ct, tl
+
+__clone:
+	andi    r6, r6, -16
+	addi    r6, r6, -16
+	swi     r5, r6, 0
+	swi     r8, r6, 4
+
+	ori     r5, r7, 0
+	ori     r8, r9, 0
+	lwi     r9, r1, 28
+	ori     r12, r0, 120
+
+	brki    r14, 8
+	beqi	r3, 1f
+	rtsd    r15, 8
+	nop
+
+1:	lwi     r3, r1, 0
+	lwi     r5, r1, 4
+	brald   r15, r3
+	nop
+	ori     r12, r0, 1
+	brki    r14, 8
libc/musl/src/thread/microblaze/syscall_cp.s
@@ -0,0 +1,27 @@
+.global __cp_begin
+.hidden __cp_begin
+.global __cp_end
+.hidden __cp_end
+.global __cp_cancel
+.hidden __cp_cancel
+.hidden __cancel
+.global __syscall_cp_asm
+.hidden __syscall_cp_asm
+.type   __syscall_cp_asm,@function
+__syscall_cp_asm:
+__cp_begin:
+	lwi     r5, r5, 0
+	bnei    r5, __cp_cancel
+	addi    r12, r6, 0
+	add     r5, r7, r0
+	add     r6, r8, r0
+	add     r7, r9, r0
+	add     r8, r10, r0
+	lwi     r9, r1, 28
+	lwi     r10, r1, 32
+	brki    r14, 0x8
+__cp_end:
+	rtsd    r15, 8
+	nop
+__cp_cancel:
+	bri     __cancel
libc/musl/src/thread/mips/__unmapself.s
@@ -0,0 +1,10 @@
+.set noreorder
+.global __unmapself
+.type   __unmapself,@function
+__unmapself:
+	move $sp, $25
+	li $2, 4091
+	syscall
+	li $4, 0
+	li $2, 4001
+	syscall
libc/musl/src/thread/mips/clone.s
@@ -0,0 +1,36 @@
+.set noreorder
+.global __clone
+.hidden __clone
+.type   __clone,@function
+__clone:
+	# Save function pointer and argument pointer on new thread stack
+	and $5, $5, -8
+	subu $5, $5, 16
+	sw $4, 0($5)
+	sw $7, 4($5)
+	# Shuffle (fn,sp,fl,arg,ptid,tls,ctid) to (fl,sp,ptid,tls,ctid)
+	move $4, $6
+	lw $6, 16($sp)
+	lw $7, 20($sp)
+	lw $9, 24($sp)
+	subu $sp, $sp, 16
+	sw $9, 16($sp)
+	li $2, 4120
+	syscall
+	beq $7, $0, 1f
+	nop
+	addu $sp, $sp, 16
+	jr $ra
+	subu $2, $0, $2
+1:	beq $2, $0, 1f
+	nop
+	addu $sp, $sp, 16
+	jr $ra
+	nop
+1:	lw $25, 0($sp)
+	lw $4, 4($sp)
+	jalr $25
+	nop
+	move $4, $2
+	li $2, 4001
+	syscall
libc/musl/src/thread/mips/syscall_cp.s
@@ -0,0 +1,53 @@
+.set    noreorder
+
+.global __cp_begin
+.hidden __cp_begin
+.type   __cp_begin,@function
+.global __cp_end
+.hidden __cp_end
+.type   __cp_end,@function
+.global __cp_cancel
+.hidden __cp_cancel
+.type   __cp_cancel,@function
+.hidden __cancel
+.global __syscall_cp_asm
+.hidden __syscall_cp_asm
+.type   __syscall_cp_asm,@function
+__syscall_cp_asm:
+	subu    $sp, $sp, 32
+__cp_begin:
+	lw      $4, 0($4)
+	bne     $4, $0, __cp_cancel
+	move    $2, $5
+	move    $4, $6
+	move    $5, $7
+	lw      $6, 48($sp)
+	lw      $7, 52($sp)
+	lw      $8, 56($sp)
+	lw      $9, 60($sp)
+	lw      $10,64($sp)
+	sw      $8, 16($sp)
+	sw      $9, 20($sp)
+	sw      $10,24($sp)
+	sw      $2, 28($sp)
+	lw      $2, 28($sp)
+	syscall
+__cp_end:
+	beq     $7, $0, 1f
+	addu    $sp, $sp, 32
+	subu    $2, $0, $2
+1:	jr      $ra
+	nop
+
+__cp_cancel:
+	move    $2, $ra
+	bal     1f
+	addu    $sp, $sp, 32
+	.gpword .
+	.gpword __cancel
+1:	lw      $3, ($ra)
+	subu    $3, $ra, $3
+	lw      $25, 4($ra)
+	addu    $25, $25, $3
+	jr      $25
+	move    $ra, $2
libc/musl/src/thread/mips64/__unmapself.s
@@ -0,0 +1,9 @@
+.set	noreorder
+.global	__unmapself
+.type	__unmapself, @function
+__unmapself:
+	li	$2, 5011
+	syscall
+	li	$4, 0
+	li	$2, 5058
+	syscall
libc/musl/src/thread/mips64/clone.s
@@ -0,0 +1,34 @@
+.set	noreorder
+.global	__clone
+.hidden __clone
+.type	__clone,@function
+__clone:
+	# Save function pointer and argument pointer on new thread stack
+	and	$5, $5, -16	# aligning stack to double word
+	dsubu	$5, $5, 16
+	sd	$4, 0($5)	# save function pointer
+	sd	$7, 8($5)	# save argument pointer
+
+	# Shuffle (fn,sp,fl,arg,ptid,tls,ctid) to (fl,sp,ptid,tls,ctid)
+	# sys_clone(u64 flags, u64 ustack_base, u64 parent_tidptr, u64 child_tidptr, u64 tls)
+	move	$4, $6
+	move	$6, $8
+	move	$7, $9
+	move	$8, $10
+	li	$2, 5055
+	syscall
+	beq	$7, $0, 1f
+	nop
+	jr	$ra
+	dsubu	$2, $0, $2
+1:	beq	$2, $0, 1f
+	nop
+	jr	$ra
+	nop
+1:	ld	$25, 0($sp)	# function pointer
+	ld	$4, 8($sp)	# argument pointer
+	jalr	$25		# call the user's function
+	nop
+	move 	$4, $2
+	li	$2, 5058
+	syscall
libc/musl/src/thread/mips64/syscall_cp.s
@@ -0,0 +1,52 @@
+.set	noreorder
+.global	__cp_begin
+.hidden	__cp_begin
+.type	__cp_begin,@function
+.global	__cp_end
+.hidden	__cp_end
+.type	__cp_end,@function
+.global	__cp_cancel
+.hidden	__cp_cancel
+.type	__cp_cancel,@function
+.global	__cp_cancel_data
+.hidden	__cp_cancel_data
+.type	__cp_cancel_data,@function
+.hidden	__cancel
+.global	__syscall_cp_asm
+.hidden	__syscall_cp_asm
+.type	__syscall_cp_asm,@function
+__syscall_cp_asm:
+__cp_begin:
+	lw	$4, 0($4)
+	bne	$4, $0, __cp_cancel
+	move	$2, $5
+	move	$4, $6
+	move	$5, $7
+	move	$6, $8
+	move	$7, $9
+	move	$8, $10
+	move	$9, $11
+	ld	$10, 0($sp)
+	syscall
+__cp_end:
+	beq	$7, $0, 1f
+	nop
+	dsubu	$2, $0, $2
+1:	jr	$ra
+	nop
+
+	# if cancellation flag is 1 then call __cancel
+__cp_cancel:
+	move	$2, $ra
+.align 8
+	bal	1f
+	nop
+__cp_cancel_data:
+	.gpdword __cp_cancel_data
+	.gpdword __cancel
+1:	ld	$3, ($ra)
+	dsubu	$3, $ra, $3
+	ld	$25, 8($ra)
+	daddu	$25, $25, $3
+	jr	$25
+	move	$ra, $2
libc/musl/src/thread/mipsn32/__unmapself.s
@@ -0,0 +1,9 @@
+.set	noreorder
+.global	__unmapself
+.type	__unmapself,@function
+__unmapself:
+	li	$2, 6011
+	syscall
+	li	$4, 0
+	li	$2, 6058
+	syscall
libc/musl/src/thread/mipsn32/clone.s
@@ -0,0 +1,34 @@
+.set	noreorder
+.global	__clone
+.hidden __clone
+.type	__clone,@function
+__clone:
+	# Save function pointer and argument pointer on new thread stack
+	and	$5, $5, -16	# aligning stack to double word
+	subu	$5, $5, 16
+	sw	$4, 0($5)	# save function pointer
+	sw	$7, 4($5)	# save argument pointer
+
+	# Shuffle (fn,sp,fl,arg,ptid,tls,ctid) to (fl,sp,ptid,tls,ctid)
+	# sys_clone(u64 flags, u64 ustack_base, u64 parent_tidptr, u64 child_tidptr, u64 tls)
+	move	$4, $6
+	move	$6, $8
+	move	$7, $9
+	move	$8, $10
+	li	$2, 6055
+	syscall
+	beq	$7, $0, 1f
+	nop
+	jr	$ra
+	subu	$2, $0, $2
+1:	beq	$2, $0, 1f
+	nop
+	jr	$ra
+	nop
+1:	lw	$25, 0($sp)	# function pointer
+	lw	$4, 4($sp)	# argument pointer
+	jalr	$25		# call the user's function
+	nop
+	move 	$4, $2
+	li	$2, 6058
+	syscall
libc/musl/src/thread/mipsn32/syscall_cp.s
@@ -0,0 +1,51 @@
+.set	noreorder
+.global	__cp_begin
+.hidden	__cp_begin
+.type	__cp_begin,@function
+.global	__cp_end
+.hidden	__cp_end
+.type	__cp_end,@function
+.global	__cp_cancel
+.hidden	__cp_cancel
+.type	__cp_cancel,@function
+.global	__cp_cancel_data
+.hidden	__cp_cancel_data
+.type	__cp_cancel_data,@function
+.hidden	__cancel
+.global	__syscall_cp_asm
+.hidden	__syscall_cp_asm
+.type	__syscall_cp_asm,@function
+__syscall_cp_asm:
+__cp_begin:
+	lw	$4, 0($4)
+	bne	$4, $0, __cp_cancel
+	move	$2, $5
+	move	$4, $6
+	move	$5, $7
+	move	$6, $8
+	move	$7, $9
+	move	$8, $10
+	move	$9, $11
+	lw	$10, 0($sp)
+	syscall
+__cp_end:
+	beq	$7, $0, 1f
+	nop
+	subu	$2, $0, $2
+1:	jr	$ra
+	nop
+
+	# if cancellation flag is 1 then call __cancel
+__cp_cancel:
+	move	$2, $ra
+	bal	1f
+	nop
+__cp_cancel_data:
+	.gpword __cp_cancel_data
+	.gpword __cancel
+1:	lw	$3, 0($ra)
+	subu	$3, $ra, $3
+	lw	$25, 4($ra)
+	addu	$25, $25, $3
+	jr	$25
+	move	$ra, $2
libc/musl/src/thread/or1k/__set_thread_area.s
@@ -0,0 +1,7 @@
+.global __set_thread_area
+.hidden __set_thread_area
+.type   __set_thread_area,@function
+__set_thread_area:
+	l.ori	r10, r3, 0
+	l.jr	r9
+	 l.ori	r11, r0, 0
libc/musl/src/thread/or1k/__unmapself.s
@@ -0,0 +1,8 @@
+.global __unmapself
+.type   __unmapself,@function
+__unmapself:
+	l.ori	r11, r0, 215 /* __NR_munmap */
+	l.sys	1
+	l.ori	r3, r0, 0
+	l.ori	r11, r0, 93 /* __NR_exit */
+	l.sys	1
libc/musl/src/thread/or1k/clone.s
@@ -0,0 +1,31 @@
+/* int clone(fn, stack, flags, arg, ptid, tls, ctid)
+ *           r3  r4     r5     r6   sp+0  sp+4 sp+8
+ * sys_clone(flags, stack, ptid, ctid, tls)
+ */
+.global __clone
+.hidden __clone
+.type   __clone,@function
+__clone:
+	l.addi	r4, r4, -8
+	l.sw	0(r4), r3
+	l.sw	4(r4), r6
+	/* (fn, st, fl, ar, pt, tl, ct) => (fl, st, pt, ct, tl) */
+	l.ori	r3, r5, 0
+	l.lwz	r5, 0(r1)
+	l.lwz	r6, 8(r1)
+	l.lwz	r7, 4(r1)
+	l.ori	r11, r0, 220 /* __NR_clone */
+	l.sys	1
+
+	l.sfeqi	r11, 0
+	l.bf	1f
+	 l.nop
+	l.jr	r9
+	 l.nop
+
+1:	l.lwz	r11, 0(r1)
+	l.jalr	r11
+	 l.lwz	r3, 4(r1)
+
+	l.ori	r11, r0, 93 /* __NR_exit */
+	l.sys	1
libc/musl/src/thread/or1k/syscall_cp.s
@@ -0,0 +1,29 @@
+.global __cp_begin
+.hidden __cp_begin
+.global __cp_end
+.hidden __cp_end
+.global __cp_cancel
+.hidden __cp_cancel
+.hidden __cancel
+.global __syscall_cp_asm
+.hidden __syscall_cp_asm
+.type   __syscall_cp_asm,@function
+__syscall_cp_asm:
+__cp_begin:
+	l.lwz	r3, 0(r3)
+	l.sfeqi	r3, 0
+	l.bnf	__cp_cancel
+	 l.ori	r11, r4, 0
+	l.ori	r3, r5, 0
+	l.ori	r4, r6, 0
+	l.ori	r5, r7, 0
+	l.ori	r6, r8, 0
+	l.lwz	r7, 0(r1)
+	l.lwz	r8, 4(r1)
+	l.sys	1
+__cp_end:
+	l.jr	r9
+	 l.nop
+__cp_cancel:
+	l.j	__cancel
+	 l.nop
libc/musl/src/thread/powerpc/__set_thread_area.s
@@ -0,0 +1,12 @@
+.text
+.global __set_thread_area
+.hidden __set_thread_area
+.type   __set_thread_area, %function
+__set_thread_area:
+	# mov pointer in reg3 into r2
+	mr 2, 3
+	# put 0 into return reg
+	li 3, 0
+	# return
+	blr
+
libc/musl/src/thread/powerpc/__unmapself.s
@@ -0,0 +1,9 @@
+	.text
+	.global __unmapself
+	.type   __unmapself,%function
+__unmapself:
+	li      0, 91 # __NR_munmap
+	sc
+	li      0, 1 #__NR_exit
+	sc
+	blr
libc/musl/src/thread/powerpc/clone.s
@@ -0,0 +1,73 @@
+.text
+.global __clone
+.hidden __clone
+.type __clone, %function
+__clone:
+# int clone(fn, stack, flags, arg, ptid, tls, ctid)
+#            a  b       c     d     e    f    g
+#            3  4       5     6     7    8    9
+# pseudo C code:
+# tid = syscall(SYS_clone,c,b,e,f,g);
+# if (!tid) syscall(SYS_exit, a(d));
+# return tid;
+
+# SYS_clone = 120
+# SYS_exit = 1
+
+# store non-volatile regs r30, r31 on stack in order to put our
+# start func and its arg there
+stwu 30, -16(1)
+stw 31, 4(1)
+
+# save r3 (func) into r30, and r6(arg) into r31
+mr 30, 3
+mr 31, 6
+
+# create initial stack frame for new thread
+clrrwi 4, 4, 4
+li 0, 0
+stwu 0, -16(4)
+
+#move c into first arg
+mr 3, 5
+#mr 4, 4
+mr 5, 7
+mr 6, 8
+mr 7, 9
+
+# move syscall number into r0    
+li 0, 120
+
+sc
+
+# check for syscall error
+bns+ 1f # jump to label 1 if no summary overflow.
+#else
+neg 3, 3 #negate the result (errno)
+1:
+# compare sc result with 0
+cmpwi cr7, 3, 0
+
+# if not 0, jump to end
+bne cr7, 2f
+
+#else: we're the child
+#call funcptr: move arg (d) into r3
+mr 3, 31
+#move r30 (funcptr) into CTR reg
+mtctr 30
+# call CTR reg
+bctrl
+# mov SYS_exit into r0 (the exit param is already in r3)
+li 0, 1
+sc
+
+2:
+
+# restore stack
+lwz 30, 0(1)
+lwz 31, 4(1)
+addi 1, 1, 16
+
+blr
+
libc/musl/src/thread/powerpc/syscall_cp.s
@@ -0,0 +1,59 @@
+.global __cp_begin
+.hidden __cp_begin
+.global __cp_end
+.hidden __cp_end
+.global __cp_cancel
+.hidden __cp_cancel
+.hidden __cancel
+.global __syscall_cp_asm
+.hidden __syscall_cp_asm
+
+#r0: volatile. may be modified during linkage.
+#r1: stack frame: 16 byte alignment.
+#r2: tls/thread pointer on pp32
+#r3,r4: return values, first args
+#r5-r10: args
+#r11-r12: volatile. may be modified during linkage
+#r13: "small data area" pointer
+#r14 - r30: local vars
+#r31: local or environment pointer
+
+#r1, r14-31: belong to the caller, must be saved and restored
+#r0, r3-r12, ctr, xer: volatile, not preserved
+#r0,r11,r12: may be altered by cross-module call, 
+#"a func cannot depend on that these regs have the values placed by the caller"
+
+#the fields CR2,CR2,CR4 of the cond reg must be preserved
+#LR (link reg) shall contain the funcs return address
+	.text
+	.type   __syscall_cp_asm,%function
+__syscall_cp_asm:
+	# at enter: r3 = pointer to self->cancel, r4: syscall no, r5: first arg, r6: 2nd, r7: 3rd, r8: 4th, r9: 5th, r10: 6th
+__cp_begin:
+	# r3 holds first argument, its a pointer to self->cancel. 
+	# we must compare the dereferenced value with 0 and jump to __cancel if its not
+	
+	lwz 0, 0(3) #deref pointer into r0
+	
+	cmpwi cr7, 0, 0 #compare r0 with 0, store result in cr7. 
+	beq+ cr7, 1f #jump to label 1 if r0 was 0
+	
+	b __cp_cancel #else call cancel
+1:
+	#ok, the cancel flag was not set
+	# syscall: number goes to r0, the rest 3-8
+	mr      0, 4                  # put the system call number into r0
+	mr      3, 5                  # Shift the arguments: arg1
+	mr      4, 6                  # arg2
+	mr      5, 7                  # arg3
+	mr      6, 8                  # arg4
+	mr      7, 9                  # arg5
+	mr      8, 10                  # arg6
+	sc
+__cp_end:
+	bnslr+ # return if no summary overflow. 
+	#else negate result.
+	neg 3, 3
+	blr
+__cp_cancel:
+	b __cancel
libc/musl/src/thread/powerpc64/__set_thread_area.s
@@ -0,0 +1,9 @@
+.text
+.global __set_thread_area
+.hidden __set_thread_area
+.type   __set_thread_area, %function
+__set_thread_area:
+	mr 13, 3
+	li  3, 0
+	blr
+
libc/musl/src/thread/powerpc64/__unmapself.s
@@ -0,0 +1,9 @@
+	.text
+	.global __unmapself
+	.type   __unmapself,%function
+__unmapself:
+	li      0, 91 # __NR_munmap
+	sc
+	li      0, 1 #__NR_exit
+	sc
+	blr
libc/musl/src/thread/powerpc64/clone.s
@@ -0,0 +1,48 @@
+.text
+.global __clone
+.hidden __clone
+.type __clone, %function
+__clone:
+	# int clone(fn, stack, flags, arg, ptid, tls, ctid)
+	#            a  b       c     d     e    f    g
+	#            3  4       5     6     7    8    9
+	# pseudo C code:
+	# tid = syscall(SYS_clone,c,b,e,f,g);
+	# if (!tid) syscall(SYS_exit, a(d));
+	# return tid;
+
+	# create initial stack frame for new thread
+	clrrdi 4, 4, 4
+	li     0, 0
+	stdu   0,-32(4)
+
+	# save fn and arg to child stack
+	std    3,  8(4)
+	std    6, 16(4)
+
+	# shuffle args into correct registers and call SYS_clone
+	mr    3, 5
+	#mr   4, 4
+	mr    5, 7
+	mr    6, 8
+	mr    7, 9
+	li    0, 120  # SYS_clone = 120
+	sc
+
+	# if error, negate return (errno)
+	bns+  1f
+	neg   3, 3
+
+1:	# if we're the parent, return
+	cmpwi cr7, 3, 0
+	bnelr cr7
+
+	# we're the child. call fn(arg)
+	ld     3, 16(1)
+	ld    12,  8(1)
+	mtctr 12
+	bctrl
+
+	# call SYS_exit. exit code is already in r3 from fn return value
+	li    0, 1    # SYS_exit = 1
+	sc
libc/musl/src/thread/powerpc64/syscall_cp.s
@@ -0,0 +1,44 @@
+	.global __cp_begin
+	.hidden __cp_begin
+	.global __cp_end
+	.hidden __cp_end
+	.global __cp_cancel
+	.hidden __cp_cancel
+	.hidden __cancel
+	.global __syscall_cp_asm
+	.hidden __syscall_cp_asm
+	.text
+	.type   __syscall_cp_asm,%function
+__syscall_cp_asm:
+	# at enter: r3 = pointer to self->cancel, r4: syscall no, r5: first arg, r6: 2nd, r7: 3rd, r8: 4th, r9: 5th, r10: 6th
+__cp_begin:
+	# if (self->cancel) goto __cp_cancel
+	lwz   0, 0(3)
+	cmpwi cr7, 0, 0
+	bne-  cr7, __cp_cancel
+
+	# make syscall
+	mr    0,  4
+	mr    3,  5
+	mr    4,  6
+	mr    5,  7
+	mr    6,  8
+	mr    7,  9
+	mr    8, 10
+	sc
+
+__cp_end:
+	# return error ? -r3 : r3
+	bnslr+
+	neg 3, 3
+	blr
+
+__cp_cancel:
+	mflr 0
+	bl 1f
+	.long .TOC.-.
+1:	mflr 3
+	lwa 2, 0(3)
+	add 2, 2, 3
+	mtlr 0
+	b __cancel
libc/musl/src/thread/s390x/__set_thread_area.s
@@ -0,0 +1,10 @@
+.text
+.global __set_thread_area
+.hidden __set_thread_area
+.type   __set_thread_area, %function
+__set_thread_area:
+	sar  %a1, %r2
+	srlg %r2, %r2, 32
+	sar  %a0, %r2
+	lghi %r2, 0
+	br   %r14
libc/musl/src/thread/s390x/__tls_get_offset.s
@@ -0,0 +1,17 @@
+	.global __tls_get_offset
+	.type __tls_get_offset,%function
+__tls_get_offset:
+	stmg  %r14, %r15, 112(%r15)
+	aghi  %r15, -160
+
+	la    %r2, 0(%r2, %r12)
+	brasl %r14, __tls_get_addr
+
+	ear   %r1, %a0
+	sllg  %r1, %r1, 32
+	ear   %r1, %a1
+
+	sgr   %r2, %r1
+
+	lmg   %r14, %r15, 272(%r15)
+	br    %r14
libc/musl/src/thread/s390x/__unmapself.s
@@ -0,0 +1,6 @@
+.text
+.global __unmapself
+.type   __unmapself, @function
+__unmapself:
+	svc 91 # SYS_munmap
+	svc 1  # SYS_exit
libc/musl/src/thread/s390x/clone.s
@@ -0,0 +1,48 @@
+.text
+.global __clone
+.hidden __clone
+.type __clone, %function
+__clone:
+	# int clone(
+	#    fn,      a = r2
+	#    stack,   b = r3
+	#    flags,   c = r4
+	#    arg,     d = r5
+	#    ptid,    e = r6
+	#    tls,     f = *(r15+160)
+	#    ctid)    g = *(r15+168)
+	#
+	# pseudo C code:
+	# tid = syscall(SYS_clone,b,c,e,g,f);
+	# if (!tid) syscall(SYS_exit, a(d));
+	# return tid;
+
+	# create initial stack frame for new thread
+	nill %r3, 0xfff8
+	aghi %r3, -160
+	lghi %r0, 0
+	stg  %r0, 0(%r3)
+
+	# save fn and arg to child stack
+	stg  %r2,  8(%r3)
+	stg  %r5, 16(%r3)
+
+	# shuffle args into correct registers and call SYS_clone
+	lgr  %r2, %r3
+	lgr  %r3, %r4
+	lgr  %r4, %r6
+	lg   %r5, 168(%r15)
+	lg   %r6, 160(%r15)
+	svc  120
+
+	# if error or if we're the parent, return
+	ltgr %r2, %r2
+	bnzr %r14
+
+	# we're the child. call fn(arg)
+	lg   %r1,  8(%r15)
+	lg   %r2, 16(%r15)
+	basr %r14, %r1
+
+	# call SYS_exit. exit code is already in r2 from fn return value
+	svc  1
libc/musl/src/thread/s390x/syscall_cp.s
@@ -0,0 +1,32 @@
+	.global __cp_begin
+	.hidden __cp_begin
+	.global __cp_end
+	.hidden __cp_end
+	.global __cp_cancel
+	.hidden __cp_cancel
+	.hidden __cancel
+	.global __syscall_cp_asm
+	.hidden __syscall_cp_asm
+	.text
+	.type   __syscall_cp_asm,%function
+__syscall_cp_asm:
+__cp_begin:
+	icm %r2, 15, 0(%r2)
+	jne __cp_cancel
+
+	stg %r7, 56(%r15)
+	lgr %r1, %r3
+	lgr %r2, %r4
+	lgr %r3, %r5
+	lgr %r4, %r6
+	lg  %r5, 160(%r15)
+	lg  %r6, 168(%r15)
+	lg  %r7, 176(%r15)
+	svc 0
+
+__cp_end:
+	lg  %r7, 56(%r15)
+	br  %r14
+
+__cp_cancel:
+	jg  __cancel
libc/musl/src/thread/sh/__set_thread_area.c
@@ -0,0 +1,37 @@
+#include "pthread_impl.h"
+#include "libc.h"
+#include <elf.h>
+
+/* Also perform sh-specific init */
+
+#define CPU_HAS_LLSC 0x0040
+#define CPU_HAS_CAS_L 0x0400
+
+extern hidden const char __sh_cas_gusa[], __sh_cas_llsc[], __sh_cas_imask[], __sh_cas_cas_l[];
+
+hidden const void *__sh_cas_ptr;
+
+hidden unsigned __sh_nommu;
+
+int __set_thread_area(void *p)
+{
+	size_t *aux;
+	__asm__ __volatile__ ( "ldc %0, gbr" : : "r"(p) : "memory" );
+#ifndef __SH4A__
+	__sh_cas_ptr = __sh_cas_gusa;
+#if !defined(__SH3__) && !defined(__SH4__)
+	for (aux=libc.auxv; *aux; aux+=2) {
+		if (*aux != AT_PLATFORM) continue;
+		const char *s = (void *)aux[1];
+		if (s[0]!='s' || s[1]!='h' || s[2]!='2' || s[3]-'0'<10u) break;
+		__sh_cas_ptr = __sh_cas_imask;
+		__sh_nommu = 1;
+	}
+#endif
+	if (__hwcap & CPU_HAS_CAS_L)
+		__sh_cas_ptr = __sh_cas_cas_l;
+	else if (__hwcap & CPU_HAS_LLSC)
+		__sh_cas_ptr = __sh_cas_llsc;
+#endif
+	return 0;
+}
libc/musl/src/thread/sh/__unmapself.c
@@ -0,0 +1,24 @@
+#include "pthread_impl.h"
+
+hidden void __unmapself_sh_mmu(void *, size_t);
+hidden void __unmapself_sh_nommu(void *, size_t);
+
+#if !defined(__SH3__) && !defined(__SH4__)
+#define __unmapself __unmapself_sh_nommu
+#include "dynlink.h"
+#undef CRTJMP
+#define CRTJMP(pc,sp) __asm__ __volatile__( \
+	"mov.l @%0+,r0 ; mov.l @%0,r12 ; jmp @r0 ; mov %1,r15" \
+	: : "r"(pc), "r"(sp) : "r0", "memory" )
+#include "../__unmapself.c"
+#undef __unmapself
+extern hidden unsigned __sh_nommu;
+#else
+#define __sh_nommu 0
+#endif
+
+void __unmapself(void *base, size_t size)
+{
+	if (__sh_nommu) __unmapself_sh_nommu(base, size);
+	else __unmapself_sh_mmu(base, size);
+}
libc/musl/src/thread/sh/__unmapself_mmu.s
@@ -0,0 +1,23 @@
+.text
+.global __unmapself_sh_mmu
+.hidden __unmapself_sh_mmu
+.type   __unmapself_sh_mmu, @function
+__unmapself_sh_mmu:
+	mov   #91, r3  ! SYS_munmap
+	trapa #31
+
+	or    r0, r0
+	or    r0, r0
+	or    r0, r0
+	or    r0, r0
+	or    r0, r0
+
+	mov   #1, r3   ! SYS_exit
+	mov   #0, r4
+	trapa #31
+
+	or    r0, r0
+	or    r0, r0
+	or    r0, r0
+	or    r0, r0
+	or    r0, r0
libc/musl/src/thread/sh/atomics.s
@@ -0,0 +1,65 @@
+/* Contract for all versions is same as cas.l r2,r3,@r0
+ * pr and r1 are also clobbered (by jsr & r1 as temp).
+ * r0,r2,r4-r15 must be preserved.
+ * r3 contains result (==r2 iff cas succeeded). */
+
+	.align 2
+.global __sh_cas_gusa
+.hidden __sh_cas_gusa
+__sh_cas_gusa:
+	mov.l r5,@-r15
+	mov.l r4,@-r15
+	mov r0,r4
+	mova 1f,r0
+	mov r15,r1
+	mov #(0f-1f),r15
+0:	mov.l @r4,r5
+	cmp/eq r5,r2
+	bf 1f
+	mov.l r3,@r4
+1:	mov r1,r15
+	mov r5,r3
+	mov r4,r0
+	mov.l @r15+,r4
+	rts
+	 mov.l @r15+,r5
+
+.global __sh_cas_llsc
+.hidden __sh_cas_llsc
+__sh_cas_llsc:
+	mov r0,r1
+	.word 0x00ab /* synco */
+0:	.word 0x0163 /* movli.l @r1,r0 */
+	cmp/eq r0,r2
+	bf 1f
+	mov r3,r0
+	.word 0x0173 /* movco.l r0,@r1 */
+	bf 0b
+	mov r2,r0
+1:	.word 0x00ab /* synco */
+	mov r0,r3
+	rts
+	 mov r1,r0
+
+.global __sh_cas_imask
+.hidden __sh_cas_imask
+__sh_cas_imask:
+	mov r0,r1
+	stc sr,r0
+	mov.l r0,@-r15
+	or #0xf0,r0
+	ldc r0,sr
+	mov.l @r1,r0
+	cmp/eq r0,r2
+	bf 1f
+	mov.l r3,@r1
+1:	ldc.l @r15+,sr
+	mov r0,r3
+	rts
+	 mov r1,r0
+
+.global __sh_cas_cas_l
+.hidden __sh_cas_cas_l
+__sh_cas_cas_l:
+	rts
+	 .word 0x2323 /* cas.l r2,r3,@r0 */
libc/musl/src/thread/sh/clone.s
@@ -0,0 +1,54 @@
+.text
+.global __clone
+.hidden __clone
+.type   __clone, @function
+__clone:
+! incoming: fn stack flags arg ptid tls      ctid
+!           r4 r5    r6    r7  @r15 @(4,r15) @(8,r15)
+
+	mov   #-16, r0
+	and   r0, r5
+
+	mov   r4, r1         ! r1 = fn
+	mov   r7, r2         ! r2 = arg
+
+	mov   #120,     r3   ! r3 = __NR_clone
+	mov   r6,       r4   ! r4 = flags
+	!mov  r5,       r5   ! r5 = stack
+	mov.l @r15,     r6   ! r6 = ptid
+	mov.l @(8,r15), r7   ! r7 = ctid
+	mov.l @(4,r15), r0   ! r0 = tls
+	trapa #31
+
+	or r0, r0
+	or r0, r0
+	or r0, r0
+	or r0, r0
+	or r0, r0
+
+	cmp/eq #0, r0
+	bt     1f
+
+	! we are the parent, return
+	rts
+	 nop
+
+1:	! we are the child, call fn(arg)
+	mov.l  1f, r0
+	mov    r1, r5
+	bsrf   r0
+	 mov    r2, r4
+
+2:	mov   #1, r3   ! __NR_exit
+	mov   r0, r4
+	trapa #31
+
+	or   r0, r0
+	or   r0, r0
+	or   r0, r0
+	or   r0, r0
+	or   r0, r0
+
+.align 2
+.hidden __shcall
+1:	.long __shcall@PCREL+(.-2b)
libc/musl/src/thread/sh/syscall_cp.s
@@ -0,0 +1,45 @@
+.text
+.global __cp_begin
+.hidden __cp_begin
+.global __cp_end
+.hidden __cp_end
+.global __cp_cancel
+.hidden __cp_cancel
+.hidden __cancel
+.global __syscall_cp_asm
+.hidden __syscall_cp_asm
+.type   __syscall_cp_asm, @function
+__syscall_cp_asm:
+
+__cp_begin:
+	mov.l @r4, r4
+	tst   r4, r4
+	bf    __cp_cancel
+	mov   r5, r3
+	mov   r6, r4
+	mov   r7, r5
+	mov.l @r15, r6
+	mov.l @(4,r15), r7
+	mov.l @(8,r15), r0
+	mov.l @(12,r15), r1
+	trapa #31
+
+__cp_end:
+	! work around hardware bug
+	or   r0, r0
+	or   r0, r0
+	or   r0, r0
+	or   r0, r0
+	or   r0, r0
+
+	rts
+	 nop
+
+__cp_cancel:
+	mov.l 2f, r0
+	braf  r0
+	 nop
+1:
+
+.align 2
+2:	.long __cancel@PCREL-(1b-.)
libc/musl/src/thread/x32/__set_thread_area.s
@@ -0,0 +1,11 @@
+/* Copyright 2011-2012 Nicholas J. Kain, licensed under standard MIT license */
+.text
+.global __set_thread_area
+.hidden __set_thread_area
+.type __set_thread_area,@function
+__set_thread_area:
+	mov %edi,%esi           /* shift for syscall */
+	movl $0x1002,%edi       /* SET_FS register */
+	movl $0x4000009e,%eax          /* set fs segment to */
+	syscall                 /* arch_prctl(SET_FS, arg)*/
+	ret
libc/musl/src/thread/x32/__unmapself.s
@@ -0,0 +1,10 @@
+/* Copyright 2011-2012 Nicholas J. Kain, licensed under standard MIT license */
+.text
+.global __unmapself
+.type   __unmapself,@function
+__unmapself:
+	movl $0x4000000b,%eax   /* SYS_munmap */
+	syscall         /* munmap(arg2,arg3) */
+	xor %rdi,%rdi   /* exit() args: always return success */
+	movl $0x4000003c,%eax   /* SYS_exit */
+	syscall         /* exit(0) */
libc/musl/src/thread/x32/clone.s
@@ -0,0 +1,26 @@
+.text
+.global __clone
+.hidden __clone
+.type   __clone,@function
+__clone:
+	movl $0x40000038,%eax /* SYS_clone */
+	mov %rdi,%r11
+	mov %rdx,%rdi
+	mov %r8,%rdx
+	mov %r9,%r8
+	mov 8(%rsp),%r10
+	mov %r11,%r9
+	and $-16,%rsi
+	sub $8,%rsi
+	mov %rcx,(%rsi)
+	syscall
+	test %eax,%eax
+	jnz 1f
+	xor %ebp,%ebp
+	pop %rdi
+	call *%r9
+	mov %eax,%edi
+	movl $0x4000003c,%eax /* SYS_exit */
+	syscall
+	hlt
+1:	ret
libc/musl/src/thread/x32/syscall_cp.s
@@ -0,0 +1,31 @@
+.text
+.global __cp_begin
+.hidden __cp_begin
+.global __cp_end
+.hidden __cp_end
+.global __cp_cancel
+.hidden __cp_cancel
+.hidden __cancel
+.global __syscall_cp_internal
+.hidden __syscall_cp_internal
+.type   __syscall_cp_internal,@function
+__syscall_cp_internal:
+
+__cp_begin:
+	mov (%rdi),%eax
+	test %eax,%eax
+	jnz __cp_cancel
+	mov %rdi,%r11
+	mov %rsi,%rax
+	mov %rdx,%rdi
+	mov %rcx,%rsi
+	mov %r8,%rdx
+	mov %r9,%r10
+	mov 8(%rsp),%r8
+	mov 16(%rsp),%r9
+	mov %r11,8(%rsp)
+	syscall
+__cp_end:
+	ret
+__cp_cancel:
+	jmp __cancel
libc/musl/src/thread/x32/syscall_cp_fixup.c
@@ -0,0 +1,39 @@
+#include <sys/syscall.h>
+#include <features.h>
+
+hidden long __syscall_cp_internal(volatile void*, long long, long long,
+                                  long long, long long, long long,
+                                  long long, long long);
+
+struct __timespec { long long tv_sec; long tv_nsec; };
+struct __timespec_kernel { long long tv_sec; long long tv_nsec; };
+#define __tsc(X) ((struct __timespec*)(unsigned long)(X))
+#define __fixup(X) do { if(X) { \
+	ts->tv_sec = __tsc(X)->tv_sec; \
+	ts->tv_nsec = __tsc(X)->tv_nsec; \
+	(X) = (unsigned long)ts; } } while(0)
+
+hidden long __syscall_cp_asm (volatile void * foo, long long n, long long a1,
+                              long long a2, long long a3, long long a4,
+                              long long a5, long long a6)
+{
+	struct __timespec_kernel ts[1];
+	switch (n) {
+	case SYS_mq_timedsend: case SYS_mq_timedreceive: case SYS_pselect6:
+		__fixup(a5);
+		break;
+	case SYS_futex:
+		if((a2 & (~128 /* FUTEX_PRIVATE_FLAG */)) == 0 /* FUTEX_WAIT */)
+			__fixup(a4);
+		break;
+	case SYS_clock_nanosleep:
+	case SYS_rt_sigtimedwait: case SYS_ppoll:
+		__fixup(a3);
+		break;
+	case SYS_nanosleep:
+		__fixup(a1);
+		break;
+	}
+	return __syscall_cp_internal(foo, n, a1, a2, a3, a4, a5, a6);
+}
+
libc/musl/src/thread/x86_64/__set_thread_area.s
@@ -0,0 +1,11 @@
+/* Copyright 2011-2012 Nicholas J. Kain, licensed under standard MIT license */
+.text
+.global __set_thread_area
+.hidden __set_thread_area
+.type __set_thread_area,@function
+__set_thread_area:
+	mov %rdi,%rsi           /* shift for syscall */
+	movl $0x1002,%edi       /* SET_FS register */
+	movl $158,%eax          /* set fs segment to */
+	syscall                 /* arch_prctl(SET_FS, arg)*/
+	ret
libc/musl/src/thread/x86_64/__unmapself.s
@@ -0,0 +1,10 @@
+/* Copyright 2011-2012 Nicholas J. Kain, licensed under standard MIT license */
+.text
+.global __unmapself
+.type   __unmapself,@function
+__unmapself:
+	movl $11,%eax   /* SYS_munmap */
+	syscall         /* munmap(arg2,arg3) */
+	xor %rdi,%rdi   /* exit() args: always return success */
+	movl $60,%eax   /* SYS_exit */
+	syscall         /* exit(0) */
libc/musl/src/thread/x86_64/clone.s
@@ -0,0 +1,28 @@
+.text
+.global __clone
+.hidden __clone
+.type   __clone,@function
+__clone:
+	xor %eax,%eax
+	mov $56,%al
+	mov %rdi,%r11
+	mov %rdx,%rdi
+	mov %r8,%rdx
+	mov %r9,%r8
+	mov 8(%rsp),%r10
+	mov %r11,%r9
+	and $-16,%rsi
+	sub $8,%rsi
+	mov %rcx,(%rsi)
+	syscall
+	test %eax,%eax
+	jnz 1f
+	xor %ebp,%ebp
+	pop %rdi
+	call *%r9
+	mov %eax,%edi
+	xor %eax,%eax
+	mov $60,%al
+	syscall
+	hlt
+1:	ret
libc/musl/src/thread/x86_64/syscall_cp.s
@@ -0,0 +1,31 @@
+.text
+.global __cp_begin
+.hidden __cp_begin
+.global __cp_end
+.hidden __cp_end
+.global __cp_cancel
+.hidden __cp_cancel
+.hidden __cancel
+.global __syscall_cp_asm
+.hidden __syscall_cp_asm
+.type   __syscall_cp_asm,@function
+__syscall_cp_asm:
+
+__cp_begin:
+	mov (%rdi),%eax
+	test %eax,%eax
+	jnz __cp_cancel
+	mov %rdi,%r11
+	mov %rsi,%rax
+	mov %rdx,%rdi
+	mov %rcx,%rsi
+	mov %r8,%rdx
+	mov %r9,%r10
+	mov 8(%rsp),%r8
+	mov 16(%rsp),%r9
+	mov %r11,8(%rsp)
+	syscall
+__cp_end:
+	ret
+__cp_cancel:
+	jmp __cancel
libc/musl/src/thread/__lock.c
@@ -0,0 +1,60 @@
+#include "pthread_impl.h"
+
+/* This lock primitive combines a flag (in the sign bit) and a
+ * congestion count (= threads inside the critical section, CS) in a
+ * single int that is accessed through atomic operations. The states
+ * of the int for value x are:
+ *
+ * x == 0: unlocked and no thread inside the critical section
+ *
+ * x < 0: locked with a congestion of x-INT_MIN, including the thread
+ * that holds the lock
+ *
+ * x > 0: unlocked with a congestion of x
+ *
+ * or in an equivalent formulation x is the congestion count or'ed
+ * with INT_MIN as a lock flag.
+ */
+
+void __lock(volatile int *l)
+{
+	if (!libc.threads_minus_1) return;
+	/* fast path: INT_MIN for the lock, +1 for the congestion */
+	int current = a_cas(l, 0, INT_MIN + 1);
+	if (!current) return;
+	/* A first spin loop, for medium congestion. */
+	for (unsigned i = 0; i < 10; ++i) {
+		if (current < 0) current -= INT_MIN + 1;
+		// assertion: current >= 0
+		int val = a_cas(l, current, INT_MIN + (current + 1));
+		if (val == current) return;
+		current = val;
+	}
+	// Spinning failed, so mark ourselves as being inside the CS.
+	current = a_fetch_add(l, 1) + 1;
+	/* The main lock acquisition loop for heavy congestion. The only
+	 * change to the value performed inside that loop is a successful
+	 * lock via the CAS that acquires the lock. */
+	for (;;) {
+		/* We can only go into wait, if we know that somebody holds the
+		 * lock and will eventually wake us up, again. */
+		if (current < 0) {
+			__futexwait(l, current, 1);
+			current -= INT_MIN + 1;
+		}
+		/* assertion: current > 0, the count includes us already. */
+		int val = a_cas(l, current, INT_MIN + current);
+		if (val == current) return;
+		current = val;
+	}
+}
+
+void __unlock(volatile int *l)
+{
+	/* Check l[0] to see if we are multi-threaded. */
+	if (l[0] < 0) {
+		if (a_fetch_add(l, -(INT_MIN + 1)) != (INT_MIN + 1)) {
+			__wake(l, 1, 1);
+		}
+	}
+}
libc/musl/src/thread/__set_thread_area.c
@@ -0,0 +1,10 @@
+#include "pthread_impl.h"
+
+int __set_thread_area(void *p)
+{
+#ifdef SYS_set_thread_area
+	return __syscall(SYS_set_thread_area, p);
+#else
+	return -ENOSYS;
+#endif
+}
libc/musl/src/thread/__syscall_cp.c
@@ -0,0 +1,20 @@
+#include "pthread_impl.h"
+#include "syscall.h"
+
+hidden long __syscall_cp_c();
+
+static long sccp(syscall_arg_t nr,
+                 syscall_arg_t u, syscall_arg_t v, syscall_arg_t w,
+                 syscall_arg_t x, syscall_arg_t y, syscall_arg_t z)
+{
+	return (__syscall)(nr, u, v, w, x, y, z);
+}
+
+weak_alias(sccp, __syscall_cp_c);
+
+long (__syscall_cp)(syscall_arg_t nr,
+                    syscall_arg_t u, syscall_arg_t v, syscall_arg_t w,
+                    syscall_arg_t x, syscall_arg_t y, syscall_arg_t z)
+{
+	return __syscall_cp_c(nr, u, v, w, x, y, z);
+}
libc/musl/src/thread/__timedwait.c
@@ -0,0 +1,51 @@
+#include <pthread.h>
+#include <time.h>
+#include <errno.h>
+#include "futex.h"
+#include "syscall.h"
+#include "pthread_impl.h"
+
+static volatile int dummy = 0;
+weak_alias(dummy, __eintr_valid_flag);
+
+int __timedwait_cp(volatile int *addr, int val,
+	clockid_t clk, const struct timespec *at, int priv)
+{
+	int r;
+	struct timespec to, *top=0;
+
+	if (priv) priv = FUTEX_PRIVATE;
+
+	if (at) {
+		if (at->tv_nsec >= 1000000000UL) return EINVAL;
+		if (__clock_gettime(clk, &to)) return EINVAL;
+		to.tv_sec = at->tv_sec - to.tv_sec;
+		if ((to.tv_nsec = at->tv_nsec - to.tv_nsec) < 0) {
+			to.tv_sec--;
+			to.tv_nsec += 1000000000;
+		}
+		if (to.tv_sec < 0) return ETIMEDOUT;
+		top = &to;
+	}
+
+	r = -__syscall_cp(SYS_futex, addr, FUTEX_WAIT|priv, val, top);
+	if (r == ENOSYS) r = -__syscall_cp(SYS_futex, addr, FUTEX_WAIT, val, top);
+	if (r != EINTR && r != ETIMEDOUT && r != ECANCELED) r = 0;
+	/* Mitigate bug in old kernels wrongly reporting EINTR for non-
+	 * interrupting (SA_RESTART) signal handlers. This is only practical
+	 * when NO interrupting signal handlers have been installed, and
+	 * works by sigaction tracking whether that's the case. */
+	if (r == EINTR && !__eintr_valid_flag) r = 0;
+
+	return r;
+}
+
+int __timedwait(volatile int *addr, int val,
+	clockid_t clk, const struct timespec *at, int priv)
+{
+	int cs, r;
+	__pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cs);
+	r = __timedwait_cp(addr, val, clk, at, priv);
+	__pthread_setcancelstate(cs, 0);
+	return r;
+}
libc/musl/src/thread/__tls_get_addr.c
@@ -0,0 +1,12 @@
+#include <stddef.h>
+#include "pthread_impl.h"
+
+void *__tls_get_addr(tls_mod_off_t *v)
+{
+	pthread_t self = __pthread_self();
+	if (v[0] <= self->dtv[0])
+		return (void *)(self->dtv[v[0]] + v[1]);
+	return __tls_get_new(v);
+}
+
+weak_alias(__tls_get_addr, __tls_get_new);
libc/musl/src/thread/__unmapself.c
@@ -0,0 +1,29 @@
+#include "pthread_impl.h"
+#include "atomic.h"
+#include "syscall.h"
+/* cheat and reuse CRTJMP macro from dynlink code */
+#include "dynlink.h"
+
+static volatile int lock;
+static void *unmap_base;
+static size_t unmap_size;
+static char shared_stack[256];
+
+static void do_unmap()
+{
+	__syscall(SYS_munmap, unmap_base, unmap_size);
+	__syscall(SYS_exit);
+}
+
+void __unmapself(void *base, size_t size)
+{
+	int tid=__pthread_self()->tid;
+	char *stack = shared_stack + sizeof shared_stack;
+	stack -= (uintptr_t)stack % 16;
+	while (lock || a_cas(&lock, 0, tid))
+		a_spin();
+	__syscall(SYS_set_tid_address, &lock);
+	unmap_base = base;
+	unmap_size = size;
+	CRTJMP(do_unmap, stack);
+}
libc/musl/src/thread/__wait.c
@@ -0,0 +1,17 @@
+#include "pthread_impl.h"
+
+void __wait(volatile int *addr, volatile int *waiters, int val, int priv)
+{
+	int spins=100;
+	if (priv) priv = FUTEX_PRIVATE;
+	while (spins-- && (!waiters || !*waiters)) {
+		if (*addr==val) a_spin();
+		else return;
+	}
+	if (waiters) a_inc(waiters);
+	while (*addr==val) {
+		__syscall(SYS_futex, addr, FUTEX_WAIT|priv, val, 0) != -ENOSYS
+		|| __syscall(SYS_futex, addr, FUTEX_WAIT, val, 0);
+	}
+	if (waiters) a_dec(waiters);
+}
libc/musl/src/thread/call_once.c
@@ -0,0 +1,7 @@
+#include <threads.h>
+#include <pthread.h>
+
+void call_once(once_flag *flag, void (*func)(void))
+{
+	__pthread_once(flag, func);
+}
libc/musl/src/thread/clone.c
@@ -0,0 +1,7 @@
+#include <errno.h>
+#include "pthread_impl.h"
+
+int __clone(int (*func)(void *), void *stack, int flags, void *arg, ...)
+{
+	return -ENOSYS;
+}
libc/musl/src/thread/cnd_broadcast.c
@@ -0,0 +1,9 @@
+#include <threads.h>
+#include <pthread.h>
+
+int cnd_broadcast(cnd_t *c)
+{
+	/* This internal function never fails, and always returns zero,
+	 * which matches the value thrd_success is defined with. */
+	return __private_cond_signal((pthread_cond_t *)c, -1);
+}
libc/musl/src/thread/cnd_destroy.c
@@ -0,0 +1,6 @@
+#include <threads.h>
+
+void cnd_destroy(cnd_t *c)
+{
+	/* For private cv this is a no-op */
+}
libc/musl/src/thread/cnd_init.c
@@ -0,0 +1,7 @@
+#include <threads.h>
+
+int cnd_init(cnd_t *c)
+{
+	*c = (cnd_t){ 0 };
+	return thrd_success;
+}
libc/musl/src/thread/cnd_signal.c
@@ -0,0 +1,9 @@
+#include <threads.h>
+#include <pthread.h>
+
+int cnd_signal(cnd_t *c)
+{
+	/* This internal function never fails, and always returns zero,
+	 * which matches the value thrd_success is defined with. */
+	return __private_cond_signal((pthread_cond_t *)c, 1);
+}
libc/musl/src/thread/cnd_timedwait.c
@@ -0,0 +1,14 @@
+#include <threads.h>
+#include <pthread.h>
+#include <errno.h>
+
+int cnd_timedwait(cnd_t *restrict c, mtx_t *restrict m, const struct timespec *restrict ts)
+{
+	int ret = __pthread_cond_timedwait((pthread_cond_t *)c, (pthread_mutex_t *)m, ts);
+	switch (ret) {
+	/* May also return EINVAL or EPERM. */
+	default:        return thrd_error;
+	case 0:         return thrd_success;
+	case ETIMEDOUT: return thrd_timedout;
+	}
+}
libc/musl/src/thread/cnd_wait.c
@@ -0,0 +1,9 @@
+#include <threads.h>
+
+int cnd_wait(cnd_t *c, mtx_t *m)
+{
+	/* Calling cnd_timedwait with a null pointer is an extension.
+	 * It is convenient here to avoid duplication of the logic
+	 * for return values. */
+	return cnd_timedwait(c, m, 0);
+}
libc/musl/src/thread/default_attr.c
@@ -0,0 +1,4 @@
+#include "pthread_impl.h"
+
+unsigned __default_stacksize = DEFAULT_STACK_SIZE;
+unsigned __default_guardsize = DEFAULT_GUARD_SIZE;
libc/musl/src/thread/lock_ptc.c
@@ -0,0 +1,18 @@
+#include <pthread.h>
+
+static pthread_rwlock_t lock = PTHREAD_RWLOCK_INITIALIZER;
+
+void __inhibit_ptc()
+{
+	pthread_rwlock_wrlock(&lock);
+}
+
+void __acquire_ptc()
+{
+	pthread_rwlock_rdlock(&lock);
+}
+
+void __release_ptc()
+{
+	pthread_rwlock_unlock(&lock);
+}
libc/musl/src/thread/mtx_destroy.c
@@ -0,0 +1,5 @@
+#include <threads.h>
+
+void mtx_destroy(mtx_t *mtx)
+{
+}
libc/musl/src/thread/mtx_init.c
@@ -0,0 +1,10 @@
+#include "pthread_impl.h"
+#include <threads.h>
+
+int mtx_init(mtx_t *m, int type)
+{
+	*m = (mtx_t){
+		._m_type = ((type&mtx_recursive) ? PTHREAD_MUTEX_RECURSIVE : PTHREAD_MUTEX_NORMAL),
+	};
+	return thrd_success;
+}
libc/musl/src/thread/mtx_lock.c
@@ -0,0 +1,12 @@
+#include "pthread_impl.h"
+#include <threads.h>
+
+int mtx_lock(mtx_t *m)
+{
+	if (m->_m_type == PTHREAD_MUTEX_NORMAL && !a_cas(&m->_m_lock, 0, EBUSY))
+		return thrd_success;
+	/* Calling mtx_timedlock with a null pointer is an extension.
+	 * It is convenient, here to avoid duplication of the logic
+	 * for return values. */
+	return mtx_timedlock(m, 0);
+}
libc/musl/src/thread/mtx_timedlock.c
@@ -0,0 +1,13 @@
+#include <threads.h>
+#include <pthread.h>
+#include <errno.h>
+
+int mtx_timedlock(mtx_t *restrict m, const struct timespec *restrict ts)
+{
+	int ret = __pthread_mutex_timedlock((pthread_mutex_t *)m, ts);
+	switch (ret) {
+	default:        return thrd_error;
+	case 0:         return thrd_success;
+	case ETIMEDOUT: return thrd_timedout;
+	}
+}
libc/musl/src/thread/mtx_trylock.c
@@ -0,0 +1,15 @@
+#include "pthread_impl.h"
+#include <threads.h>
+
+int mtx_trylock(mtx_t *m)
+{
+	if (m->_m_type == PTHREAD_MUTEX_NORMAL)
+		return (a_cas(&m->_m_lock, 0, EBUSY) & EBUSY) ? thrd_busy : thrd_success;
+
+	int ret = __pthread_mutex_trylock((pthread_mutex_t *)m);
+	switch (ret) {
+	default:    return thrd_error;
+	case 0:     return thrd_success;
+	case EBUSY: return thrd_busy;
+	}
+}
libc/musl/src/thread/mtx_unlock.c
@@ -0,0 +1,10 @@
+#include <threads.h>
+#include <pthread.h>
+
+int mtx_unlock(mtx_t *mtx)
+{
+	/* The only cases where pthread_mutex_unlock can return an
+	 * error are undefined behavior for C11 mtx_unlock, so we can
+	 * assume it does not return an error and simply tail call. */
+	return __pthread_mutex_unlock((pthread_mutex_t *)mtx);
+}
libc/musl/src/thread/pthread_atfork.c
@@ -0,0 +1,49 @@
+#include <pthread.h>
+#include "libc.h"
+#include "lock.h"
+
+static struct atfork_funcs {
+	void (*prepare)(void);
+	void (*parent)(void);
+	void (*child)(void);
+	struct atfork_funcs *prev, *next;
+} *funcs;
+
+static volatile int lock[1];
+
+void __fork_handler(int who)
+{
+	struct atfork_funcs *p;
+	if (!funcs) return;
+	if (who < 0) {
+		LOCK(lock);
+		for (p=funcs; p; p = p->next) {
+			if (p->prepare) p->prepare();
+			funcs = p;
+		}
+	} else {
+		for (p=funcs; p; p = p->prev) {
+			if (!who && p->parent) p->parent();
+			else if (who && p->child) p->child();
+			funcs = p;
+		}
+		UNLOCK(lock);
+	}
+}
+
+int pthread_atfork(void (*prepare)(void), void (*parent)(void), void (*child)(void))
+{
+	struct atfork_funcs *new = malloc(sizeof *new);
+	if (!new) return -1;
+
+	LOCK(lock);
+	new->next = funcs;
+	new->prev = 0;
+	new->prepare = prepare;
+	new->parent = parent;
+	new->child = child;
+	if (funcs) funcs->prev = new;
+	funcs = new;
+	UNLOCK(lock);
+	return 0;
+}
libc/musl/src/thread/pthread_attr_destroy.c
@@ -0,0 +1,6 @@
+#include "pthread_impl.h"
+
+int pthread_attr_destroy(pthread_attr_t *a)
+{
+	return 0;
+}
libc/musl/src/thread/pthread_attr_get.c
@@ -0,0 +1,98 @@
+#include "pthread_impl.h"
+
+int pthread_attr_getdetachstate(const pthread_attr_t *a, int *state)
+{
+	*state = a->_a_detach;
+	return 0;
+}
+int pthread_attr_getguardsize(const pthread_attr_t *restrict a, size_t *restrict size)
+{
+	*size = a->_a_guardsize;
+	return 0;
+}
+
+int pthread_attr_getinheritsched(const pthread_attr_t *restrict a, int *restrict inherit)
+{
+	*inherit = a->_a_sched;
+	return 0;
+}
+
+int pthread_attr_getschedparam(const pthread_attr_t *restrict a, struct sched_param *restrict param)
+{
+	param->sched_priority = a->_a_prio;
+	return 0;
+}
+
+int pthread_attr_getschedpolicy(const pthread_attr_t *restrict a, int *restrict policy)
+{
+	*policy = a->_a_policy;
+	return 0;
+}
+
+int pthread_attr_getscope(const pthread_attr_t *restrict a, int *restrict scope)
+{
+	*scope = PTHREAD_SCOPE_SYSTEM;
+	return 0;
+}
+
+int pthread_attr_getstack(const pthread_attr_t *restrict a, void **restrict addr, size_t *restrict size)
+{
+	if (!a->_a_stackaddr)
+		return EINVAL;
+	*size = a->_a_stacksize;
+	*addr = (void *)(a->_a_stackaddr - *size);
+	return 0;
+}
+
+int pthread_attr_getstacksize(const pthread_attr_t *restrict a, size_t *restrict size)
+{
+	*size = a->_a_stacksize;
+	return 0;
+}
+
+int pthread_barrierattr_getpshared(const pthread_barrierattr_t *restrict a, int *restrict pshared)
+{
+	*pshared = !!a->__attr;
+	return 0;
+}
+
+int pthread_condattr_getclock(const pthread_condattr_t *restrict a, clockid_t *restrict clk)
+{
+	*clk = a->__attr & 0x7fffffff;
+	return 0;
+}
+
+int pthread_condattr_getpshared(const pthread_condattr_t *restrict a, int *restrict pshared)
+{
+	*pshared = a->__attr>>31;
+	return 0;
+}
+
+int pthread_mutexattr_getprotocol(const pthread_mutexattr_t *restrict a, int *restrict protocol)
+{
+	*protocol = PTHREAD_PRIO_NONE;
+	return 0;
+}
+int pthread_mutexattr_getpshared(const pthread_mutexattr_t *restrict a, int *restrict pshared)
+{
+	*pshared = a->__attr / 128U % 2;
+	return 0;
+}
+
+int pthread_mutexattr_getrobust(const pthread_mutexattr_t *restrict a, int *restrict robust)
+{
+	*robust = a->__attr / 4U % 2;
+	return 0;
+}
+
+int pthread_mutexattr_gettype(const pthread_mutexattr_t *restrict a, int *restrict type)
+{
+	*type = a->__attr & 3;
+	return 0;
+}
+
+int pthread_rwlockattr_getpshared(const pthread_rwlockattr_t *restrict a, int *restrict pshared)
+{
+	*pshared = a->__attr[0];
+	return 0;
+}
libc/musl/src/thread/pthread_attr_init.c
@@ -0,0 +1,11 @@
+#include "pthread_impl.h"
+
+int pthread_attr_init(pthread_attr_t *a)
+{
+	*a = (pthread_attr_t){0};
+	__acquire_ptc();
+	a->_a_stacksize = __default_stacksize;
+	a->_a_guardsize = __default_guardsize;
+	__release_ptc();
+	return 0;
+}
libc/musl/src/thread/pthread_attr_setdetachstate.c
@@ -0,0 +1,8 @@
+#include "pthread_impl.h"
+
+int pthread_attr_setdetachstate(pthread_attr_t *a, int state)
+{
+	if (state > 1U) return EINVAL;
+	a->_a_detach = state;
+	return 0;
+}
libc/musl/src/thread/pthread_attr_setguardsize.c
@@ -0,0 +1,8 @@
+#include "pthread_impl.h"
+
+int pthread_attr_setguardsize(pthread_attr_t *a, size_t size)
+{
+	if (size > SIZE_MAX/8) return EINVAL;
+	a->_a_guardsize = size;
+	return 0;
+}
libc/musl/src/thread/pthread_attr_setinheritsched.c
@@ -0,0 +1,28 @@
+#include "pthread_impl.h"
+#include "syscall.h"
+
+hidden void *__start_sched(void *p)
+{
+	struct start_sched_args *ssa = p;
+	void *start_arg = ssa->start_arg;
+	void *(*start_fn)(void *) = ssa->start_fn;
+	pthread_t self = __pthread_self();
+
+	int ret = -__syscall(SYS_sched_setscheduler, self->tid,
+		ssa->attr->_a_policy, &ssa->attr->_a_prio);
+	if (!ret) __restore_sigs(&ssa->mask);
+	a_store(&ssa->futex, ret);
+	__wake(&ssa->futex, 1, 1);
+	if (ret) {
+		self->detach_state = DT_DYNAMIC;
+		return 0;
+	}
+	return start_fn(start_arg);
+}
+
+int pthread_attr_setinheritsched(pthread_attr_t *a, int inherit)
+{
+	if (inherit > 1U) return EINVAL;
+	a->_a_sched = inherit;
+	return 0;
+}
libc/musl/src/thread/pthread_attr_setschedparam.c
@@ -0,0 +1,7 @@
+#include "pthread_impl.h"
+
+int pthread_attr_setschedparam(pthread_attr_t *restrict a, const struct sched_param *restrict param)
+{
+	a->_a_prio = param->sched_priority;
+	return 0;
+}
libc/musl/src/thread/pthread_attr_setschedpolicy.c
@@ -0,0 +1,7 @@
+#include "pthread_impl.h"
+
+int pthread_attr_setschedpolicy(pthread_attr_t *a, int policy)
+{
+	a->_a_policy = policy;
+	return 0;
+}
libc/musl/src/thread/pthread_attr_setscope.c
@@ -0,0 +1,13 @@
+#include "pthread_impl.h"
+
+int pthread_attr_setscope(pthread_attr_t *a, int scope)
+{
+	switch (scope) {
+	case PTHREAD_SCOPE_SYSTEM:
+		return 0;
+	case PTHREAD_SCOPE_PROCESS:
+		return ENOTSUP;
+	default:
+		return EINVAL;
+	}
+}
libc/musl/src/thread/pthread_attr_setstack.c
@@ -0,0 +1,9 @@
+#include "pthread_impl.h"
+
+int pthread_attr_setstack(pthread_attr_t *a, void *addr, size_t size)
+{
+	if (size-PTHREAD_STACK_MIN > SIZE_MAX/4) return EINVAL;
+	a->_a_stackaddr = (size_t)addr + size;
+	a->_a_stacksize = size;
+	return 0;
+}
libc/musl/src/thread/pthread_attr_setstacksize.c
@@ -0,0 +1,9 @@
+#include "pthread_impl.h"
+
+int pthread_attr_setstacksize(pthread_attr_t *a, size_t size)
+{
+	if (size-PTHREAD_STACK_MIN > SIZE_MAX/4) return EINVAL;
+	a->_a_stackaddr = 0;
+	a->_a_stacksize = size;
+	return 0;
+}
libc/musl/src/thread/pthread_barrier_destroy.c
@@ -0,0 +1,15 @@
+#include "pthread_impl.h"
+
+int pthread_barrier_destroy(pthread_barrier_t *b)
+{
+	if (b->_b_limit < 0) {
+		if (b->_b_lock) {
+			int v;
+			a_or(&b->_b_lock, INT_MIN);
+			while ((v = b->_b_lock) & INT_MAX)
+				__wait(&b->_b_lock, 0, v, 0);
+		}
+		__vm_wait();
+	}
+	return 0;
+}
libc/musl/src/thread/pthread_barrier_init.c
@@ -0,0 +1,8 @@
+#include "pthread_impl.h"
+
+int pthread_barrier_init(pthread_barrier_t *restrict b, const pthread_barrierattr_t *restrict a, unsigned count)
+{
+	if (count-1 > INT_MAX-1) return EINVAL;
+	*b = (pthread_barrier_t){ ._b_limit = count-1 | (a?a->__attr:0) };
+	return 0;
+}
libc/musl/src/thread/pthread_barrier_wait.c
@@ -0,0 +1,111 @@
+#include "pthread_impl.h"
+
+static int pshared_barrier_wait(pthread_barrier_t *b)
+{
+	int limit = (b->_b_limit & INT_MAX) + 1;
+	int ret = 0;
+	int v, w;
+
+	if (limit==1) return PTHREAD_BARRIER_SERIAL_THREAD;
+
+	while ((v=a_cas(&b->_b_lock, 0, limit)))
+		__wait(&b->_b_lock, &b->_b_waiters, v, 0);
+
+	/* Wait for <limit> threads to get to the barrier */
+	if (++b->_b_count == limit) {
+		a_store(&b->_b_count, 0);
+		ret = PTHREAD_BARRIER_SERIAL_THREAD;
+		if (b->_b_waiters2) __wake(&b->_b_count, -1, 0);
+	} else {
+		a_store(&b->_b_lock, 0);
+		if (b->_b_waiters) __wake(&b->_b_lock, 1, 0);
+		while ((v=b->_b_count)>0)
+			__wait(&b->_b_count, &b->_b_waiters2, v, 0);
+	}
+
+	__vm_lock();
+
+	/* Ensure all threads have a vm lock before proceeding */
+	if (a_fetch_add(&b->_b_count, -1)==1-limit) {
+		a_store(&b->_b_count, 0);
+		if (b->_b_waiters2) __wake(&b->_b_count, -1, 0);
+	} else {
+		while ((v=b->_b_count))
+			__wait(&b->_b_count, &b->_b_waiters2, v, 0);
+	}
+	
+	/* Perform a recursive unlock suitable for self-sync'd destruction */
+	do {
+		v = b->_b_lock;
+		w = b->_b_waiters;
+	} while (a_cas(&b->_b_lock, v, v==INT_MIN+1 ? 0 : v-1) != v);
+
+	/* Wake a thread waiting to reuse or destroy the barrier */
+	if (v==INT_MIN+1 || (v==1 && w))
+		__wake(&b->_b_lock, 1, 0);
+
+	__vm_unlock();
+
+	return ret;
+}
+
+struct instance
+{
+	volatile int count;
+	volatile int last;
+	volatile int waiters;
+	volatile int finished;
+};
+
+int pthread_barrier_wait(pthread_barrier_t *b)
+{
+	int limit = b->_b_limit;
+	struct instance *inst;
+
+	/* Trivial case: count was set at 1 */
+	if (!limit) return PTHREAD_BARRIER_SERIAL_THREAD;
+
+	/* Process-shared barriers require a separate, inefficient wait */
+	if (limit < 0) return pshared_barrier_wait(b);
+
+	/* Otherwise we need a lock on the barrier object */
+	while (a_swap(&b->_b_lock, 1))
+		__wait(&b->_b_lock, &b->_b_waiters, 1, 1);
+	inst = b->_b_inst;
+
+	/* First thread to enter the barrier becomes the "instance owner" */
+	if (!inst) {
+		struct instance new_inst = { 0 };
+		int spins = 200;
+		b->_b_inst = inst = &new_inst;
+		a_store(&b->_b_lock, 0);
+		if (b->_b_waiters) __wake(&b->_b_lock, 1, 1);
+		while (spins-- && !inst->finished)
+			a_spin();
+		a_inc(&inst->finished);
+		while (inst->finished == 1)
+			__syscall(SYS_futex,&inst->finished,FUTEX_WAIT|FUTEX_PRIVATE,1,0) != -ENOSYS
+			|| __syscall(SYS_futex,&inst->finished,FUTEX_WAIT,1,0);
+		return PTHREAD_BARRIER_SERIAL_THREAD;
+	}
+
+	/* Last thread to enter the barrier wakes all non-instance-owners */
+	if (++inst->count == limit) {
+		b->_b_inst = 0;
+		a_store(&b->_b_lock, 0);
+		if (b->_b_waiters) __wake(&b->_b_lock, 1, 1);
+		a_store(&inst->last, 1);
+		if (inst->waiters)
+			__wake(&inst->last, -1, 1);
+	} else {
+		a_store(&b->_b_lock, 0);
+		if (b->_b_waiters) __wake(&b->_b_lock, 1, 1);
+		__wait(&inst->last, &inst->waiters, 0, 1);
+	}
+
+	/* Last thread to exit the barrier wakes the instance owner */
+	if (a_fetch_add(&inst->count,-1)==1 && a_fetch_add(&inst->finished,1))
+		__wake(&inst->finished, 1, 1);
+
+	return 0;
+}
libc/musl/src/thread/pthread_barrierattr_destroy.c
@@ -0,0 +1,6 @@
+#include "pthread_impl.h"
+
+int pthread_barrierattr_destroy(pthread_barrierattr_t *a)
+{
+	return 0;
+}
libc/musl/src/thread/pthread_barrierattr_init.c
@@ -0,0 +1,7 @@
+#include "pthread_impl.h"
+
+int pthread_barrierattr_init(pthread_barrierattr_t *a)
+{
+	*a = (pthread_barrierattr_t){0};
+	return 0;
+}
libc/musl/src/thread/pthread_barrierattr_setpshared.c
@@ -0,0 +1,8 @@
+#include "pthread_impl.h"
+
+int pthread_barrierattr_setpshared(pthread_barrierattr_t *a, int pshared)
+{
+	if (pshared > 1U) return EINVAL;
+	a->__attr = pshared ? INT_MIN : 0;
+	return 0;
+}
libc/musl/src/thread/pthread_cancel.c
@@ -0,0 +1,101 @@
+#define _GNU_SOURCE
+#include <string.h>
+#include "pthread_impl.h"
+#include "syscall.h"
+
+hidden long __cancel(), __syscall_cp_asm(), __syscall_cp_c();
+
+long __cancel()
+{
+	pthread_t self = __pthread_self();
+	if (self->canceldisable == PTHREAD_CANCEL_ENABLE || self->cancelasync)
+		pthread_exit(PTHREAD_CANCELED);
+	self->canceldisable = PTHREAD_CANCEL_DISABLE;
+	return -ECANCELED;
+}
+
+long __syscall_cp_asm(volatile void *, syscall_arg_t,
+                      syscall_arg_t, syscall_arg_t, syscall_arg_t,
+                      syscall_arg_t, syscall_arg_t, syscall_arg_t);
+
+long __syscall_cp_c(syscall_arg_t nr,
+                    syscall_arg_t u, syscall_arg_t v, syscall_arg_t w,
+                    syscall_arg_t x, syscall_arg_t y, syscall_arg_t z)
+{
+	pthread_t self;
+	long r;
+	int st;
+
+	if ((st=(self=__pthread_self())->canceldisable)
+	    && (st==PTHREAD_CANCEL_DISABLE || nr==SYS_close))
+		return __syscall(nr, u, v, w, x, y, z);
+
+	r = __syscall_cp_asm(&self->cancel, nr, u, v, w, x, y, z);
+	if (r==-EINTR && nr!=SYS_close && self->cancel &&
+	    self->canceldisable != PTHREAD_CANCEL_DISABLE)
+		r = __cancel();
+	return r;
+}
+
+static void _sigaddset(sigset_t *set, int sig)
+{
+	unsigned s = sig-1;
+	set->__bits[s/8/sizeof *set->__bits] |= 1UL<<(s&8*sizeof *set->__bits-1);
+}
+
+extern hidden const char __cp_begin[1], __cp_end[1], __cp_cancel[1];
+
+static void cancel_handler(int sig, siginfo_t *si, void *ctx)
+{
+	pthread_t self = __pthread_self();
+	ucontext_t *uc = ctx;
+	uintptr_t pc = uc->uc_mcontext.MC_PC;
+
+	a_barrier();
+	if (!self->cancel || self->canceldisable == PTHREAD_CANCEL_DISABLE) return;
+
+	_sigaddset(&uc->uc_sigmask, SIGCANCEL);
+
+	if (self->cancelasync || pc >= (uintptr_t)__cp_begin && pc < (uintptr_t)__cp_end) {
+		uc->uc_mcontext.MC_PC = (uintptr_t)__cp_cancel;
+#ifdef CANCEL_GOT
+		uc->uc_mcontext.MC_GOT = CANCEL_GOT;
+#endif
+		return;
+	}
+
+	__syscall(SYS_tkill, self->tid, SIGCANCEL);
+}
+
+void __testcancel()
+{
+	pthread_t self = __pthread_self();
+	if (self->cancel && !self->canceldisable)
+		__cancel();
+}
+
+static void init_cancellation()
+{
+	struct sigaction sa = {
+		.sa_flags = SA_SIGINFO | SA_RESTART,
+		.sa_sigaction = cancel_handler
+	};
+	memset(&sa.sa_mask, -1, _NSIG/8);
+	__libc_sigaction(SIGCANCEL, &sa, 0);
+}
+
+int pthread_cancel(pthread_t t)
+{
+	static int init;
+	if (!init) {
+		init_cancellation();
+		init = 1;
+	}
+	a_store(&t->cancel, 1);
+	if (t == pthread_self()) {
+		if (t->canceldisable == PTHREAD_CANCEL_ENABLE && t->cancelasync)
+			pthread_exit(PTHREAD_CANCELED);
+		return 0;
+	}
+	return pthread_kill(t, SIGCANCEL);
+}
libc/musl/src/thread/pthread_cleanup_push.c
@@ -0,0 +1,20 @@
+#include "pthread_impl.h"
+
+static void dummy(struct __ptcb *cb)
+{
+}
+weak_alias(dummy, __do_cleanup_push);
+weak_alias(dummy, __do_cleanup_pop);
+
+void _pthread_cleanup_push(struct __ptcb *cb, void (*f)(void *), void *x)
+{
+	cb->__f = f;
+	cb->__x = x;
+	__do_cleanup_push(cb);
+}
+
+void _pthread_cleanup_pop(struct __ptcb *cb, int run)
+{
+	__do_cleanup_pop(cb);
+	if (run) cb->__f(cb->__x);
+}
libc/musl/src/thread/pthread_cond_broadcast.c
@@ -0,0 +1,10 @@
+#include "pthread_impl.h"
+
+int pthread_cond_broadcast(pthread_cond_t *c)
+{
+	if (!c->_c_shared) return __private_cond_signal(c, -1);
+	if (!c->_c_waiters) return 0;
+	a_inc(&c->_c_seq);
+	__wake(&c->_c_seq, -1, 0);
+	return 0;
+}
libc/musl/src/thread/pthread_cond_destroy.c
@@ -0,0 +1,14 @@
+#include "pthread_impl.h"
+
+int pthread_cond_destroy(pthread_cond_t *c)
+{
+	if (c->_c_shared && c->_c_waiters) {
+		int cnt;
+		a_or(&c->_c_waiters, 0x80000000);
+		a_inc(&c->_c_seq);
+		__wake(&c->_c_seq, -1, 0);
+		while ((cnt = c->_c_waiters) & 0x7fffffff)
+			__wait(&c->_c_waiters, 0, cnt, 0);
+	}
+	return 0;
+}
libc/musl/src/thread/pthread_cond_init.c
@@ -0,0 +1,11 @@
+#include "pthread_impl.h"
+
+int pthread_cond_init(pthread_cond_t *restrict c, const pthread_condattr_t *restrict a)
+{
+	*c = (pthread_cond_t){0};
+	if (a) {
+		c->_c_clock = a->__attr & 0x7fffffff;
+		if (a->__attr>>31) c->_c_shared = (void *)-1;
+	}
+	return 0;
+}
libc/musl/src/thread/pthread_cond_signal.c
@@ -0,0 +1,10 @@
+#include "pthread_impl.h"
+
+int pthread_cond_signal(pthread_cond_t *c)
+{
+	if (!c->_c_shared) return __private_cond_signal(c, 1);
+	if (!c->_c_waiters) return 0;
+	a_inc(&c->_c_seq);
+	__wake(&c->_c_seq, 1, 0);
+	return 0;
+}
libc/musl/src/thread/pthread_cond_timedwait.c
@@ -0,0 +1,209 @@
+#include "pthread_impl.h"
+
+/*
+ * struct waiter
+ *
+ * Waiter objects have automatic storage on the waiting thread, and
+ * are used in building a linked list representing waiters currently
+ * waiting on the condition variable or a group of waiters woken
+ * together by a broadcast or signal; in the case of signal, this is a
+ * degenerate list of one member.
+ *
+ * Waiter lists attached to the condition variable itself are
+ * protected by the lock on the cv. Detached waiter lists are never
+ * modified again, but can only be traversed in reverse order, and are
+ * protected by the "barrier" locks in each node, which are unlocked
+ * in turn to control wake order.
+ *
+ * Since process-shared cond var semantics do not necessarily allow
+ * one thread to see another's automatic storage (they may be in
+ * different processes), the waiter list is not used for the
+ * process-shared case, but the structure is still used to store data
+ * needed by the cancellation cleanup handler.
+ */
+
+struct waiter {
+	struct waiter *prev, *next;
+	volatile int state, barrier;
+	volatile int *notify;
+};
+
+/* Self-synchronized-destruction-safe lock functions */
+
+static inline void lock(volatile int *l)
+{
+	if (a_cas(l, 0, 1)) {
+		a_cas(l, 1, 2);
+		do __wait(l, 0, 2, 1);
+		while (a_cas(l, 0, 2));
+	}
+}
+
+static inline void unlock(volatile int *l)
+{
+	if (a_swap(l, 0)==2)
+		__wake(l, 1, 1);
+}
+
+static inline void unlock_requeue(volatile int *l, volatile int *r, int w)
+{
+	a_store(l, 0);
+	if (w) __wake(l, 1, 1);
+	else __syscall(SYS_futex, l, FUTEX_REQUEUE|FUTEX_PRIVATE, 0, 1, r) != -ENOSYS
+		|| __syscall(SYS_futex, l, FUTEX_REQUEUE, 0, 1, r);
+}
+
+enum {
+	WAITING,
+	SIGNALED,
+	LEAVING,
+};
+
+int __pthread_cond_timedwait(pthread_cond_t *restrict c, pthread_mutex_t *restrict m, const struct timespec *restrict ts)
+{
+	struct waiter node = { 0 };
+	int e, seq, clock = c->_c_clock, cs, shared=0, oldstate, tmp;
+	volatile int *fut;
+
+	if ((m->_m_type&15) && (m->_m_lock&INT_MAX) != __pthread_self()->tid)
+		return EPERM;
+
+	if (ts && ts->tv_nsec >= 1000000000UL)
+		return EINVAL;
+
+	__pthread_testcancel();
+
+	if (c->_c_shared) {
+		shared = 1;
+		fut = &c->_c_seq;
+		seq = c->_c_seq;
+		a_inc(&c->_c_waiters);
+	} else {
+		lock(&c->_c_lock);
+
+		seq = node.barrier = 2;
+		fut = &node.barrier;
+		node.state = WAITING;
+		node.next = c->_c_head;
+		c->_c_head = &node;
+		if (!c->_c_tail) c->_c_tail = &node;
+		else node.next->prev = &node;
+
+		unlock(&c->_c_lock);
+	}
+
+	__pthread_mutex_unlock(m);
+
+	__pthread_setcancelstate(PTHREAD_CANCEL_MASKED, &cs);
+	if (cs == PTHREAD_CANCEL_DISABLE) __pthread_setcancelstate(cs, 0);
+
+	do e = __timedwait_cp(fut, seq, clock, ts, !shared);
+	while (*fut==seq && (!e || e==EINTR));
+	if (e == EINTR) e = 0;
+
+	if (shared) {
+		/* Suppress cancellation if a signal was potentially
+		 * consumed; this is a legitimate form of spurious
+		 * wake even if not. */
+		if (e == ECANCELED && c->_c_seq != seq) e = 0;
+		if (a_fetch_add(&c->_c_waiters, -1) == -0x7fffffff)
+			__wake(&c->_c_waiters, 1, 0);
+		oldstate = WAITING;
+		goto relock;
+	}
+
+	oldstate = a_cas(&node.state, WAITING, LEAVING);
+
+	if (oldstate == WAITING) {
+		/* Access to cv object is valid because this waiter was not
+		 * yet signaled and a new signal/broadcast cannot return
+		 * after seeing a LEAVING waiter without getting notified
+		 * via the futex notify below. */
+
+		lock(&c->_c_lock);
+		
+		if (c->_c_head == &node) c->_c_head = node.next;
+		else if (node.prev) node.prev->next = node.next;
+		if (c->_c_tail == &node) c->_c_tail = node.prev;
+		else if (node.next) node.next->prev = node.prev;
+		
+		unlock(&c->_c_lock);
+
+		if (node.notify) {
+			if (a_fetch_add(node.notify, -1)==1)
+				__wake(node.notify, 1, 1);
+		}
+	} else {
+		/* Lock barrier first to control wake order. */
+		lock(&node.barrier);
+	}
+
+relock:
+	/* Errors locking the mutex override any existing error or
+	 * cancellation, since the caller must see them to know the
+	 * state of the mutex. */
+	if ((tmp = pthread_mutex_lock(m))) e = tmp;
+
+	if (oldstate == WAITING) goto done;
+
+	if (!node.next) a_inc(&m->_m_waiters);
+
+	/* Unlock the barrier that's holding back the next waiter, and
+	 * either wake it or requeue it to the mutex. */
+	if (node.prev)
+		unlock_requeue(&node.prev->barrier, &m->_m_lock, m->_m_type & 128);
+	else
+		a_dec(&m->_m_waiters);
+
+	/* Since a signal was consumed, cancellation is not permitted. */
+	if (e == ECANCELED) e = 0;
+
+done:
+	__pthread_setcancelstate(cs, 0);
+
+	if (e == ECANCELED) {
+		__pthread_testcancel();
+		__pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, 0);
+	}
+
+	return e;
+}
+
+int __private_cond_signal(pthread_cond_t *c, int n)
+{
+	struct waiter *p, *first=0;
+	volatile int ref = 0;
+	int cur;
+
+	lock(&c->_c_lock);
+	for (p=c->_c_tail; n && p; p=p->prev) {
+		if (a_cas(&p->state, WAITING, SIGNALED) != WAITING) {
+			ref++;
+			p->notify = &ref;
+		} else {
+			n--;
+			if (!first) first=p;
+		}
+	}
+	/* Split the list, leaving any remainder on the cv. */
+	if (p) {
+		if (p->next) p->next->prev = 0;
+		p->next = 0;
+	} else {
+		c->_c_head = 0;
+	}
+	c->_c_tail = p;
+	unlock(&c->_c_lock);
+
+	/* Wait for any waiters in the LEAVING state to remove
+	 * themselves from the list before returning or allowing
+	 * signaled threads to proceed. */
+	while ((cur = ref)) __wait(&ref, 0, cur, 1);
+
+	/* Allow first signaled waiter, if any, to proceed. */
+	if (first) unlock(&first->barrier);
+
+	return 0;
+}
+
+weak_alias(__pthread_cond_timedwait, pthread_cond_timedwait);
libc/musl/src/thread/pthread_cond_wait.c
@@ -0,0 +1,6 @@
+#include "pthread_impl.h"
+
+int pthread_cond_wait(pthread_cond_t *restrict c, pthread_mutex_t *restrict m)
+{
+	return pthread_cond_timedwait(c, m, 0);
+}
libc/musl/src/thread/pthread_condattr_destroy.c
@@ -0,0 +1,6 @@
+#include "pthread_impl.h"
+
+int pthread_condattr_destroy(pthread_condattr_t *a)
+{
+	return 0;
+}
libc/musl/src/thread/pthread_condattr_init.c
@@ -0,0 +1,7 @@
+#include "pthread_impl.h"
+
+int pthread_condattr_init(pthread_condattr_t *a)
+{
+	*a = (pthread_condattr_t){0};
+	return 0;
+}
libc/musl/src/thread/pthread_condattr_setclock.c
@@ -0,0 +1,9 @@
+#include "pthread_impl.h"
+
+int pthread_condattr_setclock(pthread_condattr_t *a, clockid_t clk)
+{
+	if (clk < 0 || clk-2U < 2) return EINVAL;
+	a->__attr &= 0x80000000;
+	a->__attr |= clk;
+	return 0;
+}
libc/musl/src/thread/pthread_condattr_setpshared.c
@@ -0,0 +1,9 @@
+#include "pthread_impl.h"
+
+int pthread_condattr_setpshared(pthread_condattr_t *a, int pshared)
+{
+	if (pshared > 1U) return EINVAL;
+	a->__attr &= 0x7fffffff;
+	a->__attr |= (unsigned)pshared<<31;
+	return 0;
+}
libc/musl/src/thread/pthread_create.c
@@ -0,0 +1,314 @@
+#define _GNU_SOURCE
+#include "pthread_impl.h"
+#include "stdio_impl.h"
+#include "libc.h"
+#include "lock.h"
+#include <sys/mman.h>
+#include <string.h>
+#include <stddef.h>
+
+static void dummy_0()
+{
+}
+weak_alias(dummy_0, __acquire_ptc);
+weak_alias(dummy_0, __release_ptc);
+weak_alias(dummy_0, __pthread_tsd_run_dtors);
+weak_alias(dummy_0, __do_orphaned_stdio_locks);
+weak_alias(dummy_0, __dl_thread_cleanup);
+
+static void *dummy_1(void *p)
+{
+	return 0;
+}
+weak_alias(dummy_1, __start_sched);
+
+_Noreturn void __pthread_exit(void *result)
+{
+	pthread_t self = __pthread_self();
+	sigset_t set;
+
+	self->canceldisable = 1;
+	self->cancelasync = 0;
+	self->result = result;
+
+	while (self->cancelbuf) {
+		void (*f)(void *) = self->cancelbuf->__f;
+		void *x = self->cancelbuf->__x;
+		self->cancelbuf = self->cancelbuf->__next;
+		f(x);
+	}
+
+	__pthread_tsd_run_dtors();
+
+	/* Access to target the exiting thread with syscalls that use
+	 * its kernel tid is controlled by killlock. For detached threads,
+	 * any use past this point would have undefined behavior, but for
+	 * joinable threads it's a valid usage that must be handled. */
+	LOCK(self->killlock);
+
+	/* Block all signals before decrementing the live thread count.
+	 * This is important to ensure that dynamically allocated TLS
+	 * is not under-allocated/over-committed, and possibly for other
+	 * reasons as well. */
+	__block_all_sigs(&set);
+
+	/* It's impossible to determine whether this is "the last thread"
+	 * until performing the atomic decrement, since multiple threads
+	 * could exit at the same time. For the last thread, revert the
+	 * decrement, restore the tid, and unblock signals to give the
+	 * atexit handlers and stdio cleanup code a consistent state. */
+	if (a_fetch_add(&libc.threads_minus_1, -1)==0) {
+		libc.threads_minus_1 = 0;
+		UNLOCK(self->killlock);
+		__restore_sigs(&set);
+		exit(0);
+	}
+
+	/* Process robust list in userspace to handle non-pshared mutexes
+	 * and the detached thread case where the robust list head will
+	 * be invalid when the kernel would process it. */
+	__vm_lock();
+	volatile void *volatile *rp;
+	while ((rp=self->robust_list.head) && rp != &self->robust_list.head) {
+		pthread_mutex_t *m = (void *)((char *)rp
+			- offsetof(pthread_mutex_t, _m_next));
+		int waiters = m->_m_waiters;
+		int priv = (m->_m_type & 128) ^ 128;
+		self->robust_list.pending = rp;
+		self->robust_list.head = *rp;
+		int cont = a_swap(&m->_m_lock, 0x40000000);
+		self->robust_list.pending = 0;
+		if (cont < 0 || waiters)
+			__wake(&m->_m_lock, 1, priv);
+	}
+	__vm_unlock();
+
+	__do_orphaned_stdio_locks();
+	__dl_thread_cleanup();
+
+	/* This atomic potentially competes with a concurrent pthread_detach
+	 * call; the loser is responsible for freeing thread resources. */
+	int state = a_cas(&self->detach_state, DT_JOINABLE, DT_EXITING);
+
+	if (state>=DT_DETACHED && self->map_base) {
+		/* Detached threads must avoid the kernel clear_child_tid
+		 * feature, since the virtual address will have been
+		 * unmapped and possibly already reused by a new mapping
+		 * at the time the kernel would perform the write. In
+		 * the case of threads that started out detached, the
+		 * initial clone flags are correct, but if the thread was
+		 * detached later, we need to clear it here. */
+		if (state == DT_DYNAMIC) __syscall(SYS_set_tid_address, 0);
+
+		/* Robust list will no longer be valid, and was already
+		 * processed above, so unregister it with the kernel. */
+		if (self->robust_list.off)
+			__syscall(SYS_set_robust_list, 0, 3*sizeof(long));
+
+		/* Since __unmapself bypasses the normal munmap code path,
+		 * explicitly wait for vmlock holders first. */
+		__vm_wait();
+
+		/* The following call unmaps the thread's stack mapping
+		 * and then exits without touching the stack. */
+		__unmapself(self->map_base, self->map_size);
+	}
+
+	/* After the kernel thread exits, its tid may be reused. Clear it
+	 * to prevent inadvertent use and inform functions that would use
+	 * it that it's no longer available. */
+	self->tid = 0;
+	UNLOCK(self->killlock);
+
+	for (;;) __syscall(SYS_exit, 0);
+}
+
+void __do_cleanup_push(struct __ptcb *cb)
+{
+	struct pthread *self = __pthread_self();
+	cb->__next = self->cancelbuf;
+	self->cancelbuf = cb;
+}
+
+void __do_cleanup_pop(struct __ptcb *cb)
+{
+	__pthread_self()->cancelbuf = cb->__next;
+}
+
+static int start(void *p)
+{
+	pthread_t self = p;
+	if (self->unblock_cancel)
+		__syscall(SYS_rt_sigprocmask, SIG_UNBLOCK,
+			SIGPT_SET, 0, _NSIG/8);
+	__pthread_exit(self->start(self->start_arg));
+	return 0;
+}
+
+static int start_c11(void *p)
+{
+	pthread_t self = p;
+	int (*start)(void*) = (int(*)(void*)) self->start;
+	__pthread_exit((void *)(uintptr_t)start(self->start_arg));
+	return 0;
+}
+
+#define ROUND(x) (((x)+PAGE_SIZE-1)&-PAGE_SIZE)
+
+/* pthread_key_create.c overrides this */
+static volatile size_t dummy = 0;
+weak_alias(dummy, __pthread_tsd_size);
+static void *dummy_tsd[1] = { 0 };
+weak_alias(dummy_tsd, __pthread_tsd_main);
+
+volatile int __block_new_threads = 0;
+
+static FILE *volatile dummy_file = 0;
+weak_alias(dummy_file, __stdin_used);
+weak_alias(dummy_file, __stdout_used);
+weak_alias(dummy_file, __stderr_used);
+
+static void init_file_lock(FILE *f)
+{
+	if (f && f->lock<0) f->lock = 0;
+}
+
+int __pthread_create(pthread_t *restrict res, const pthread_attr_t *restrict attrp, void *(*entry)(void *), void *restrict arg)
+{
+	int ret, c11 = (attrp == __ATTRP_C11_THREAD);
+	size_t size, guard;
+	struct pthread *self, *new;
+	unsigned char *map = 0, *stack = 0, *tsd = 0, *stack_limit;
+	unsigned flags = CLONE_VM | CLONE_FS | CLONE_FILES | CLONE_SIGHAND
+		| CLONE_THREAD | CLONE_SYSVSEM | CLONE_SETTLS
+		| CLONE_PARENT_SETTID | CLONE_CHILD_CLEARTID | CLONE_DETACHED;
+	int do_sched = 0;
+	pthread_attr_t attr = { 0 };
+	struct start_sched_args ssa;
+
+	if (!libc.can_do_threads) return ENOSYS;
+	self = __pthread_self();
+	if (!libc.threaded) {
+		for (FILE *f=*__ofl_lock(); f; f=f->next)
+			init_file_lock(f);
+		__ofl_unlock();
+		init_file_lock(__stdin_used);
+		init_file_lock(__stdout_used);
+		init_file_lock(__stderr_used);
+		__syscall(SYS_rt_sigprocmask, SIG_UNBLOCK, SIGPT_SET, 0, _NSIG/8);
+		self->tsd = (void **)__pthread_tsd_main;
+		libc.threaded = 1;
+	}
+	if (attrp && !c11) attr = *attrp;
+
+	__acquire_ptc();
+	if (!attrp || c11) {
+		attr._a_stacksize = __default_stacksize;
+		attr._a_guardsize = __default_guardsize;
+	}
+
+	if (__block_new_threads) __wait(&__block_new_threads, 0, 1, 1);
+
+	if (attr._a_stackaddr) {
+		size_t need = libc.tls_size + __pthread_tsd_size;
+		size = attr._a_stacksize;
+		stack = (void *)(attr._a_stackaddr & -16);
+		stack_limit = (void *)(attr._a_stackaddr - size);
+		/* Use application-provided stack for TLS only when
+		 * it does not take more than ~12% or 2k of the
+		 * application's stack space. */
+		if (need < size/8 && need < 2048) {
+			tsd = stack - __pthread_tsd_size;
+			stack = tsd - libc.tls_size;
+			memset(stack, 0, need);
+		} else {
+			size = ROUND(need);
+		}
+		guard = 0;
+	} else {
+		guard = ROUND(attr._a_guardsize);
+		size = guard + ROUND(attr._a_stacksize
+			+ libc.tls_size +  __pthread_tsd_size);
+	}
+
+	if (!tsd) {
+		if (guard) {
+			map = __mmap(0, size, PROT_NONE, MAP_PRIVATE|MAP_ANON, -1, 0);
+			if (map == MAP_FAILED) goto fail;
+			if (__mprotect(map+guard, size-guard, PROT_READ|PROT_WRITE)
+			    && errno != ENOSYS) {
+				__munmap(map, size);
+				goto fail;
+			}
+		} else {
+			map = __mmap(0, size, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANON, -1, 0);
+			if (map == MAP_FAILED) goto fail;
+		}
+		tsd = map + size - __pthread_tsd_size;
+		if (!stack) {
+			stack = tsd - libc.tls_size;
+			stack_limit = map + guard;
+		}
+	}
+
+	new = __copy_tls(tsd - libc.tls_size);
+	new->map_base = map;
+	new->map_size = size;
+	new->stack = stack;
+	new->stack_size = stack - stack_limit;
+	new->guard_size = guard;
+	new->start = entry;
+	new->start_arg = arg;
+	new->self = new;
+	new->tsd = (void *)tsd;
+	new->locale = &libc.global_locale;
+	if (attr._a_detach) {
+		new->detach_state = DT_DETACHED;
+		flags -= CLONE_CHILD_CLEARTID;
+	} else {
+		new->detach_state = DT_JOINABLE;
+	}
+	if (attr._a_sched) {
+		do_sched = 1;
+		ssa.futex = -1;
+		ssa.start_fn = new->start;
+		ssa.start_arg = new->start_arg;
+		ssa.attr = &attr;
+		new->start = __start_sched;
+		new->start_arg = &ssa;
+		__block_app_sigs(&ssa.mask);
+	}
+	new->robust_list.head = &new->robust_list.head;
+	new->unblock_cancel = self->cancel;
+	new->CANARY = self->CANARY;
+
+	a_inc(&libc.threads_minus_1);
+	ret = __clone((c11 ? start_c11 : start), stack, flags, new, &new->tid, TP_ADJ(new), &new->detach_state);
+
+	__release_ptc();
+
+	if (do_sched) {
+		__restore_sigs(&ssa.mask);
+	}
+
+	if (ret < 0) {
+		a_dec(&libc.threads_minus_1);
+		if (map) __munmap(map, size);
+		return EAGAIN;
+	}
+
+	if (do_sched) {
+		__futexwait(&ssa.futex, -1, 1);
+		ret = ssa.futex;
+		if (ret) return ret;
+	}
+
+	*res = new;
+	return 0;
+fail:
+	__release_ptc();
+	return EAGAIN;
+}
+
+weak_alias(__pthread_exit, pthread_exit);
+weak_alias(__pthread_create, pthread_create);
libc/musl/src/thread/pthread_detach.c
@@ -0,0 +1,14 @@
+#include "pthread_impl.h"
+#include <threads.h>
+
+static int __pthread_detach(pthread_t t)
+{
+	/* If the cas fails, detach state is either already-detached
+	 * or exiting/exited, and pthread_join will trap or cleanup. */
+	if (a_cas(&t->detach_state, DT_JOINABLE, DT_DYNAMIC) != DT_JOINABLE)
+		return __pthread_join(t, 0);
+	return 0;
+}
+
+weak_alias(__pthread_detach, pthread_detach);
+weak_alias(__pthread_detach, thrd_detach);
libc/musl/src/thread/pthread_equal.c
@@ -0,0 +1,10 @@
+#include <pthread.h>
+#include <threads.h>
+
+static int __pthread_equal(pthread_t a, pthread_t b)
+{
+	return a==b;
+}
+
+weak_alias(__pthread_equal, pthread_equal);
+weak_alias(__pthread_equal, thrd_equal);
libc/musl/src/thread/pthread_getattr_np.c
@@ -0,0 +1,24 @@
+#define _GNU_SOURCE
+#include "pthread_impl.h"
+#include "libc.h"
+#include <sys/mman.h>
+
+int pthread_getattr_np(pthread_t t, pthread_attr_t *a)
+{
+	*a = (pthread_attr_t){0};
+	a->_a_detach = t->detach_state>=DT_DETACHED;
+	a->_a_guardsize = t->guard_size;
+	if (t->stack) {
+		a->_a_stackaddr = (uintptr_t)t->stack;
+		a->_a_stacksize = t->stack_size;
+	} else {
+		char *p = (void *)libc.auxv;
+		size_t l = PAGE_SIZE;
+		p += -(uintptr_t)p & PAGE_SIZE-1;
+		a->_a_stackaddr = (uintptr_t)p;
+		while (mremap(p-l-PAGE_SIZE, PAGE_SIZE, 2*PAGE_SIZE, 0)==MAP_FAILED && errno==ENOMEM)
+			l += PAGE_SIZE;
+		a->_a_stacksize = l;
+	}
+	return 0;
+}
libc/musl/src/thread/pthread_getconcurrency.c
@@ -0,0 +1,6 @@
+#include <pthread.h>
+
+int pthread_getconcurrency()
+{
+	return 0;
+}
libc/musl/src/thread/pthread_getcpuclockid.c
@@ -0,0 +1,7 @@
+#include "pthread_impl.h"
+
+int pthread_getcpuclockid(pthread_t t, clockid_t *clockid)
+{
+	*clockid = (-t->tid-1)*8U + 6;
+	return 0;
+}
libc/musl/src/thread/pthread_getschedparam.c
@@ -0,0 +1,18 @@
+#include "pthread_impl.h"
+#include "lock.h"
+
+int pthread_getschedparam(pthread_t t, int *restrict policy, struct sched_param *restrict param)
+{
+	int r;
+	LOCK(t->killlock);
+	if (!t->tid) {
+		r = ESRCH;
+	} else {
+		r = -__syscall(SYS_sched_getparam, t->tid, param);
+		if (!r) {
+			*policy = __syscall(SYS_sched_getscheduler, t->tid);
+		}
+	}
+	UNLOCK(t->killlock);
+	return r;
+}
libc/musl/src/thread/pthread_getspecific.c
@@ -0,0 +1,11 @@
+#include "pthread_impl.h"
+#include <threads.h>
+
+static void *__pthread_getspecific(pthread_key_t k)
+{
+	struct pthread *self = __pthread_self();
+	return self->tsd[k];
+}
+
+weak_alias(__pthread_getspecific, pthread_getspecific);
+weak_alias(__pthread_getspecific, tss_get);
libc/musl/src/thread/pthread_join.c
@@ -0,0 +1,34 @@
+#include "pthread_impl.h"
+#include <sys/mman.h>
+
+static int __pthread_timedjoin_np(pthread_t t, void **res, const struct timespec *at)
+{
+	int state, cs, r = 0;
+	__pthread_testcancel();
+	__pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cs);
+	if (cs == PTHREAD_CANCEL_ENABLE) __pthread_setcancelstate(cs, 0);
+	while ((state = t->detach_state) && r != ETIMEDOUT && r != EINVAL) {
+		if (state >= DT_DETACHED) a_crash();
+		r = __timedwait_cp(&t->detach_state, state, CLOCK_REALTIME, at, 0);
+	}
+	__pthread_setcancelstate(cs, 0);
+	if (r == ETIMEDOUT || r == EINVAL) return r;
+	a_barrier();
+	if (res) *res = t->result;
+	if (t->map_base) __munmap(t->map_base, t->map_size);
+	return 0;
+}
+
+int __pthread_join(pthread_t t, void **res)
+{
+	return __pthread_timedjoin_np(t, res, 0);
+}
+
+static int __pthread_tryjoin_np(pthread_t t, void **res)
+{
+	return t->detach_state==DT_JOINABLE ? EBUSY : __pthread_join(t, res);
+}
+
+weak_alias(__pthread_tryjoin_np, pthread_tryjoin_np);
+weak_alias(__pthread_timedjoin_np, pthread_timedjoin_np);
+weak_alias(__pthread_join, pthread_join);
libc/musl/src/thread/pthread_key_create.c
@@ -0,0 +1,131 @@
+#include "pthread_impl.h"
+
+volatile size_t __pthread_tsd_size = sizeof(void *) * PTHREAD_KEYS_MAX;
+void *__pthread_tsd_main[PTHREAD_KEYS_MAX] = { 0 };
+
+static void (*keys[PTHREAD_KEYS_MAX])(void *);
+
+static pthread_rwlock_t key_lock = PTHREAD_RWLOCK_INITIALIZER;
+
+static pthread_key_t next_key;
+
+static void nodtor(void *dummy)
+{
+}
+
+static void dirty(void *dummy)
+{
+}
+
+struct cleanup_args {
+	pthread_t caller;
+	int ret;
+};
+
+static void clean_dirty_tsd_callback(void *p)
+{
+	struct cleanup_args *args = p;
+	pthread_t self = __pthread_self();
+	pthread_key_t i;
+	for (i=0; i<PTHREAD_KEYS_MAX; i++) {
+		if (keys[i] == dirty && self->tsd[i])
+			self->tsd[i] = 0;
+	}
+	/* Arbitrary choice to avoid data race. */
+	if (args->caller == self) args->ret = 0;
+}
+
+static void dummy2(void (*f)(void *), void *p)
+{
+}
+
+weak_alias(dummy2, __pthread_key_delete_synccall);
+
+static int clean_dirty_tsd(void)
+{
+	struct cleanup_args args = {
+		.caller = __pthread_self(),
+		.ret = EAGAIN
+	};
+	__pthread_key_delete_synccall(clean_dirty_tsd_callback, &args);
+	return args.ret;
+}
+
+int __pthread_key_create(pthread_key_t *k, void (*dtor)(void *))
+{
+	pthread_key_t j = next_key;
+	pthread_t self = __pthread_self();
+	int found_dirty = 0;
+
+	/* This can only happen in the main thread before
+	 * pthread_create has been called. */
+	if (!self->tsd) self->tsd = __pthread_tsd_main;
+
+	/* Purely a sentinel value since null means slot is free. */
+	if (!dtor) dtor = nodtor;
+
+	pthread_rwlock_wrlock(&key_lock);
+	do {
+		if (!keys[j]) {
+			keys[next_key = *k = j] = dtor;
+			pthread_rwlock_unlock(&key_lock);
+			return 0;
+		} else if (keys[j] == dirty) {
+			found_dirty = 1;
+		}
+	} while ((j=(j+1)%PTHREAD_KEYS_MAX) != next_key);
+
+	/* It's possible that all slots are in use or __synccall fails. */
+	if (!found_dirty || clean_dirty_tsd()) {
+		pthread_rwlock_unlock(&key_lock);
+		return EAGAIN;
+	}
+
+	/* If this point is reached there is necessarily a newly-cleaned
+	 * slot to allocate to satisfy the caller's request. Find it and
+	 * mark any additional previously-dirty slots clean. */
+	for (j=0; j<PTHREAD_KEYS_MAX; j++) {
+		if (keys[j] == dirty) {
+			if (dtor) {
+				keys[next_key = *k = j] = dtor;
+				dtor = 0;
+			} else {
+				keys[j] = 0;
+			}
+		}
+	}
+
+	pthread_rwlock_unlock(&key_lock);
+	return 0;
+}
+
+int __pthread_key_delete_impl(pthread_key_t k)
+{
+	pthread_rwlock_wrlock(&key_lock);
+	keys[k] = dirty;
+	pthread_rwlock_unlock(&key_lock);
+	return 0;
+}
+
+void __pthread_tsd_run_dtors()
+{
+	pthread_t self = __pthread_self();
+	int i, j;
+	for (j=0; self->tsd_used && j<PTHREAD_DESTRUCTOR_ITERATIONS; j++) {
+		pthread_rwlock_rdlock(&key_lock);
+		self->tsd_used = 0;
+		for (i=0; i<PTHREAD_KEYS_MAX; i++) {
+			void *val = self->tsd[i];
+			void (*dtor)(void *) = keys[i];
+			self->tsd[i] = 0;
+			if (val && dtor && dtor != nodtor && dtor != dirty) {
+				pthread_rwlock_unlock(&key_lock);
+				dtor(val);
+				pthread_rwlock_rdlock(&key_lock);
+			}
+		}
+		pthread_rwlock_unlock(&key_lock);
+	}
+}
+
+weak_alias(__pthread_key_create, pthread_key_create);
libc/musl/src/thread/pthread_key_delete.c
@@ -0,0 +1,14 @@
+#include "pthread_impl.h"
+#include "libc.h"
+
+void __pthread_key_delete_synccall(void (*f)(void *), void *p)
+{
+	__synccall(f, p);
+}
+
+int __pthread_key_delete(pthread_key_t k)
+{
+	return __pthread_key_delete_impl(k);
+}
+
+weak_alias(__pthread_key_delete, pthread_key_delete);
libc/musl/src/thread/pthread_kill.c
@@ -0,0 +1,12 @@
+#include "pthread_impl.h"
+#include "lock.h"
+
+int pthread_kill(pthread_t t, int sig)
+{
+	int r;
+	LOCK(t->killlock);
+	r = t->tid ? -__syscall(SYS_tkill, t->tid, sig)
+		: (sig+0U >= _NSIG ? EINVAL : 0);
+	UNLOCK(t->killlock);
+	return r;
+}
libc/musl/src/thread/pthread_mutex_consistent.c
@@ -0,0 +1,10 @@
+#include "pthread_impl.h"
+
+int pthread_mutex_consistent(pthread_mutex_t *m)
+{
+	if (!(m->_m_type & 8)) return EINVAL;
+	if ((m->_m_lock & 0x7fffffff) != __pthread_self()->tid)
+		return EPERM;
+	m->_m_type &= ~8U;
+	return 0;
+}
libc/musl/src/thread/pthread_mutex_destroy.c
@@ -0,0 +1,6 @@
+#include <pthread.h>
+
+int pthread_mutex_destroy(pthread_mutex_t *mutex)
+{
+	return 0;
+}
libc/musl/src/thread/pthread_mutex_getprioceiling.c
@@ -0,0 +1,6 @@
+#include "pthread_impl.h"
+
+int pthread_mutex_getprioceiling(const pthread_mutex_t *restrict m, int *restrict ceiling)
+{
+	return EINVAL;
+}
libc/musl/src/thread/pthread_mutex_init.c
@@ -0,0 +1,8 @@
+#include "pthread_impl.h"
+
+int pthread_mutex_init(pthread_mutex_t *restrict m, const pthread_mutexattr_t *restrict a)
+{
+	*m = (pthread_mutex_t){0};
+	if (a) m->_m_type = a->__attr;
+	return 0;
+}
libc/musl/src/thread/pthread_mutex_lock.c
@@ -0,0 +1,12 @@
+#include "pthread_impl.h"
+
+int __pthread_mutex_lock(pthread_mutex_t *m)
+{
+	if ((m->_m_type&15) == PTHREAD_MUTEX_NORMAL
+	    && !a_cas(&m->_m_lock, 0, EBUSY))
+		return 0;
+
+	return __pthread_mutex_timedlock(m, 0);
+}
+
+weak_alias(__pthread_mutex_lock, pthread_mutex_lock);
libc/musl/src/thread/pthread_mutex_setprioceiling.c
@@ -0,0 +1,6 @@
+#include "pthread_impl.h"
+
+int pthread_mutex_setprioceiling(pthread_mutex_t *restrict m, int ceiling, int *restrict old)
+{
+	return EINVAL;
+}
libc/musl/src/thread/pthread_mutex_timedlock.c
@@ -0,0 +1,35 @@
+#include "pthread_impl.h"
+
+int __pthread_mutex_timedlock(pthread_mutex_t *restrict m, const struct timespec *restrict at)
+{
+	if ((m->_m_type&15) == PTHREAD_MUTEX_NORMAL
+	    && !a_cas(&m->_m_lock, 0, EBUSY))
+		return 0;
+
+	int type = m->_m_type;
+	int r, t, priv = (type & 128) ^ 128;
+
+	r = pthread_mutex_trylock(m);
+	if (r != EBUSY) return r;
+	
+	int spins = 100;
+	while (spins-- && m->_m_lock && !m->_m_waiters) a_spin();
+
+	while ((r=__pthread_mutex_trylock(m)) == EBUSY) {
+		if (!(r=m->_m_lock) || ((r&0x40000000) && (type&4)))
+			continue;
+		if ((type&3) == PTHREAD_MUTEX_ERRORCHECK
+		 && (r&0x7fffffff) == __pthread_self()->tid)
+			return EDEADLK;
+
+		a_inc(&m->_m_waiters);
+		t = r | 0x80000000;
+		a_cas(&m->_m_lock, r, t);
+		r = __timedwait(&m->_m_lock, t, CLOCK_REALTIME, at, priv);
+		a_dec(&m->_m_waiters);
+		if (r && r != EINTR) break;
+	}
+	return r;
+}
+
+weak_alias(__pthread_mutex_timedlock, pthread_mutex_timedlock);
libc/musl/src/thread/pthread_mutex_trylock.c
@@ -0,0 +1,58 @@
+#include "pthread_impl.h"
+
+int __pthread_mutex_trylock_owner(pthread_mutex_t *m)
+{
+	int old, own;
+	int type = m->_m_type & 15;
+	pthread_t self = __pthread_self();
+	int tid = self->tid;
+
+	old = m->_m_lock;
+	own = old & 0x7fffffff;
+	if (own == tid && (type&3) == PTHREAD_MUTEX_RECURSIVE) {
+		if ((unsigned)m->_m_count >= INT_MAX) return EAGAIN;
+		m->_m_count++;
+		return 0;
+	}
+	if (own == 0x7fffffff) return ENOTRECOVERABLE;
+	if (own && (!(own & 0x40000000) || !(type & 4))) return EBUSY;
+
+	if (m->_m_type & 128) {
+		if (!self->robust_list.off) {
+			self->robust_list.off = (char*)&m->_m_lock-(char *)&m->_m_next;
+			__syscall(SYS_set_robust_list, &self->robust_list, 3*sizeof(long));
+		}
+		if (m->_m_waiters) tid |= 0x80000000;
+		self->robust_list.pending = &m->_m_next;
+	}
+
+	if (a_cas(&m->_m_lock, old, tid) != old) {
+		self->robust_list.pending = 0;
+		return EBUSY;
+	}
+
+	volatile void *next = self->robust_list.head;
+	m->_m_next = next;
+	m->_m_prev = &self->robust_list.head;
+	if (next != &self->robust_list.head) *(volatile void *volatile *)
+		((char *)next - sizeof(void *)) = &m->_m_next;
+	self->robust_list.head = &m->_m_next;
+	self->robust_list.pending = 0;
+
+	if (own) {
+		m->_m_count = 0;
+		m->_m_type |= 8;
+		return EOWNERDEAD;
+	}
+
+	return 0;
+}
+
+int __pthread_mutex_trylock(pthread_mutex_t *m)
+{
+	if ((m->_m_type&15) == PTHREAD_MUTEX_NORMAL)
+		return a_cas(&m->_m_lock, 0, EBUSY) & EBUSY;
+	return __pthread_mutex_trylock_owner(m);
+}
+
+weak_alias(__pthread_mutex_trylock, pthread_mutex_trylock);
libc/musl/src/thread/pthread_mutex_unlock.c
@@ -0,0 +1,37 @@
+#include "pthread_impl.h"
+
+int __pthread_mutex_unlock(pthread_mutex_t *m)
+{
+	pthread_t self;
+	int waiters = m->_m_waiters;
+	int cont;
+	int type = m->_m_type & 15;
+	int priv = (m->_m_type & 128) ^ 128;
+
+	if (type != PTHREAD_MUTEX_NORMAL) {
+		self = __pthread_self();
+		if ((m->_m_lock&0x7fffffff) != self->tid)
+			return EPERM;
+		if ((type&3) == PTHREAD_MUTEX_RECURSIVE && m->_m_count)
+			return m->_m_count--, 0;
+		if (!priv) {
+			self->robust_list.pending = &m->_m_next;
+			__vm_lock();
+		}
+		volatile void *prev = m->_m_prev;
+		volatile void *next = m->_m_next;
+		*(volatile void *volatile *)prev = next;
+		if (next != &self->robust_list.head) *(volatile void *volatile *)
+			((char *)next - sizeof(void *)) = prev;
+	}
+	cont = a_swap(&m->_m_lock, (type & 8) ? 0x7fffffff : 0);
+	if (type != PTHREAD_MUTEX_NORMAL && !priv) {
+		self->robust_list.pending = 0;
+		__vm_unlock();
+	}
+	if (waiters || cont<0)
+		__wake(&m->_m_lock, 1, priv);
+	return 0;
+}
+
+weak_alias(__pthread_mutex_unlock, pthread_mutex_unlock);
libc/musl/src/thread/pthread_mutexattr_destroy.c
@@ -0,0 +1,6 @@
+#include "pthread_impl.h"
+
+int pthread_mutexattr_destroy(pthread_mutexattr_t *a)
+{
+	return 0;
+}
libc/musl/src/thread/pthread_mutexattr_init.c
@@ -0,0 +1,7 @@
+#include "pthread_impl.h"
+
+int pthread_mutexattr_init(pthread_mutexattr_t *a)
+{
+	*a = (pthread_mutexattr_t){0};
+	return 0;
+}
libc/musl/src/thread/pthread_mutexattr_setprotocol.c
@@ -0,0 +1,7 @@
+#include "pthread_impl.h"
+
+int pthread_mutexattr_setprotocol(pthread_mutexattr_t *a, int protocol)
+{
+	if (protocol) return ENOTSUP;
+	return 0;
+}
libc/musl/src/thread/pthread_mutexattr_setpshared.c
@@ -0,0 +1,9 @@
+#include "pthread_impl.h"
+
+int pthread_mutexattr_setpshared(pthread_mutexattr_t *a, int pshared)
+{
+	if (pshared > 1U) return EINVAL;
+	a->__attr &= ~128U;
+	a->__attr |= pshared<<7;
+	return 0;
+}
libc/musl/src/thread/pthread_mutexattr_setrobust.c
@@ -0,0 +1,25 @@
+#include "pthread_impl.h"
+#include "syscall.h"
+
+static pthread_once_t check_robust_once;
+static int check_robust_result;
+
+static void check_robust()
+{
+	void *p;
+	size_t l;
+	check_robust_result = -__syscall(SYS_get_robust_list, 0, &p, &l);
+}
+
+int pthread_mutexattr_setrobust(pthread_mutexattr_t *a, int robust)
+{
+	if (robust > 1U) return EINVAL;
+	if (robust) {
+		pthread_once(&check_robust_once, check_robust);
+		if (check_robust_result) return check_robust_result;
+		a->__attr |= 4;
+		return 0;
+	}
+	a->__attr &= ~4;
+	return 0;
+}
libc/musl/src/thread/pthread_mutexattr_settype.c
@@ -0,0 +1,8 @@
+#include "pthread_impl.h"
+
+int pthread_mutexattr_settype(pthread_mutexattr_t *a, int type)
+{
+	if ((unsigned)type > 2) return EINVAL;
+	a->__attr = (a->__attr & ~3) | type;
+	return 0;
+}
libc/musl/src/thread/pthread_once.c
@@ -0,0 +1,50 @@
+#include "pthread_impl.h"
+
+static void undo(void *control)
+{
+	/* Wake all waiters, since the waiter status is lost when
+	 * resetting control to the initial state. */
+	if (a_swap(control, 0) == 3)
+		__wake(control, -1, 1);
+}
+
+hidden int __pthread_once_full(pthread_once_t *control, void (*init)(void))
+{
+	/* Try to enter initializing state. Four possibilities:
+	 *  0 - we're the first or the other cancelled; run init
+	 *  1 - another thread is running init; wait
+	 *  2 - another thread finished running init; just return
+	 *  3 - another thread is running init, waiters present; wait */
+
+	for (;;) switch (a_cas(control, 0, 1)) {
+	case 0:
+		pthread_cleanup_push(undo, control);
+		init();
+		pthread_cleanup_pop(0);
+
+		if (a_swap(control, 2) == 3)
+			__wake(control, -1, 1);
+		return 0;
+	case 1:
+		/* If this fails, so will __wait. */
+		a_cas(control, 1, 3);
+	case 3:
+		__wait(control, 0, 3, 1);
+		continue;
+	case 2:
+		return 0;
+	}
+}
+
+int __pthread_once(pthread_once_t *control, void (*init)(void))
+{
+	/* Return immediately if init finished before, but ensure that
+	 * effects of the init routine are visible to the caller. */
+	if (*(volatile int *)control == 2) {
+		a_barrier();
+		return 0;
+	}
+	return __pthread_once_full(control, init);
+}
+
+weak_alias(__pthread_once, pthread_once);
libc/musl/src/thread/pthread_rwlock_destroy.c
@@ -0,0 +1,6 @@
+#include "pthread_impl.h"
+
+int pthread_rwlock_destroy(pthread_rwlock_t *rw)
+{
+	return 0;
+}
libc/musl/src/thread/pthread_rwlock_init.c
@@ -0,0 +1,8 @@
+#include "pthread_impl.h"
+
+int pthread_rwlock_init(pthread_rwlock_t *restrict rw, const pthread_rwlockattr_t *restrict a)
+{
+	*rw = (pthread_rwlock_t){0};
+	if (a) rw->_rw_shared = a->__attr[0]*128;
+	return 0;
+}
libc/musl/src/thread/pthread_rwlock_rdlock.c
@@ -0,0 +1,6 @@
+#include "pthread_impl.h"
+
+int pthread_rwlock_rdlock(pthread_rwlock_t *rw)
+{
+	return pthread_rwlock_timedrdlock(rw, 0);
+}
libc/musl/src/thread/pthread_rwlock_timedrdlock.c
@@ -0,0 +1,23 @@
+#include "pthread_impl.h"
+
+int pthread_rwlock_timedrdlock(pthread_rwlock_t *restrict rw, const struct timespec *restrict at)
+{
+	int r, t;
+
+	r = pthread_rwlock_tryrdlock(rw);
+	if (r != EBUSY) return r;
+	
+	int spins = 100;
+	while (spins-- && rw->_rw_lock && !rw->_rw_waiters) a_spin();
+
+	while ((r=pthread_rwlock_tryrdlock(rw))==EBUSY) {
+		if (!(r=rw->_rw_lock) || (r&0x7fffffff)!=0x7fffffff) continue;
+		t = r | 0x80000000;
+		a_inc(&rw->_rw_waiters);
+		a_cas(&rw->_rw_lock, r, t);
+		r = __timedwait(&rw->_rw_lock, t, CLOCK_REALTIME, at, rw->_rw_shared^128);
+		a_dec(&rw->_rw_waiters);
+		if (r && r != EINTR) return r;
+	}
+	return r;
+}
libc/musl/src/thread/pthread_rwlock_timedwrlock.c
@@ -0,0 +1,23 @@
+#include "pthread_impl.h"
+
+int pthread_rwlock_timedwrlock(pthread_rwlock_t *restrict rw, const struct timespec *restrict at)
+{
+	int r, t;
+	
+	r = pthread_rwlock_trywrlock(rw);
+	if (r != EBUSY) return r;
+	
+	int spins = 100;
+	while (spins-- && rw->_rw_lock && !rw->_rw_waiters) a_spin();
+
+	while ((r=pthread_rwlock_trywrlock(rw))==EBUSY) {
+		if (!(r=rw->_rw_lock)) continue;
+		t = r | 0x80000000;
+		a_inc(&rw->_rw_waiters);
+		a_cas(&rw->_rw_lock, r, t);
+		r = __timedwait(&rw->_rw_lock, t, CLOCK_REALTIME, at, rw->_rw_shared^128);
+		a_dec(&rw->_rw_waiters);
+		if (r && r != EINTR) return r;
+	}
+	return r;
+}
libc/musl/src/thread/pthread_rwlock_tryrdlock.c
@@ -0,0 +1,13 @@
+#include "pthread_impl.h"
+
+int pthread_rwlock_tryrdlock(pthread_rwlock_t *rw)
+{
+	int val, cnt;
+	do {
+		val = rw->_rw_lock;
+		cnt = val & 0x7fffffff;
+		if (cnt == 0x7fffffff) return EBUSY;
+		if (cnt == 0x7ffffffe) return EAGAIN;
+	} while (a_cas(&rw->_rw_lock, val, val+1) != val);
+	return 0;
+}
libc/musl/src/thread/pthread_rwlock_trywrlock.c
@@ -0,0 +1,7 @@
+#include "pthread_impl.h"
+
+int pthread_rwlock_trywrlock(pthread_rwlock_t *rw)
+{
+	if (a_cas(&rw->_rw_lock, 0, 0x7fffffff)) return EBUSY;
+	return 0;
+}
libc/musl/src/thread/pthread_rwlock_unlock.c
@@ -0,0 +1,18 @@
+#include "pthread_impl.h"
+
+int pthread_rwlock_unlock(pthread_rwlock_t *rw)
+{
+	int val, cnt, waiters, new, priv = rw->_rw_shared^128;
+
+	do {
+		val = rw->_rw_lock;
+		cnt = val & 0x7fffffff;
+		waiters = rw->_rw_waiters;
+		new = (cnt == 0x7fffffff || cnt == 1) ? 0 : val-1;
+	} while (a_cas(&rw->_rw_lock, val, new) != val);
+
+	if (!new && (waiters || val<0))
+		__wake(&rw->_rw_lock, cnt, priv);
+
+	return 0;
+}
libc/musl/src/thread/pthread_rwlock_wrlock.c
@@ -0,0 +1,6 @@
+#include "pthread_impl.h"
+
+int pthread_rwlock_wrlock(pthread_rwlock_t *rw)
+{
+	return pthread_rwlock_timedwrlock(rw, 0);
+}
libc/musl/src/thread/pthread_rwlockattr_destroy.c
@@ -0,0 +1,6 @@
+#include "pthread_impl.h"
+
+int pthread_rwlockattr_destroy(pthread_rwlockattr_t *a)
+{
+	return 0;
+}
libc/musl/src/thread/pthread_rwlockattr_init.c
@@ -0,0 +1,7 @@
+#include "pthread_impl.h"
+
+int pthread_rwlockattr_init(pthread_rwlockattr_t *a)
+{
+	*a = (pthread_rwlockattr_t){0};
+	return 0;
+}
libc/musl/src/thread/pthread_rwlockattr_setpshared.c
@@ -0,0 +1,8 @@
+#include "pthread_impl.h"
+
+int pthread_rwlockattr_setpshared(pthread_rwlockattr_t *a, int pshared)
+{
+	if (pshared > 1U) return EINVAL;
+	a->__attr[0] = pshared;
+	return 0;
+}
libc/musl/src/thread/pthread_self.c
@@ -0,0 +1,10 @@
+#include "pthread_impl.h"
+#include <threads.h>
+
+static pthread_t __pthread_self_internal()
+{
+	return __pthread_self();
+}
+
+weak_alias(__pthread_self_internal, pthread_self);
+weak_alias(__pthread_self_internal, thrd_current);
libc/musl/src/thread/pthread_setattr_default_np.c
@@ -0,0 +1,37 @@
+#define _GNU_SOURCE
+#include "pthread_impl.h"
+#include <string.h>
+
+#define MIN(a,b) ((a)<(b) ? (a) : (b))
+#define MAX(a,b) ((a)>(b) ? (a) : (b))
+
+int pthread_setattr_default_np(const pthread_attr_t *attrp)
+{
+	/* Reject anything in the attr object other than stack/guard size. */
+	pthread_attr_t tmp = *attrp, zero = { 0 };
+	tmp._a_stacksize = 0;
+	tmp._a_guardsize = 0;
+	if (memcmp(&tmp, &zero, sizeof tmp))
+		return EINVAL;
+
+	unsigned stack = MIN(attrp->_a_stacksize, DEFAULT_STACK_MAX);
+	unsigned guard = MIN(attrp->_a_guardsize, DEFAULT_GUARD_MAX);
+
+	__inhibit_ptc();
+	__default_stacksize = MAX(__default_stacksize, stack);
+	__default_guardsize = MAX(__default_guardsize, guard);
+	__release_ptc();
+
+	return 0;
+}
+
+int pthread_getattr_default_np(pthread_attr_t *attrp)
+{
+	__acquire_ptc();
+	*attrp = (pthread_attr_t) {
+		._a_stacksize = __default_stacksize,
+		._a_guardsize = __default_guardsize,
+	};
+	__release_ptc();
+	return 0;
+}
libc/musl/src/thread/pthread_setcancelstate.c
@@ -0,0 +1,12 @@
+#include "pthread_impl.h"
+
+int __pthread_setcancelstate(int new, int *old)
+{
+	if (new > 2U) return EINVAL;
+	struct pthread *self = __pthread_self();
+	if (old) *old = self->canceldisable;
+	self->canceldisable = new;
+	return 0;
+}
+
+weak_alias(__pthread_setcancelstate, pthread_setcancelstate);
libc/musl/src/thread/pthread_setcanceltype.c
@@ -0,0 +1,11 @@
+#include "pthread_impl.h"
+
+int pthread_setcanceltype(int new, int *old)
+{
+	struct pthread *self = __pthread_self();
+	if (new > 1U) return EINVAL;
+	if (old) *old = self->cancelasync;
+	self->cancelasync = new;
+	if (new) pthread_testcancel();
+	return 0;
+}
libc/musl/src/thread/pthread_setconcurrency.c
@@ -0,0 +1,9 @@
+#include <pthread.h>
+#include <errno.h>
+
+int pthread_setconcurrency(int val)
+{
+	if (val < 0) return EINVAL;
+	if (val > 0) return EAGAIN;
+	return 0;
+}
libc/musl/src/thread/pthread_setname_np.c
@@ -0,0 +1,26 @@
+#define _GNU_SOURCE
+#include <fcntl.h>
+#include <string.h>
+#include <unistd.h>
+#include <sys/prctl.h>
+
+#include "pthread_impl.h"
+
+int pthread_setname_np(pthread_t thread, const char *name)
+{
+	int fd, cs, status = 0;
+	char f[sizeof "/proc/self/task//comm" + 3*sizeof(int)];
+	size_t len;
+
+	if ((len = strnlen(name, 16)) > 15) return ERANGE;
+
+	if (thread == pthread_self())
+		return prctl(PR_SET_NAME, (unsigned long)name, 0UL, 0UL, 0UL) ? errno : 0;
+
+	snprintf(f, sizeof f, "/proc/self/task/%d/comm", thread->tid);
+	pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cs);
+	if ((fd = open(f, O_WRONLY)) < 0 || write(fd, name, len) < 0) status = errno;
+	if (fd >= 0) close(fd);
+	pthread_setcancelstate(cs, 0);
+	return status;
+}
libc/musl/src/thread/pthread_setschedparam.c
@@ -0,0 +1,11 @@
+#include "pthread_impl.h"
+#include "lock.h"
+
+int pthread_setschedparam(pthread_t t, int policy, const struct sched_param *param)
+{
+	int r;
+	LOCK(t->killlock);
+	r = !t->tid ? ESRCH : -__syscall(SYS_sched_setscheduler, t->tid, policy, param);
+	UNLOCK(t->killlock);
+	return r;
+}
libc/musl/src/thread/pthread_setschedprio.c
@@ -0,0 +1,11 @@
+#include "pthread_impl.h"
+#include "lock.h"
+
+int pthread_setschedprio(pthread_t t, int prio)
+{
+	int r;
+	LOCK(t->killlock);
+	r = !t->tid ? ESRCH : -__syscall(SYS_sched_setparam, t->tid, &prio);
+	UNLOCK(t->killlock);
+	return r;
+}
libc/musl/src/thread/pthread_setspecific.c
@@ -0,0 +1,12 @@
+#include "pthread_impl.h"
+
+int pthread_setspecific(pthread_key_t k, const void *x)
+{
+	struct pthread *self = __pthread_self();
+	/* Avoid unnecessary COW */
+	if (self->tsd[k] != x) {
+		self->tsd[k] = (void *)x;
+		self->tsd_used = 1;
+	}
+	return 0;
+}
libc/musl/src/thread/pthread_sigmask.c
@@ -0,0 +1,19 @@
+#include <signal.h>
+#include <errno.h>
+#include "syscall.h"
+
+int pthread_sigmask(int how, const sigset_t *restrict set, sigset_t *restrict old)
+{
+	int ret;
+	if (set && (unsigned)how - SIG_BLOCK > 2U) return EINVAL;
+	ret = -__syscall(SYS_rt_sigprocmask, how, set, old, _NSIG/8);
+	if (!ret && old) {
+		if (sizeof old->__bits[0] == 8) {
+			old->__bits[0] &= ~0x380000000ULL;
+		} else {
+			old->__bits[0] &= ~0x80000000UL;
+			old->__bits[1] &= ~0x3UL;
+		}
+	}
+	return ret;
+}
libc/musl/src/thread/pthread_spin_destroy.c
@@ -0,0 +1,6 @@
+#include "pthread_impl.h"
+
+int pthread_spin_destroy(pthread_spinlock_t *s)
+{
+	return 0;
+}
libc/musl/src/thread/pthread_spin_init.c
@@ -0,0 +1,6 @@
+#include "pthread_impl.h"
+
+int pthread_spin_init(pthread_spinlock_t *s, int shared)
+{
+	return *s = 0;
+}
libc/musl/src/thread/pthread_spin_lock.c
@@ -0,0 +1,8 @@
+#include "pthread_impl.h"
+#include <errno.h>
+
+int pthread_spin_lock(pthread_spinlock_t *s)
+{
+	while (*(volatile int *)s || a_cas(s, 0, EBUSY)) a_spin();
+	return 0;
+}
libc/musl/src/thread/pthread_spin_trylock.c
@@ -0,0 +1,7 @@
+#include "pthread_impl.h"
+#include <errno.h>
+
+int pthread_spin_trylock(pthread_spinlock_t *s)
+{
+	return a_cas(s, 0, EBUSY);
+}
libc/musl/src/thread/pthread_spin_unlock.c
@@ -0,0 +1,7 @@
+#include "pthread_impl.h"
+
+int pthread_spin_unlock(pthread_spinlock_t *s)
+{
+	a_store(s, 0);
+	return 0;
+}
libc/musl/src/thread/pthread_testcancel.c
@@ -0,0 +1,14 @@
+#include "pthread_impl.h"
+
+static void dummy()
+{
+}
+
+weak_alias(dummy, __testcancel);
+
+void __pthread_testcancel()
+{
+	__testcancel();
+}
+
+weak_alias(__pthread_testcancel, pthread_testcancel);
libc/musl/src/thread/sem_destroy.c
@@ -0,0 +1,6 @@
+#include <semaphore.h>
+
+int sem_destroy(sem_t *sem)
+{
+	return 0;
+}
libc/musl/src/thread/sem_getvalue.c
@@ -0,0 +1,8 @@
+#include <semaphore.h>
+
+int sem_getvalue(sem_t *restrict sem, int *restrict valp)
+{
+	int val = sem->__val[0];
+	*valp = val < 0 ? 0 : val;
+	return 0;
+}
libc/musl/src/thread/sem_init.c
@@ -0,0 +1,15 @@
+#include <semaphore.h>
+#include <limits.h>
+#include <errno.h>
+
+int sem_init(sem_t *sem, int pshared, unsigned value)
+{
+	if (value > SEM_VALUE_MAX) {
+		errno = EINVAL;
+		return -1;
+	}
+	sem->__val[0] = value;
+	sem->__val[1] = 0;
+	sem->__val[2] = pshared ? 0 : 128;
+	return 0;
+}
libc/musl/src/thread/sem_open.c
@@ -0,0 +1,173 @@
+#include <semaphore.h>
+#include <sys/mman.h>
+#include <limits.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <string.h>
+#include <stdarg.h>
+#include <errno.h>
+#include <time.h>
+#include <stdio.h>
+#include <sys/stat.h>
+#include <stdlib.h>
+#include <pthread.h>
+#include "lock.h"
+
+static struct {
+	ino_t ino;
+	sem_t *sem;
+	int refcnt;
+} *semtab;
+static volatile int lock[1];
+
+#define FLAGS (O_RDWR|O_NOFOLLOW|O_CLOEXEC|O_NONBLOCK)
+
+sem_t *sem_open(const char *name, int flags, ...)
+{
+	va_list ap;
+	mode_t mode;
+	unsigned value;
+	int fd, i, e, slot, first=1, cnt, cs;
+	sem_t newsem;
+	void *map;
+	char tmp[64];
+	struct timespec ts;
+	struct stat st;
+	char buf[NAME_MAX+10];
+
+	if (!(name = __shm_mapname(name, buf)))
+		return SEM_FAILED;
+
+	LOCK(lock);
+	/* Allocate table if we don't have one yet */
+	if (!semtab && !(semtab = calloc(sizeof *semtab, SEM_NSEMS_MAX))) {
+		UNLOCK(lock);
+		return SEM_FAILED;
+	}
+
+	/* Reserve a slot in case this semaphore is not mapped yet;
+	 * this is necessary because there is no way to handle
+	 * failures after creation of the file. */
+	slot = -1;
+	for (cnt=i=0; i<SEM_NSEMS_MAX; i++) {
+		cnt += semtab[i].refcnt;
+		if (!semtab[i].sem && slot < 0) slot = i;
+	}
+	/* Avoid possibility of overflow later */
+	if (cnt == INT_MAX || slot < 0) {
+		errno = EMFILE;
+		UNLOCK(lock);
+		return SEM_FAILED;
+	}
+	/* Dummy pointer to make a reservation */
+	semtab[slot].sem = (sem_t *)-1;
+	UNLOCK(lock);
+
+	flags &= (O_CREAT|O_EXCL);
+
+	pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cs);
+
+	/* Early failure check for exclusive open; otherwise the case
+	 * where the semaphore already exists is expensive. */
+	if (flags == (O_CREAT|O_EXCL) && access(name, F_OK) == 0) {
+		errno = EEXIST;
+		goto fail;
+	}
+
+	for (;;) {
+		/* If exclusive mode is not requested, try opening an
+		 * existing file first and fall back to creation. */
+		if (flags != (O_CREAT|O_EXCL)) {
+			fd = open(name, FLAGS);
+			if (fd >= 0) {
+				if (fstat(fd, &st) < 0 ||
+				    (map = mmap(0, sizeof(sem_t), PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0)) == MAP_FAILED) {
+					close(fd);
+					goto fail;
+				}
+				close(fd);
+				break;
+			}
+			if (errno != ENOENT)
+				goto fail;
+		}
+		if (!(flags & O_CREAT))
+			goto fail;
+		if (first) {
+			first = 0;
+			va_start(ap, flags);
+			mode = va_arg(ap, mode_t) & 0666;
+			value = va_arg(ap, unsigned);
+			va_end(ap);
+			if (value > SEM_VALUE_MAX) {
+				errno = EINVAL;
+				goto fail;
+			}
+			sem_init(&newsem, 1, value);
+		}
+		/* Create a temp file with the new semaphore contents
+		 * and attempt to atomically link it as the new name */
+		clock_gettime(CLOCK_REALTIME, &ts);
+		snprintf(tmp, sizeof(tmp), "/dev/shm/tmp-%d", (int)ts.tv_nsec);
+		fd = open(tmp, O_CREAT|O_EXCL|FLAGS, mode);
+		if (fd < 0) {
+			if (errno == EEXIST) continue;
+			goto fail;
+		}
+		if (write(fd, &newsem, sizeof newsem) != sizeof newsem || fstat(fd, &st) < 0 ||
+		    (map = mmap(0, sizeof(sem_t), PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0)) == MAP_FAILED) {
+			close(fd);
+			unlink(tmp);
+			goto fail;
+		}
+		close(fd);
+		e = link(tmp, name) ? errno : 0;
+		unlink(tmp);
+		if (!e) break;
+		munmap(map, sizeof(sem_t));
+		/* Failure is only fatal when doing an exclusive open;
+		 * otherwise, next iteration will try to open the
+		 * existing file. */
+		if (e != EEXIST || flags == (O_CREAT|O_EXCL))
+			goto fail;
+	}
+
+	/* See if the newly mapped semaphore is already mapped. If
+	 * so, unmap the new mapping and use the existing one. Otherwise,
+	 * add it to the table of mapped semaphores. */
+	LOCK(lock);
+	for (i=0; i<SEM_NSEMS_MAX && semtab[i].ino != st.st_ino; i++);
+	if (i<SEM_NSEMS_MAX) {
+		munmap(map, sizeof(sem_t));
+		semtab[slot].sem = 0;
+		slot = i;
+		map = semtab[i].sem;
+	}
+	semtab[slot].refcnt++;
+	semtab[slot].sem = map;
+	semtab[slot].ino = st.st_ino;
+	UNLOCK(lock);
+	pthread_setcancelstate(cs, 0);
+	return map;
+
+fail:
+	pthread_setcancelstate(cs, 0);
+	LOCK(lock);
+	semtab[slot].sem = 0;
+	UNLOCK(lock);
+	return SEM_FAILED;
+}
+
+int sem_close(sem_t *sem)
+{
+	int i;
+	LOCK(lock);
+	for (i=0; i<SEM_NSEMS_MAX && semtab[i].sem != sem; i++);
+	if (!--semtab[i].refcnt) {
+		semtab[i].sem = 0;
+		semtab[i].ino = 0;
+	}
+	UNLOCK(lock);
+	munmap(sem, sizeof *sem);
+	return 0;
+}
libc/musl/src/thread/sem_post.c
@@ -0,0 +1,17 @@
+#include <semaphore.h>
+#include "pthread_impl.h"
+
+int sem_post(sem_t *sem)
+{
+	int val, waiters, priv = sem->__val[2];
+	do {
+		val = sem->__val[0];
+		waiters = sem->__val[1];
+		if (val == SEM_VALUE_MAX) {
+			errno = EOVERFLOW;
+			return -1;
+		}
+	} while (a_cas(sem->__val, val, val+1+(val<0)) != val);
+	if (val<0 || waiters) __wake(sem->__val, 1, priv);
+	return 0;
+}
libc/musl/src/thread/sem_timedwait.c
@@ -0,0 +1,31 @@
+#include <semaphore.h>
+#include "pthread_impl.h"
+
+static void cleanup(void *p)
+{
+	a_dec(p);
+}
+
+int sem_timedwait(sem_t *restrict sem, const struct timespec *restrict at)
+{
+	pthread_testcancel();
+
+	if (!sem_trywait(sem)) return 0;
+
+	int spins = 100;
+	while (spins-- && sem->__val[0] <= 0 && !sem->__val[1]) a_spin();
+
+	while (sem_trywait(sem)) {
+		int r;
+		a_inc(sem->__val+1);
+		a_cas(sem->__val, 0, -1);
+		pthread_cleanup_push(cleanup, (void *)(sem->__val+1));
+		r = __timedwait_cp(sem->__val, -1, CLOCK_REALTIME, at, sem->__val[2]);
+		pthread_cleanup_pop(1);
+		if (r) {
+			errno = r;
+			return -1;
+		}
+	}
+	return 0;
+}
libc/musl/src/thread/sem_trywait.c
@@ -0,0 +1,13 @@
+#include <semaphore.h>
+#include "pthread_impl.h"
+
+int sem_trywait(sem_t *sem)
+{
+	int val;
+	while ((val=sem->__val[0]) > 0) {
+		int new = val-1-(val==1 && sem->__val[1]);
+		if (a_cas(sem->__val, val, new)==val) return 0;
+	}
+	errno = EAGAIN;
+	return -1;
+}
libc/musl/src/thread/sem_unlink.c
@@ -0,0 +1,7 @@
+#include <semaphore.h>
+#include <sys/mman.h>
+
+int sem_unlink(const char *name)
+{
+	return shm_unlink(name);
+}
libc/musl/src/thread/sem_wait.c
@@ -0,0 +1,6 @@
+#include <semaphore.h>
+
+int sem_wait(sem_t *sem)
+{
+	return sem_timedwait(sem, 0);
+}
libc/musl/src/thread/synccall.c
@@ -0,0 +1,179 @@
+#include "pthread_impl.h"
+#include <semaphore.h>
+#include <unistd.h>
+#include <dirent.h>
+#include <string.h>
+#include <ctype.h>
+#include "futex.h"
+#include "atomic.h"
+#include "../dirent/__dirent.h"
+#include "lock.h"
+
+static struct chain {
+	struct chain *next;
+	int tid;
+	sem_t target_sem, caller_sem;
+} *volatile head;
+
+static volatile int synccall_lock[1];
+static volatile int target_tid;
+static void (*callback)(void *), *context;
+static volatile int dummy = 0;
+weak_alias(dummy, __block_new_threads);
+
+static void handler(int sig)
+{
+	struct chain ch;
+	int old_errno = errno;
+
+	sem_init(&ch.target_sem, 0, 0);
+	sem_init(&ch.caller_sem, 0, 0);
+
+	ch.tid = __syscall(SYS_gettid);
+
+	do ch.next = head;
+	while (a_cas_p(&head, ch.next, &ch) != ch.next);
+
+	if (a_cas(&target_tid, ch.tid, 0) == (ch.tid | 0x80000000))
+		__syscall(SYS_futex, &target_tid, FUTEX_UNLOCK_PI|FUTEX_PRIVATE);
+
+	sem_wait(&ch.target_sem);
+	callback(context);
+	sem_post(&ch.caller_sem);
+	sem_wait(&ch.target_sem);
+
+	errno = old_errno;
+}
+
+void __synccall(void (*func)(void *), void *ctx)
+{
+	sigset_t oldmask;
+	int cs, i, r, pid, self;;
+	DIR dir = {0};
+	struct dirent *de;
+	struct sigaction sa = { .sa_flags = SA_RESTART, .sa_handler = handler };
+	struct chain *cp, *next;
+	struct timespec ts;
+
+	/* Blocking signals in two steps, first only app-level signals
+	 * before taking the lock, then all signals after taking the lock,
+	 * is necessary to achieve AS-safety. Blocking them all first would
+	 * deadlock if multiple threads called __synccall. Waiting to block
+	 * any until after the lock would allow re-entry in the same thread
+	 * with the lock already held. */
+	__block_app_sigs(&oldmask);
+	LOCK(synccall_lock);
+	__block_all_sigs(0);
+	pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cs);
+
+	head = 0;
+
+	if (!libc.threaded) goto single_threaded;
+
+	callback = func;
+	context = ctx;
+
+	/* This atomic store ensures that any signaled threads will see the
+	 * above stores, and prevents more than a bounded number of threads,
+	 * those already in pthread_create, from creating new threads until
+	 * the value is cleared to zero again. */
+	a_store(&__block_new_threads, 1);
+
+	/* Block even implementation-internal signals, so that nothing
+	 * interrupts the SIGSYNCCALL handlers. The main possible source
+	 * of trouble is asynchronous cancellation. */
+	memset(&sa.sa_mask, -1, sizeof sa.sa_mask);
+	__libc_sigaction(SIGSYNCCALL, &sa, 0);
+
+	pid = __syscall(SYS_getpid);
+	self = __syscall(SYS_gettid);
+
+	/* Since opendir is not AS-safe, the DIR needs to be setup manually
+	 * in automatic storage. Thankfully this is easy. */
+	dir.fd = open("/proc/self/task", O_RDONLY|O_DIRECTORY|O_CLOEXEC);
+	if (dir.fd < 0) goto out;
+
+	/* Initially send one signal per counted thread. But since we can't
+	 * synchronize with thread creation/exit here, there could be too
+	 * few signals. This initial signaling is just an optimization, not
+	 * part of the logic. */
+	for (i=libc.threads_minus_1; i; i--)
+		__syscall(SYS_kill, pid, SIGSYNCCALL);
+
+	/* Loop scanning the kernel-provided thread list until it shows no
+	 * threads that have not already replied to the signal. */
+	for (;;) {
+		int miss_cnt = 0;
+		while ((de = readdir(&dir))) {
+			if (!isdigit(de->d_name[0])) continue;
+			int tid = atoi(de->d_name);
+			if (tid == self || !tid) continue;
+
+			/* Set the target thread as the PI futex owner before
+			 * checking if it's in the list of caught threads. If it
+			 * adds itself to the list after we check for it, then
+			 * it will see its own tid in the PI futex and perform
+			 * the unlock operation. */
+			a_store(&target_tid, tid);
+
+			/* Thread-already-caught is a success condition. */
+			for (cp = head; cp && cp->tid != tid; cp=cp->next);
+			if (cp) continue;
+
+			r = -__syscall(SYS_tgkill, pid, tid, SIGSYNCCALL);
+
+			/* Target thread exit is a success condition. */
+			if (r == ESRCH) continue;
+
+			/* The FUTEX_LOCK_PI operation is used to loan priority
+			 * to the target thread, which otherwise may be unable
+			 * to run. Timeout is necessary because there is a race
+			 * condition where the tid may be reused by a different
+			 * process. */
+			clock_gettime(CLOCK_REALTIME, &ts);
+			ts.tv_nsec += 10000000;
+			if (ts.tv_nsec >= 1000000000) {
+				ts.tv_sec++;
+				ts.tv_nsec -= 1000000000;
+			}
+			r = -__syscall(SYS_futex, &target_tid,
+				FUTEX_LOCK_PI|FUTEX_PRIVATE, 0, &ts);
+
+			/* Obtaining the lock means the thread responded. ESRCH
+			 * means the target thread exited, which is okay too. */
+			if (!r || r == ESRCH) continue;
+
+			miss_cnt++;
+		}
+		if (!miss_cnt) break;
+		rewinddir(&dir);
+	}
+	close(dir.fd);
+
+	/* Serialize execution of callback in caught threads. */
+	for (cp=head; cp; cp=cp->next) {
+		sem_post(&cp->target_sem);
+		sem_wait(&cp->caller_sem);
+	}
+
+	sa.sa_handler = SIG_IGN;
+	__libc_sigaction(SIGSYNCCALL, &sa, 0);
+
+single_threaded:
+	func(ctx);
+
+	/* Only release the caught threads once all threads, including the
+	 * caller, have returned from the callback function. */
+	for (cp=head; cp; cp=next) {
+		next = cp->next;
+		sem_post(&cp->target_sem);
+	}
+
+out:
+	a_store(&__block_new_threads, 0);
+	__wake(&__block_new_threads, -1, 1);
+
+	pthread_setcancelstate(cs, 0);
+	UNLOCK(synccall_lock);
+	__restore_sigs(&oldmask);
+}
libc/musl/src/thread/syscall_cp.c
libc/musl/src/thread/thrd_create.c
@@ -0,0 +1,12 @@
+#include "pthread_impl.h"
+#include <threads.h>
+
+int thrd_create(thrd_t *thr, thrd_start_t func, void *arg)
+{
+	int ret = __pthread_create(thr, __ATTRP_C11_THREAD, (void *(*)(void *))func, arg);
+	switch (ret) {
+	case 0:      return thrd_success;
+	case EAGAIN: return thrd_nomem;
+	default:     return thrd_error;
+	}
+}
libc/musl/src/thread/thrd_exit.c
@@ -0,0 +1,8 @@
+#include <threads.h>
+#include <pthread.h>
+#include <stdint.h>
+
+_Noreturn void thrd_exit(int result)
+{
+	__pthread_exit((void*)(intptr_t)result);
+}
libc/musl/src/thread/thrd_join.c
@@ -0,0 +1,11 @@
+#include <stdint.h>
+#include <threads.h>
+#include <pthread.h>
+
+int thrd_join(thrd_t t, int *res)
+{
+        void *pthread_res;
+        __pthread_join(t, &pthread_res);
+        if (res) *res = (int)(intptr_t)pthread_res;
+        return thrd_success;
+}
libc/musl/src/thread/thrd_sleep.c
@@ -0,0 +1,13 @@
+#include <threads.h>
+#include <errno.h>
+#include "syscall.h"
+
+int thrd_sleep(const struct timespec *req, struct timespec *rem)
+{
+	int ret = __syscall(SYS_nanosleep, req, rem);
+	switch (ret) {
+	case 0:      return 0;
+	case -EINTR: return -1; /* value specified by C11 */
+	default:     return -2;
+	}
+}
libc/musl/src/thread/thrd_yield.c
@@ -0,0 +1,7 @@
+#include <threads.h>
+#include "syscall.h"
+
+void thrd_yield()
+{
+	__syscall(SYS_sched_yield);
+}
libc/musl/src/thread/tls.c
libc/musl/src/thread/tss_create.c
@@ -0,0 +1,10 @@
+#include <threads.h>
+#include <pthread.h>
+
+int tss_create(tss_t *tss, tss_dtor_t dtor)
+{
+	/* Different error returns are possible. C glues them together into
+	 * just failure notification. Can't be optimized to a tail call,
+	 * unless thrd_error equals EAGAIN. */
+	return __pthread_key_create(tss, dtor) ? thrd_error : thrd_success;
+}
libc/musl/src/thread/tss_delete.c
@@ -0,0 +1,7 @@
+#include <threads.h>
+#include <pthread.h>
+
+void tss_delete(tss_t key)
+{
+	__pthread_key_delete(key);
+}
libc/musl/src/thread/tss_set.c
@@ -0,0 +1,13 @@
+#include "pthread_impl.h"
+#include <threads.h>
+
+int tss_set(tss_t k, void *x)
+{
+	struct pthread *self = __pthread_self();
+	/* Avoid unnecessary COW */
+	if (self->tsd[k] != x) {
+		self->tsd[k] = x;
+		self->tsd_used = 1;
+	}
+	return thrd_success;
+}
libc/musl/src/thread/vmlock.c
@@ -0,0 +1,21 @@
+#include "pthread_impl.h"
+
+static volatile int vmlock[2];
+
+void __vm_wait()
+{
+	int tmp;
+	while ((tmp=vmlock[0]))
+		__wait(vmlock, vmlock+1, tmp, 1);
+}
+
+void __vm_lock()
+{
+	a_inc(vmlock);
+}
+
+void __vm_unlock()
+{
+	if (a_fetch_add(vmlock, -1)==1 && vmlock[1])
+		__wake(vmlock, -1, 1);
+}
libc/musl/src/time/__map_file.c
@@ -0,0 +1,18 @@
+#include <sys/mman.h>
+#include <fcntl.h>
+#include <sys/stat.h>
+#include "syscall.h"
+
+const char unsigned *__map_file(const char *pathname, size_t *size)
+{
+	struct stat st;
+	const unsigned char *map = MAP_FAILED;
+	int fd = sys_open(pathname, O_RDONLY|O_CLOEXEC|O_NONBLOCK);
+	if (fd < 0) return 0;
+	if (!syscall(SYS_fstat, fd, &st)) {
+		map = __mmap(0, st.st_size, PROT_READ, MAP_SHARED, fd, 0);
+		*size = st.st_size;
+	}
+	__syscall(SYS_close, fd);
+	return map == MAP_FAILED ? 0 : map;
+}
libc/musl/src/time/__month_to_secs.c
@@ -0,0 +1,10 @@
+int __month_to_secs(int month, int is_leap)
+{
+	static const int secs_through_month[] = {
+		0, 31*86400, 59*86400, 90*86400,
+		120*86400, 151*86400, 181*86400, 212*86400,
+		243*86400, 273*86400, 304*86400, 334*86400 };
+	int t = secs_through_month[month];
+	if (is_leap && month >= 2) t+=86400;
+	return t;
+}
libc/musl/src/time/__secs_to_tm.c
@@ -0,0 +1,82 @@
+#include "time_impl.h"
+#include <limits.h>
+
+/* 2000-03-01 (mod 400 year, immediately after feb29 */
+#define LEAPOCH (946684800LL + 86400*(31+29))
+
+#define DAYS_PER_400Y (365*400 + 97)
+#define DAYS_PER_100Y (365*100 + 24)
+#define DAYS_PER_4Y   (365*4   + 1)
+
+int __secs_to_tm(long long t, struct tm *tm)
+{
+	long long days, secs, years;
+	int remdays, remsecs, remyears;
+	int qc_cycles, c_cycles, q_cycles;
+	int months;
+	int wday, yday, leap;
+	static const char days_in_month[] = {31,30,31,30,31,31,30,31,30,31,31,29};
+
+	/* Reject time_t values whose year would overflow int */
+	if (t < INT_MIN * 31622400LL || t > INT_MAX * 31622400LL)
+		return -1;
+
+	secs = t - LEAPOCH;
+	days = secs / 86400;
+	remsecs = secs % 86400;
+	if (remsecs < 0) {
+		remsecs += 86400;
+		days--;
+	}
+
+	wday = (3+days)%7;
+	if (wday < 0) wday += 7;
+
+	qc_cycles = days / DAYS_PER_400Y;
+	remdays = days % DAYS_PER_400Y;
+	if (remdays < 0) {
+		remdays += DAYS_PER_400Y;
+		qc_cycles--;
+	}
+
+	c_cycles = remdays / DAYS_PER_100Y;
+	if (c_cycles == 4) c_cycles--;
+	remdays -= c_cycles * DAYS_PER_100Y;
+
+	q_cycles = remdays / DAYS_PER_4Y;
+	if (q_cycles == 25) q_cycles--;
+	remdays -= q_cycles * DAYS_PER_4Y;
+
+	remyears = remdays / 365;
+	if (remyears == 4) remyears--;
+	remdays -= remyears * 365;
+
+	leap = !remyears && (q_cycles || !c_cycles);
+	yday = remdays + 31 + 28 + leap;
+	if (yday >= 365+leap) yday -= 365+leap;
+
+	years = remyears + 4*q_cycles + 100*c_cycles + 400LL*qc_cycles;
+
+	for (months=0; days_in_month[months] <= remdays; months++)
+		remdays -= days_in_month[months];
+
+	if (months >= 10) {
+		months -= 12;
+		years++;
+	}
+
+	if (years+100 > INT_MAX || years+100 < INT_MIN)
+		return -1;
+
+	tm->tm_year = years + 100;
+	tm->tm_mon = months + 2;
+	tm->tm_mday = remdays + 1;
+	tm->tm_wday = wday;
+	tm->tm_yday = yday;
+
+	tm->tm_hour = remsecs / 3600;
+	tm->tm_min = remsecs / 60 % 60;
+	tm->tm_sec = remsecs % 60;
+
+	return 0;
+}
libc/musl/src/time/__tm_to_secs.c
@@ -0,0 +1,24 @@
+#include "time_impl.h"
+
+long long __tm_to_secs(const struct tm *tm)
+{
+	int is_leap;
+	long long year = tm->tm_year;
+	int month = tm->tm_mon;
+	if (month >= 12 || month < 0) {
+		int adj = month / 12;
+		month %= 12;
+		if (month < 0) {
+			adj--;
+			month += 12;
+		}
+		year += adj;
+	}
+	long long t = __year_to_secs(year, &is_leap);
+	t += __month_to_secs(month, is_leap);
+	t += 86400LL * (tm->tm_mday-1);
+	t += 3600LL * tm->tm_hour;
+	t += 60LL * tm->tm_min;
+	t += tm->tm_sec;
+	return t;
+}
libc/musl/src/time/__tz.c
@@ -0,0 +1,422 @@
+#include "time_impl.h"
+#include <stdint.h>
+#include <limits.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/mman.h>
+#include "libc.h"
+#include "lock.h"
+
+long  __timezone = 0;
+int   __daylight = 0;
+char *__tzname[2] = { 0, 0 };
+
+weak_alias(__timezone, timezone);
+weak_alias(__daylight, daylight);
+weak_alias(__tzname, tzname);
+
+static char std_name[TZNAME_MAX+1];
+static char dst_name[TZNAME_MAX+1];
+const char __utc[] = "UTC";
+
+static int dst_off;
+static int r0[5], r1[5];
+
+static const unsigned char *zi, *trans, *index, *types, *abbrevs, *abbrevs_end;
+static size_t map_size;
+
+static char old_tz_buf[32];
+static char *old_tz = old_tz_buf;
+static size_t old_tz_size = sizeof old_tz_buf;
+
+static volatile int lock[1];
+
+static int getint(const char **p)
+{
+	unsigned x;
+	for (x=0; **p-'0'<10U; (*p)++) x = **p-'0' + 10*x;
+	return x;
+}
+
+static int getoff(const char **p)
+{
+	int neg = 0;
+	if (**p == '-') {
+		++*p;
+		neg = 1;
+	} else if (**p == '+') {
+		++*p;
+	}
+	int off = 3600*getint(p);
+	if (**p == ':') {
+		++*p;
+		off += 60*getint(p);
+		if (**p == ':') {
+			++*p;
+			off += getint(p);
+		}
+	}
+	return neg ? -off : off;
+}
+
+static void getrule(const char **p, int rule[5])
+{
+	int r = rule[0] = **p;
+
+	if (r!='M') {
+		if (r=='J') ++*p;
+		else rule[0] = 0;
+		rule[1] = getint(p);
+	} else {
+		++*p; rule[1] = getint(p);
+		++*p; rule[2] = getint(p);
+		++*p; rule[3] = getint(p);
+	}
+
+	if (**p=='/') {
+		++*p;
+		rule[4] = getoff(p);
+	} else {
+		rule[4] = 7200;
+	}
+}
+
+static void getname(char *d, const char **p)
+{
+	int i;
+	if (**p == '<') {
+		++*p;
+		for (i=0; (*p)[i]!='>' && i<TZNAME_MAX; i++)
+			d[i] = (*p)[i];
+		++*p;
+	} else {
+		for (i=0; ((*p)[i]|32)-'a'<26U && i<TZNAME_MAX; i++)
+			d[i] = (*p)[i];
+	}
+	*p += i;
+	d[i] = 0;
+}
+
+#define VEC(...) ((const unsigned char[]){__VA_ARGS__})
+
+static uint32_t zi_read32(const unsigned char *z)
+{
+	return (unsigned)z[0]<<24 | z[1]<<16 | z[2]<<8 | z[3];
+}
+
+static size_t zi_dotprod(const unsigned char *z, const unsigned char *v, size_t n)
+{
+	size_t y;
+	uint32_t x;
+	for (y=0; n; n--, z+=4, v++) {
+		x = zi_read32(z);
+		y += x * *v;
+	}
+	return y;
+}
+
+static void do_tzset()
+{
+	char buf[NAME_MAX+25], *pathname=buf+24;
+	const char *try, *s, *p;
+	const unsigned char *map = 0;
+	size_t i;
+	static const char search[] =
+		"/usr/share/zoneinfo/\0/share/zoneinfo/\0/etc/zoneinfo/\0";
+
+	s = getenv("TZ");
+	if (!s) s = "/etc/localtime";
+	if (!*s) s = __utc;
+
+	if (old_tz && !strcmp(s, old_tz)) return;
+
+	for (i=0; i<5; i++) r0[i] = r1[i] = 0;
+
+	if (zi) __munmap((void *)zi, map_size);
+
+	/* Cache the old value of TZ to check if it has changed. Avoid
+	 * free so as not to pull it into static programs. Growth
+	 * strategy makes it so free would have minimal benefit anyway. */
+	i = strlen(s);
+	if (i > PATH_MAX+1) s = __utc, i = 3;
+	if (i >= old_tz_size) {
+		old_tz_size *= 2;
+		if (i >= old_tz_size) old_tz_size = i+1;
+		if (old_tz_size > PATH_MAX+2) old_tz_size = PATH_MAX+2;
+		old_tz = malloc(old_tz_size);
+	}
+	if (old_tz) memcpy(old_tz, s, i+1);
+
+	/* Non-suid can use an absolute tzfile pathname or a relative
+	 * pathame beginning with "."; in secure mode, only the
+	 * standard path will be searched. */
+	if (*s == ':' || ((p=strchr(s, '/')) && !memchr(s, ',', p-s))) {
+		if (*s == ':') s++;
+		if (*s == '/' || *s == '.') {
+			if (!libc.secure || !strcmp(s, "/etc/localtime"))
+				map = __map_file(s, &map_size);
+		} else {
+			size_t l = strlen(s);
+			if (l <= NAME_MAX && !strchr(s, '.')) {
+				memcpy(pathname, s, l+1);
+				pathname[l] = 0;
+				for (try=search; !map && *try; try+=l+1) {
+					l = strlen(try);
+					memcpy(pathname-l, try, l);
+					map = __map_file(pathname-l, &map_size);
+				}
+			}
+		}
+		if (!map) s = __utc;
+	}
+	if (map && (map_size < 44 || memcmp(map, "TZif", 4))) {
+		__munmap((void *)map, map_size);
+		map = 0;
+		s = __utc;
+	}
+
+	zi = map;
+	if (map) {
+		int scale = 2;
+		if (sizeof(time_t) > 4 && map[4]=='2') {
+			size_t skip = zi_dotprod(zi+20, VEC(1,1,8,5,6,1), 6);
+			trans = zi+skip+44+44;
+			scale++;
+		} else {
+			trans = zi+44;
+		}
+		index = trans + (zi_read32(trans-12) << scale);
+		types = index + zi_read32(trans-12);
+		abbrevs = types + 6*zi_read32(trans-8);
+		abbrevs_end = abbrevs + zi_read32(trans-4);
+		if (zi[map_size-1] == '\n') {
+			for (s = (const char *)zi+map_size-2; *s!='\n'; s--);
+			s++;
+		} else {
+			const unsigned char *p;
+			__tzname[0] = __tzname[1] = 0;
+			__daylight = __timezone = dst_off = 0;
+			for (p=types; p<abbrevs; p+=6) {
+				if (!p[4] && !__tzname[0]) {
+					__tzname[0] = (char *)abbrevs + p[5];
+					__timezone = -zi_read32(p);
+				}
+				if (p[4] && !__tzname[1]) {
+					__tzname[1] = (char *)abbrevs + p[5];
+					dst_off = -zi_read32(p);
+					__daylight = 1;
+				}
+			}
+			if (!__tzname[0]) __tzname[0] = __tzname[1];
+			if (!__tzname[0]) __tzname[0] = (char *)__utc;
+			if (!__daylight) {
+				__tzname[1] = __tzname[0];
+				dst_off = __timezone;
+			}
+			return;
+		}
+	}
+
+	if (!s) s = __utc;
+	getname(std_name, &s);
+	__tzname[0] = std_name;
+	__timezone = getoff(&s);
+	getname(dst_name, &s);
+	__tzname[1] = dst_name;
+	if (dst_name[0]) {
+		__daylight = 1;
+		if (*s == '+' || *s=='-' || *s-'0'<10U)
+			dst_off = getoff(&s);
+		else
+			dst_off = __timezone - 3600;
+	} else {
+		__daylight = 0;
+		dst_off = __timezone;
+	}
+
+	if (*s == ',') s++, getrule(&s, r0);
+	if (*s == ',') s++, getrule(&s, r1);
+}
+
+/* Search zoneinfo rules to find the one that applies to the given time,
+ * and determine alternate opposite-DST-status rule that may be needed. */
+
+static size_t scan_trans(long long t, int local, size_t *alt)
+{
+	int scale = 3 - (trans == zi+44);
+	uint64_t x;
+	int off = 0;
+
+	size_t a = 0, n = (index-trans)>>scale, m;
+
+	if (!n) {
+		if (alt) *alt = 0;
+		return 0;
+	}
+
+	/* Binary search for 'most-recent rule before t'. */
+	while (n > 1) {
+		m = a + n/2;
+		x = zi_read32(trans + (m<<scale));
+		if (scale == 3) x = x<<32 | zi_read32(trans + (m<<scale) + 4);
+		else x = (int32_t)x;
+		if (local) off = (int32_t)zi_read32(types + 6 * index[m-1]);
+		if (t - off < (int64_t)x) {
+			n /= 2;
+		} else {
+			a = m;
+			n -= n/2;
+		}
+	}
+
+	/* First and last entry are special. First means to use lowest-index
+	 * non-DST type. Last means to apply POSIX-style rule if available. */
+	n = (index-trans)>>scale;
+	if (a == n-1) return -1;
+	if (a == 0) {
+		x = zi_read32(trans + (a<<scale));
+		if (scale == 3) x = x<<32 | zi_read32(trans + (a<<scale) + 4);
+		else x = (int32_t)x;
+		if (local) off = (int32_t)zi_read32(types + 6 * index[a-1]);
+		if (t - off < (int64_t)x) {
+			for (a=0; a<(abbrevs-types)/6; a++) {
+				if (types[6*a+4] != types[4]) break;
+			}
+			if (a == (abbrevs-types)/6) a = 0;
+			if (types[6*a+4]) {
+				*alt = a;
+				return 0;
+			} else {
+				*alt = 0;
+				return a;
+			}
+		}
+	}
+
+	/* Try to find a neighboring opposite-DST-status rule. */
+	if (alt) {
+		if (a && types[6*index[a-1]+4] != types[6*index[a]+4])
+			*alt = index[a-1];
+		else if (a+1<n && types[6*index[a+1]+4] != types[6*index[a]+4])
+			*alt = index[a+1];
+		else
+			*alt = index[a];
+	}
+
+	return index[a];
+}
+
+static int days_in_month(int m, int is_leap)
+{
+	if (m==2) return 28+is_leap;
+	else return 30+((0xad5>>(m-1))&1);
+}
+
+/* Convert a POSIX DST rule plus year to seconds since epoch. */
+
+static long long rule_to_secs(const int *rule, int year)
+{
+	int is_leap;
+	long long t = __year_to_secs(year, &is_leap);
+	int x, m, n, d;
+	if (rule[0]!='M') {
+		x = rule[1];
+		if (rule[0]=='J' && (x < 60 || !is_leap)) x--;
+		t += 86400 * x;
+	} else {
+		m = rule[1];
+		n = rule[2];
+		d = rule[3];
+		t += __month_to_secs(m-1, is_leap);
+		int wday = (int)((t + 4*86400) % (7*86400)) / 86400;
+		int days = d - wday;
+		if (days < 0) days += 7;
+		if (n == 5 && days+28 >= days_in_month(m, is_leap)) n = 4;
+		t += 86400 * (days + 7*(n-1));
+	}
+	t += rule[4];
+	return t;
+}
+
+/* Determine the time zone in effect for a given time in seconds since the
+ * epoch. It can be given in local or universal time. The results will
+ * indicate whether DST is in effect at the queried time, and will give both
+ * the GMT offset for the active zone/DST rule and the opposite DST. This
+ * enables a caller to efficiently adjust for the case where an explicit
+ * DST specification mismatches what would be in effect at the time. */
+
+void __secs_to_zone(long long t, int local, int *isdst, long *offset, long *oppoff, const char **zonename)
+{
+	LOCK(lock);
+
+	do_tzset();
+
+	if (zi) {
+		size_t alt, i = scan_trans(t, local, &alt);
+		if (i != -1) {
+			*isdst = types[6*i+4];
+			*offset = (int32_t)zi_read32(types+6*i);
+			*zonename = (const char *)abbrevs + types[6*i+5];
+			if (oppoff) *oppoff = (int32_t)zi_read32(types+6*alt);
+			UNLOCK(lock);
+			return;
+		}
+	}
+
+	if (!__daylight) goto std;
+
+	/* FIXME: may be broken if DST changes right at year boundary?
+	 * Also, this could be more efficient.*/
+	long long y = t / 31556952 + 70;
+	while (__year_to_secs(y, 0) > t) y--;
+	while (__year_to_secs(y+1, 0) < t) y++;
+
+	long long t0 = rule_to_secs(r0, y);
+	long long t1 = rule_to_secs(r1, y);
+
+	if (!local) {
+		t0 += __timezone;
+		t1 += dst_off;
+	}
+	if (t0 < t1) {
+		if (t >= t0 && t < t1) goto dst;
+		goto std;
+	} else {
+		if (t >= t1 && t < t0) goto std;
+		goto dst;
+	}
+std:
+	*isdst = 0;
+	*offset = -__timezone;
+	if (oppoff) *oppoff = -dst_off;
+	*zonename = __tzname[0];
+	UNLOCK(lock);
+	return;
+dst:
+	*isdst = 1;
+	*offset = -dst_off;
+	if (oppoff) *oppoff = -__timezone;
+	*zonename = __tzname[1];
+	UNLOCK(lock);
+}
+
+static void __tzset()
+{
+	LOCK(lock);
+	do_tzset();
+	UNLOCK(lock);
+}
+
+weak_alias(__tzset, tzset);
+
+const char *__tm_to_tzname(const struct tm *tm)
+{
+	const void *p = tm->__tm_zone;
+	LOCK(lock);
+	do_tzset();
+	if (p != __utc && p != __tzname[0] && p != __tzname[1] &&
+	    (!zi || (uintptr_t)p-(uintptr_t)abbrevs >= abbrevs_end - abbrevs))
+		p = "";
+	UNLOCK(lock);
+	return p;
+}
libc/musl/src/time/__year_to_secs.c
@@ -0,0 +1,47 @@
+long long __year_to_secs(long long year, int *is_leap)
+{
+	if (year-2ULL <= 136) {
+		int y = year;
+		int leaps = (y-68)>>2;
+		if (!((y-68)&3)) {
+			leaps--;
+			if (is_leap) *is_leap = 1;
+		} else if (is_leap) *is_leap = 0;
+		return 31536000*(y-70) + 86400*leaps;
+	}
+
+	int cycles, centuries, leaps, rem;
+
+	if (!is_leap) is_leap = &(int){0};
+	cycles = (year-100) / 400;
+	rem = (year-100) % 400;
+	if (rem < 0) {
+		cycles--;
+		rem += 400;
+	}
+	if (!rem) {
+		*is_leap = 1;
+		centuries = 0;
+		leaps = 0;
+	} else {
+		if (rem >= 200) {
+			if (rem >= 300) centuries = 3, rem -= 300;
+			else centuries = 2, rem -= 200;
+		} else {
+			if (rem >= 100) centuries = 1, rem -= 100;
+			else centuries = 0;
+		}
+		if (!rem) {
+			*is_leap = 0;
+			leaps = 0;
+		} else {
+			leaps = rem / 4U;
+			rem %= 4U;
+			*is_leap = !rem;
+		}
+	}
+
+	leaps += 97*cycles + 24*centuries - *is_leap;
+
+	return (year-100) * 31536000LL + leaps * 86400LL + 946684800 + 86400;
+}
libc/musl/src/time/asctime.c
@@ -0,0 +1,7 @@
+#include <time.h>
+
+char *asctime(const struct tm *tm)
+{
+	static char buf[26];
+	return __asctime_r(tm, buf);
+}
libc/musl/src/time/asctime_r.c
@@ -0,0 +1,28 @@
+#include <time.h>
+#include <stdio.h>
+#include <langinfo.h>
+#include "locale_impl.h"
+#include "atomic.h"
+
+char *__asctime_r(const struct tm *restrict tm, char *restrict buf)
+{
+	if (snprintf(buf, 26, "%.3s %.3s%3d %.2d:%.2d:%.2d %d\n",
+		__nl_langinfo_l(ABDAY_1+tm->tm_wday, C_LOCALE),
+		__nl_langinfo_l(ABMON_1+tm->tm_mon, C_LOCALE),
+		tm->tm_mday, tm->tm_hour,
+		tm->tm_min, tm->tm_sec,
+		1900 + tm->tm_year) >= 26)
+	{
+		/* ISO C requires us to use the above format string,
+		 * even if it will not fit in the buffer. Thus asctime_r
+		 * is _supposed_ to crash if the fields in tm are too large.
+		 * We follow this behavior and crash "gracefully" to warn
+		 * application developers that they may not be so lucky
+		 * on other implementations (e.g. stack smashing..).
+		 */
+		a_crash();
+	}
+	return buf;
+}
+
+weak_alias(__asctime_r, asctime_r);
libc/musl/src/time/clock.c
@@ -0,0 +1,16 @@
+#include <time.h>
+#include <limits.h>
+
+clock_t clock()
+{
+	struct timespec ts;
+
+	if (__clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &ts))
+		return -1;
+
+	if (ts.tv_sec > LONG_MAX/1000000
+	 || ts.tv_nsec/1000 > LONG_MAX-1000000*ts.tv_sec)
+		return -1;
+
+	return ts.tv_sec*1000000 + ts.tv_nsec/1000;
+}
libc/musl/src/time/clock_getcpuclockid.c
@@ -0,0 +1,14 @@
+#include <time.h>
+#include <errno.h>
+#include <unistd.h>
+#include "syscall.h"
+
+int clock_getcpuclockid(pid_t pid, clockid_t *clk)
+{
+	struct timespec ts;
+	clockid_t id = (-pid-1)*8U + 2;
+	int ret = __syscall(SYS_clock_getres, id, &ts);
+	if (ret) return -ret;
+	*clk = id;
+	return 0;
+}
libc/musl/src/time/clock_getres.c
@@ -0,0 +1,7 @@
+#include <time.h>
+#include "syscall.h"
+
+int clock_getres(clockid_t clk, struct timespec *ts)
+{
+	return syscall(SYS_clock_getres, clk, ts);
+}
libc/musl/src/time/clock_gettime.c
@@ -0,0 +1,55 @@
+#include <time.h>
+#include <errno.h>
+#include <stdint.h>
+#include "syscall.h"
+#include "atomic.h"
+
+#ifdef VDSO_CGT_SYM
+
+static void *volatile vdso_func;
+
+static int cgt_init(clockid_t clk, struct timespec *ts)
+{
+	void *p = __vdsosym(VDSO_CGT_VER, VDSO_CGT_SYM);
+	int (*f)(clockid_t, struct timespec *) =
+		(int (*)(clockid_t, struct timespec *))p;
+	a_cas_p(&vdso_func, (void *)cgt_init, p);
+	return f ? f(clk, ts) : -ENOSYS;
+}
+
+static void *volatile vdso_func = (void *)cgt_init;
+
+#endif
+
+int __clock_gettime(clockid_t clk, struct timespec *ts)
+{
+	int r;
+
+#ifdef VDSO_CGT_SYM
+	int (*f)(clockid_t, struct timespec *) =
+		(int (*)(clockid_t, struct timespec *))vdso_func;
+	if (f) {
+		r = f(clk, ts);
+		if (!r) return r;
+		if (r == -EINVAL) return __syscall_ret(r);
+		/* Fall through on errors other than EINVAL. Some buggy
+		 * vdso implementations return ENOSYS for clocks they
+		 * can't handle, rather than making the syscall. This
+		 * also handles the case where cgt_init fails to find
+		 * a vdso function to use. */
+	}
+#endif
+
+	r = __syscall(SYS_clock_gettime, clk, ts);
+	if (r == -ENOSYS) {
+		if (clk == CLOCK_REALTIME) {
+			__syscall(SYS_gettimeofday, ts, 0);
+			ts->tv_nsec = (int)ts->tv_nsec * 1000;
+			return 0;
+		}
+		r = -EINVAL;
+	}
+	return __syscall_ret(r);
+}
+
+weak_alias(__clock_gettime, clock_gettime);
libc/musl/src/time/clock_nanosleep.c
@@ -0,0 +1,9 @@
+#include <time.h>
+#include <errno.h>
+#include "syscall.h"
+
+int clock_nanosleep(clockid_t clk, int flags, const struct timespec *req, struct timespec *rem)
+{
+	int r = -__syscall_cp(SYS_clock_nanosleep, clk, flags, req, rem);
+	return clk == CLOCK_THREAD_CPUTIME_ID ? EINVAL : r;
+}
libc/musl/src/time/clock_settime.c
@@ -0,0 +1,7 @@
+#include <time.h>
+#include "syscall.h"
+
+int clock_settime(clockid_t clk, const struct timespec *ts)
+{
+	return syscall(SYS_clock_settime, clk, ts);
+}
libc/musl/src/time/ctime.c
@@ -0,0 +1,8 @@
+#include <time.h>
+
+char *ctime(const time_t *t)
+{
+	struct tm *tm = localtime(t);
+	if (!tm) return 0;
+	return asctime(tm);
+}
libc/musl/src/time/ctime_r.c
@@ -0,0 +1,7 @@
+#include <time.h>
+
+char *ctime_r(const time_t *t, char *buf)
+{
+	struct tm tm, *tm_p = localtime_r(t, &tm);
+	return tm_p ? asctime_r(tm_p, buf) : 0;
+}
libc/musl/src/time/difftime.c
@@ -0,0 +1,6 @@
+#include <time.h>
+
+double difftime(time_t t1, time_t t0)
+{
+	return t1-t0;
+}
libc/musl/src/time/ftime.c
@@ -0,0 +1,12 @@
+#include <sys/timeb.h>
+#include <time.h>
+
+int ftime(struct timeb *tp)
+{
+	struct timespec ts;
+	clock_gettime(CLOCK_REALTIME, &ts);
+	tp->time = ts.tv_sec;
+	tp->millitm = ts.tv_nsec / 1000000;
+	tp->timezone = tp->dstflag = 0;
+	return 0;
+}
libc/musl/src/time/getdate.c
@@ -0,0 +1,46 @@
+#include <time.h>
+#include <pthread.h>
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+int getdate_err;
+
+struct tm *getdate(const char *s)
+{
+	static struct tm tmbuf;
+	struct tm *ret = 0;
+	char *datemsk = getenv("DATEMSK");
+	FILE *f = 0;
+	char fmt[100], *p;
+	int cs;
+
+	pthread_setcancelstate(PTHREAD_CANCEL_DEFERRED, &cs);
+
+	if (!datemsk) {
+		getdate_err = 1;
+		goto out;
+	}
+
+	f = fopen(datemsk, "rbe");
+	if (!f) {
+		if (errno == ENOMEM) getdate_err = 6;
+		else getdate_err = 2;
+		goto out;
+	}
+
+	while (fgets(fmt, sizeof fmt, f)) {
+		p = strptime(s, fmt, &tmbuf);
+		if (p && !*p) {
+			ret = &tmbuf;
+			goto out;
+		}
+	}
+
+	if (ferror(f)) getdate_err = 5;
+	else getdate_err = 7;
+out:
+	if (f) fclose(f);
+	pthread_setcancelstate(cs, 0);
+	return ret;
+}
libc/musl/src/time/gettimeofday.c
@@ -0,0 +1,13 @@
+#include <time.h>
+#include <sys/time.h>
+#include "syscall.h"
+
+int gettimeofday(struct timeval *restrict tv, void *restrict tz)
+{
+	struct timespec ts;
+	if (!tv) return 0;
+	clock_gettime(CLOCK_REALTIME, &ts);
+	tv->tv_sec = ts.tv_sec;
+	tv->tv_usec = (int)ts.tv_nsec / 1000;
+	return 0;
+}
libc/musl/src/time/gmtime.c
@@ -0,0 +1,8 @@
+#include "time_impl.h"
+#include <errno.h>
+
+struct tm *gmtime(const time_t *t)
+{
+	static struct tm tm;
+	return __gmtime_r(t, &tm);
+}
libc/musl/src/time/gmtime_r.c
@@ -0,0 +1,16 @@
+#include "time_impl.h"
+#include <errno.h>
+
+struct tm *__gmtime_r(const time_t *restrict t, struct tm *restrict tm)
+{
+	if (__secs_to_tm(*t, tm) < 0) {
+		errno = EOVERFLOW;
+		return 0;
+	}
+	tm->tm_isdst = 0;
+	tm->__tm_gmtoff = 0;
+	tm->__tm_zone = __utc;
+	return tm;
+}
+
+weak_alias(__gmtime_r, gmtime_r);
libc/musl/src/time/localtime.c
@@ -0,0 +1,7 @@
+#include "time_impl.h"
+
+struct tm *localtime(const time_t *t)
+{
+	static struct tm tm;
+	return __localtime_r(t, &tm);
+}
libc/musl/src/time/localtime_r.c
@@ -0,0 +1,21 @@
+#include "time_impl.h"
+#include <errno.h>
+#include <limits.h>
+
+struct tm *__localtime_r(const time_t *restrict t, struct tm *restrict tm)
+{
+	/* Reject time_t values whose year would overflow int because
+	 * __secs_to_zone cannot safely handle them. */
+	if (*t < INT_MIN * 31622400LL || *t > INT_MAX * 31622400LL) {
+		errno = EOVERFLOW;
+		return 0;
+	}
+	__secs_to_zone(*t, 0, &tm->tm_isdst, &tm->__tm_gmtoff, 0, &tm->__tm_zone);
+	if (__secs_to_tm((long long)*t + tm->__tm_gmtoff, tm) < 0) {
+		errno = EOVERFLOW;
+		return 0;
+	}
+	return tm;
+}
+
+weak_alias(__localtime_r, localtime_r);
libc/musl/src/time/mktime.c
@@ -0,0 +1,28 @@
+#include "time_impl.h"
+#include <errno.h>
+
+time_t mktime(struct tm *tm)
+{
+	struct tm new;
+	long opp;
+	long long t = __tm_to_secs(tm);
+
+	__secs_to_zone(t, 1, &new.tm_isdst, &new.__tm_gmtoff, &opp, &new.__tm_zone);
+
+	if (tm->tm_isdst>=0 && new.tm_isdst!=tm->tm_isdst)
+		t -= opp - new.__tm_gmtoff;
+
+	t -= new.__tm_gmtoff;
+	if ((time_t)t != t) goto error;
+
+	__secs_to_zone(t, 0, &new.tm_isdst, &new.__tm_gmtoff, &opp, &new.__tm_zone);
+
+	if (__secs_to_tm(t + new.__tm_gmtoff, &new) < 0) goto error;
+
+	*tm = new;
+	return t;
+
+error:
+	errno = EOVERFLOW;
+	return -1;
+}
libc/musl/src/time/nanosleep.c
@@ -0,0 +1,7 @@
+#include <time.h>
+#include "syscall.h"
+
+int nanosleep(const struct timespec *req, struct timespec *rem)
+{
+	return syscall_cp(SYS_nanosleep, req, rem);
+}
libc/musl/src/time/strftime.c
@@ -0,0 +1,281 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <langinfo.h>
+#include <locale.h>
+#include <time.h>
+#include <limits.h>
+#include "locale_impl.h"
+#include "time_impl.h"
+
+static int is_leap(int y)
+{
+	/* Avoid overflow */
+	if (y>INT_MAX-1900) y -= 2000;
+	y += 1900;
+	return !(y%4) && ((y%100) || !(y%400));
+}
+
+static int week_num(const struct tm *tm)
+{
+	int val = (tm->tm_yday + 7U - (tm->tm_wday+6U)%7) / 7;
+	/* If 1 Jan is just 1-3 days past Monday,
+	 * the previous week is also in this year. */
+	if ((tm->tm_wday + 371U - tm->tm_yday - 2) % 7 <= 2)
+		val++;
+	if (!val) {
+		val = 52;
+		/* If 31 December of prev year a Thursday,
+		 * or Friday of a leap year, then the
+		 * prev year has 53 weeks. */
+		int dec31 = (tm->tm_wday + 7U - tm->tm_yday - 1) % 7;
+		if (dec31 == 4 || (dec31 == 5 && is_leap(tm->tm_year%400-1)))
+			val++;
+	} else if (val == 53) {
+		/* If 1 January is not a Thursday, and not
+		 * a Wednesday of a leap year, then this
+		 * year has only 52 weeks. */
+		int jan1 = (tm->tm_wday + 371U - tm->tm_yday) % 7;
+		if (jan1 != 4 && (jan1 != 3 || !is_leap(tm->tm_year)))
+			val = 1;
+	}
+	return val;
+}
+
+const char *__strftime_fmt_1(char (*s)[100], size_t *l, int f, const struct tm *tm, locale_t loc, int pad)
+{
+	nl_item item;
+	long long val;
+	const char *fmt = "-";
+	int width = 2, def_pad = '0';
+
+	switch (f) {
+	case 'a':
+		if (tm->tm_wday > 6U) goto string;
+		item = ABDAY_1 + tm->tm_wday;
+		goto nl_strcat;
+	case 'A':
+		if (tm->tm_wday > 6U) goto string;
+		item = DAY_1 + tm->tm_wday;
+		goto nl_strcat;
+	case 'h':
+	case 'b':
+		if (tm->tm_mon > 11U) goto string;
+		item = ABMON_1 + tm->tm_mon;
+		goto nl_strcat;
+	case 'B':
+		if (tm->tm_mon > 11U) goto string;
+		item = MON_1 + tm->tm_mon;
+		goto nl_strcat;
+	case 'c':
+		item = D_T_FMT;
+		goto nl_strftime;
+	case 'C':
+		val = (1900LL+tm->tm_year) / 100;
+		goto number;
+	case 'e':
+		def_pad = '_';
+	case 'd':
+		val = tm->tm_mday;
+		goto number;
+	case 'D':
+		fmt = "%m/%d/%y";
+		goto recu_strftime;
+	case 'F':
+		fmt = "%Y-%m-%d";
+		goto recu_strftime;
+	case 'g':
+	case 'G':
+		val = tm->tm_year + 1900LL;
+		if (tm->tm_yday < 3 && week_num(tm) != 1) val--;
+		else if (tm->tm_yday > 360 && week_num(tm) == 1) val++;
+		if (f=='g') val %= 100;
+		else width = 4;
+		goto number;
+	case 'H':
+		val = tm->tm_hour;
+		goto number;
+	case 'I':
+		val = tm->tm_hour;
+		if (!val) val = 12;
+		else if (val > 12) val -= 12;
+		goto number;
+	case 'j':
+		val = tm->tm_yday+1;
+		width = 3;
+		goto number;
+	case 'm':
+		val = tm->tm_mon+1;
+		goto number;
+	case 'M':
+		val = tm->tm_min;
+		goto number;
+	case 'n':
+		*l = 1;
+		return "\n";
+	case 'p':
+		item = tm->tm_hour >= 12 ? PM_STR : AM_STR;
+		goto nl_strcat;
+	case 'r':
+		item = T_FMT_AMPM;
+		goto nl_strftime;
+	case 'R':
+		fmt = "%H:%M";
+		goto recu_strftime;
+	case 's':
+		val = __tm_to_secs(tm) - tm->__tm_gmtoff;
+		width = 1;
+		goto number;
+	case 'S':
+		val = tm->tm_sec;
+		goto number;
+	case 't':
+		*l = 1;
+		return "\t";
+	case 'T':
+		fmt = "%H:%M:%S";
+		goto recu_strftime;
+	case 'u':
+		val = tm->tm_wday ? tm->tm_wday : 7;
+		width = 1;
+		goto number;
+	case 'U':
+		val = (tm->tm_yday + 7U - tm->tm_wday) / 7;
+		goto number;
+	case 'W':
+		val = (tm->tm_yday + 7U - (tm->tm_wday+6U)%7) / 7;
+		goto number;
+	case 'V':
+		val = week_num(tm);
+		goto number;
+	case 'w':
+		val = tm->tm_wday;
+		width = 1;
+		goto number;
+	case 'x':
+		item = D_FMT;
+		goto nl_strftime;
+	case 'X':
+		item = T_FMT;
+		goto nl_strftime;
+	case 'y':
+		val = (tm->tm_year + 1900LL) % 100;
+		if (val < 0) val = -val;
+		goto number;
+	case 'Y':
+		val = tm->tm_year + 1900LL;
+		if (val >= 10000) {
+			*l = snprintf(*s, sizeof *s, "+%lld", val);
+			return *s;
+		}
+		width = 4;
+		goto number;
+	case 'z':
+		if (tm->tm_isdst < 0) {
+			*l = 0;
+			return "";
+		}
+		*l = snprintf(*s, sizeof *s, "%+.4ld",
+			tm->__tm_gmtoff/3600*100 + tm->__tm_gmtoff%3600/60);
+		return *s;
+	case 'Z':
+		if (tm->tm_isdst < 0) {
+			*l = 0;
+			return "";
+		}
+		fmt = __tm_to_tzname(tm);
+		goto string;
+	case '%':
+		*l = 1;
+		return "%";
+	default:
+		return 0;
+	}
+number:
+	switch (pad ? pad : def_pad) {
+	case '-': *l = snprintf(*s, sizeof *s, "%lld", val); break;
+	case '_': *l = snprintf(*s, sizeof *s, "%*lld", width, val); break;
+	case '0':
+	default:  *l = snprintf(*s, sizeof *s, "%0*lld", width, val); break;
+	}
+	return *s;
+nl_strcat:
+	fmt = __nl_langinfo_l(item, loc);
+string:
+	*l = strlen(fmt);
+	return fmt;
+nl_strftime:
+	fmt = __nl_langinfo_l(item, loc);
+recu_strftime:
+	*l = __strftime_l(*s, sizeof *s, fmt, tm, loc);
+	if (!*l) return 0;
+	return *s;
+}
+
+size_t __strftime_l(char *restrict s, size_t n, const char *restrict f, const struct tm *restrict tm, locale_t loc)
+{
+	size_t l, k;
+	char buf[100];
+	char *p;
+	const char *t;
+	int pad, plus;
+	unsigned long width;
+	for (l=0; l<n; f++) {
+		if (!*f) {
+			s[l] = 0;
+			return l;
+		}
+		if (*f != '%') {
+			s[l++] = *f;
+			continue;
+		}
+		f++;
+		pad = 0;
+		if (*f == '-' || *f == '_' || *f == '0') pad = *f++;
+		if ((plus = (*f == '+'))) f++;
+		width = strtoul(f, &p, 10);
+		if (*p == 'C' || *p == 'F' || *p == 'G' || *p == 'Y') {
+			if (!width && p!=f) width = 1;
+		} else {
+			width = 0;
+		}
+		f = p;
+		if (*f == 'E' || *f == 'O') f++;
+		t = __strftime_fmt_1(&buf, &k, *f, tm, loc, pad);
+		if (!t) break;
+		if (width) {
+			/* Trim off any sign and leading zeros, then
+			 * count remaining digits to determine behavior
+			 * for the + flag. */
+			if (*t=='+' || *t=='-') t++, k--;
+			for (; *t=='0' && t[1]-'0'<10U; t++, k--);
+			if (width < k) width = k;
+			size_t d;
+			for (d=0; t[d]-'0'<10U; d++);
+			if (tm->tm_year < -1900) {
+				s[l++] = '-';
+				width--;
+			} else if (plus && d+(width-k) >= (*p=='C'?3:5)) {
+				s[l++] = '+';
+				width--;
+			}
+			for (; width > k && l < n; width--)
+				s[l++] = '0';
+		}
+		if (k > n-l) k = n-l;
+		memcpy(s+l, t, k);
+		l += k;
+	}
+	if (n) {
+		if (l==n) l=n-1;
+		s[l] = 0;
+	}
+	return 0;
+}
+
+size_t strftime(char *restrict s, size_t n, const char *restrict f, const struct tm *restrict tm)
+{
+	return __strftime_l(s, n, f, tm, CURRENT_LOCALE);
+}
+
+weak_alias(__strftime_l, strftime_l);
libc/musl/src/time/strptime.c
@@ -0,0 +1,206 @@
+#include <stdlib.h>
+#include <langinfo.h>
+#include <time.h>
+#include <ctype.h>
+#include <stddef.h>
+#include <string.h>
+#include <strings.h>
+
+char *strptime(const char *restrict s, const char *restrict f, struct tm *restrict tm)
+{
+	int i, w, neg, adj, min, range, *dest, dummy;
+	const char *ex;
+	size_t len;
+	int want_century = 0, century = 0, relyear = 0;
+	while (*f) {
+		if (*f != '%') {
+			if (isspace(*f)) for (; *s && isspace(*s); s++);
+			else if (*s != *f) return 0;
+			else s++;
+			f++;
+			continue;
+		}
+		f++;
+		if (*f == '+') f++;
+		if (isdigit(*f)) {
+			char *new_f;
+			w=strtoul(f, &new_f, 10);
+			f = new_f;
+		} else {
+			w=-1;
+		}
+		adj=0;
+		switch (*f++) {
+		case 'a': case 'A':
+			dest = &tm->tm_wday;
+			min = ABDAY_1;
+			range = 7;
+			goto symbolic_range;
+		case 'b': case 'B': case 'h':
+			dest = &tm->tm_mon;
+			min = ABMON_1;
+			range = 12;
+			goto symbolic_range;
+		case 'c':
+			s = strptime(s, nl_langinfo(D_T_FMT), tm);
+			if (!s) return 0;
+			break;
+		case 'C':
+			dest = &century;
+			if (w<0) w=2;
+			want_century |= 2;
+			goto numeric_digits;
+		case 'd': case 'e':
+			dest = &tm->tm_mday;
+			min = 1;
+			range = 31;
+			goto numeric_range;
+		case 'D':
+			s = strptime(s, "%m/%d/%y", tm);
+			if (!s) return 0;
+			break;
+		case 'H':
+			dest = &tm->tm_hour;
+			min = 0;
+			range = 24;
+			goto numeric_range;
+		case 'I':
+			dest = &tm->tm_hour;
+			min = 1;
+			range = 12;
+			goto numeric_range;
+		case 'j':
+			dest = &tm->tm_yday;
+			min = 1;
+			range = 366;
+			adj = 1;
+			goto numeric_range;
+		case 'm':
+			dest = &tm->tm_mon;
+			min = 1;
+			range = 12;
+			adj = 1;
+			goto numeric_range;
+		case 'M':
+			dest = &tm->tm_min;
+			min = 0;
+			range = 60;
+			goto numeric_range;
+		case 'n': case 't':
+			for (; *s && isspace(*s); s++);
+			break;
+		case 'p':
+			ex = nl_langinfo(AM_STR);
+			len = strlen(ex);
+			if (!strncasecmp(s, ex, len)) {
+				tm->tm_hour %= 12;
+				s += len;
+				break;
+			}
+			ex = nl_langinfo(PM_STR);
+			len = strlen(ex);
+			if (!strncasecmp(s, ex, len)) {
+				tm->tm_hour %= 12;
+				tm->tm_hour += 12;
+				s += len;
+				break;
+			}
+			return 0;
+		case 'r':
+			s = strptime(s, nl_langinfo(T_FMT_AMPM), tm);
+			if (!s) return 0;
+			break;
+		case 'R':
+			s = strptime(s, "%H:%M", tm);
+			if (!s) return 0;
+			break;
+		case 'S':
+			dest = &tm->tm_sec;
+			min = 0;
+			range = 61;
+			goto numeric_range;
+		case 'T':
+			s = strptime(s, "%H:%M:%S", tm);
+			if (!s) return 0;
+			break;
+		case 'U':
+		case 'W':
+			/* Throw away result, for now. (FIXME?) */
+			dest = &dummy;
+			min = 0;
+			range = 54;
+			goto numeric_range;
+		case 'w':
+			dest = &tm->tm_wday;
+			min = 0;
+			range = 7;
+			goto numeric_range;
+		case 'x':
+			s = strptime(s, nl_langinfo(D_FMT), tm);
+			if (!s) return 0;
+			break;
+		case 'X':
+			s = strptime(s, nl_langinfo(T_FMT), tm);
+			if (!s) return 0;
+			break;
+		case 'y':
+			dest = &relyear;
+			w = 2;
+			want_century |= 1;
+			goto numeric_digits;
+		case 'Y':
+			dest = &tm->tm_year;
+			if (w<0) w=4;
+			adj = 1900;
+			want_century = 0;
+			goto numeric_digits;
+		case '%':
+			if (*s++ != '%') return 0;
+			break;
+		default:
+			return 0;
+		numeric_range:
+			if (!isdigit(*s)) return 0;
+			*dest = 0;
+			for (i=1; i<=min+range && isdigit(*s); i*=10)
+				*dest = *dest * 10 + *s++ - '0';
+			if (*dest - min >= (unsigned)range) return 0;
+			*dest -= adj;
+			switch((char *)dest - (char *)tm) {
+			case offsetof(struct tm, tm_yday):
+				;
+			}
+			goto update;
+		numeric_digits:
+			neg = 0;
+			if (*s == '+') s++;
+			else if (*s == '-') neg=1, s++;
+			if (!isdigit(*s)) return 0;
+			for (*dest=i=0; i<w && isdigit(*s); i++)
+				*dest = *dest * 10 + *s++ - '0';
+			if (neg) *dest = -*dest;
+			*dest -= adj;
+			goto update;
+		symbolic_range:
+			for (i=2*range-1; i>=0; i--) {
+				ex = nl_langinfo(min+i);
+				len = strlen(ex);
+				if (strncasecmp(s, ex, len)) continue;
+				s += len;
+				*dest = i % range;
+				break;
+			}
+			if (i<0) return 0;
+			goto update;
+		update:
+			//FIXME
+			;
+		}
+	}
+	if (want_century) {
+		tm->tm_year = relyear;
+		if (want_century & 2) tm->tm_year += century * 100 - 1900;
+		else if (tm->tm_year <= 68) tm->tm_year += 100;
+	}
+	return (char *)s;
+}
libc/musl/src/time/time.c
@@ -0,0 +1,10 @@
+#include <time.h>
+#include "syscall.h"
+
+time_t time(time_t *t)
+{
+	struct timespec ts;
+	__clock_gettime(CLOCK_REALTIME, &ts);
+	if (t) *t = ts.tv_sec;
+	return ts.tv_sec;
+}
libc/musl/src/time/time_impl.h
@@ -0,0 +1,11 @@
+#include <time.h>
+
+hidden int __days_in_month(int, int);
+hidden int __month_to_secs(int, int);
+hidden long long __year_to_secs(long long, int *);
+hidden long long __tm_to_secs(const struct tm *);
+hidden const char *__tm_to_tzname(const struct tm *);
+hidden int __secs_to_tm(long long, struct tm *);
+hidden void __secs_to_zone(long long, int, int *, long *, long *, const char **);
+hidden const char *__strftime_fmt_1(char (*)[100], size_t *, int, const struct tm *, locale_t, int);
+extern hidden const char __utc[];
libc/musl/src/time/timegm.c
@@ -0,0 +1,18 @@
+#define _GNU_SOURCE
+#include "time_impl.h"
+#include <errno.h>
+
+time_t timegm(struct tm *tm)
+{
+	struct tm new;
+	long long t = __tm_to_secs(tm);
+	if (__secs_to_tm(t, &new) < 0) {
+		errno = EOVERFLOW;
+		return -1;
+	}
+	*tm = new;
+	tm->tm_isdst = 0;
+	tm->__tm_gmtoff = 0;
+	tm->__tm_zone = __utc;
+	return t;
+}
libc/musl/src/time/timer_create.c
@@ -0,0 +1,139 @@
+#include <time.h>
+#include <setjmp.h>
+#include "pthread_impl.h"
+
+struct ksigevent {
+	union sigval sigev_value;
+	int sigev_signo;
+	int sigev_notify;
+	int sigev_tid;
+};
+
+struct start_args {
+	pthread_barrier_t b;
+	struct sigevent *sev;
+};
+
+static void dummy_0()
+{
+}
+weak_alias(dummy_0, __pthread_tsd_run_dtors);
+
+static void cleanup_fromsig(void *p)
+{
+	pthread_t self = __pthread_self();
+	__pthread_tsd_run_dtors();
+	self->cancel = 0;
+	self->cancelbuf = 0;
+	self->canceldisable = 0;
+	self->cancelasync = 0;
+	self->unblock_cancel = 0;
+	__reset_tls();
+	longjmp(p, 1);
+}
+
+static void timer_handler(int sig, siginfo_t *si, void *ctx)
+{
+	pthread_t self = __pthread_self();
+	jmp_buf jb;
+	void (*notify)(union sigval) = (void (*)(union sigval))self->start;
+	union sigval val = { .sival_ptr = self->start_arg };
+
+	if (!setjmp(jb) && si->si_code == SI_TIMER) {
+		pthread_cleanup_push(cleanup_fromsig, jb);
+		notify(val);
+		pthread_cleanup_pop(1);
+	}
+}
+
+static void install_handler()
+{
+	struct sigaction sa = {
+		.sa_sigaction = timer_handler,
+		.sa_flags = SA_SIGINFO | SA_RESTART
+	};
+	__libc_sigaction(SIGTIMER, &sa, 0);
+}
+
+static void *start(void *arg)
+{
+	pthread_t self = __pthread_self();
+	struct start_args *args = arg;
+	int id;
+
+	/* Reuse no-longer-needed thread structure fields to avoid
+	 * needing the timer address in the signal handler. */
+	self->start = (void *(*)(void *))args->sev->sigev_notify_function;
+	self->start_arg = args->sev->sigev_value.sival_ptr;
+
+	pthread_barrier_wait(&args->b);
+	if ((id = self->timer_id) >= 0) {
+		__syscall(SYS_rt_sigprocmask, SIG_UNBLOCK,
+			SIGTIMER_SET, 0, _NSIG/8);
+		__wait(&self->timer_id, 0, id, 1);
+		__syscall(SYS_timer_delete, id);
+	}
+	return 0;
+}
+
+int timer_create(clockid_t clk, struct sigevent *restrict evp, timer_t *restrict res)
+{
+	static pthread_once_t once = PTHREAD_ONCE_INIT;
+	pthread_t td;
+	pthread_attr_t attr;
+	int r;
+	struct start_args args;
+	struct ksigevent ksev, *ksevp=0;
+	int timerid;
+	sigset_t set;
+
+	switch (evp ? evp->sigev_notify : SIGEV_SIGNAL) {
+	case SIGEV_NONE:
+	case SIGEV_SIGNAL:
+		if (evp) {
+			ksev.sigev_value = evp->sigev_value;
+			ksev.sigev_signo = evp->sigev_signo;
+			ksev.sigev_notify = evp->sigev_notify;
+			ksev.sigev_tid = 0;
+			ksevp = &ksev;
+		}
+		if (syscall(SYS_timer_create, clk, ksevp, &timerid) < 0)
+			return -1;
+		*res = (void *)(intptr_t)timerid;
+		break;
+	case SIGEV_THREAD:
+		pthread_once(&once, install_handler);
+		if (evp->sigev_notify_attributes)
+			attr = *evp->sigev_notify_attributes;
+		else
+			pthread_attr_init(&attr);
+		pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
+		pthread_barrier_init(&args.b, 0, 2);
+		args.sev = evp;
+
+		__block_app_sigs(&set);
+		r = pthread_create(&td, &attr, start, &args);
+		__restore_sigs(&set);
+		if (r) {
+			errno = r;
+			return -1;
+		}
+
+		ksev.sigev_value.sival_ptr = 0;
+		ksev.sigev_signo = SIGTIMER;
+		ksev.sigev_notify = 4; /* SIGEV_THREAD_ID */
+		ksev.sigev_tid = td->tid;
+		if (syscall(SYS_timer_create, clk, &ksev, &timerid) < 0)
+			timerid = -1;
+		td->timer_id = timerid;
+		pthread_barrier_wait(&args.b);
+		if (timerid < 0) return -1;
+		*res = (void *)(INTPTR_MIN | (uintptr_t)td>>1);
+		break;
+	default:
+		errno = EINVAL;
+		return -1;
+	}
+
+	return 0;
+}
libc/musl/src/time/timer_delete.c
@@ -0,0 +1,14 @@
+#include <time.h>
+#include <limits.h>
+#include "pthread_impl.h"
+
+int timer_delete(timer_t t)
+{
+	if ((intptr_t)t < 0) {
+		pthread_t td = (void *)((uintptr_t)t << 1);
+		a_store(&td->timer_id, td->timer_id | INT_MIN);
+		__wake(&td->timer_id, 1, 1);
+		return 0;
+	}
+	return __syscall(SYS_timer_delete, t);
+}
libc/musl/src/time/timer_getoverrun.c
@@ -0,0 +1,12 @@
+#include <time.h>
+#include <limits.h>
+#include "pthread_impl.h"
+
+int timer_getoverrun(timer_t t)
+{
+	if ((intptr_t)t < 0) {
+		pthread_t td = (void *)((uintptr_t)t << 1);
+		t = (void *)(uintptr_t)(td->timer_id & INT_MAX);
+	}
+	return syscall(SYS_timer_getoverrun, t);
+}
libc/musl/src/time/timer_gettime.c
@@ -0,0 +1,12 @@
+#include <time.h>
+#include <limits.h>
+#include "pthread_impl.h"
+
+int timer_gettime(timer_t t, struct itimerspec *val)
+{
+	if ((intptr_t)t < 0) {
+		pthread_t td = (void *)((uintptr_t)t << 1);
+		t = (void *)(uintptr_t)(td->timer_id & INT_MAX);
+	}
+	return syscall(SYS_timer_gettime, t, val);
+}
libc/musl/src/time/timer_settime.c
@@ -0,0 +1,12 @@
+#include <time.h>
+#include <limits.h>
+#include "pthread_impl.h"
+
+int timer_settime(timer_t t, int flags, const struct itimerspec *restrict val, struct itimerspec *restrict old)
+{
+	if ((intptr_t)t < 0) {
+		pthread_t td = (void *)((uintptr_t)t << 1);
+		t = (void *)(uintptr_t)(td->timer_id & INT_MAX);
+	}
+	return syscall(SYS_timer_settime, t, flags, val, old);
+}
libc/musl/src/time/times.c
@@ -0,0 +1,7 @@
+#include <sys/times.h>
+#include "syscall.h"
+
+clock_t times(struct tms *tms)
+{
+	return __syscall(SYS_times, tms);
+}
libc/musl/src/time/timespec_get.c
@@ -0,0 +1,10 @@
+#include <time.h>
+
+/* There is no other implemented value than TIME_UTC; all other values
+ * are considered erroneous. */
+int timespec_get(struct timespec * ts, int base)
+{
+	if (base != TIME_UTC) return 0;
+	int ret = __clock_gettime(CLOCK_REALTIME, ts);
+	return ret < 0 ? 0 : base;
+}
libc/musl/src/time/utime.c
@@ -0,0 +1,11 @@
+#include <utime.h>
+#include <sys/stat.h>
+#include <time.h>
+#include <fcntl.h>
+
+int utime(const char *path, const struct utimbuf *times)
+{
+	return utimensat(AT_FDCWD, path, times ? ((struct timespec [2]){
+		{ .tv_sec = times->actime }, { .tv_sec = times->modtime }})
+		: 0, 0);
+}
libc/musl/src/time/wcsftime.c
@@ -0,0 +1,71 @@
+#include <wchar.h>
+#include <time.h>
+#include <locale.h>
+#include "locale_impl.h"
+#include "time_impl.h"
+
+size_t __wcsftime_l(wchar_t *restrict s, size_t n, const wchar_t *restrict f, const struct tm *restrict tm, locale_t loc)
+{
+	size_t l, k;
+	char buf[100];
+	wchar_t wbuf[100];
+	wchar_t *p;
+	const char *t_mb;
+	const wchar_t *t;
+	int pad, plus;
+	unsigned long width;
+	for (l=0; l<n; f++) {
+		if (!*f) {
+			s[l] = 0;
+			return l;
+		}
+		if (*f != '%') {
+			s[l++] = *f;
+			continue;
+		}
+		f++;
+		pad = 0;
+		if (*f == '-' || *f == '_' || *f == '0') pad = *f++;
+		if ((plus = (*f == '+'))) f++;
+		width = wcstoul(f, &p, 10);
+		if (*p == 'C' || *p == 'F' || *p == 'G' || *p == 'Y') {
+			if (!width && p!=f) width = 1;
+		} else {
+			width = 0;
+		}
+		f = p;
+		if (*f == 'E' || *f == 'O') f++;
+		t_mb = __strftime_fmt_1(&buf, &k, *f, tm, loc, pad);
+		if (!t_mb) break;
+		k = mbstowcs(wbuf, t_mb, sizeof wbuf / sizeof *wbuf);
+		if (k == (size_t)-1) return 0;
+		t = wbuf;
+		if (width) {
+			for (; *t=='+' || *t=='-' || (*t=='0'&&t[1]); t++, k--);
+			width--;
+			if (plus && tm->tm_year >= 10000-1900)
+				s[l++] = '+';
+			else if (tm->tm_year < -1900)
+				s[l++] = '-';
+			else
+				width++;
+			for (; width > k && l < n; width--)
+				s[l++] = '0';
+		}
+		if (k >= n-l) k = n-l;
+		wmemcpy(s+l, t, k);
+		l += k;
+	}
+	if (n) {
+		if (l==n) l=n-1;
+		s[l] = 0;
+	}
+	return 0;
+}
+
+size_t wcsftime(wchar_t *restrict wcs, size_t n, const wchar_t *restrict f, const struct tm *restrict tm)
+{
+	return __wcsftime_l(wcs, n, f, tm, CURRENT_LOCALE);
+}
+
+weak_alias(__wcsftime_l, wcsftime_l);
libc/musl/src/unistd/mips/pipe.s
@@ -0,0 +1,20 @@
+.set noreorder
+
+.global pipe
+.type   pipe,@function
+pipe:
+	lui $gp, %hi(_gp_disp)
+	addiu $gp, %lo(_gp_disp)
+	addu $gp, $gp, $25
+	li $2, 4042
+	syscall
+	beq $7, $0, 1f
+	nop
+	lw $25, %call16(__syscall_ret)($gp)
+	jr $25
+	subu $4, $0, $2
+1:	sw $2, 0($4)
+	sw $3, 4($4)
+	move $2, $0
+	jr $ra
+	nop
libc/musl/src/unistd/mips64/pipe.s
@@ -0,0 +1,19 @@
+.set	noreorder
+.global	pipe
+.type	pipe,@function
+pipe:
+	lui	$3, %hi(%neg(%gp_rel(pipe)))
+	daddiu	$3, $3, %lo(%neg(%gp_rel(pipe)))
+	daddu	$3, $3, $25
+	li	$2, 5021
+	syscall
+	beq	$7, $0, 1f
+	nop
+	ld	$25, %got_disp(__syscall_ret)($3)
+	jr	$25
+	dsubu	$4, $0, $2
+1:	sw	$2, 0($4)
+	sw	$3, 4($4)
+	move	$2, $0
+	jr	$ra
+	nop
libc/musl/src/unistd/mipsn32/pipe.s
@@ -0,0 +1,19 @@
+.set	noreorder
+.global	pipe
+.type	pipe,@function
+pipe:
+	lui	$3, %hi(%neg(%gp_rel(pipe)))
+	addiu	$3, $3, %lo(%neg(%gp_rel(pipe)))
+	addu	$3, $3, $25
+	li	$2, 6021
+	syscall
+	beq	$7, $0, 1f
+	nop
+	lw	$25, %got_disp(__syscall_ret)($3)
+	jr	$25
+	subu	$4, $0, $2
+1:	sw	$2, 0($4)
+	sw	$3, 4($4)
+	move	$2, $0
+	jr	$ra
+	nop
libc/musl/src/unistd/sh/pipe.s
@@ -0,0 +1,27 @@
+.global pipe
+.type   pipe, @function
+pipe:
+	mov    #42, r3
+	trapa  #31
+
+	! work around hardware bug
+	or     r0, r0
+	or     r0, r0
+	or     r0, r0
+	or     r0, r0
+	or     r0, r0
+
+	cmp/pz r0
+	bt     1f
+
+	mov.l  L1, r1
+	braf   r1
+	 mov   r0, r4
+
+1:	mov.l  r0, @(0,r4)
+	mov.l  r1, @(4,r4)
+	rts
+	 mov   #0, r0
+
+.align 2
+L1:	.long __syscall_ret@PLT-(1b-.)
libc/musl/src/unistd/_exit.c
@@ -0,0 +1,7 @@
+#include <unistd.h>
+#include <stdlib.h>
+
+_Noreturn void _exit(int status)
+{
+	_Exit(status);
+}
libc/musl/src/unistd/access.c
@@ -0,0 +1,12 @@
+#include <unistd.h>
+#include <fcntl.h>
+#include "syscall.h"
+
+int access(const char *filename, int amode)
+{
+#ifdef SYS_access
+	return syscall(SYS_access, filename, amode);
+#else
+	return syscall(SYS_faccessat, AT_FDCWD, filename, amode, 0);
+#endif
+}
libc/musl/src/unistd/acct.c
@@ -0,0 +1,8 @@
+#define _GNU_SOURCE
+#include <unistd.h>
+#include "syscall.h"
+
+int acct(const char *filename)
+{
+	return syscall(SYS_acct, filename);
+}
libc/musl/src/unistd/alarm.c
@@ -0,0 +1,10 @@
+#include <unistd.h>
+#include <sys/time.h>
+#include "syscall.h"
+
+unsigned alarm(unsigned seconds)
+{
+	struct itimerval it = { .it_value.tv_sec = seconds };
+	__syscall(SYS_setitimer, ITIMER_REAL, &it, &it);
+	return it.it_value.tv_sec + !!it.it_value.tv_usec;
+}
libc/musl/src/unistd/chdir.c
@@ -0,0 +1,7 @@
+#include <unistd.h>
+#include "syscall.h"
+
+int chdir(const char *path)
+{
+	return syscall(SYS_chdir, path);
+}
libc/musl/src/unistd/chown.c
@@ -0,0 +1,12 @@
+#include <unistd.h>
+#include <fcntl.h>
+#include "syscall.h"
+
+int chown(const char *path, uid_t uid, gid_t gid)
+{
+#ifdef SYS_chown
+	return syscall(SYS_chown, path, uid, gid);
+#else
+	return syscall(SYS_fchownat, AT_FDCWD, path, uid, gid, 0);
+#endif
+}
libc/musl/src/unistd/close.c
@@ -0,0 +1,18 @@
+#include <unistd.h>
+#include <errno.h>
+#include "syscall.h"
+
+static int dummy(int fd)
+{
+	return fd;
+}
+
+weak_alias(dummy, __aio_close);
+
+int close(int fd)
+{
+	fd = __aio_close(fd);
+	int r = __syscall_cp(SYS_close, fd);
+	if (r == -EINTR) r = 0;
+	return __syscall_ret(r);
+}
libc/musl/src/unistd/ctermid.c
@@ -0,0 +1,7 @@
+#include <stdio.h>
+#include <string.h>
+
+char *ctermid(char *s)
+{
+	return s ? strcpy(s, "/dev/tty") : "/dev/tty";
+}
libc/musl/src/unistd/dup.c
@@ -0,0 +1,7 @@
+#include <unistd.h>
+#include "syscall.h"
+
+int dup(int fd)
+{
+	return syscall(SYS_dup, fd);
+}
libc/musl/src/unistd/dup2.c
@@ -0,0 +1,20 @@
+#include <unistd.h>
+#include <errno.h>
+#include <fcntl.h>
+#include "syscall.h"
+
+int dup2(int old, int new)
+{
+	int r;
+#ifdef SYS_dup2
+	while ((r=__syscall(SYS_dup2, old, new))==-EBUSY);
+#else
+	if (old==new) {
+		r = __syscall(SYS_fcntl, old, F_GETFD);
+		if (r >= 0) return old;
+	} else {
+		while ((r=__syscall(SYS_dup3, old, new, 0))==-EBUSY);
+	}
+#endif
+	return __syscall_ret(r);
+}
libc/musl/src/unistd/dup3.c
@@ -0,0 +1,24 @@
+#define _GNU_SOURCE
+#include <unistd.h>
+#include <errno.h>
+#include <fcntl.h>
+#include "syscall.h"
+
+int __dup3(int old, int new, int flags)
+{
+	int r;
+#ifdef SYS_dup2
+	if (old==new) return __syscall_ret(-EINVAL);
+	if (flags & O_CLOEXEC) {
+		while ((r=__syscall(SYS_dup3, old, new, flags))==-EBUSY);
+		if (r!=-ENOSYS) return __syscall_ret(r);
+	}
+	while ((r=__syscall(SYS_dup2, old, new))==-EBUSY);
+	if (flags & O_CLOEXEC) __syscall(SYS_fcntl, new, F_SETFD, FD_CLOEXEC);
+#else
+	while ((r=__syscall(SYS_dup3, old, new, flags))==-EBUSY);
+#endif
+	return __syscall_ret(r);
+}
+
+weak_alias(__dup3, dup3);
libc/musl/src/unistd/faccessat.c
@@ -0,0 +1,56 @@
+#include <unistd.h>
+#include <fcntl.h>
+#include <sys/wait.h>
+#include "syscall.h"
+#include "pthread_impl.h"
+
+struct ctx {
+	int fd;
+	const char *filename;
+	int amode;
+	int p;
+};
+
+static int checker(void *p)
+{
+	struct ctx *c = p;
+	int ret;
+	if (__syscall(SYS_setregid, __syscall(SYS_getegid), -1)
+	    || __syscall(SYS_setreuid, __syscall(SYS_geteuid), -1))
+		__syscall(SYS_exit, 1);
+	ret = __syscall(SYS_faccessat, c->fd, c->filename, c->amode, 0);
+	__syscall(SYS_write, c->p, &ret, sizeof ret);
+	return 0;
+}
+
+int faccessat(int fd, const char *filename, int amode, int flag)
+{
+	if (!flag || (flag==AT_EACCESS && getuid()==geteuid() && getgid()==getegid()))
+		return syscall(SYS_faccessat, fd, filename, amode, flag);
+
+	if (flag != AT_EACCESS)
+		return __syscall_ret(-EINVAL);
+
+	char stack[1024];
+	sigset_t set;
+	pid_t pid;
+	int status;
+	int ret, p[2];
+
+	if (pipe2(p, O_CLOEXEC)) return __syscall_ret(-EBUSY);
+	struct ctx c = { .fd = fd, .filename = filename, .amode = amode, .p = p[1] };
+
+	__block_all_sigs(&set);
+	
+	pid = __clone(checker, stack+sizeof stack, 0, &c);
+	__syscall(SYS_close, p[1]);
+
+	if (pid<0 || __syscall(SYS_read, p[0], &ret, sizeof ret) != sizeof(ret))
+		ret = -EBUSY;
+	__syscall(SYS_close, p[0]);
+	__syscall(SYS_wait4, pid, &status, __WCLONE, 0);
+
+	__restore_sigs(&set);
+
+	return __syscall_ret(ret);
+}
libc/musl/src/unistd/fchdir.c
@@ -0,0 +1,15 @@
+#include <unistd.h>
+#include <errno.h>
+#include <fcntl.h>
+#include "syscall.h"
+
+int fchdir(int fd)
+{
+	int ret = __syscall(SYS_fchdir, fd);
+	if (ret != -EBADF || __syscall(SYS_fcntl, fd, F_GETFD) < 0)
+		return __syscall_ret(ret);
+
+	char buf[15+3*sizeof(int)];
+	__procfdname(buf, fd);
+	return syscall(SYS_chdir, buf);
+}
libc/musl/src/unistd/fchown.c
@@ -0,0 +1,20 @@
+#include <unistd.h>
+#include <errno.h>
+#include <fcntl.h>
+#include "syscall.h"
+
+int fchown(int fd, uid_t uid, gid_t gid)
+{
+	int ret = __syscall(SYS_fchown, fd, uid, gid);
+	if (ret != -EBADF || __syscall(SYS_fcntl, fd, F_GETFD) < 0)
+		return __syscall_ret(ret);
+
+	char buf[15+3*sizeof(int)];
+	__procfdname(buf, fd);
+#ifdef SYS_chown
+	return syscall(SYS_chown, buf, uid, gid);
+#else
+	return syscall(SYS_fchownat, AT_FDCWD, buf, uid, gid, 0);
+#endif
+
+}
libc/musl/src/unistd/fchownat.c
@@ -0,0 +1,7 @@
+#include <unistd.h>
+#include "syscall.h"
+
+int fchownat(int fd, const char *path, uid_t uid, gid_t gid, int flag)
+{
+	return syscall(SYS_fchownat, fd, path, uid, gid, flag);
+}
libc/musl/src/unistd/fdatasync.c
@@ -0,0 +1,7 @@
+#include <unistd.h>
+#include "syscall.h"
+
+int fdatasync(int fd)
+{
+	return syscall_cp(SYS_fdatasync, fd);
+}
libc/musl/src/unistd/fsync.c
@@ -0,0 +1,7 @@
+#include <unistd.h>
+#include "syscall.h"
+
+int fsync(int fd)
+{
+	return syscall_cp(SYS_fsync, fd);
+}
libc/musl/src/unistd/ftruncate.c
@@ -0,0 +1,9 @@
+#include <unistd.h>
+#include "syscall.h"
+
+int ftruncate(int fd, off_t length)
+{
+	return syscall(SYS_ftruncate, fd, __SYSCALL_LL_O(length));
+}
+
+weak_alias(ftruncate, ftruncate64);
libc/musl/src/unistd/getcwd.c
@@ -0,0 +1,25 @@
+#include <unistd.h>
+#include <errno.h>
+#include <limits.h>
+#include <string.h>
+#include "syscall.h"
+
+char *getcwd(char *buf, size_t size)
+{
+	char tmp[buf ? 1 : PATH_MAX];
+	if (!buf) {
+		buf = tmp;
+		size = sizeof tmp;
+	} else if (!size) {
+		errno = EINVAL;
+		return 0;
+	}
+	long ret = syscall(SYS_getcwd, buf, size);
+	if (ret < 0)
+		return 0;
+	if (ret == 0 || buf[0] != '/') {
+		errno = ENOENT;
+		return 0;
+	}
+	return buf == tmp ? strdup(buf) : buf;
+}
libc/musl/src/unistd/getegid.c
@@ -0,0 +1,7 @@
+#include <unistd.h>
+#include "syscall.h"
+
+gid_t getegid(void)
+{
+	return __syscall(SYS_getegid);
+}
libc/musl/src/unistd/geteuid.c
@@ -0,0 +1,7 @@
+#include <unistd.h>
+#include "syscall.h"
+
+uid_t geteuid(void)
+{
+	return __syscall(SYS_geteuid);
+}
libc/musl/src/unistd/getgid.c
@@ -0,0 +1,7 @@
+#include <unistd.h>
+#include "syscall.h"
+
+gid_t getgid(void)
+{
+	return __syscall(SYS_getgid);
+}
libc/musl/src/unistd/getgroups.c
@@ -0,0 +1,7 @@
+#include <unistd.h>
+#include "syscall.h"
+
+int getgroups(int count, gid_t list[])
+{
+	return syscall(SYS_getgroups, count, list);
+}
libc/musl/src/unistd/gethostname.c
@@ -0,0 +1,13 @@
+#include <unistd.h>
+#include <sys/utsname.h>
+
+int gethostname(char *name, size_t len)
+{
+	size_t i;
+	struct utsname uts;
+	if (uname(&uts)) return -1;
+	if (len > sizeof uts.nodename) len = sizeof uts.nodename;
+	for (i=0; i<len && (name[i] = uts.nodename[i]); i++);
+	if (i && i==len) name[i-1] = 0;
+	return 0;
+}
libc/musl/src/unistd/getlogin.c
@@ -0,0 +1,7 @@
+#include <unistd.h>
+#include <stdlib.h>
+
+char *getlogin(void)
+{
+	return getenv("LOGNAME");
+}
libc/musl/src/unistd/getlogin_r.c
@@ -0,0 +1,12 @@
+#include <unistd.h>
+#include <string.h>
+#include <errno.h>
+
+int getlogin_r(char *name, size_t size)
+{
+	char *logname = getlogin();
+	if (!logname) return ENXIO; /* or...? */
+	if (strlen(logname) >= size) return ERANGE;
+	strcpy(name, logname);
+	return 0;
+}
libc/musl/src/unistd/getpgid.c
@@ -0,0 +1,7 @@
+#include <unistd.h>
+#include "syscall.h"
+
+pid_t getpgid(pid_t pid)
+{
+	return syscall(SYS_getpgid, pid);
+}
libc/musl/src/unistd/getpgrp.c
@@ -0,0 +1,7 @@
+#include <unistd.h>
+#include "syscall.h"
+
+pid_t getpgrp(void)
+{
+	return __syscall(SYS_getpgid, 0);
+}
libc/musl/src/unistd/getpid.c
@@ -0,0 +1,7 @@
+#include <unistd.h>
+#include "syscall.h"
+
+pid_t getpid(void)
+{
+	return __syscall(SYS_getpid);
+}
libc/musl/src/unistd/getppid.c
@@ -0,0 +1,7 @@
+#include <unistd.h>
+#include "syscall.h"
+
+pid_t getppid(void)
+{
+	return __syscall(SYS_getppid);
+}
libc/musl/src/unistd/getsid.c
@@ -0,0 +1,7 @@
+#include <unistd.h>
+#include "syscall.h"
+
+pid_t getsid(pid_t pid)
+{
+	return syscall(SYS_getsid, pid);
+}
libc/musl/src/unistd/getuid.c
@@ -0,0 +1,7 @@
+#include <unistd.h>
+#include "syscall.h"
+
+uid_t getuid(void)
+{
+	return __syscall(SYS_getuid);
+}
libc/musl/src/unistd/isatty.c
@@ -0,0 +1,13 @@
+#include <unistd.h>
+#include <errno.h>
+#include <sys/ioctl.h>
+#include "syscall.h"
+
+int isatty(int fd)
+{
+	struct winsize wsz;
+	unsigned long r = syscall(SYS_ioctl, fd, TIOCGWINSZ, &wsz);
+	if (r == 0) return 1;
+	if (errno != EBADF) errno = ENOTTY;
+	return 0;
+}
libc/musl/src/unistd/lchown.c
@@ -0,0 +1,12 @@
+#include <unistd.h>
+#include <fcntl.h>
+#include "syscall.h"
+
+int lchown(const char *path, uid_t uid, gid_t gid)
+{
+#ifdef SYS_lchown
+	return syscall(SYS_lchown, path, uid, gid);
+#else
+	return syscall(SYS_fchownat, AT_FDCWD, path, uid, gid, AT_SYMLINK_NOFOLLOW);
+#endif
+}
libc/musl/src/unistd/link.c
@@ -0,0 +1,12 @@
+#include <unistd.h>
+#include <fcntl.h>
+#include "syscall.h"
+
+int link(const char *existing, const char *new)
+{
+#ifdef SYS_link
+	return syscall(SYS_link, existing, new);
+#else
+	return syscall(SYS_linkat, AT_FDCWD, existing, AT_FDCWD, new, 0);
+#endif
+}
libc/musl/src/unistd/linkat.c
@@ -0,0 +1,7 @@
+#include <unistd.h>
+#include "syscall.h"
+
+int linkat(int fd1, const char *existing, int fd2, const char *new, int flag)
+{
+	return syscall(SYS_linkat, fd1, existing, fd2, new, flag);
+}
libc/musl/src/unistd/lseek.c
@@ -0,0 +1,14 @@
+#include <unistd.h>
+#include "syscall.h"
+
+off_t lseek(int fd, off_t offset, int whence)
+{
+#ifdef SYS__llseek
+	off_t result;
+	return syscall(SYS__llseek, fd, offset>>32, offset, &result, whence) ? -1 : result;
+#else
+	return syscall(SYS_lseek, fd, offset, whence);
+#endif
+}
+
+weak_alias(lseek, lseek64);
libc/musl/src/unistd/nice.c
@@ -0,0 +1,16 @@
+#include <unistd.h>
+#include <sys/resource.h>
+#include <limits.h>
+#include "syscall.h"
+
+int nice(int inc)
+{
+	int prio = inc;
+	// Only query old priority if it can affect the result.
+	// This also avoids issues with integer overflow.
+	if (inc > -2*NZERO && inc < 2*NZERO)
+		prio += getpriority(PRIO_PROCESS, 0);
+	if (prio > NZERO-1) prio = NZERO-1;
+	if (prio < -NZERO) prio = -NZERO;
+	return setpriority(PRIO_PROCESS, 0, prio) ? -1 : prio;
+}
libc/musl/src/unistd/pause.c
@@ -0,0 +1,11 @@
+#include <unistd.h>
+#include "syscall.h"
+
+int pause(void)
+{
+#ifdef SYS_pause
+	return syscall_cp(SYS_pause);
+#else
+	return syscall_cp(SYS_ppoll, 0, 0, 0, 0);
+#endif
+}
libc/musl/src/unistd/pipe.c
@@ -0,0 +1,11 @@
+#include <unistd.h>
+#include "syscall.h"
+
+int pipe(int fd[2])
+{
+#ifdef SYS_pipe
+	return syscall(SYS_pipe, fd);
+#else
+	return syscall(SYS_pipe2, fd, 0);
+#endif
+}
libc/musl/src/unistd/pipe2.c
@@ -0,0 +1,22 @@
+#include <unistd.h>
+#include <errno.h>
+#include <fcntl.h>
+#include "syscall.h"
+
+int pipe2(int fd[2], int flag)
+{
+	if (!flag) return pipe(fd);
+	int ret = __syscall(SYS_pipe2, fd, flag);
+	if (ret != -ENOSYS) return __syscall_ret(ret);
+	ret = pipe(fd);
+	if (ret) return ret;
+	if (flag & O_CLOEXEC) {
+		__syscall(SYS_fcntl, fd[0], F_SETFD, FD_CLOEXEC);
+		__syscall(SYS_fcntl, fd[1], F_SETFD, FD_CLOEXEC);
+	}
+	if (flag & O_NONBLOCK) {
+		__syscall(SYS_fcntl, fd[0], F_SETFL, O_NONBLOCK);
+		__syscall(SYS_fcntl, fd[1], F_SETFL, O_NONBLOCK);
+	}
+	return 0;
+}
libc/musl/src/unistd/posix_close.c
@@ -0,0 +1,6 @@
+#include <unistd.h>
+
+int posix_close(int fd, int flags)
+{
+	return close(fd);
+}
libc/musl/src/unistd/pread.c
@@ -0,0 +1,9 @@
+#include <unistd.h>
+#include "syscall.h"
+
+ssize_t pread(int fd, void *buf, size_t size, off_t ofs)
+{
+	return syscall_cp(SYS_pread, fd, buf, size, __SYSCALL_LL_PRW(ofs));
+}
+
+weak_alias(pread, pread64);
libc/musl/src/unistd/preadv.c
@@ -0,0 +1,12 @@
+#define _BSD_SOURCE
+#include <sys/uio.h>
+#include <unistd.h>
+#include "syscall.h"
+
+ssize_t preadv(int fd, const struct iovec *iov, int count, off_t ofs)
+{
+	return syscall_cp(SYS_preadv, fd, iov, count,
+		(long)(ofs), (long)(ofs>>32));
+}
+
+weak_alias(preadv, preadv64);
libc/musl/src/unistd/pwrite.c
@@ -0,0 +1,9 @@
+#include <unistd.h>
+#include "syscall.h"
+
+ssize_t pwrite(int fd, const void *buf, size_t size, off_t ofs)
+{
+	return syscall_cp(SYS_pwrite, fd, buf, size, __SYSCALL_LL_PRW(ofs));
+}
+
+weak_alias(pwrite, pwrite64);
libc/musl/src/unistd/pwritev.c
@@ -0,0 +1,12 @@
+#define _BSD_SOURCE
+#include <sys/uio.h>
+#include <unistd.h>
+#include "syscall.h"
+
+ssize_t pwritev(int fd, const struct iovec *iov, int count, off_t ofs)
+{
+	return syscall_cp(SYS_pwritev, fd, iov, count,
+		(long)(ofs), (long)(ofs>>32));
+}
+
+weak_alias(pwritev, pwritev64);
libc/musl/src/unistd/read.c
@@ -0,0 +1,7 @@
+#include <unistd.h>
+#include "syscall.h"
+
+ssize_t read(int fd, void *buf, size_t count)
+{
+	return syscall_cp(SYS_read, fd, buf, count);
+}
libc/musl/src/unistd/readlink.c
@@ -0,0 +1,12 @@
+#include <unistd.h>
+#include <fcntl.h>
+#include "syscall.h"
+
+ssize_t readlink(const char *restrict path, char *restrict buf, size_t bufsize)
+{
+#ifdef SYS_readlink
+	return syscall(SYS_readlink, path, buf, bufsize);
+#else
+	return syscall(SYS_readlinkat, AT_FDCWD, path, buf, bufsize);
+#endif
+}
libc/musl/src/unistd/readlinkat.c
@@ -0,0 +1,7 @@
+#include <unistd.h>
+#include "syscall.h"
+
+ssize_t readlinkat(int fd, const char *restrict path, char *restrict buf, size_t bufsize)
+{
+	return syscall(SYS_readlinkat, fd, path, buf, bufsize);
+}
libc/musl/src/unistd/readv.c
@@ -0,0 +1,7 @@
+#include <sys/uio.h>
+#include "syscall.h"
+
+ssize_t readv(int fd, const struct iovec *iov, int count)
+{
+	return syscall_cp(SYS_readv, fd, iov, count);
+}
libc/musl/src/unistd/renameat.c
@@ -0,0 +1,7 @@
+#include <stdio.h>
+#include "syscall.h"
+
+int renameat(int oldfd, const char *old, int newfd, const char *new)
+{
+	return syscall(SYS_renameat, oldfd, old, newfd, new);
+}
libc/musl/src/unistd/rmdir.c
@@ -0,0 +1,12 @@
+#include <unistd.h>
+#include <fcntl.h>
+#include "syscall.h"
+
+int rmdir(const char *path)
+{
+#ifdef SYS_rmdir
+	return syscall(SYS_rmdir, path);
+#else
+	return syscall(SYS_unlinkat, AT_FDCWD, path, AT_REMOVEDIR);
+#endif
+}
libc/musl/src/unistd/setegid.c
@@ -0,0 +1,8 @@
+#include <unistd.h>
+#include "libc.h"
+#include "syscall.h"
+
+int setegid(gid_t egid)
+{
+	return __setxid(SYS_setresgid, -1, egid, -1);
+}
libc/musl/src/unistd/seteuid.c
@@ -0,0 +1,8 @@
+#include <unistd.h>
+#include "syscall.h"
+#include "libc.h"
+
+int seteuid(uid_t euid)
+{
+	return __setxid(SYS_setresuid, -1, euid, -1);
+}
libc/musl/src/unistd/setgid.c
@@ -0,0 +1,8 @@
+#include <unistd.h>
+#include "syscall.h"
+#include "libc.h"
+
+int setgid(gid_t gid)
+{
+	return __setxid(SYS_setgid, gid, 0, 0);
+}
libc/musl/src/unistd/setpgid.c
@@ -0,0 +1,7 @@
+#include <unistd.h>
+#include "syscall.h"
+
+int setpgid(pid_t pid, pid_t pgid)
+{
+	return syscall(SYS_setpgid, pid, pgid);
+}
libc/musl/src/unistd/setpgrp.c
@@ -0,0 +1,6 @@
+#include <unistd.h>
+
+pid_t setpgrp(void)
+{
+	return setpgid(0, 0);
+}
libc/musl/src/unistd/setregid.c
@@ -0,0 +1,8 @@
+#include <unistd.h>
+#include "syscall.h"
+#include "libc.h"
+
+int setregid(gid_t rgid, gid_t egid)
+{
+	return __setxid(SYS_setregid, rgid, egid, 0);
+}
libc/musl/src/unistd/setresgid.c
@@ -0,0 +1,9 @@
+#define _GNU_SOURCE
+#include <unistd.h>
+#include "syscall.h"
+#include "libc.h"
+
+int setresgid(gid_t rgid, gid_t egid, gid_t sgid)
+{
+	return __setxid(SYS_setresgid, rgid, egid, sgid);
+}
libc/musl/src/unistd/setresuid.c
@@ -0,0 +1,9 @@
+#define _GNU_SOURCE
+#include <unistd.h>
+#include "syscall.h"
+#include "libc.h"
+
+int setresuid(uid_t ruid, uid_t euid, uid_t suid)
+{
+	return __setxid(SYS_setresuid, ruid, euid, suid);
+}
libc/musl/src/unistd/setreuid.c
@@ -0,0 +1,8 @@
+#include <unistd.h>
+#include "syscall.h"
+#include "libc.h"
+
+int setreuid(uid_t ruid, uid_t euid)
+{
+	return __setxid(SYS_setreuid, ruid, euid, 0);
+}
libc/musl/src/unistd/setsid.c
@@ -0,0 +1,7 @@
+#include <unistd.h>
+#include "syscall.h"
+
+pid_t setsid(void)
+{
+	return syscall(SYS_setsid);
+}
libc/musl/src/unistd/setuid.c
@@ -0,0 +1,8 @@
+#include <unistd.h>
+#include "syscall.h"
+#include "libc.h"
+
+int setuid(uid_t uid)
+{
+	return __setxid(SYS_setuid, uid, 0, 0);
+}
libc/musl/src/unistd/setxid.c
@@ -0,0 +1,39 @@
+#include <unistd.h>
+#include <errno.h>
+#include "syscall.h"
+#include "libc.h"
+#include "pthread_impl.h"
+
+struct ctx {
+	int id, eid, sid;
+	int nr, err;
+};
+
+static void do_setxid(void *p)
+{
+	struct ctx *c = p;
+	if (c->err>0) return;
+	int ret = -__syscall(c->nr, c->id, c->eid, c->sid);
+	if (ret && !c->err) {
+		/* If one thread fails to set ids after another has already
+		 * succeeded, forcibly killing the process is the only safe
+		 * thing to do. State is inconsistent and dangerous. Use
+		 * SIGKILL because it is uncatchable. */
+		__block_all_sigs(0);
+		__syscall(SYS_kill, __syscall(SYS_getpid), SIGKILL);
+	}
+	c->err = ret;
+}
+
+int __setxid(int nr, int id, int eid, int sid)
+{
+	/* err is initially nonzero so that failure of the first thread does not
+	 * trigger the safety kill above. */
+	struct ctx c = { .nr = nr, .id = id, .eid = eid, .sid = sid, .err = -1 };
+	__synccall(do_setxid, &c);
+	if (c.err) {
+		if (c.err>0) errno = c.err;
+		return -1;
+	}
+	return 0;
+}
libc/musl/src/unistd/sleep.c
@@ -0,0 +1,10 @@
+#include <unistd.h>
+#include <time.h>
+
+unsigned sleep(unsigned seconds)
+{
+	struct timespec tv = { .tv_sec = seconds, .tv_nsec = 0 };
+	if (nanosleep(&tv, &tv))
+		return tv.tv_sec;
+	return 0;
+}
libc/musl/src/unistd/symlink.c
@@ -0,0 +1,12 @@
+#include <unistd.h>
+#include <fcntl.h>
+#include "syscall.h"
+
+int symlink(const char *existing, const char *new)
+{
+#ifdef SYS_symlink
+	return syscall(SYS_symlink, existing, new);
+#else
+	return syscall(SYS_symlinkat, existing, AT_FDCWD, new);
+#endif
+}
libc/musl/src/unistd/symlinkat.c
@@ -0,0 +1,7 @@
+#include <unistd.h>
+#include "syscall.h"
+
+int symlinkat(const char *existing, int fd, const char *new)
+{
+	return syscall(SYS_symlinkat, existing, fd, new);
+}
libc/musl/src/unistd/sync.c
@@ -0,0 +1,7 @@
+#include <unistd.h>
+#include "syscall.h"
+
+void sync(void)
+{
+	__syscall(SYS_sync);
+}
libc/musl/src/unistd/tcgetpgrp.c
@@ -0,0 +1,11 @@
+#include <unistd.h>
+#include <termios.h>
+#include <sys/ioctl.h>
+
+pid_t tcgetpgrp(int fd)
+{
+	int pgrp;
+	if (ioctl(fd, TIOCGPGRP, &pgrp) < 0)
+		return -1;
+	return pgrp;
+}
libc/musl/src/unistd/tcsetpgrp.c
@@ -0,0 +1,9 @@
+#include <unistd.h>
+#include <termios.h>
+#include <sys/ioctl.h>
+
+int tcsetpgrp(int fd, pid_t pgrp)
+{
+	int pgrp_int = pgrp;
+	return ioctl(fd, TIOCSPGRP, &pgrp_int);
+}
libc/musl/src/unistd/truncate.c
@@ -0,0 +1,9 @@
+#include <unistd.h>
+#include "syscall.h"
+
+int truncate(const char *path, off_t length)
+{
+	return syscall(SYS_truncate, path, __SYSCALL_LL_O(length));
+}
+
+weak_alias(truncate, truncate64);
libc/musl/src/unistd/ttyname.c
@@ -0,0 +1,14 @@
+#include <unistd.h>
+#include <errno.h>
+#include <limits.h>
+
+char *ttyname(int fd)
+{
+	static char buf[TTY_NAME_MAX];
+	int result;
+	if ((result = ttyname_r(fd, buf, sizeof buf))) {
+		errno = result;
+		return NULL;
+	}
+	return buf;
+}
libc/musl/src/unistd/ttyname_r.c
@@ -0,0 +1,28 @@
+#include <unistd.h>
+#include <errno.h>
+#include <sys/stat.h>
+#include "syscall.h"
+
+int ttyname_r(int fd, char *name, size_t size)
+{
+	struct stat st1, st2;
+	char procname[sizeof "/proc/self/fd/" + 3*sizeof(int) + 2];
+	ssize_t l;
+
+	if (!isatty(fd)) return errno;
+
+	__procfdname(procname, fd);
+	l = readlink(procname, name, size);
+
+	if (l < 0) return errno;
+	else if (l == size) return ERANGE;
+
+	name[l] = 0;
+
+	if (stat(name, &st1) || fstat(fd, &st2))
+		return errno;
+	if (st1.st_dev != st2.st_dev || st1.st_ino != st2.st_ino)
+		return ENODEV;
+
+	return 0;
+}
libc/musl/src/unistd/ualarm.c
@@ -0,0 +1,13 @@
+#define _GNU_SOURCE
+#include <unistd.h>
+#include <sys/time.h>
+
+unsigned ualarm(unsigned value, unsigned interval)
+{
+	struct itimerval it = {
+		.it_interval.tv_usec = interval,
+		.it_value.tv_usec = value
+	};
+	setitimer(ITIMER_REAL, &it, &it);
+	return it.it_value.tv_sec*1000000 + it.it_value.tv_usec;
+}
libc/musl/src/unistd/unlink.c
@@ -0,0 +1,12 @@
+#include <unistd.h>
+#include <fcntl.h>
+#include "syscall.h"
+
+int unlink(const char *path)
+{
+#ifdef SYS_unlink
+	return syscall(SYS_unlink, path);
+#else
+	return syscall(SYS_unlinkat, AT_FDCWD, path, 0);
+#endif
+}
libc/musl/src/unistd/unlinkat.c
@@ -0,0 +1,7 @@
+#include <unistd.h>
+#include "syscall.h"
+
+int unlinkat(int fd, const char *path, int flag)
+{
+	return syscall(SYS_unlinkat, fd, path, flag);
+}
libc/musl/src/unistd/usleep.c
@@ -0,0 +1,12 @@
+#define _GNU_SOURCE
+#include <unistd.h>
+#include <time.h>
+
+int usleep(unsigned useconds)
+{
+	struct timespec tv = {
+		.tv_sec = useconds/1000000,
+		.tv_nsec = (useconds%1000000)*1000
+	};
+	return nanosleep(&tv, &tv);
+}
libc/musl/src/unistd/write.c
@@ -0,0 +1,7 @@
+#include <unistd.h>
+#include "syscall.h"
+
+ssize_t write(int fd, const void *buf, size_t count)
+{
+	return syscall_cp(SYS_write, fd, buf, count);
+}
libc/musl/src/unistd/writev.c
@@ -0,0 +1,7 @@
+#include <sys/uio.h>
+#include "syscall.h"
+
+ssize_t writev(int fd, const struct iovec *iov, int count)
+{
+	return syscall_cp(SYS_writev, fd, iov, count);
+}
src/codegen.cpp
@@ -8014,11 +8014,14 @@ static void detect_libc(CodeGen *g) {
     } else if ((g->out_type == OutTypeExe || (g->out_type == OutTypeLib && !g->is_static)) &&
         !target_is_darwin(g->zig_target))
     {
-        // Currently darwin is the only platform that we can link libc on when not compiling natively,
-        // without a cross compiling libc kit.
         fprintf(stderr,
-            "Cannot link against libc for non-native OS '%s' without providing a libc installation file.\n"
-            "See `zig libc --help` for more details.\n", target_os_name(g->zig_target->os));
+            "Zig is unable to provide a libc for the chosen target '%s-%s-%s'.\n"
+            "The target is non-native, so Zig also cannot use the native libc installation.\n"
+            "Choose a target which has a libc available, or provide a libc installation text file.\n"
+            "See `zig libc --help` for more details.\n",
+            target_arch_name(g->zig_target->arch),
+            target_os_name(g->zig_target->os),
+            target_abi_name(g->zig_target->abi));
         exit(1);
     }
 }
src/config.h.in
@@ -22,8 +22,6 @@
 #define ZIG_LLD_INCLUDE_PATH "@LLD_INCLUDE_DIRS@"
 #define ZIG_LLD_LIBRARIES "@LLD_LIBRARIES@"
 #define ZIG_LLVM_CONFIG_EXE "@LLVM_CONFIG_EXE@"
-#define ZIG_STD_FILES "@ZIG_STD_FILES@"
-#define ZIG_C_HEADER_FILES "@ZIG_C_HEADER_FILES@"
 #define ZIG_DIA_GUIDS_LIB "@ZIG_DIA_GUIDS_LIB_ESCAPED@"
 
 #endif
src/install_files.h.in
@@ -0,0 +1,15 @@
+/*
+ * Copyright (c) 2019 Andrew Kelley
+ *
+ * This file is part of zig, which is MIT licensed.
+ * See http://opensource.org/licenses/MIT
+ */
+
+#ifndef ZIG_INSTALL_FILES_H
+#define ZIG_INSTALL_FILES_H
+
+#define ZIG_MUSL_SRC_FILES "@ZIG_MUSL_SRC_FILES@"
+#define ZIG_STD_FILES "@ZIG_STD_FILES@"
+#define ZIG_C_HEADER_FILES "@ZIG_C_HEADER_FILES@"
+
+#endif
src/link.cpp
@@ -10,7 +10,7 @@
 #include "codegen.hpp"
 #include "analyze.hpp"
 #include "compiler.hpp"
-
+#include "install_files.h"
 
 struct LinkJob {
     CodeGen *codegen;
@@ -458,11 +458,157 @@ static void musl_add_cc_args(CodeGen *parent, CFile *c_file) {
     c_file->args.append("-fno-asynchronous-unwind-tables");
     c_file->args.append("-ffunction-sections");
     c_file->args.append("-fdata-sections");
+}
 
-    c_file->args.append("-fno-stack-protector");
-    c_file->args.append("-DCRT");
+static const char *musl_arch_names[] = {
+    "aarch64",
+    "arm",
+    "generic",
+    "i386",
+    "m68k",
+    "microblaze",
+    "mips",
+    "mips64",
+    "mipsn32",
+    "or1k",
+    "powerpc",
+    "powerpc64",
+    "s390x",
+    "sh",
+    "x32",
+    "x86_64",
+};
+
+static bool is_musl_arch_name(const char *name) {
+    for (size_t i = 0; i < array_length(musl_arch_names); i += 1) {
+        if (strcmp(name, musl_arch_names[i]) == 0)
+            return true;
+    }
+    return false;
 }
 
+static const char *build_musl(CodeGen *parent) {
+    CodeGen *child_gen = create_child_codegen(parent, nullptr, OutTypeLib, nullptr);
+    codegen_set_out_name(child_gen, buf_create_from_str("c"));
+    child_gen->is_static = true;
+
+    // When there is a src/<arch>/foo.* then it should substitute for src/foo.*
+    // Even a .s file can substitute for a .c file.
+
+    enum MuslSrc {
+        MuslSrcAsm,
+        MuslSrcNormal,
+        MuslSrcO3,
+    };
+
+    HashMap<Buf *, MuslSrc, buf_hash, buf_eql_buf> source_table = {};
+    source_table.init(1800);
+
+    SplitIterator install_h_it = memSplit(str(ZIG_MUSL_SRC_FILES), str(";"));
+    const char *target_musl_arch_name = musl_arch_name(parent->zig_target);
+    for (;;) {
+        Optional<Slice<uint8_t>> opt_item = SplitIterator_next(&install_h_it);
+        if (!opt_item.is_some) break;
+        Buf *src_file = buf_create_from_slice(opt_item.value);
+
+        MuslSrc src_kind;
+        if (buf_ends_with_str(src_file, ".c")) {
+            assert(buf_starts_with_str(src_file, "musl/src/"));
+            bool want_O3 = buf_starts_with_str(src_file, "musl/src/malloc/") ||
+                buf_starts_with_str(src_file, "musl/src/string/") ||
+                buf_starts_with_str(src_file, "musl/src/internal/");
+            src_kind = want_O3 ? MuslSrcO3 : MuslSrcNormal;
+        } else if (buf_ends_with_str(src_file, ".s") || buf_ends_with_str(src_file, ".S")) {
+            src_kind = MuslSrcAsm;
+        } else {
+            continue;
+        }
+        if (ZIG_OS_SEP_CHAR != '/') {
+            buf_replace(src_file, '/', ZIG_OS_SEP_CHAR);
+        }
+        source_table.put_unique(src_file, src_kind);
+    }
+
+    ZigList<CFile *> c_source_files = {0};
+
+    Buf dirname = BUF_INIT;
+    Buf basename = BUF_INIT;
+    Buf noextbasename = BUF_INIT;
+    Buf dirbasename = BUF_INIT;
+    Buf before_arch_dir = BUF_INIT;
+    Buf override_c = BUF_INIT;
+    Buf override_s = BUF_INIT;
+    Buf override_S = BUF_INIT;
+
+    auto source_it = source_table.entry_iterator();
+    for (;;) {
+        auto *entry = source_it.next();
+        if (!entry) break;
+
+        Buf *src_file = entry->key;
+        MuslSrc src_kind = entry->value;
+
+        os_path_split(src_file, &dirname, &basename);
+        os_path_extname(&basename, &noextbasename, nullptr);
+        os_path_split(&dirname, &before_arch_dir, &dirbasename);
+        if (is_musl_arch_name(buf_ptr(&dirbasename))) {
+            // We find these by explicitly looking for overrides.
+            continue;
+        }
+        // Look for an arch specific override.
+        buf_resize(&override_c, 0);
+        buf_resize(&override_s, 0);
+        buf_resize(&override_S, 0);
+
+        buf_appendf(&override_c, "%s" OS_SEP "%s" OS_SEP "%s.c",
+                buf_ptr(&dirname), target_musl_arch_name, buf_ptr(&noextbasename));
+        buf_appendf(&override_s, "%s" OS_SEP "%s" OS_SEP "%s.s",
+                buf_ptr(&dirname), target_musl_arch_name, buf_ptr(&noextbasename));
+        buf_appendf(&override_S, "%s" OS_SEP "%s" OS_SEP "%s.S",
+                buf_ptr(&dirname), target_musl_arch_name, buf_ptr(&noextbasename));
+
+        if (source_table.maybe_get(&override_c) != nullptr) {
+            src_file = &override_c;
+            src_kind = (src_kind == MuslSrcAsm) ? MuslSrcNormal : src_kind;
+        } else if (source_table.maybe_get(&override_s) != nullptr) {
+            src_file = &override_s;
+            src_kind = MuslSrcAsm;
+        } else if (source_table.maybe_get(&override_S) != nullptr) {
+            src_file = &override_S;
+            src_kind = MuslSrcAsm;
+        }
+
+        Buf *full_path = buf_sprintf("%s" OS_SEP "libc" OS_SEP "%s",
+                buf_ptr(parent->zig_lib_dir), buf_ptr(src_file));
+
+        if (src_kind == MuslSrcAsm) {
+            codegen_add_assembly(child_gen, full_path);
+        } else {
+            CFile *c_file = allocate<CFile>(1);
+            c_file->source_path = buf_ptr(full_path);
+            musl_add_cc_args(parent, c_file);
+            c_file->args.append("-Wno-ignored-attributes");
+            c_file->args.append("-Wno-bitwise-op-parentheses");
+            c_file->args.append("-Wno-logical-op-parentheses");
+            c_file->args.append("-Wno-dangling-else");
+            c_file->args.append("-Wno-shift-op-parentheses");
+            c_file->args.append("-Qunused-arguments");
+            c_file->args.append("-Wno-unknown-pragmas");
+            c_file->args.append("-Wno-string-plus-int");
+            c_file->args.append("-Wno-parentheses");
+            if (src_kind == MuslSrcO3) {
+                c_file->args.append("-O3");
+            }
+            c_source_files.append(c_file);
+        }
+    }
+
+    child_gen->c_source_files = c_source_files;
+    codegen_build_and_link(child_gen);
+    return buf_ptr(&child_gen->output_file_path);
+}
+
+
 static const char *get_libc_crt_file(CodeGen *parent, const char *file) {
     if (parent->libc == nullptr && target_is_glibc(parent)) {
         if (strcmp(file, "crti.o") == 0) {
@@ -620,12 +766,16 @@ static const char *get_libc_crt_file(CodeGen *parent, const char *file) {
             CFile *c_file = allocate<CFile>(1);
             c_file->source_path = path_from_libc(parent, "musl" OS_SEP "crt" OS_SEP "crt1.c");
             musl_add_cc_args(parent, c_file);
+            c_file->args.append("-fno-stack-protector");
+            c_file->args.append("-DCRT");
             return build_libc_object(parent, "crt1", c_file);
         } else if (strcmp(file, "Scrt1.o") == 0) {
             CFile *c_file = allocate<CFile>(1);
             c_file->source_path = path_from_libc(parent, "musl" OS_SEP "crt" OS_SEP "Scrt1.c");
             musl_add_cc_args(parent, c_file);
             c_file->args.append("-fPIC");
+            c_file->args.append("-fno-stack-protector");
+            c_file->args.append("-DCRT");
             return build_libc_object(parent, "Scrt1", c_file);
         } else {
             zig_unreachable();
@@ -937,7 +1087,8 @@ static void construct_linker_job_elf(LinkJob *lj) {
             lj->args.append(build_dummy_so(g, "rt", 1));
             lj->args.append(get_libc_crt_file(g, "libc_nonshared.a"));
         } else if (target_is_musl(g)) {
-            //lj->args.append(build_musl(g)); TODO
+            lj->args.append(build_libunwind(g));
+            lj->args.append(build_musl(g));
         } else {
             zig_unreachable();
         }
src/main.cpp
@@ -10,6 +10,7 @@
 #include "codegen.hpp"
 #include "compiler.hpp"
 #include "config.h"
+#include "install_files.h"
 #include "error.hpp"
 #include "os.hpp"
 #include "target.hpp"
CMakeLists.txt
@@ -808,6 +808,1807 @@ set(ZIG_C_HEADER_FILES
     "xtestintrin.h"
 )
 
+set(ZIG_MUSL_SRC_FILES
+    "musl/src/aio/aio.c"
+    "musl/src/aio/aio_suspend.c"
+    "musl/src/aio/lio_listio.c"
+    "musl/src/complex/__cexp.c"
+    "musl/src/complex/__cexpf.c"
+    "musl/src/complex/cabs.c"
+    "musl/src/complex/cabsf.c"
+    "musl/src/complex/cabsl.c"
+    "musl/src/complex/cacos.c"
+    "musl/src/complex/cacosf.c"
+    "musl/src/complex/cacosh.c"
+    "musl/src/complex/cacoshf.c"
+    "musl/src/complex/cacoshl.c"
+    "musl/src/complex/cacosl.c"
+    "musl/src/complex/carg.c"
+    "musl/src/complex/cargf.c"
+    "musl/src/complex/cargl.c"
+    "musl/src/complex/casin.c"
+    "musl/src/complex/casinf.c"
+    "musl/src/complex/casinh.c"
+    "musl/src/complex/casinhf.c"
+    "musl/src/complex/casinhl.c"
+    "musl/src/complex/casinl.c"
+    "musl/src/complex/catan.c"
+    "musl/src/complex/catanf.c"
+    "musl/src/complex/catanh.c"
+    "musl/src/complex/catanhf.c"
+    "musl/src/complex/catanhl.c"
+    "musl/src/complex/catanl.c"
+    "musl/src/complex/ccos.c"
+    "musl/src/complex/ccosf.c"
+    "musl/src/complex/ccosh.c"
+    "musl/src/complex/ccoshf.c"
+    "musl/src/complex/ccoshl.c"
+    "musl/src/complex/ccosl.c"
+    "musl/src/complex/cexp.c"
+    "musl/src/complex/cexpf.c"
+    "musl/src/complex/cexpl.c"
+    "musl/src/complex/cimag.c"
+    "musl/src/complex/cimagf.c"
+    "musl/src/complex/cimagl.c"
+    "musl/src/complex/clog.c"
+    "musl/src/complex/clogf.c"
+    "musl/src/complex/clogl.c"
+    "musl/src/complex/conj.c"
+    "musl/src/complex/conjf.c"
+    "musl/src/complex/conjl.c"
+    "musl/src/complex/cpow.c"
+    "musl/src/complex/cpowf.c"
+    "musl/src/complex/cpowl.c"
+    "musl/src/complex/cproj.c"
+    "musl/src/complex/cprojf.c"
+    "musl/src/complex/cprojl.c"
+    "musl/src/complex/creal.c"
+    "musl/src/complex/crealf.c"
+    "musl/src/complex/creall.c"
+    "musl/src/complex/csin.c"
+    "musl/src/complex/csinf.c"
+    "musl/src/complex/csinh.c"
+    "musl/src/complex/csinhf.c"
+    "musl/src/complex/csinhl.c"
+    "musl/src/complex/csinl.c"
+    "musl/src/complex/csqrt.c"
+    "musl/src/complex/csqrtf.c"
+    "musl/src/complex/csqrtl.c"
+    "musl/src/complex/ctan.c"
+    "musl/src/complex/ctanf.c"
+    "musl/src/complex/ctanh.c"
+    "musl/src/complex/ctanhf.c"
+    "musl/src/complex/ctanhl.c"
+    "musl/src/complex/ctanl.c"
+    "musl/src/conf/confstr.c"
+    "musl/src/conf/fpathconf.c"
+    "musl/src/conf/legacy.c"
+    "musl/src/conf/pathconf.c"
+    "musl/src/conf/sysconf.c"
+    "musl/src/crypt/crypt.c"
+    "musl/src/crypt/crypt_blowfish.c"
+    "musl/src/crypt/crypt_des.c"
+    "musl/src/crypt/crypt_des.h"
+    "musl/src/crypt/crypt_md5.c"
+    "musl/src/crypt/crypt_r.c"
+    "musl/src/crypt/crypt_sha256.c"
+    "musl/src/crypt/crypt_sha512.c"
+    "musl/src/crypt/encrypt.c"
+    "musl/src/ctype/__ctype_b_loc.c"
+    "musl/src/ctype/__ctype_get_mb_cur_max.c"
+    "musl/src/ctype/__ctype_tolower_loc.c"
+    "musl/src/ctype/__ctype_toupper_loc.c"
+    "musl/src/ctype/alpha.h"
+    "musl/src/ctype/isalnum.c"
+    "musl/src/ctype/isalpha.c"
+    "musl/src/ctype/isascii.c"
+    "musl/src/ctype/isblank.c"
+    "musl/src/ctype/iscntrl.c"
+    "musl/src/ctype/isdigit.c"
+    "musl/src/ctype/isgraph.c"
+    "musl/src/ctype/islower.c"
+    "musl/src/ctype/isprint.c"
+    "musl/src/ctype/ispunct.c"
+    "musl/src/ctype/isspace.c"
+    "musl/src/ctype/isupper.c"
+    "musl/src/ctype/iswalnum.c"
+    "musl/src/ctype/iswalpha.c"
+    "musl/src/ctype/iswblank.c"
+    "musl/src/ctype/iswcntrl.c"
+    "musl/src/ctype/iswctype.c"
+    "musl/src/ctype/iswdigit.c"
+    "musl/src/ctype/iswgraph.c"
+    "musl/src/ctype/iswlower.c"
+    "musl/src/ctype/iswprint.c"
+    "musl/src/ctype/iswpunct.c"
+    "musl/src/ctype/iswspace.c"
+    "musl/src/ctype/iswupper.c"
+    "musl/src/ctype/iswxdigit.c"
+    "musl/src/ctype/isxdigit.c"
+    "musl/src/ctype/nonspacing.h"
+    "musl/src/ctype/punct.h"
+    "musl/src/ctype/toascii.c"
+    "musl/src/ctype/tolower.c"
+    "musl/src/ctype/toupper.c"
+    "musl/src/ctype/towctrans.c"
+    "musl/src/ctype/wcswidth.c"
+    "musl/src/ctype/wctrans.c"
+    "musl/src/ctype/wcwidth.c"
+    "musl/src/ctype/wide.h"
+    "musl/src/dirent/__dirent.h"
+    "musl/src/dirent/alphasort.c"
+    "musl/src/dirent/closedir.c"
+    "musl/src/dirent/dirfd.c"
+    "musl/src/dirent/fdopendir.c"
+    "musl/src/dirent/opendir.c"
+    "musl/src/dirent/readdir.c"
+    "musl/src/dirent/readdir_r.c"
+    "musl/src/dirent/rewinddir.c"
+    "musl/src/dirent/scandir.c"
+    "musl/src/dirent/seekdir.c"
+    "musl/src/dirent/telldir.c"
+    "musl/src/dirent/versionsort.c"
+    "musl/src/env/__environ.c"
+    "musl/src/env/__init_tls.c"
+    "musl/src/env/__libc_start_main.c"
+    "musl/src/env/__reset_tls.c"
+    "musl/src/env/__stack_chk_fail.c"
+    "musl/src/env/clearenv.c"
+    "musl/src/env/getenv.c"
+    "musl/src/env/putenv.c"
+    "musl/src/env/setenv.c"
+    "musl/src/env/unsetenv.c"
+    "musl/src/errno/__errno_location.c"
+    "musl/src/errno/__strerror.h"
+    "musl/src/errno/strerror.c"
+    "musl/src/exit/_Exit.c"
+    "musl/src/exit/abort.c"
+    "musl/src/exit/arm/__aeabi_atexit.c"
+    "musl/src/exit/assert.c"
+    "musl/src/exit/at_quick_exit.c"
+    "musl/src/exit/atexit.c"
+    "musl/src/exit/exit.c"
+    "musl/src/exit/quick_exit.c"
+    "musl/src/fcntl/creat.c"
+    "musl/src/fcntl/fcntl.c"
+    "musl/src/fcntl/open.c"
+    "musl/src/fcntl/openat.c"
+    "musl/src/fcntl/posix_fadvise.c"
+    "musl/src/fcntl/posix_fallocate.c"
+    "musl/src/fenv/__flt_rounds.c"
+    "musl/src/fenv/aarch64/fenv.s"
+    "musl/src/fenv/arm/fenv-hf.S"
+    "musl/src/fenv/arm/fenv.c"
+    "musl/src/fenv/fegetexceptflag.c"
+    "musl/src/fenv/feholdexcept.c"
+    "musl/src/fenv/fenv.c"
+    "musl/src/fenv/fesetexceptflag.c"
+    "musl/src/fenv/fesetround.c"
+    "musl/src/fenv/feupdateenv.c"
+    "musl/src/fenv/i386/fenv.s"
+    "musl/src/fenv/m68k/fenv.c"
+    "musl/src/fenv/mips/fenv-sf.c"
+    "musl/src/fenv/mips/fenv.S"
+    "musl/src/fenv/mips64/fenv-sf.c"
+    "musl/src/fenv/mips64/fenv.S"
+    "musl/src/fenv/mipsn32/fenv-sf.c"
+    "musl/src/fenv/mipsn32/fenv.S"
+    "musl/src/fenv/powerpc/fenv-sf.c"
+    "musl/src/fenv/powerpc/fenv.S"
+    "musl/src/fenv/powerpc64/fenv.c"
+    "musl/src/fenv/s390x/fenv.c"
+    "musl/src/fenv/sh/fenv-nofpu.c"
+    "musl/src/fenv/sh/fenv.S"
+    "musl/src/fenv/x32/fenv.s"
+    "musl/src/fenv/x86_64/fenv.s"
+    "musl/src/include/arpa/inet.h"
+    "musl/src/include/crypt.h"
+    "musl/src/include/errno.h"
+    "musl/src/include/features.h"
+    "musl/src/include/langinfo.h"
+    "musl/src/include/pthread.h"
+    "musl/src/include/resolv.h"
+    "musl/src/include/signal.h"
+    "musl/src/include/stdio.h"
+    "musl/src/include/stdlib.h"
+    "musl/src/include/string.h"
+    "musl/src/include/sys/auxv.h"
+    "musl/src/include/sys/mman.h"
+    "musl/src/include/sys/sysinfo.h"
+    "musl/src/include/sys/time.h"
+    "musl/src/include/time.h"
+    "musl/src/include/unistd.h"
+    "musl/src/internal/aarch64/syscall.s"
+    "musl/src/internal/arm/syscall.s"
+    "musl/src/internal/atomic.h"
+    "musl/src/internal/dynlink.h"
+    "musl/src/internal/fdpic_crt.h"
+    "musl/src/internal/floatscan.c"
+    "musl/src/internal/floatscan.h"
+    "musl/src/internal/futex.h"
+    "musl/src/internal/i386/syscall.s"
+    "musl/src/internal/intscan.c"
+    "musl/src/internal/intscan.h"
+    "musl/src/internal/ksigaction.h"
+    "musl/src/internal/libc.c"
+    "musl/src/internal/libc.h"
+    "musl/src/internal/libm.h"
+    "musl/src/internal/locale_impl.h"
+    "musl/src/internal/lock.h"
+    "musl/src/internal/m68k/syscall.s"
+    "musl/src/internal/malloc_impl.h"
+    "musl/src/internal/microblaze/syscall.s"
+    "musl/src/internal/mips/syscall.s"
+    "musl/src/internal/mips64/syscall.s"
+    "musl/src/internal/mipsn32/syscall.s"
+    "musl/src/internal/or1k/syscall.s"
+    "musl/src/internal/powerpc/syscall.s"
+    "musl/src/internal/powerpc64/syscall.s"
+    "musl/src/internal/procfdname.c"
+    "musl/src/internal/pthread_impl.h"
+    "musl/src/internal/s390x/syscall.s"
+    "musl/src/internal/sh/__shcall.c"
+    "musl/src/internal/sh/syscall.s"
+    "musl/src/internal/shgetc.c"
+    "musl/src/internal/shgetc.h"
+    "musl/src/internal/stdio_impl.h"
+    "musl/src/internal/syscall.c"
+    "musl/src/internal/syscall.h"
+    "musl/src/internal/syscall_ret.c"
+    "musl/src/internal/vdso.c"
+    "musl/src/internal/version.c"
+    "musl/src/internal/version.h"
+    "musl/src/internal/x32/syscall.s"
+    "musl/src/internal/x86_64/syscall.s"
+    "musl/src/ipc/ftok.c"
+    "musl/src/ipc/ipc.h"
+    "musl/src/ipc/msgctl.c"
+    "musl/src/ipc/msgget.c"
+    "musl/src/ipc/msgrcv.c"
+    "musl/src/ipc/msgsnd.c"
+    "musl/src/ipc/semctl.c"
+    "musl/src/ipc/semget.c"
+    "musl/src/ipc/semop.c"
+    "musl/src/ipc/semtimedop.c"
+    "musl/src/ipc/shmat.c"
+    "musl/src/ipc/shmctl.c"
+    "musl/src/ipc/shmdt.c"
+    "musl/src/ipc/shmget.c"
+    "musl/src/ldso/__dlsym.c"
+    "musl/src/ldso/aarch64/dlsym.s"
+    "musl/src/ldso/aarch64/tlsdesc.s"
+    "musl/src/ldso/arm/dlsym.s"
+    "musl/src/ldso/arm/find_exidx.c"
+    "musl/src/ldso/arm/tlsdesc.S"
+    "musl/src/ldso/dl_iterate_phdr.c"
+    "musl/src/ldso/dladdr.c"
+    "musl/src/ldso/dlclose.c"
+    "musl/src/ldso/dlerror.c"
+    "musl/src/ldso/dlinfo.c"
+    "musl/src/ldso/dlopen.c"
+    "musl/src/ldso/dlsym.c"
+    "musl/src/ldso/i386/dlsym.s"
+    "musl/src/ldso/i386/tlsdesc.s"
+    "musl/src/ldso/m68k/dlsym.s"
+    "musl/src/ldso/microblaze/dlsym.s"
+    "musl/src/ldso/mips/dlsym.s"
+    "musl/src/ldso/mips64/dlsym.s"
+    "musl/src/ldso/mipsn32/dlsym.s"
+    "musl/src/ldso/or1k/dlsym.s"
+    "musl/src/ldso/powerpc/dlsym.s"
+    "musl/src/ldso/powerpc64/dlsym.s"
+    "musl/src/ldso/s390x/dlsym.s"
+    "musl/src/ldso/sh/dlsym.s"
+    "musl/src/ldso/tlsdesc.c"
+    "musl/src/ldso/x32/dlsym.s"
+    "musl/src/ldso/x86_64/dlsym.s"
+    "musl/src/ldso/x86_64/tlsdesc.s"
+    "musl/src/legacy/cuserid.c"
+    "musl/src/legacy/daemon.c"
+    "musl/src/legacy/err.c"
+    "musl/src/legacy/euidaccess.c"
+    "musl/src/legacy/ftw.c"
+    "musl/src/legacy/futimes.c"
+    "musl/src/legacy/getdtablesize.c"
+    "musl/src/legacy/getloadavg.c"
+    "musl/src/legacy/getpagesize.c"
+    "musl/src/legacy/getpass.c"
+    "musl/src/legacy/getusershell.c"
+    "musl/src/legacy/isastream.c"
+    "musl/src/legacy/lutimes.c"
+    "musl/src/legacy/ulimit.c"
+    "musl/src/legacy/utmpx.c"
+    "musl/src/legacy/valloc.c"
+    "musl/src/linux/adjtime.c"
+    "musl/src/linux/adjtimex.c"
+    "musl/src/linux/arch_prctl.c"
+    "musl/src/linux/brk.c"
+    "musl/src/linux/cache.c"
+    "musl/src/linux/cap.c"
+    "musl/src/linux/chroot.c"
+    "musl/src/linux/clock_adjtime.c"
+    "musl/src/linux/clone.c"
+    "musl/src/linux/epoll.c"
+    "musl/src/linux/eventfd.c"
+    "musl/src/linux/fallocate.c"
+    "musl/src/linux/fanotify.c"
+    "musl/src/linux/flock.c"
+    "musl/src/linux/getdents.c"
+    "musl/src/linux/getrandom.c"
+    "musl/src/linux/inotify.c"
+    "musl/src/linux/ioperm.c"
+    "musl/src/linux/iopl.c"
+    "musl/src/linux/klogctl.c"
+    "musl/src/linux/memfd_create.c"
+    "musl/src/linux/mlock2.c"
+    "musl/src/linux/module.c"
+    "musl/src/linux/mount.c"
+    "musl/src/linux/name_to_handle_at.c"
+    "musl/src/linux/open_by_handle_at.c"
+    "musl/src/linux/personality.c"
+    "musl/src/linux/pivot_root.c"
+    "musl/src/linux/ppoll.c"
+    "musl/src/linux/prctl.c"
+    "musl/src/linux/prlimit.c"
+    "musl/src/linux/process_vm.c"
+    "musl/src/linux/ptrace.c"
+    "musl/src/linux/quotactl.c"
+    "musl/src/linux/readahead.c"
+    "musl/src/linux/reboot.c"
+    "musl/src/linux/remap_file_pages.c"
+    "musl/src/linux/sbrk.c"
+    "musl/src/linux/sendfile.c"
+    "musl/src/linux/setfsgid.c"
+    "musl/src/linux/setfsuid.c"
+    "musl/src/linux/setgroups.c"
+    "musl/src/linux/sethostname.c"
+    "musl/src/linux/setns.c"
+    "musl/src/linux/settimeofday.c"
+    "musl/src/linux/signalfd.c"
+    "musl/src/linux/splice.c"
+    "musl/src/linux/stime.c"
+    "musl/src/linux/swap.c"
+    "musl/src/linux/sync_file_range.c"
+    "musl/src/linux/syncfs.c"
+    "musl/src/linux/sysinfo.c"
+    "musl/src/linux/tee.c"
+    "musl/src/linux/timerfd.c"
+    "musl/src/linux/unshare.c"
+    "musl/src/linux/utimes.c"
+    "musl/src/linux/vhangup.c"
+    "musl/src/linux/vmsplice.c"
+    "musl/src/linux/wait3.c"
+    "musl/src/linux/wait4.c"
+    "musl/src/linux/x32/sysinfo.c"
+    "musl/src/linux/xattr.c"
+    "musl/src/locale/__lctrans.c"
+    "musl/src/locale/__mo_lookup.c"
+    "musl/src/locale/big5.h"
+    "musl/src/locale/bind_textdomain_codeset.c"
+    "musl/src/locale/c_locale.c"
+    "musl/src/locale/catclose.c"
+    "musl/src/locale/catgets.c"
+    "musl/src/locale/catopen.c"
+    "musl/src/locale/codepages.h"
+    "musl/src/locale/dcngettext.c"
+    "musl/src/locale/duplocale.c"
+    "musl/src/locale/freelocale.c"
+    "musl/src/locale/gb18030.h"
+    "musl/src/locale/hkscs.h"
+    "musl/src/locale/iconv.c"
+    "musl/src/locale/iconv_close.c"
+    "musl/src/locale/jis0208.h"
+    "musl/src/locale/ksc.h"
+    "musl/src/locale/langinfo.c"
+    "musl/src/locale/legacychars.h"
+    "musl/src/locale/locale_map.c"
+    "musl/src/locale/localeconv.c"
+    "musl/src/locale/newlocale.c"
+    "musl/src/locale/pleval.c"
+    "musl/src/locale/pleval.h"
+    "musl/src/locale/revjis.h"
+    "musl/src/locale/setlocale.c"
+    "musl/src/locale/strcoll.c"
+    "musl/src/locale/strfmon.c"
+    "musl/src/locale/strxfrm.c"
+    "musl/src/locale/textdomain.c"
+    "musl/src/locale/uselocale.c"
+    "musl/src/locale/wcscoll.c"
+    "musl/src/locale/wcsxfrm.c"
+    "musl/src/malloc/DESIGN"
+    "musl/src/malloc/aligned_alloc.c"
+    "musl/src/malloc/expand_heap.c"
+    "musl/src/malloc/lite_malloc.c"
+    "musl/src/malloc/malloc.c"
+    "musl/src/malloc/malloc_usable_size.c"
+    "musl/src/malloc/memalign.c"
+    "musl/src/malloc/posix_memalign.c"
+    "musl/src/math/__cos.c"
+    "musl/src/math/__cosdf.c"
+    "musl/src/math/__cosl.c"
+    "musl/src/math/__expo2.c"
+    "musl/src/math/__expo2f.c"
+    "musl/src/math/__fpclassify.c"
+    "musl/src/math/__fpclassifyf.c"
+    "musl/src/math/__fpclassifyl.c"
+    "musl/src/math/__invtrigl.c"
+    "musl/src/math/__invtrigl.h"
+    "musl/src/math/__polevll.c"
+    "musl/src/math/__rem_pio2.c"
+    "musl/src/math/__rem_pio2_large.c"
+    "musl/src/math/__rem_pio2f.c"
+    "musl/src/math/__rem_pio2l.c"
+    "musl/src/math/__signbit.c"
+    "musl/src/math/__signbitf.c"
+    "musl/src/math/__signbitl.c"
+    "musl/src/math/__sin.c"
+    "musl/src/math/__sindf.c"
+    "musl/src/math/__sinl.c"
+    "musl/src/math/__tan.c"
+    "musl/src/math/__tandf.c"
+    "musl/src/math/__tanl.c"
+    "musl/src/math/aarch64/ceil.c"
+    "musl/src/math/aarch64/ceilf.c"
+    "musl/src/math/aarch64/fabs.c"
+    "musl/src/math/aarch64/fabsf.c"
+    "musl/src/math/aarch64/floor.c"
+    "musl/src/math/aarch64/floorf.c"
+    "musl/src/math/aarch64/fma.c"
+    "musl/src/math/aarch64/fmaf.c"
+    "musl/src/math/aarch64/fmax.c"
+    "musl/src/math/aarch64/fmaxf.c"
+    "musl/src/math/aarch64/fmin.c"
+    "musl/src/math/aarch64/fminf.c"
+    "musl/src/math/aarch64/llrint.c"
+    "musl/src/math/aarch64/llrintf.c"
+    "musl/src/math/aarch64/llround.c"
+    "musl/src/math/aarch64/llroundf.c"
+    "musl/src/math/aarch64/lrint.c"
+    "musl/src/math/aarch64/lrintf.c"
+    "musl/src/math/aarch64/lround.c"
+    "musl/src/math/aarch64/lroundf.c"
+    "musl/src/math/aarch64/nearbyint.c"
+    "musl/src/math/aarch64/nearbyintf.c"
+    "musl/src/math/aarch64/rint.c"
+    "musl/src/math/aarch64/rintf.c"
+    "musl/src/math/aarch64/round.c"
+    "musl/src/math/aarch64/roundf.c"
+    "musl/src/math/aarch64/sqrt.c"
+    "musl/src/math/aarch64/sqrtf.c"
+    "musl/src/math/aarch64/trunc.c"
+    "musl/src/math/aarch64/truncf.c"
+    "musl/src/math/acos.c"
+    "musl/src/math/acosf.c"
+    "musl/src/math/acosh.c"
+    "musl/src/math/acoshf.c"
+    "musl/src/math/acoshl.c"
+    "musl/src/math/acosl.c"
+    "musl/src/math/arm/fabs.c"
+    "musl/src/math/arm/fabsf.c"
+    "musl/src/math/arm/fma.c"
+    "musl/src/math/arm/fmaf.c"
+    "musl/src/math/arm/sqrt.c"
+    "musl/src/math/arm/sqrtf.c"
+    "musl/src/math/asin.c"
+    "musl/src/math/asinf.c"
+    "musl/src/math/asinh.c"
+    "musl/src/math/asinhf.c"
+    "musl/src/math/asinhl.c"
+    "musl/src/math/asinl.c"
+    "musl/src/math/atan.c"
+    "musl/src/math/atan2.c"
+    "musl/src/math/atan2f.c"
+    "musl/src/math/atan2l.c"
+    "musl/src/math/atanf.c"
+    "musl/src/math/atanh.c"
+    "musl/src/math/atanhf.c"
+    "musl/src/math/atanhl.c"
+    "musl/src/math/atanl.c"
+    "musl/src/math/cbrt.c"
+    "musl/src/math/cbrtf.c"
+    "musl/src/math/cbrtl.c"
+    "musl/src/math/ceil.c"
+    "musl/src/math/ceilf.c"
+    "musl/src/math/ceill.c"
+    "musl/src/math/copysign.c"
+    "musl/src/math/copysignf.c"
+    "musl/src/math/copysignl.c"
+    "musl/src/math/cos.c"
+    "musl/src/math/cosf.c"
+    "musl/src/math/cosh.c"
+    "musl/src/math/coshf.c"
+    "musl/src/math/coshl.c"
+    "musl/src/math/cosl.c"
+    "musl/src/math/erf.c"
+    "musl/src/math/erff.c"
+    "musl/src/math/erfl.c"
+    "musl/src/math/exp.c"
+    "musl/src/math/exp10.c"
+    "musl/src/math/exp10f.c"
+    "musl/src/math/exp10l.c"
+    "musl/src/math/exp2.c"
+    "musl/src/math/exp2f.c"
+    "musl/src/math/exp2l.c"
+    "musl/src/math/expf.c"
+    "musl/src/math/expl.c"
+    "musl/src/math/expm1.c"
+    "musl/src/math/expm1f.c"
+    "musl/src/math/expm1l.c"
+    "musl/src/math/fabs.c"
+    "musl/src/math/fabsf.c"
+    "musl/src/math/fabsl.c"
+    "musl/src/math/fdim.c"
+    "musl/src/math/fdimf.c"
+    "musl/src/math/fdiml.c"
+    "musl/src/math/finite.c"
+    "musl/src/math/finitef.c"
+    "musl/src/math/floor.c"
+    "musl/src/math/floorf.c"
+    "musl/src/math/floorl.c"
+    "musl/src/math/fma.c"
+    "musl/src/math/fmaf.c"
+    "musl/src/math/fmal.c"
+    "musl/src/math/fmax.c"
+    "musl/src/math/fmaxf.c"
+    "musl/src/math/fmaxl.c"
+    "musl/src/math/fmin.c"
+    "musl/src/math/fminf.c"
+    "musl/src/math/fminl.c"
+    "musl/src/math/fmod.c"
+    "musl/src/math/fmodf.c"
+    "musl/src/math/fmodl.c"
+    "musl/src/math/frexp.c"
+    "musl/src/math/frexpf.c"
+    "musl/src/math/frexpl.c"
+    "musl/src/math/hypot.c"
+    "musl/src/math/hypotf.c"
+    "musl/src/math/hypotl.c"
+    "musl/src/math/i386/__invtrigl.s"
+    "musl/src/math/i386/acos.s"
+    "musl/src/math/i386/acosf.s"
+    "musl/src/math/i386/acosl.s"
+    "musl/src/math/i386/asin.s"
+    "musl/src/math/i386/asinf.s"
+    "musl/src/math/i386/asinl.s"
+    "musl/src/math/i386/atan.s"
+    "musl/src/math/i386/atan2.s"
+    "musl/src/math/i386/atan2f.s"
+    "musl/src/math/i386/atan2l.s"
+    "musl/src/math/i386/atanf.s"
+    "musl/src/math/i386/atanl.s"
+    "musl/src/math/i386/ceil.s"
+    "musl/src/math/i386/ceilf.s"
+    "musl/src/math/i386/ceill.s"
+    "musl/src/math/i386/exp.s"
+    "musl/src/math/i386/exp2.s"
+    "musl/src/math/i386/exp2f.s"
+    "musl/src/math/i386/exp2l.s"
+    "musl/src/math/i386/expf.s"
+    "musl/src/math/i386/expl.s"
+    "musl/src/math/i386/expm1.s"
+    "musl/src/math/i386/expm1f.s"
+    "musl/src/math/i386/expm1l.s"
+    "musl/src/math/i386/fabs.s"
+    "musl/src/math/i386/fabsf.s"
+    "musl/src/math/i386/fabsl.s"
+    "musl/src/math/i386/floor.s"
+    "musl/src/math/i386/floorf.s"
+    "musl/src/math/i386/floorl.s"
+    "musl/src/math/i386/fmod.s"
+    "musl/src/math/i386/fmodf.s"
+    "musl/src/math/i386/fmodl.s"
+    "musl/src/math/i386/hypot.s"
+    "musl/src/math/i386/hypotf.s"
+    "musl/src/math/i386/ldexp.s"
+    "musl/src/math/i386/ldexpf.s"
+    "musl/src/math/i386/ldexpl.s"
+    "musl/src/math/i386/llrint.s"
+    "musl/src/math/i386/llrintf.s"
+    "musl/src/math/i386/llrintl.s"
+    "musl/src/math/i386/log.s"
+    "musl/src/math/i386/log10.s"
+    "musl/src/math/i386/log10f.s"
+    "musl/src/math/i386/log10l.s"
+    "musl/src/math/i386/log1p.s"
+    "musl/src/math/i386/log1pf.s"
+    "musl/src/math/i386/log1pl.s"
+    "musl/src/math/i386/log2.s"
+    "musl/src/math/i386/log2f.s"
+    "musl/src/math/i386/log2l.s"
+    "musl/src/math/i386/logf.s"
+    "musl/src/math/i386/logl.s"
+    "musl/src/math/i386/lrint.s"
+    "musl/src/math/i386/lrintf.s"
+    "musl/src/math/i386/lrintl.s"
+    "musl/src/math/i386/remainder.s"
+    "musl/src/math/i386/remainderf.s"
+    "musl/src/math/i386/remainderl.s"
+    "musl/src/math/i386/remquo.s"
+    "musl/src/math/i386/remquof.s"
+    "musl/src/math/i386/remquol.s"
+    "musl/src/math/i386/rint.s"
+    "musl/src/math/i386/rintf.s"
+    "musl/src/math/i386/rintl.s"
+    "musl/src/math/i386/scalbln.s"
+    "musl/src/math/i386/scalblnf.s"
+    "musl/src/math/i386/scalblnl.s"
+    "musl/src/math/i386/scalbn.s"
+    "musl/src/math/i386/scalbnf.s"
+    "musl/src/math/i386/scalbnl.s"
+    "musl/src/math/i386/sqrt.s"
+    "musl/src/math/i386/sqrtf.s"
+    "musl/src/math/i386/sqrtl.s"
+    "musl/src/math/i386/trunc.s"
+    "musl/src/math/i386/truncf.s"
+    "musl/src/math/i386/truncl.s"
+    "musl/src/math/ilogb.c"
+    "musl/src/math/ilogbf.c"
+    "musl/src/math/ilogbl.c"
+    "musl/src/math/j0.c"
+    "musl/src/math/j0f.c"
+    "musl/src/math/j1.c"
+    "musl/src/math/j1f.c"
+    "musl/src/math/jn.c"
+    "musl/src/math/jnf.c"
+    "musl/src/math/ldexp.c"
+    "musl/src/math/ldexpf.c"
+    "musl/src/math/ldexpl.c"
+    "musl/src/math/lgamma.c"
+    "musl/src/math/lgamma_r.c"
+    "musl/src/math/lgammaf.c"
+    "musl/src/math/lgammaf_r.c"
+    "musl/src/math/lgammal.c"
+    "musl/src/math/llrint.c"
+    "musl/src/math/llrintf.c"
+    "musl/src/math/llrintl.c"
+    "musl/src/math/llround.c"
+    "musl/src/math/llroundf.c"
+    "musl/src/math/llroundl.c"
+    "musl/src/math/log.c"
+    "musl/src/math/log10.c"
+    "musl/src/math/log10f.c"
+    "musl/src/math/log10l.c"
+    "musl/src/math/log1p.c"
+    "musl/src/math/log1pf.c"
+    "musl/src/math/log1pl.c"
+    "musl/src/math/log2.c"
+    "musl/src/math/log2f.c"
+    "musl/src/math/log2l.c"
+    "musl/src/math/logb.c"
+    "musl/src/math/logbf.c"
+    "musl/src/math/logbl.c"
+    "musl/src/math/logf.c"
+    "musl/src/math/logl.c"
+    "musl/src/math/lrint.c"
+    "musl/src/math/lrintf.c"
+    "musl/src/math/lrintl.c"
+    "musl/src/math/lround.c"
+    "musl/src/math/lroundf.c"
+    "musl/src/math/lroundl.c"
+    "musl/src/math/modf.c"
+    "musl/src/math/modff.c"
+    "musl/src/math/modfl.c"
+    "musl/src/math/nan.c"
+    "musl/src/math/nanf.c"
+    "musl/src/math/nanl.c"
+    "musl/src/math/nearbyint.c"
+    "musl/src/math/nearbyintf.c"
+    "musl/src/math/nearbyintl.c"
+    "musl/src/math/nextafter.c"
+    "musl/src/math/nextafterf.c"
+    "musl/src/math/nextafterl.c"
+    "musl/src/math/nexttoward.c"
+    "musl/src/math/nexttowardf.c"
+    "musl/src/math/nexttowardl.c"
+    "musl/src/math/pow.c"
+    "musl/src/math/powerpc/fabs.c"
+    "musl/src/math/powerpc/fabsf.c"
+    "musl/src/math/powerpc/fma.c"
+    "musl/src/math/powerpc/fmaf.c"
+    "musl/src/math/powerpc/sqrt.c"
+    "musl/src/math/powerpc/sqrtf.c"
+    "musl/src/math/powerpc64/ceil.c"
+    "musl/src/math/powerpc64/ceilf.c"
+    "musl/src/math/powerpc64/fabs.c"
+    "musl/src/math/powerpc64/fabsf.c"
+    "musl/src/math/powerpc64/floor.c"
+    "musl/src/math/powerpc64/floorf.c"
+    "musl/src/math/powerpc64/fma.c"
+    "musl/src/math/powerpc64/fmaf.c"
+    "musl/src/math/powerpc64/fmax.c"
+    "musl/src/math/powerpc64/fmaxf.c"
+    "musl/src/math/powerpc64/fmin.c"
+    "musl/src/math/powerpc64/fminf.c"
+    "musl/src/math/powerpc64/lrint.c"
+    "musl/src/math/powerpc64/lrintf.c"
+    "musl/src/math/powerpc64/lround.c"
+    "musl/src/math/powerpc64/lroundf.c"
+    "musl/src/math/powerpc64/round.c"
+    "musl/src/math/powerpc64/roundf.c"
+    "musl/src/math/powerpc64/sqrt.c"
+    "musl/src/math/powerpc64/sqrtf.c"
+    "musl/src/math/powerpc64/trunc.c"
+    "musl/src/math/powerpc64/truncf.c"
+    "musl/src/math/powf.c"
+    "musl/src/math/powl.c"
+    "musl/src/math/remainder.c"
+    "musl/src/math/remainderf.c"
+    "musl/src/math/remainderl.c"
+    "musl/src/math/remquo.c"
+    "musl/src/math/remquof.c"
+    "musl/src/math/remquol.c"
+    "musl/src/math/rint.c"
+    "musl/src/math/rintf.c"
+    "musl/src/math/rintl.c"
+    "musl/src/math/round.c"
+    "musl/src/math/roundf.c"
+    "musl/src/math/roundl.c"
+    "musl/src/math/s390x/ceil.c"
+    "musl/src/math/s390x/ceilf.c"
+    "musl/src/math/s390x/ceill.c"
+    "musl/src/math/s390x/fabs.c"
+    "musl/src/math/s390x/fabsf.c"
+    "musl/src/math/s390x/fabsl.c"
+    "musl/src/math/s390x/floor.c"
+    "musl/src/math/s390x/floorf.c"
+    "musl/src/math/s390x/floorl.c"
+    "musl/src/math/s390x/fma.c"
+    "musl/src/math/s390x/fmaf.c"
+    "musl/src/math/s390x/nearbyint.c"
+    "musl/src/math/s390x/nearbyintf.c"
+    "musl/src/math/s390x/nearbyintl.c"
+    "musl/src/math/s390x/rint.c"
+    "musl/src/math/s390x/rintf.c"
+    "musl/src/math/s390x/rintl.c"
+    "musl/src/math/s390x/round.c"
+    "musl/src/math/s390x/roundf.c"
+    "musl/src/math/s390x/roundl.c"
+    "musl/src/math/s390x/sqrt.c"
+    "musl/src/math/s390x/sqrtf.c"
+    "musl/src/math/s390x/sqrtl.c"
+    "musl/src/math/s390x/trunc.c"
+    "musl/src/math/s390x/truncf.c"
+    "musl/src/math/s390x/truncl.c"
+    "musl/src/math/scalb.c"
+    "musl/src/math/scalbf.c"
+    "musl/src/math/scalbln.c"
+    "musl/src/math/scalblnf.c"
+    "musl/src/math/scalblnl.c"
+    "musl/src/math/scalbn.c"
+    "musl/src/math/scalbnf.c"
+    "musl/src/math/scalbnl.c"
+    "musl/src/math/signgam.c"
+    "musl/src/math/significand.c"
+    "musl/src/math/significandf.c"
+    "musl/src/math/sin.c"
+    "musl/src/math/sincos.c"
+    "musl/src/math/sincosf.c"
+    "musl/src/math/sincosl.c"
+    "musl/src/math/sinf.c"
+    "musl/src/math/sinh.c"
+    "musl/src/math/sinhf.c"
+    "musl/src/math/sinhl.c"
+    "musl/src/math/sinl.c"
+    "musl/src/math/sqrt.c"
+    "musl/src/math/sqrtf.c"
+    "musl/src/math/sqrtl.c"
+    "musl/src/math/tan.c"
+    "musl/src/math/tanf.c"
+    "musl/src/math/tanh.c"
+    "musl/src/math/tanhf.c"
+    "musl/src/math/tanhl.c"
+    "musl/src/math/tanl.c"
+    "musl/src/math/tgamma.c"
+    "musl/src/math/tgammaf.c"
+    "musl/src/math/tgammal.c"
+    "musl/src/math/trunc.c"
+    "musl/src/math/truncf.c"
+    "musl/src/math/truncl.c"
+    "musl/src/math/x32/__invtrigl.s"
+    "musl/src/math/x32/acosl.s"
+    "musl/src/math/x32/asinl.s"
+    "musl/src/math/x32/atan2l.s"
+    "musl/src/math/x32/atanl.s"
+    "musl/src/math/x32/ceill.s"
+    "musl/src/math/x32/exp2l.s"
+    "musl/src/math/x32/expl.s"
+    "musl/src/math/x32/expm1l.s"
+    "musl/src/math/x32/fabs.s"
+    "musl/src/math/x32/fabsf.s"
+    "musl/src/math/x32/fabsl.s"
+    "musl/src/math/x32/floorl.s"
+    "musl/src/math/x32/fma.c"
+    "musl/src/math/x32/fmaf.c"
+    "musl/src/math/x32/fmodl.s"
+    "musl/src/math/x32/llrint.s"
+    "musl/src/math/x32/llrintf.s"
+    "musl/src/math/x32/llrintl.s"
+    "musl/src/math/x32/log10l.s"
+    "musl/src/math/x32/log1pl.s"
+    "musl/src/math/x32/log2l.s"
+    "musl/src/math/x32/logl.s"
+    "musl/src/math/x32/lrint.s"
+    "musl/src/math/x32/lrintf.s"
+    "musl/src/math/x32/lrintl.s"
+    "musl/src/math/x32/remainderl.s"
+    "musl/src/math/x32/rintl.s"
+    "musl/src/math/x32/sqrt.s"
+    "musl/src/math/x32/sqrtf.s"
+    "musl/src/math/x32/sqrtl.s"
+    "musl/src/math/x32/truncl.s"
+    "musl/src/math/x86_64/__invtrigl.s"
+    "musl/src/math/x86_64/acosl.s"
+    "musl/src/math/x86_64/asinl.s"
+    "musl/src/math/x86_64/atan2l.s"
+    "musl/src/math/x86_64/atanl.s"
+    "musl/src/math/x86_64/ceill.s"
+    "musl/src/math/x86_64/exp2l.s"
+    "musl/src/math/x86_64/expl.s"
+    "musl/src/math/x86_64/expm1l.s"
+    "musl/src/math/x86_64/fabs.s"
+    "musl/src/math/x86_64/fabsf.s"
+    "musl/src/math/x86_64/fabsl.s"
+    "musl/src/math/x86_64/floorl.s"
+    "musl/src/math/x86_64/fma.c"
+    "musl/src/math/x86_64/fmaf.c"
+    "musl/src/math/x86_64/fmodl.s"
+    "musl/src/math/x86_64/llrint.s"
+    "musl/src/math/x86_64/llrintf.s"
+    "musl/src/math/x86_64/llrintl.s"
+    "musl/src/math/x86_64/log10l.s"
+    "musl/src/math/x86_64/log1pl.s"
+    "musl/src/math/x86_64/log2l.s"
+    "musl/src/math/x86_64/logl.s"
+    "musl/src/math/x86_64/lrint.s"
+    "musl/src/math/x86_64/lrintf.s"
+    "musl/src/math/x86_64/lrintl.s"
+    "musl/src/math/x86_64/remainderl.s"
+    "musl/src/math/x86_64/rintl.s"
+    "musl/src/math/x86_64/sqrt.s"
+    "musl/src/math/x86_64/sqrtf.s"
+    "musl/src/math/x86_64/sqrtl.s"
+    "musl/src/math/x86_64/truncl.s"
+    "musl/src/misc/a64l.c"
+    "musl/src/misc/basename.c"
+    "musl/src/misc/dirname.c"
+    "musl/src/misc/ffs.c"
+    "musl/src/misc/ffsl.c"
+    "musl/src/misc/ffsll.c"
+    "musl/src/misc/fmtmsg.c"
+    "musl/src/misc/forkpty.c"
+    "musl/src/misc/get_current_dir_name.c"
+    "musl/src/misc/getauxval.c"
+    "musl/src/misc/getdomainname.c"
+    "musl/src/misc/getentropy.c"
+    "musl/src/misc/gethostid.c"
+    "musl/src/misc/getopt.c"
+    "musl/src/misc/getopt_long.c"
+    "musl/src/misc/getpriority.c"
+    "musl/src/misc/getresgid.c"
+    "musl/src/misc/getresuid.c"
+    "musl/src/misc/getrlimit.c"
+    "musl/src/misc/getrusage.c"
+    "musl/src/misc/getsubopt.c"
+    "musl/src/misc/initgroups.c"
+    "musl/src/misc/ioctl.c"
+    "musl/src/misc/issetugid.c"
+    "musl/src/misc/lockf.c"
+    "musl/src/misc/login_tty.c"
+    "musl/src/misc/mntent.c"
+    "musl/src/misc/nftw.c"
+    "musl/src/misc/openpty.c"
+    "musl/src/misc/ptsname.c"
+    "musl/src/misc/pty.c"
+    "musl/src/misc/realpath.c"
+    "musl/src/misc/setdomainname.c"
+    "musl/src/misc/setpriority.c"
+    "musl/src/misc/setrlimit.c"
+    "musl/src/misc/syscall.c"
+    "musl/src/misc/syslog.c"
+    "musl/src/misc/uname.c"
+    "musl/src/misc/wordexp.c"
+    "musl/src/mman/madvise.c"
+    "musl/src/mman/mincore.c"
+    "musl/src/mman/mlock.c"
+    "musl/src/mman/mlockall.c"
+    "musl/src/mman/mmap.c"
+    "musl/src/mman/mprotect.c"
+    "musl/src/mman/mremap.c"
+    "musl/src/mman/msync.c"
+    "musl/src/mman/munlock.c"
+    "musl/src/mman/munlockall.c"
+    "musl/src/mman/munmap.c"
+    "musl/src/mman/posix_madvise.c"
+    "musl/src/mman/shm_open.c"
+    "musl/src/mq/mq_close.c"
+    "musl/src/mq/mq_getattr.c"
+    "musl/src/mq/mq_notify.c"
+    "musl/src/mq/mq_open.c"
+    "musl/src/mq/mq_receive.c"
+    "musl/src/mq/mq_send.c"
+    "musl/src/mq/mq_setattr.c"
+    "musl/src/mq/mq_timedreceive.c"
+    "musl/src/mq/mq_timedsend.c"
+    "musl/src/mq/mq_unlink.c"
+    "musl/src/multibyte/btowc.c"
+    "musl/src/multibyte/c16rtomb.c"
+    "musl/src/multibyte/c32rtomb.c"
+    "musl/src/multibyte/internal.c"
+    "musl/src/multibyte/internal.h"
+    "musl/src/multibyte/mblen.c"
+    "musl/src/multibyte/mbrlen.c"
+    "musl/src/multibyte/mbrtoc16.c"
+    "musl/src/multibyte/mbrtoc32.c"
+    "musl/src/multibyte/mbrtowc.c"
+    "musl/src/multibyte/mbsinit.c"
+    "musl/src/multibyte/mbsnrtowcs.c"
+    "musl/src/multibyte/mbsrtowcs.c"
+    "musl/src/multibyte/mbstowcs.c"
+    "musl/src/multibyte/mbtowc.c"
+    "musl/src/multibyte/wcrtomb.c"
+    "musl/src/multibyte/wcsnrtombs.c"
+    "musl/src/multibyte/wcsrtombs.c"
+    "musl/src/multibyte/wcstombs.c"
+    "musl/src/multibyte/wctob.c"
+    "musl/src/multibyte/wctomb.c"
+    "musl/src/network/accept.c"
+    "musl/src/network/accept4.c"
+    "musl/src/network/bind.c"
+    "musl/src/network/connect.c"
+    "musl/src/network/dn_comp.c"
+    "musl/src/network/dn_expand.c"
+    "musl/src/network/dn_skipname.c"
+    "musl/src/network/dns_parse.c"
+    "musl/src/network/ent.c"
+    "musl/src/network/ether.c"
+    "musl/src/network/freeaddrinfo.c"
+    "musl/src/network/gai_strerror.c"
+    "musl/src/network/getaddrinfo.c"
+    "musl/src/network/gethostbyaddr.c"
+    "musl/src/network/gethostbyaddr_r.c"
+    "musl/src/network/gethostbyname.c"
+    "musl/src/network/gethostbyname2.c"
+    "musl/src/network/gethostbyname2_r.c"
+    "musl/src/network/gethostbyname_r.c"
+    "musl/src/network/getifaddrs.c"
+    "musl/src/network/getnameinfo.c"
+    "musl/src/network/getpeername.c"
+    "musl/src/network/getservbyname.c"
+    "musl/src/network/getservbyname_r.c"
+    "musl/src/network/getservbyport.c"
+    "musl/src/network/getservbyport_r.c"
+    "musl/src/network/getsockname.c"
+    "musl/src/network/getsockopt.c"
+    "musl/src/network/h_errno.c"
+    "musl/src/network/herror.c"
+    "musl/src/network/hstrerror.c"
+    "musl/src/network/htonl.c"
+    "musl/src/network/htons.c"
+    "musl/src/network/if_freenameindex.c"
+    "musl/src/network/if_indextoname.c"
+    "musl/src/network/if_nameindex.c"
+    "musl/src/network/if_nametoindex.c"
+    "musl/src/network/in6addr_any.c"
+    "musl/src/network/in6addr_loopback.c"
+    "musl/src/network/inet_addr.c"
+    "musl/src/network/inet_aton.c"
+    "musl/src/network/inet_legacy.c"
+    "musl/src/network/inet_ntoa.c"
+    "musl/src/network/inet_ntop.c"
+    "musl/src/network/inet_pton.c"
+    "musl/src/network/listen.c"
+    "musl/src/network/lookup.h"
+    "musl/src/network/lookup_ipliteral.c"
+    "musl/src/network/lookup_name.c"
+    "musl/src/network/lookup_serv.c"
+    "musl/src/network/netlink.c"
+    "musl/src/network/netlink.h"
+    "musl/src/network/netname.c"
+    "musl/src/network/ns_parse.c"
+    "musl/src/network/ntohl.c"
+    "musl/src/network/ntohs.c"
+    "musl/src/network/proto.c"
+    "musl/src/network/recv.c"
+    "musl/src/network/recvfrom.c"
+    "musl/src/network/recvmmsg.c"
+    "musl/src/network/recvmsg.c"
+    "musl/src/network/res_init.c"
+    "musl/src/network/res_mkquery.c"
+    "musl/src/network/res_msend.c"
+    "musl/src/network/res_query.c"
+    "musl/src/network/res_querydomain.c"
+    "musl/src/network/res_send.c"
+    "musl/src/network/res_state.c"
+    "musl/src/network/resolvconf.c"
+    "musl/src/network/send.c"
+    "musl/src/network/sendmmsg.c"
+    "musl/src/network/sendmsg.c"
+    "musl/src/network/sendto.c"
+    "musl/src/network/serv.c"
+    "musl/src/network/setsockopt.c"
+    "musl/src/network/shutdown.c"
+    "musl/src/network/sockatmark.c"
+    "musl/src/network/socket.c"
+    "musl/src/network/socketpair.c"
+    "musl/src/passwd/fgetgrent.c"
+    "musl/src/passwd/fgetpwent.c"
+    "musl/src/passwd/fgetspent.c"
+    "musl/src/passwd/getgr_a.c"
+    "musl/src/passwd/getgr_r.c"
+    "musl/src/passwd/getgrent.c"
+    "musl/src/passwd/getgrent_a.c"
+    "musl/src/passwd/getgrouplist.c"
+    "musl/src/passwd/getpw_a.c"
+    "musl/src/passwd/getpw_r.c"
+    "musl/src/passwd/getpwent.c"
+    "musl/src/passwd/getpwent_a.c"
+    "musl/src/passwd/getspent.c"
+    "musl/src/passwd/getspnam.c"
+    "musl/src/passwd/getspnam_r.c"
+    "musl/src/passwd/lckpwdf.c"
+    "musl/src/passwd/nscd.h"
+    "musl/src/passwd/nscd_query.c"
+    "musl/src/passwd/putgrent.c"
+    "musl/src/passwd/putpwent.c"
+    "musl/src/passwd/putspent.c"
+    "musl/src/passwd/pwf.h"
+    "musl/src/prng/__rand48_step.c"
+    "musl/src/prng/__seed48.c"
+    "musl/src/prng/drand48.c"
+    "musl/src/prng/lcong48.c"
+    "musl/src/prng/lrand48.c"
+    "musl/src/prng/mrand48.c"
+    "musl/src/prng/rand.c"
+    "musl/src/prng/rand48.h"
+    "musl/src/prng/rand_r.c"
+    "musl/src/prng/random.c"
+    "musl/src/prng/seed48.c"
+    "musl/src/prng/srand48.c"
+    "musl/src/process/arm/vfork.s"
+    "musl/src/process/execl.c"
+    "musl/src/process/execle.c"
+    "musl/src/process/execlp.c"
+    "musl/src/process/execv.c"
+    "musl/src/process/execve.c"
+    "musl/src/process/execvp.c"
+    "musl/src/process/fdop.h"
+    "musl/src/process/fexecve.c"
+    "musl/src/process/fork.c"
+    "musl/src/process/i386/vfork.s"
+    "musl/src/process/posix_spawn.c"
+    "musl/src/process/posix_spawn_file_actions_addclose.c"
+    "musl/src/process/posix_spawn_file_actions_adddup2.c"
+    "musl/src/process/posix_spawn_file_actions_addopen.c"
+    "musl/src/process/posix_spawn_file_actions_destroy.c"
+    "musl/src/process/posix_spawn_file_actions_init.c"
+    "musl/src/process/posix_spawnattr_destroy.c"
+    "musl/src/process/posix_spawnattr_getflags.c"
+    "musl/src/process/posix_spawnattr_getpgroup.c"
+    "musl/src/process/posix_spawnattr_getsigdefault.c"
+    "musl/src/process/posix_spawnattr_getsigmask.c"
+    "musl/src/process/posix_spawnattr_init.c"
+    "musl/src/process/posix_spawnattr_sched.c"
+    "musl/src/process/posix_spawnattr_setflags.c"
+    "musl/src/process/posix_spawnattr_setpgroup.c"
+    "musl/src/process/posix_spawnattr_setsigdefault.c"
+    "musl/src/process/posix_spawnattr_setsigmask.c"
+    "musl/src/process/posix_spawnp.c"
+    "musl/src/process/s390x/vfork.s"
+    "musl/src/process/sh/vfork.s"
+    "musl/src/process/system.c"
+    "musl/src/process/vfork.c"
+    "musl/src/process/wait.c"
+    "musl/src/process/waitid.c"
+    "musl/src/process/waitpid.c"
+    "musl/src/process/x32/vfork.s"
+    "musl/src/process/x86_64/vfork.s"
+    "musl/src/regex/fnmatch.c"
+    "musl/src/regex/glob.c"
+    "musl/src/regex/regcomp.c"
+    "musl/src/regex/regerror.c"
+    "musl/src/regex/regexec.c"
+    "musl/src/regex/tre-mem.c"
+    "musl/src/regex/tre.h"
+    "musl/src/sched/affinity.c"
+    "musl/src/sched/sched_cpucount.c"
+    "musl/src/sched/sched_get_priority_max.c"
+    "musl/src/sched/sched_getcpu.c"
+    "musl/src/sched/sched_getparam.c"
+    "musl/src/sched/sched_getscheduler.c"
+    "musl/src/sched/sched_rr_get_interval.c"
+    "musl/src/sched/sched_setparam.c"
+    "musl/src/sched/sched_setscheduler.c"
+    "musl/src/sched/sched_yield.c"
+    "musl/src/search/hsearch.c"
+    "musl/src/search/insque.c"
+    "musl/src/search/lsearch.c"
+    "musl/src/search/tdelete.c"
+    "musl/src/search/tdestroy.c"
+    "musl/src/search/tfind.c"
+    "musl/src/search/tsearch.c"
+    "musl/src/search/tsearch.h"
+    "musl/src/search/twalk.c"
+    "musl/src/select/poll.c"
+    "musl/src/select/pselect.c"
+    "musl/src/select/select.c"
+    "musl/src/setjmp/aarch64/longjmp.s"
+    "musl/src/setjmp/aarch64/setjmp.s"
+    "musl/src/setjmp/arm/longjmp.s"
+    "musl/src/setjmp/arm/setjmp.s"
+    "musl/src/setjmp/i386/longjmp.s"
+    "musl/src/setjmp/i386/setjmp.s"
+    "musl/src/setjmp/longjmp.c"
+    "musl/src/setjmp/m68k/longjmp.s"
+    "musl/src/setjmp/m68k/setjmp.s"
+    "musl/src/setjmp/microblaze/longjmp.s"
+    "musl/src/setjmp/microblaze/setjmp.s"
+    "musl/src/setjmp/mips/longjmp.S"
+    "musl/src/setjmp/mips/setjmp.S"
+    "musl/src/setjmp/mips64/longjmp.S"
+    "musl/src/setjmp/mips64/setjmp.S"
+    "musl/src/setjmp/mipsn32/longjmp.S"
+    "musl/src/setjmp/mipsn32/setjmp.S"
+    "musl/src/setjmp/or1k/longjmp.s"
+    "musl/src/setjmp/or1k/setjmp.s"
+    "musl/src/setjmp/powerpc/longjmp.S"
+    "musl/src/setjmp/powerpc/setjmp.S"
+    "musl/src/setjmp/powerpc64/longjmp.s"
+    "musl/src/setjmp/powerpc64/setjmp.s"
+    "musl/src/setjmp/s390x/longjmp.s"
+    "musl/src/setjmp/s390x/setjmp.s"
+    "musl/src/setjmp/setjmp.c"
+    "musl/src/setjmp/sh/longjmp.S"
+    "musl/src/setjmp/sh/setjmp.S"
+    "musl/src/setjmp/x32/longjmp.s"
+    "musl/src/setjmp/x32/setjmp.s"
+    "musl/src/setjmp/x86_64/longjmp.s"
+    "musl/src/setjmp/x86_64/setjmp.s"
+    "musl/src/signal/aarch64/restore.s"
+    "musl/src/signal/aarch64/sigsetjmp.s"
+    "musl/src/signal/arm/restore.s"
+    "musl/src/signal/arm/sigsetjmp.s"
+    "musl/src/signal/block.c"
+    "musl/src/signal/getitimer.c"
+    "musl/src/signal/i386/restore.s"
+    "musl/src/signal/i386/sigsetjmp.s"
+    "musl/src/signal/kill.c"
+    "musl/src/signal/killpg.c"
+    "musl/src/signal/m68k/sigsetjmp.s"
+    "musl/src/signal/microblaze/restore.s"
+    "musl/src/signal/microblaze/sigsetjmp.s"
+    "musl/src/signal/mips/restore.s"
+    "musl/src/signal/mips/sigsetjmp.s"
+    "musl/src/signal/mips64/restore.s"
+    "musl/src/signal/mips64/sigsetjmp.s"
+    "musl/src/signal/mipsn32/restore.s"
+    "musl/src/signal/mipsn32/sigsetjmp.s"
+    "musl/src/signal/or1k/sigsetjmp.s"
+    "musl/src/signal/powerpc/restore.s"
+    "musl/src/signal/powerpc/sigsetjmp.s"
+    "musl/src/signal/powerpc64/restore.s"
+    "musl/src/signal/powerpc64/sigsetjmp.s"
+    "musl/src/signal/psiginfo.c"
+    "musl/src/signal/psignal.c"
+    "musl/src/signal/raise.c"
+    "musl/src/signal/restore.c"
+    "musl/src/signal/s390x/restore.s"
+    "musl/src/signal/s390x/sigsetjmp.s"
+    "musl/src/signal/setitimer.c"
+    "musl/src/signal/sh/restore.s"
+    "musl/src/signal/sh/sigsetjmp.s"
+    "musl/src/signal/sigaction.c"
+    "musl/src/signal/sigaddset.c"
+    "musl/src/signal/sigaltstack.c"
+    "musl/src/signal/sigandset.c"
+    "musl/src/signal/sigdelset.c"
+    "musl/src/signal/sigemptyset.c"
+    "musl/src/signal/sigfillset.c"
+    "musl/src/signal/sighold.c"
+    "musl/src/signal/sigignore.c"
+    "musl/src/signal/siginterrupt.c"
+    "musl/src/signal/sigisemptyset.c"
+    "musl/src/signal/sigismember.c"
+    "musl/src/signal/siglongjmp.c"
+    "musl/src/signal/signal.c"
+    "musl/src/signal/sigorset.c"
+    "musl/src/signal/sigpause.c"
+    "musl/src/signal/sigpending.c"
+    "musl/src/signal/sigprocmask.c"
+    "musl/src/signal/sigqueue.c"
+    "musl/src/signal/sigrelse.c"
+    "musl/src/signal/sigrtmax.c"
+    "musl/src/signal/sigrtmin.c"
+    "musl/src/signal/sigset.c"
+    "musl/src/signal/sigsetjmp.c"
+    "musl/src/signal/sigsetjmp_tail.c"
+    "musl/src/signal/sigsuspend.c"
+    "musl/src/signal/sigtimedwait.c"
+    "musl/src/signal/sigwait.c"
+    "musl/src/signal/sigwaitinfo.c"
+    "musl/src/signal/x32/restore.s"
+    "musl/src/signal/x32/sigsetjmp.s"
+    "musl/src/signal/x86_64/restore.s"
+    "musl/src/signal/x86_64/sigsetjmp.s"
+    "musl/src/stat/__xstat.c"
+    "musl/src/stat/chmod.c"
+    "musl/src/stat/fchmod.c"
+    "musl/src/stat/fchmodat.c"
+    "musl/src/stat/fstat.c"
+    "musl/src/stat/fstatat.c"
+    "musl/src/stat/futimens.c"
+    "musl/src/stat/futimesat.c"
+    "musl/src/stat/lchmod.c"
+    "musl/src/stat/lstat.c"
+    "musl/src/stat/mkdir.c"
+    "musl/src/stat/mkdirat.c"
+    "musl/src/stat/mkfifo.c"
+    "musl/src/stat/mkfifoat.c"
+    "musl/src/stat/mknod.c"
+    "musl/src/stat/mknodat.c"
+    "musl/src/stat/stat.c"
+    "musl/src/stat/statvfs.c"
+    "musl/src/stat/umask.c"
+    "musl/src/stat/utimensat.c"
+    "musl/src/stdio/.fwrite.c.swp"
+    "musl/src/stdio/__fclose_ca.c"
+    "musl/src/stdio/__fdopen.c"
+    "musl/src/stdio/__fmodeflags.c"
+    "musl/src/stdio/__fopen_rb_ca.c"
+    "musl/src/stdio/__lockfile.c"
+    "musl/src/stdio/__overflow.c"
+    "musl/src/stdio/__stdio_close.c"
+    "musl/src/stdio/__stdio_exit.c"
+    "musl/src/stdio/__stdio_read.c"
+    "musl/src/stdio/__stdio_seek.c"
+    "musl/src/stdio/__stdio_write.c"
+    "musl/src/stdio/__stdout_write.c"
+    "musl/src/stdio/__string_read.c"
+    "musl/src/stdio/__toread.c"
+    "musl/src/stdio/__towrite.c"
+    "musl/src/stdio/__uflow.c"
+    "musl/src/stdio/asprintf.c"
+    "musl/src/stdio/clearerr.c"
+    "musl/src/stdio/dprintf.c"
+    "musl/src/stdio/ext.c"
+    "musl/src/stdio/ext2.c"
+    "musl/src/stdio/fclose.c"
+    "musl/src/stdio/feof.c"
+    "musl/src/stdio/ferror.c"
+    "musl/src/stdio/fflush.c"
+    "musl/src/stdio/fgetc.c"
+    "musl/src/stdio/fgetln.c"
+    "musl/src/stdio/fgetpos.c"
+    "musl/src/stdio/fgets.c"
+    "musl/src/stdio/fgetwc.c"
+    "musl/src/stdio/fgetws.c"
+    "musl/src/stdio/fileno.c"
+    "musl/src/stdio/flockfile.c"
+    "musl/src/stdio/fmemopen.c"
+    "musl/src/stdio/fopen.c"
+    "musl/src/stdio/fopencookie.c"
+    "musl/src/stdio/fprintf.c"
+    "musl/src/stdio/fputc.c"
+    "musl/src/stdio/fputs.c"
+    "musl/src/stdio/fputwc.c"
+    "musl/src/stdio/fputws.c"
+    "musl/src/stdio/fread.c"
+    "musl/src/stdio/freopen.c"
+    "musl/src/stdio/fscanf.c"
+    "musl/src/stdio/fseek.c"
+    "musl/src/stdio/fsetpos.c"
+    "musl/src/stdio/ftell.c"
+    "musl/src/stdio/ftrylockfile.c"
+    "musl/src/stdio/funlockfile.c"
+    "musl/src/stdio/fwide.c"
+    "musl/src/stdio/fwprintf.c"
+    "musl/src/stdio/fwrite.c"
+    "musl/src/stdio/fwscanf.c"
+    "musl/src/stdio/getc.c"
+    "musl/src/stdio/getc.h"
+    "musl/src/stdio/getc_unlocked.c"
+    "musl/src/stdio/getchar.c"
+    "musl/src/stdio/getchar_unlocked.c"
+    "musl/src/stdio/getdelim.c"
+    "musl/src/stdio/getline.c"
+    "musl/src/stdio/gets.c"
+    "musl/src/stdio/getw.c"
+    "musl/src/stdio/getwc.c"
+    "musl/src/stdio/getwchar.c"
+    "musl/src/stdio/ofl.c"
+    "musl/src/stdio/ofl_add.c"
+    "musl/src/stdio/open_memstream.c"
+    "musl/src/stdio/open_wmemstream.c"
+    "musl/src/stdio/pclose.c"
+    "musl/src/stdio/perror.c"
+    "musl/src/stdio/popen.c"
+    "musl/src/stdio/printf.c"
+    "musl/src/stdio/putc.c"
+    "musl/src/stdio/putc.h"
+    "musl/src/stdio/putc_unlocked.c"
+    "musl/src/stdio/putchar.c"
+    "musl/src/stdio/putchar_unlocked.c"
+    "musl/src/stdio/puts.c"
+    "musl/src/stdio/putw.c"
+    "musl/src/stdio/putwc.c"
+    "musl/src/stdio/putwchar.c"
+    "musl/src/stdio/remove.c"
+    "musl/src/stdio/rename.c"
+    "musl/src/stdio/rewind.c"
+    "musl/src/stdio/scanf.c"
+    "musl/src/stdio/setbuf.c"
+    "musl/src/stdio/setbuffer.c"
+    "musl/src/stdio/setlinebuf.c"
+    "musl/src/stdio/setvbuf.c"
+    "musl/src/stdio/snprintf.c"
+    "musl/src/stdio/sprintf.c"
+    "musl/src/stdio/sscanf.c"
+    "musl/src/stdio/stderr.c"
+    "musl/src/stdio/stdin.c"
+    "musl/src/stdio/stdout.c"
+    "musl/src/stdio/swprintf.c"
+    "musl/src/stdio/swscanf.c"
+    "musl/src/stdio/tempnam.c"
+    "musl/src/stdio/tmpfile.c"
+    "musl/src/stdio/tmpnam.c"
+    "musl/src/stdio/ungetc.c"
+    "musl/src/stdio/ungetwc.c"
+    "musl/src/stdio/vasprintf.c"
+    "musl/src/stdio/vdprintf.c"
+    "musl/src/stdio/vfprintf.c"
+    "musl/src/stdio/vfscanf.c"
+    "musl/src/stdio/vfwprintf.c"
+    "musl/src/stdio/vfwscanf.c"
+    "musl/src/stdio/vprintf.c"
+    "musl/src/stdio/vscanf.c"
+    "musl/src/stdio/vsnprintf.c"
+    "musl/src/stdio/vsprintf.c"
+    "musl/src/stdio/vsscanf.c"
+    "musl/src/stdio/vswprintf.c"
+    "musl/src/stdio/vswscanf.c"
+    "musl/src/stdio/vwprintf.c"
+    "musl/src/stdio/vwscanf.c"
+    "musl/src/stdio/wprintf.c"
+    "musl/src/stdio/wscanf.c"
+    "musl/src/stdlib/abs.c"
+    "musl/src/stdlib/atof.c"
+    "musl/src/stdlib/atoi.c"
+    "musl/src/stdlib/atol.c"
+    "musl/src/stdlib/atoll.c"
+    "musl/src/stdlib/bsearch.c"
+    "musl/src/stdlib/div.c"
+    "musl/src/stdlib/ecvt.c"
+    "musl/src/stdlib/fcvt.c"
+    "musl/src/stdlib/gcvt.c"
+    "musl/src/stdlib/imaxabs.c"
+    "musl/src/stdlib/imaxdiv.c"
+    "musl/src/stdlib/labs.c"
+    "musl/src/stdlib/ldiv.c"
+    "musl/src/stdlib/llabs.c"
+    "musl/src/stdlib/lldiv.c"
+    "musl/src/stdlib/qsort.c"
+    "musl/src/stdlib/strtod.c"
+    "musl/src/stdlib/strtol.c"
+    "musl/src/stdlib/wcstod.c"
+    "musl/src/stdlib/wcstol.c"
+    "musl/src/string/arm/__aeabi_memcpy.s"
+    "musl/src/string/arm/__aeabi_memset.s"
+    "musl/src/string/arm/memcpy.c"
+    "musl/src/string/arm/memcpy_le.S"
+    "musl/src/string/bcmp.c"
+    "musl/src/string/bcopy.c"
+    "musl/src/string/bzero.c"
+    "musl/src/string/explicit_bzero.c"
+    "musl/src/string/i386/memcpy.s"
+    "musl/src/string/i386/memmove.s"
+    "musl/src/string/i386/memset.s"
+    "musl/src/string/index.c"
+    "musl/src/string/memccpy.c"
+    "musl/src/string/memchr.c"
+    "musl/src/string/memcmp.c"
+    "musl/src/string/memcpy.c"
+    "musl/src/string/memmem.c"
+    "musl/src/string/memmove.c"
+    "musl/src/string/mempcpy.c"
+    "musl/src/string/memrchr.c"
+    "musl/src/string/memset.c"
+    "musl/src/string/rindex.c"
+    "musl/src/string/stpcpy.c"
+    "musl/src/string/stpncpy.c"
+    "musl/src/string/strcasecmp.c"
+    "musl/src/string/strcasestr.c"
+    "musl/src/string/strcat.c"
+    "musl/src/string/strchr.c"
+    "musl/src/string/strchrnul.c"
+    "musl/src/string/strcmp.c"
+    "musl/src/string/strcpy.c"
+    "musl/src/string/strcspn.c"
+    "musl/src/string/strdup.c"
+    "musl/src/string/strerror_r.c"
+    "musl/src/string/strlcat.c"
+    "musl/src/string/strlcpy.c"
+    "musl/src/string/strlen.c"
+    "musl/src/string/strncasecmp.c"
+    "musl/src/string/strncat.c"
+    "musl/src/string/strncmp.c"
+    "musl/src/string/strncpy.c"
+    "musl/src/string/strndup.c"
+    "musl/src/string/strnlen.c"
+    "musl/src/string/strpbrk.c"
+    "musl/src/string/strrchr.c"
+    "musl/src/string/strsep.c"
+    "musl/src/string/strsignal.c"
+    "musl/src/string/strspn.c"
+    "musl/src/string/strstr.c"
+    "musl/src/string/strtok.c"
+    "musl/src/string/strtok_r.c"
+    "musl/src/string/strverscmp.c"
+    "musl/src/string/swab.c"
+    "musl/src/string/wcpcpy.c"
+    "musl/src/string/wcpncpy.c"
+    "musl/src/string/wcscasecmp.c"
+    "musl/src/string/wcscasecmp_l.c"
+    "musl/src/string/wcscat.c"
+    "musl/src/string/wcschr.c"
+    "musl/src/string/wcscmp.c"
+    "musl/src/string/wcscpy.c"
+    "musl/src/string/wcscspn.c"
+    "musl/src/string/wcsdup.c"
+    "musl/src/string/wcslen.c"
+    "musl/src/string/wcsncasecmp.c"
+    "musl/src/string/wcsncasecmp_l.c"
+    "musl/src/string/wcsncat.c"
+    "musl/src/string/wcsncmp.c"
+    "musl/src/string/wcsncpy.c"
+    "musl/src/string/wcsnlen.c"
+    "musl/src/string/wcspbrk.c"
+    "musl/src/string/wcsrchr.c"
+    "musl/src/string/wcsspn.c"
+    "musl/src/string/wcsstr.c"
+    "musl/src/string/wcstok.c"
+    "musl/src/string/wcswcs.c"
+    "musl/src/string/wmemchr.c"
+    "musl/src/string/wmemcmp.c"
+    "musl/src/string/wmemcpy.c"
+    "musl/src/string/wmemmove.c"
+    "musl/src/string/wmemset.c"
+    "musl/src/string/x86_64/memcpy.s"
+    "musl/src/string/x86_64/memmove.s"
+    "musl/src/string/x86_64/memset.s"
+    "musl/src/temp/__randname.c"
+    "musl/src/temp/mkdtemp.c"
+    "musl/src/temp/mkostemp.c"
+    "musl/src/temp/mkostemps.c"
+    "musl/src/temp/mkstemp.c"
+    "musl/src/temp/mkstemps.c"
+    "musl/src/temp/mktemp.c"
+    "musl/src/termios/cfgetospeed.c"
+    "musl/src/termios/cfmakeraw.c"
+    "musl/src/termios/cfsetospeed.c"
+    "musl/src/termios/tcdrain.c"
+    "musl/src/termios/tcflow.c"
+    "musl/src/termios/tcflush.c"
+    "musl/src/termios/tcgetattr.c"
+    "musl/src/termios/tcgetsid.c"
+    "musl/src/termios/tcsendbreak.c"
+    "musl/src/termios/tcsetattr.c"
+    "musl/src/thread/__lock.c"
+    "musl/src/thread/__set_thread_area.c"
+    "musl/src/thread/__syscall_cp.c"
+    "musl/src/thread/__timedwait.c"
+    "musl/src/thread/__tls_get_addr.c"
+    "musl/src/thread/__unmapself.c"
+    "musl/src/thread/__wait.c"
+    "musl/src/thread/aarch64/__set_thread_area.s"
+    "musl/src/thread/aarch64/__unmapself.s"
+    "musl/src/thread/aarch64/clone.s"
+    "musl/src/thread/aarch64/syscall_cp.s"
+    "musl/src/thread/arm/__aeabi_read_tp.s"
+    "musl/src/thread/arm/__set_thread_area.c"
+    "musl/src/thread/arm/__unmapself.s"
+    "musl/src/thread/arm/atomics.s"
+    "musl/src/thread/arm/clone.s"
+    "musl/src/thread/arm/syscall_cp.s"
+    "musl/src/thread/call_once.c"
+    "musl/src/thread/clone.c"
+    "musl/src/thread/cnd_broadcast.c"
+    "musl/src/thread/cnd_destroy.c"
+    "musl/src/thread/cnd_init.c"
+    "musl/src/thread/cnd_signal.c"
+    "musl/src/thread/cnd_timedwait.c"
+    "musl/src/thread/cnd_wait.c"
+    "musl/src/thread/default_attr.c"
+    "musl/src/thread/i386/__set_thread_area.s"
+    "musl/src/thread/i386/__unmapself.s"
+    "musl/src/thread/i386/clone.s"
+    "musl/src/thread/i386/syscall_cp.s"
+    "musl/src/thread/i386/tls.s"
+    "musl/src/thread/lock_ptc.c"
+    "musl/src/thread/m68k/__m68k_read_tp.s"
+    "musl/src/thread/m68k/clone.s"
+    "musl/src/thread/m68k/syscall_cp.s"
+    "musl/src/thread/microblaze/__set_thread_area.s"
+    "musl/src/thread/microblaze/__unmapself.s"
+    "musl/src/thread/microblaze/clone.s"
+    "musl/src/thread/microblaze/syscall_cp.s"
+    "musl/src/thread/mips/__unmapself.s"
+    "musl/src/thread/mips/clone.s"
+    "musl/src/thread/mips/syscall_cp.s"
+    "musl/src/thread/mips64/__unmapself.s"
+    "musl/src/thread/mips64/clone.s"
+    "musl/src/thread/mips64/syscall_cp.s"
+    "musl/src/thread/mipsn32/__unmapself.s"
+    "musl/src/thread/mipsn32/clone.s"
+    "musl/src/thread/mipsn32/syscall_cp.s"
+    "musl/src/thread/mtx_destroy.c"
+    "musl/src/thread/mtx_init.c"
+    "musl/src/thread/mtx_lock.c"
+    "musl/src/thread/mtx_timedlock.c"
+    "musl/src/thread/mtx_trylock.c"
+    "musl/src/thread/mtx_unlock.c"
+    "musl/src/thread/or1k/__set_thread_area.s"
+    "musl/src/thread/or1k/__unmapself.s"
+    "musl/src/thread/or1k/clone.s"
+    "musl/src/thread/or1k/syscall_cp.s"
+    "musl/src/thread/powerpc/__set_thread_area.s"
+    "musl/src/thread/powerpc/__unmapself.s"
+    "musl/src/thread/powerpc/clone.s"
+    "musl/src/thread/powerpc/syscall_cp.s"
+    "musl/src/thread/powerpc64/__set_thread_area.s"
+    "musl/src/thread/powerpc64/__unmapself.s"
+    "musl/src/thread/powerpc64/clone.s"
+    "musl/src/thread/powerpc64/syscall_cp.s"
+    "musl/src/thread/pthread_atfork.c"
+    "musl/src/thread/pthread_attr_destroy.c"
+    "musl/src/thread/pthread_attr_get.c"
+    "musl/src/thread/pthread_attr_init.c"
+    "musl/src/thread/pthread_attr_setdetachstate.c"
+    "musl/src/thread/pthread_attr_setguardsize.c"
+    "musl/src/thread/pthread_attr_setinheritsched.c"
+    "musl/src/thread/pthread_attr_setschedparam.c"
+    "musl/src/thread/pthread_attr_setschedpolicy.c"
+    "musl/src/thread/pthread_attr_setscope.c"
+    "musl/src/thread/pthread_attr_setstack.c"
+    "musl/src/thread/pthread_attr_setstacksize.c"
+    "musl/src/thread/pthread_barrier_destroy.c"
+    "musl/src/thread/pthread_barrier_init.c"
+    "musl/src/thread/pthread_barrier_wait.c"
+    "musl/src/thread/pthread_barrierattr_destroy.c"
+    "musl/src/thread/pthread_barrierattr_init.c"
+    "musl/src/thread/pthread_barrierattr_setpshared.c"
+    "musl/src/thread/pthread_cancel.c"
+    "musl/src/thread/pthread_cleanup_push.c"
+    "musl/src/thread/pthread_cond_broadcast.c"
+    "musl/src/thread/pthread_cond_destroy.c"
+    "musl/src/thread/pthread_cond_init.c"
+    "musl/src/thread/pthread_cond_signal.c"
+    "musl/src/thread/pthread_cond_timedwait.c"
+    "musl/src/thread/pthread_cond_wait.c"
+    "musl/src/thread/pthread_condattr_destroy.c"
+    "musl/src/thread/pthread_condattr_init.c"
+    "musl/src/thread/pthread_condattr_setclock.c"
+    "musl/src/thread/pthread_condattr_setpshared.c"
+    "musl/src/thread/pthread_create.c"
+    "musl/src/thread/pthread_detach.c"
+    "musl/src/thread/pthread_equal.c"
+    "musl/src/thread/pthread_getattr_np.c"
+    "musl/src/thread/pthread_getconcurrency.c"
+    "musl/src/thread/pthread_getcpuclockid.c"
+    "musl/src/thread/pthread_getschedparam.c"
+    "musl/src/thread/pthread_getspecific.c"
+    "musl/src/thread/pthread_join.c"
+    "musl/src/thread/pthread_key_create.c"
+    "musl/src/thread/pthread_key_delete.c"
+    "musl/src/thread/pthread_kill.c"
+    "musl/src/thread/pthread_mutex_consistent.c"
+    "musl/src/thread/pthread_mutex_destroy.c"
+    "musl/src/thread/pthread_mutex_getprioceiling.c"
+    "musl/src/thread/pthread_mutex_init.c"
+    "musl/src/thread/pthread_mutex_lock.c"
+    "musl/src/thread/pthread_mutex_setprioceiling.c"
+    "musl/src/thread/pthread_mutex_timedlock.c"
+    "musl/src/thread/pthread_mutex_trylock.c"
+    "musl/src/thread/pthread_mutex_unlock.c"
+    "musl/src/thread/pthread_mutexattr_destroy.c"
+    "musl/src/thread/pthread_mutexattr_init.c"
+    "musl/src/thread/pthread_mutexattr_setprotocol.c"
+    "musl/src/thread/pthread_mutexattr_setpshared.c"
+    "musl/src/thread/pthread_mutexattr_setrobust.c"
+    "musl/src/thread/pthread_mutexattr_settype.c"
+    "musl/src/thread/pthread_once.c"
+    "musl/src/thread/pthread_rwlock_destroy.c"
+    "musl/src/thread/pthread_rwlock_init.c"
+    "musl/src/thread/pthread_rwlock_rdlock.c"
+    "musl/src/thread/pthread_rwlock_timedrdlock.c"
+    "musl/src/thread/pthread_rwlock_timedwrlock.c"
+    "musl/src/thread/pthread_rwlock_tryrdlock.c"
+    "musl/src/thread/pthread_rwlock_trywrlock.c"
+    "musl/src/thread/pthread_rwlock_unlock.c"
+    "musl/src/thread/pthread_rwlock_wrlock.c"
+    "musl/src/thread/pthread_rwlockattr_destroy.c"
+    "musl/src/thread/pthread_rwlockattr_init.c"
+    "musl/src/thread/pthread_rwlockattr_setpshared.c"
+    "musl/src/thread/pthread_self.c"
+    "musl/src/thread/pthread_setattr_default_np.c"
+    "musl/src/thread/pthread_setcancelstate.c"
+    "musl/src/thread/pthread_setcanceltype.c"
+    "musl/src/thread/pthread_setconcurrency.c"
+    "musl/src/thread/pthread_setname_np.c"
+    "musl/src/thread/pthread_setschedparam.c"
+    "musl/src/thread/pthread_setschedprio.c"
+    "musl/src/thread/pthread_setspecific.c"
+    "musl/src/thread/pthread_sigmask.c"
+    "musl/src/thread/pthread_spin_destroy.c"
+    "musl/src/thread/pthread_spin_init.c"
+    "musl/src/thread/pthread_spin_lock.c"
+    "musl/src/thread/pthread_spin_trylock.c"
+    "musl/src/thread/pthread_spin_unlock.c"
+    "musl/src/thread/pthread_testcancel.c"
+    "musl/src/thread/s390x/__set_thread_area.s"
+    "musl/src/thread/s390x/__tls_get_offset.s"
+    "musl/src/thread/s390x/__unmapself.s"
+    "musl/src/thread/s390x/clone.s"
+    "musl/src/thread/s390x/syscall_cp.s"
+    "musl/src/thread/sem_destroy.c"
+    "musl/src/thread/sem_getvalue.c"
+    "musl/src/thread/sem_init.c"
+    "musl/src/thread/sem_open.c"
+    "musl/src/thread/sem_post.c"
+    "musl/src/thread/sem_timedwait.c"
+    "musl/src/thread/sem_trywait.c"
+    "musl/src/thread/sem_unlink.c"
+    "musl/src/thread/sem_wait.c"
+    "musl/src/thread/sh/__set_thread_area.c"
+    "musl/src/thread/sh/__unmapself.c"
+    "musl/src/thread/sh/__unmapself_mmu.s"
+    "musl/src/thread/sh/atomics.s"
+    "musl/src/thread/sh/clone.s"
+    "musl/src/thread/sh/syscall_cp.s"
+    "musl/src/thread/synccall.c"
+    "musl/src/thread/syscall_cp.c"
+    "musl/src/thread/thrd_create.c"
+    "musl/src/thread/thrd_exit.c"
+    "musl/src/thread/thrd_join.c"
+    "musl/src/thread/thrd_sleep.c"
+    "musl/src/thread/thrd_yield.c"
+    "musl/src/thread/tls.c"
+    "musl/src/thread/tss_create.c"
+    "musl/src/thread/tss_delete.c"
+    "musl/src/thread/tss_set.c"
+    "musl/src/thread/vmlock.c"
+    "musl/src/thread/x32/__set_thread_area.s"
+    "musl/src/thread/x32/__unmapself.s"
+    "musl/src/thread/x32/clone.s"
+    "musl/src/thread/x32/syscall_cp.s"
+    "musl/src/thread/x32/syscall_cp_fixup.c"
+    "musl/src/thread/x86_64/__set_thread_area.s"
+    "musl/src/thread/x86_64/__unmapself.s"
+    "musl/src/thread/x86_64/clone.s"
+    "musl/src/thread/x86_64/syscall_cp.s"
+    "musl/src/time/__map_file.c"
+    "musl/src/time/__month_to_secs.c"
+    "musl/src/time/__secs_to_tm.c"
+    "musl/src/time/__tm_to_secs.c"
+    "musl/src/time/__tz.c"
+    "musl/src/time/__year_to_secs.c"
+    "musl/src/time/asctime.c"
+    "musl/src/time/asctime_r.c"
+    "musl/src/time/clock.c"
+    "musl/src/time/clock_getcpuclockid.c"
+    "musl/src/time/clock_getres.c"
+    "musl/src/time/clock_gettime.c"
+    "musl/src/time/clock_nanosleep.c"
+    "musl/src/time/clock_settime.c"
+    "musl/src/time/ctime.c"
+    "musl/src/time/ctime_r.c"
+    "musl/src/time/difftime.c"
+    "musl/src/time/ftime.c"
+    "musl/src/time/getdate.c"
+    "musl/src/time/gettimeofday.c"
+    "musl/src/time/gmtime.c"
+    "musl/src/time/gmtime_r.c"
+    "musl/src/time/localtime.c"
+    "musl/src/time/localtime_r.c"
+    "musl/src/time/mktime.c"
+    "musl/src/time/nanosleep.c"
+    "musl/src/time/strftime.c"
+    "musl/src/time/strptime.c"
+    "musl/src/time/time.c"
+    "musl/src/time/time_impl.h"
+    "musl/src/time/timegm.c"
+    "musl/src/time/timer_create.c"
+    "musl/src/time/timer_delete.c"
+    "musl/src/time/timer_getoverrun.c"
+    "musl/src/time/timer_gettime.c"
+    "musl/src/time/timer_settime.c"
+    "musl/src/time/times.c"
+    "musl/src/time/timespec_get.c"
+    "musl/src/time/utime.c"
+    "musl/src/time/wcsftime.c"
+    "musl/src/unistd/_exit.c"
+    "musl/src/unistd/access.c"
+    "musl/src/unistd/acct.c"
+    "musl/src/unistd/alarm.c"
+    "musl/src/unistd/chdir.c"
+    "musl/src/unistd/chown.c"
+    "musl/src/unistd/close.c"
+    "musl/src/unistd/ctermid.c"
+    "musl/src/unistd/dup.c"
+    "musl/src/unistd/dup2.c"
+    "musl/src/unistd/dup3.c"
+    "musl/src/unistd/faccessat.c"
+    "musl/src/unistd/fchdir.c"
+    "musl/src/unistd/fchown.c"
+    "musl/src/unistd/fchownat.c"
+    "musl/src/unistd/fdatasync.c"
+    "musl/src/unistd/fsync.c"
+    "musl/src/unistd/ftruncate.c"
+    "musl/src/unistd/getcwd.c"
+    "musl/src/unistd/getegid.c"
+    "musl/src/unistd/geteuid.c"
+    "musl/src/unistd/getgid.c"
+    "musl/src/unistd/getgroups.c"
+    "musl/src/unistd/gethostname.c"
+    "musl/src/unistd/getlogin.c"
+    "musl/src/unistd/getlogin_r.c"
+    "musl/src/unistd/getpgid.c"
+    "musl/src/unistd/getpgrp.c"
+    "musl/src/unistd/getpid.c"
+    "musl/src/unistd/getppid.c"
+    "musl/src/unistd/getsid.c"
+    "musl/src/unistd/getuid.c"
+    "musl/src/unistd/isatty.c"
+    "musl/src/unistd/lchown.c"
+    "musl/src/unistd/link.c"
+    "musl/src/unistd/linkat.c"
+    "musl/src/unistd/lseek.c"
+    "musl/src/unistd/mips/pipe.s"
+    "musl/src/unistd/mips64/pipe.s"
+    "musl/src/unistd/mipsn32/pipe.s"
+    "musl/src/unistd/nice.c"
+    "musl/src/unistd/pause.c"
+    "musl/src/unistd/pipe.c"
+    "musl/src/unistd/pipe2.c"
+    "musl/src/unistd/posix_close.c"
+    "musl/src/unistd/pread.c"
+    "musl/src/unistd/preadv.c"
+    "musl/src/unistd/pwrite.c"
+    "musl/src/unistd/pwritev.c"
+    "musl/src/unistd/read.c"
+    "musl/src/unistd/readlink.c"
+    "musl/src/unistd/readlinkat.c"
+    "musl/src/unistd/readv.c"
+    "musl/src/unistd/renameat.c"
+    "musl/src/unistd/rmdir.c"
+    "musl/src/unistd/setegid.c"
+    "musl/src/unistd/seteuid.c"
+    "musl/src/unistd/setgid.c"
+    "musl/src/unistd/setpgid.c"
+    "musl/src/unistd/setpgrp.c"
+    "musl/src/unistd/setregid.c"
+    "musl/src/unistd/setresgid.c"
+    "musl/src/unistd/setresuid.c"
+    "musl/src/unistd/setreuid.c"
+    "musl/src/unistd/setsid.c"
+    "musl/src/unistd/setuid.c"
+    "musl/src/unistd/setxid.c"
+    "musl/src/unistd/sh/pipe.s"
+    "musl/src/unistd/sleep.c"
+    "musl/src/unistd/symlink.c"
+    "musl/src/unistd/symlinkat.c"
+    "musl/src/unistd/sync.c"
+    "musl/src/unistd/tcgetpgrp.c"
+    "musl/src/unistd/tcsetpgrp.c"
+    "musl/src/unistd/truncate.c"
+    "musl/src/unistd/ttyname.c"
+    "musl/src/unistd/ttyname_r.c"
+    "musl/src/unistd/ualarm.c"
+    "musl/src/unistd/unlink.c"
+    "musl/src/unistd/unlinkat.c"
+    "musl/src/unistd/usleep.c"
+    "musl/src/unistd/write.c"
+    "musl/src/unistd/writev.c"
+)
+
 set(ZIG_LIBC_FILES
     "dummy/c.zig"
     "dummy/c/i386.zig"
@@ -4299,314 +6100,313 @@ set(ZIG_LIBC_FILES
     "include/x86_64-linux-musl/bits/stat.h"
     "include/x86_64-linux-musl/bits/syscall.h"
     "include/x86_64-linux-musl/bits/user.h"
-    "musl/crt/mips64/crtn.s"
-    "musl/crt/mips64/crti.s"
-    "musl/crt/crt1.c"
-    "musl/crt/x32/crtn.s"
-    "musl/crt/x32/crti.s"
-    "musl/crt/crtn.c"
-    "musl/crt/powerpc64/crtn.s"
-    "musl/crt/powerpc64/crti.s"
-    "musl/crt/crti.c"
-    "musl/crt/microblaze/crtn.s"
-    "musl/crt/microblaze/crti.s"
-    "musl/crt/arm/crtn.s"
-    "musl/crt/arm/crti.s"
-    "musl/crt/rcrt1.c"
-    "musl/crt/s390x/crtn.s"
-    "musl/crt/s390x/crti.s"
-    "musl/crt/mips/crtn.s"
-    "musl/crt/mips/crti.s"
-    "musl/crt/x86_64/crtn.s"
-    "musl/crt/x86_64/crti.s"
-    "musl/crt/i386/crtn.s"
-    "musl/crt/i386/crti.s"
-    "musl/crt/aarch64/crtn.s"
-    "musl/crt/aarch64/crti.s"
-    "musl/crt/mipsn32/crtn.s"
-    "musl/crt/mipsn32/crti.s"
-    "musl/crt/or1k/crtn.s"
-    "musl/crt/or1k/crti.s"
-    "musl/crt/powerpc/crtn.s"
-    "musl/crt/powerpc/crti.s"
-    "musl/crt/Scrt1.c"
-    "musl/crt/sh/crtn.s"
-    "musl/crt/sh/crti.s"
-    "musl/src/internal/libc.h"
-    "musl/src/include/features.h"
-    "musl/arch/mips64/pthread_arch.h"
-    "musl/arch/mips64/crt_arch.h"
-    "musl/arch/mips64/ksigaction.h"
-    "musl/arch/mips64/reloc.h"
-    "musl/arch/mips64/syscall_arch.h"
+    "musl/arch/aarch64/atomic_arch.h"
+    "musl/arch/aarch64/bits/alltypes.h.in"
+    "musl/arch/aarch64/bits/endian.h"
+    "musl/arch/aarch64/bits/fcntl.h"
+    "musl/arch/aarch64/bits/fenv.h"
+    "musl/arch/aarch64/bits/float.h"
+    "musl/arch/aarch64/bits/hwcap.h"
+    "musl/arch/aarch64/bits/ipc.h"
+    "musl/arch/aarch64/bits/limits.h"
+    "musl/arch/aarch64/bits/msg.h"
+    "musl/arch/aarch64/bits/posix.h"
+    "musl/arch/aarch64/bits/reg.h"
+    "musl/arch/aarch64/bits/sem.h"
+    "musl/arch/aarch64/bits/setjmp.h"
+    "musl/arch/aarch64/bits/shm.h"
+    "musl/arch/aarch64/bits/signal.h"
+    "musl/arch/aarch64/bits/socket.h"
+    "musl/arch/aarch64/bits/stat.h"
+    "musl/arch/aarch64/bits/stdint.h"
+    "musl/arch/aarch64/bits/syscall.h.in"
+    "musl/arch/aarch64/bits/user.h"
+    "musl/arch/aarch64/crt_arch.h"
+    "musl/arch/aarch64/pthread_arch.h"
+    "musl/arch/aarch64/reloc.h"
+    "musl/arch/aarch64/syscall_arch.h"
+    "musl/arch/arm/atomic_arch.h"
+    "musl/arch/arm/bits/alltypes.h.in"
+    "musl/arch/arm/bits/endian.h"
+    "musl/arch/arm/bits/fcntl.h"
+    "musl/arch/arm/bits/fenv.h"
+    "musl/arch/arm/bits/float.h"
+    "musl/arch/arm/bits/hwcap.h"
+    "musl/arch/arm/bits/ioctl_fix.h"
+    "musl/arch/arm/bits/limits.h"
+    "musl/arch/arm/bits/posix.h"
+    "musl/arch/arm/bits/ptrace.h"
+    "musl/arch/arm/bits/reg.h"
+    "musl/arch/arm/bits/setjmp.h"
+    "musl/arch/arm/bits/signal.h"
+    "musl/arch/arm/bits/stat.h"
+    "musl/arch/arm/bits/stdint.h"
+    "musl/arch/arm/bits/syscall.h.in"
+    "musl/arch/arm/bits/user.h"
+    "musl/arch/arm/crt_arch.h"
+    "musl/arch/arm/pthread_arch.h"
+    "musl/arch/arm/reloc.h"
+    "musl/arch/arm/syscall_arch.h"
+    "musl/arch/generic/bits/errno.h"
+    "musl/arch/generic/bits/fcntl.h"
+    "musl/arch/generic/bits/fenv.h"
+    "musl/arch/generic/bits/hwcap.h"
+    "musl/arch/generic/bits/io.h"
+    "musl/arch/generic/bits/ioctl.h"
+    "musl/arch/generic/bits/ioctl_fix.h"
+    "musl/arch/generic/bits/ipc.h"
+    "musl/arch/generic/bits/kd.h"
+    "musl/arch/generic/bits/link.h"
+    "musl/arch/generic/bits/mman.h"
+    "musl/arch/generic/bits/msg.h"
+    "musl/arch/generic/bits/poll.h"
+    "musl/arch/generic/bits/ptrace.h"
+    "musl/arch/generic/bits/resource.h"
+    "musl/arch/generic/bits/sem.h"
+    "musl/arch/generic/bits/shm.h"
+    "musl/arch/generic/bits/socket.h"
+    "musl/arch/generic/bits/soundcard.h"
+    "musl/arch/generic/bits/statfs.h"
+    "musl/arch/generic/bits/termios.h"
+    "musl/arch/generic/bits/vt.h"
+    "musl/arch/i386/atomic_arch.h"
+    "musl/arch/i386/bits/alltypes.h.in"
+    "musl/arch/i386/bits/endian.h"
+    "musl/arch/i386/bits/fenv.h"
+    "musl/arch/i386/bits/float.h"
+    "musl/arch/i386/bits/io.h"
+    "musl/arch/i386/bits/limits.h"
+    "musl/arch/i386/bits/mman.h"
+    "musl/arch/i386/bits/posix.h"
+    "musl/arch/i386/bits/ptrace.h"
+    "musl/arch/i386/bits/reg.h"
+    "musl/arch/i386/bits/setjmp.h"
+    "musl/arch/i386/bits/signal.h"
+    "musl/arch/i386/bits/stat.h"
+    "musl/arch/i386/bits/stdint.h"
+    "musl/arch/i386/bits/syscall.h.in"
+    "musl/arch/i386/bits/user.h"
+    "musl/arch/i386/crt_arch.h"
+    "musl/arch/i386/pthread_arch.h"
+    "musl/arch/i386/reloc.h"
+    "musl/arch/i386/syscall_arch.h"
+    "musl/arch/mips/atomic_arch.h"
+    "musl/arch/mips/bits/alltypes.h.in"
+    "musl/arch/mips/bits/endian.h"
+    "musl/arch/mips/bits/errno.h"
+    "musl/arch/mips/bits/fcntl.h"
+    "musl/arch/mips/bits/fenv.h"
+    "musl/arch/mips/bits/float.h"
+    "musl/arch/mips/bits/hwcap.h"
+    "musl/arch/mips/bits/ioctl.h"
+    "musl/arch/mips/bits/limits.h"
+    "musl/arch/mips/bits/mman.h"
+    "musl/arch/mips/bits/msg.h"
+    "musl/arch/mips/bits/poll.h"
+    "musl/arch/mips/bits/posix.h"
+    "musl/arch/mips/bits/ptrace.h"
+    "musl/arch/mips/bits/reg.h"
+    "musl/arch/mips/bits/resource.h"
+    "musl/arch/mips/bits/sem.h"
+    "musl/arch/mips/bits/setjmp.h"
+    "musl/arch/mips/bits/shm.h"
+    "musl/arch/mips/bits/signal.h"
+    "musl/arch/mips/bits/socket.h"
+    "musl/arch/mips/bits/stat.h"
+    "musl/arch/mips/bits/statfs.h"
+    "musl/arch/mips/bits/stdint.h"
+    "musl/arch/mips/bits/syscall.h.in"
+    "musl/arch/mips/bits/termios.h"
+    "musl/arch/mips/bits/user.h"
+    "musl/arch/mips/crt_arch.h"
+    "musl/arch/mips/ksigaction.h"
+    "musl/arch/mips/pthread_arch.h"
+    "musl/arch/mips/reloc.h"
+    "musl/arch/mips/syscall_arch.h"
     "musl/arch/mips64/atomic_arch.h"
-    "musl/arch/mips64/bits/float.h"
+    "musl/arch/mips64/bits/alltypes.h.in"
+    "musl/arch/mips64/bits/endian.h"
     "musl/arch/mips64/bits/errno.h"
-    "musl/arch/mips64/bits/mman.h"
-    "musl/arch/mips64/bits/stdint.h"
-    "musl/arch/mips64/bits/termios.h"
-    "musl/arch/mips64/bits/reg.h"
-    "musl/arch/mips64/bits/ipc.h"
+    "musl/arch/mips64/bits/fcntl.h"
     "musl/arch/mips64/bits/fenv.h"
+    "musl/arch/mips64/bits/float.h"
+    "musl/arch/mips64/bits/hwcap.h"
+    "musl/arch/mips64/bits/ioctl.h"
+    "musl/arch/mips64/bits/ipc.h"
+    "musl/arch/mips64/bits/limits.h"
+    "musl/arch/mips64/bits/mman.h"
     "musl/arch/mips64/bits/msg.h"
+    "musl/arch/mips64/bits/poll.h"
+    "musl/arch/mips64/bits/posix.h"
     "musl/arch/mips64/bits/ptrace.h"
+    "musl/arch/mips64/bits/reg.h"
     "musl/arch/mips64/bits/resource.h"
-    "musl/arch/mips64/bits/posix.h"
+    "musl/arch/mips64/bits/sem.h"
     "musl/arch/mips64/bits/setjmp.h"
-    "musl/arch/mips64/bits/alltypes.h.in"
-    "musl/arch/mips64/bits/syscall.h.in"
     "musl/arch/mips64/bits/shm.h"
-    "musl/arch/mips64/bits/hwcap.h"
-    "musl/arch/mips64/bits/endian.h"
-    "musl/arch/mips64/bits/limits.h"
-    "musl/arch/mips64/bits/poll.h"
-    "musl/arch/mips64/bits/ioctl.h"
-    "musl/arch/mips64/bits/fcntl.h"
     "musl/arch/mips64/bits/signal.h"
-    "musl/arch/mips64/bits/stat.h"
-    "musl/arch/mips64/bits/user.h"
-    "musl/arch/mips64/bits/sem.h"
     "musl/arch/mips64/bits/socket.h"
+    "musl/arch/mips64/bits/stat.h"
     "musl/arch/mips64/bits/statfs.h"
-    "musl/arch/generic/bits/errno.h"
-    "musl/arch/generic/bits/mman.h"
-    "musl/arch/generic/bits/termios.h"
-    "musl/arch/generic/bits/kd.h"
-    "musl/arch/generic/bits/ipc.h"
-    "musl/arch/generic/bits/fenv.h"
-    "musl/arch/generic/bits/msg.h"
-    "musl/arch/generic/bits/vt.h"
-    "musl/arch/generic/bits/ptrace.h"
-    "musl/arch/generic/bits/io.h"
-    "musl/arch/generic/bits/resource.h"
-    "musl/arch/generic/bits/link.h"
-    "musl/arch/generic/bits/shm.h"
-    "musl/arch/generic/bits/hwcap.h"
-    "musl/arch/generic/bits/poll.h"
-    "musl/arch/generic/bits/ioctl.h"
-    "musl/arch/generic/bits/fcntl.h"
-    "musl/arch/generic/bits/ioctl_fix.h"
-    "musl/arch/generic/bits/sem.h"
-    "musl/arch/generic/bits/socket.h"
-    "musl/arch/generic/bits/statfs.h"
-    "musl/arch/generic/bits/soundcard.h"
-    "musl/arch/powerpc64/pthread_arch.h"
-    "musl/arch/powerpc64/crt_arch.h"
-    "musl/arch/powerpc64/reloc.h"
-    "musl/arch/powerpc64/syscall_arch.h"
-    "musl/arch/powerpc64/atomic_arch.h"
-    "musl/arch/powerpc64/bits/float.h"
-    "musl/arch/powerpc64/bits/errno.h"
-    "musl/arch/powerpc64/bits/mman.h"
-    "musl/arch/powerpc64/bits/stdint.h"
-    "musl/arch/powerpc64/bits/termios.h"
-    "musl/arch/powerpc64/bits/reg.h"
-    "musl/arch/powerpc64/bits/ipc.h"
-    "musl/arch/powerpc64/bits/fenv.h"
-    "musl/arch/powerpc64/bits/msg.h"
-    "musl/arch/powerpc64/bits/ptrace.h"
-    "musl/arch/powerpc64/bits/posix.h"
-    "musl/arch/powerpc64/bits/setjmp.h"
-    "musl/arch/powerpc64/bits/alltypes.h.in"
-    "musl/arch/powerpc64/bits/syscall.h.in"
-    "musl/arch/powerpc64/bits/shm.h"
-    "musl/arch/powerpc64/bits/hwcap.h"
-    "musl/arch/powerpc64/bits/endian.h"
-    "musl/arch/powerpc64/bits/limits.h"
-    "musl/arch/powerpc64/bits/ioctl.h"
-    "musl/arch/powerpc64/bits/fcntl.h"
-    "musl/arch/powerpc64/bits/signal.h"
-    "musl/arch/powerpc64/bits/stat.h"
-    "musl/arch/powerpc64/bits/user.h"
-    "musl/arch/powerpc64/bits/sem.h"
-    "musl/arch/powerpc64/bits/socket.h"
-    "musl/arch/arm/pthread_arch.h"
-    "musl/arch/arm/crt_arch.h"
-    "musl/arch/arm/reloc.h"
-    "musl/arch/arm/syscall_arch.h"
-    "musl/arch/arm/atomic_arch.h"
-    "musl/arch/arm/bits/float.h"
-    "musl/arch/arm/bits/stdint.h"
-    "musl/arch/arm/bits/reg.h"
-    "musl/arch/arm/bits/fenv.h"
-    "musl/arch/arm/bits/ptrace.h"
-    "musl/arch/arm/bits/posix.h"
-    "musl/arch/arm/bits/setjmp.h"
-    "musl/arch/arm/bits/alltypes.h.in"
-    "musl/arch/arm/bits/syscall.h.in"
-    "musl/arch/arm/bits/hwcap.h"
-    "musl/arch/arm/bits/endian.h"
-    "musl/arch/arm/bits/limits.h"
-    "musl/arch/arm/bits/fcntl.h"
-    "musl/arch/arm/bits/signal.h"
-    "musl/arch/arm/bits/stat.h"
-    "musl/arch/arm/bits/user.h"
-    "musl/arch/arm/bits/ioctl_fix.h"
-    "musl/arch/s390x/pthread_arch.h"
-    "musl/arch/s390x/crt_arch.h"
-    "musl/arch/s390x/reloc.h"
-    "musl/arch/s390x/syscall_arch.h"
+    "musl/arch/mips64/bits/stdint.h"
+    "musl/arch/mips64/bits/syscall.h.in"
+    "musl/arch/mips64/bits/termios.h"
+    "musl/arch/mips64/bits/user.h"
+    "musl/arch/mips64/crt_arch.h"
+    "musl/arch/mips64/ksigaction.h"
+    "musl/arch/mips64/pthread_arch.h"
+    "musl/arch/mips64/reloc.h"
+    "musl/arch/mips64/syscall_arch.h"
+    "musl/arch/powerpc/atomic_arch.h"
+    "musl/arch/powerpc/bits/alltypes.h.in"
+    "musl/arch/powerpc/bits/endian.h"
+    "musl/arch/powerpc/bits/errno.h"
+    "musl/arch/powerpc/bits/fcntl.h"
+    "musl/arch/powerpc/bits/fenv.h"
+    "musl/arch/powerpc/bits/float.h"
+    "musl/arch/powerpc/bits/hwcap.h"
+    "musl/arch/powerpc/bits/ioctl.h"
+    "musl/arch/powerpc/bits/ipc.h"
+    "musl/arch/powerpc/bits/limits.h"
+    "musl/arch/powerpc/bits/mman.h"
+    "musl/arch/powerpc/bits/msg.h"
+    "musl/arch/powerpc/bits/posix.h"
+    "musl/arch/powerpc/bits/ptrace.h"
+    "musl/arch/powerpc/bits/reg.h"
+    "musl/arch/powerpc/bits/sem.h"
+    "musl/arch/powerpc/bits/setjmp.h"
+    "musl/arch/powerpc/bits/shm.h"
+    "musl/arch/powerpc/bits/signal.h"
+    "musl/arch/powerpc/bits/socket.h"
+    "musl/arch/powerpc/bits/stat.h"
+    "musl/arch/powerpc/bits/stdint.h"
+    "musl/arch/powerpc/bits/syscall.h.in"
+    "musl/arch/powerpc/bits/termios.h"
+    "musl/arch/powerpc/bits/user.h"
+    "musl/arch/powerpc/crt_arch.h"
+    "musl/arch/powerpc/pthread_arch.h"
+    "musl/arch/powerpc/reloc.h"
+    "musl/arch/powerpc/syscall_arch.h"
+    "musl/arch/powerpc64/atomic_arch.h"
+    "musl/arch/powerpc64/bits/alltypes.h.in"
+    "musl/arch/powerpc64/bits/endian.h"
+    "musl/arch/powerpc64/bits/errno.h"
+    "musl/arch/powerpc64/bits/fcntl.h"
+    "musl/arch/powerpc64/bits/fenv.h"
+    "musl/arch/powerpc64/bits/float.h"
+    "musl/arch/powerpc64/bits/hwcap.h"
+    "musl/arch/powerpc64/bits/ioctl.h"
+    "musl/arch/powerpc64/bits/ipc.h"
+    "musl/arch/powerpc64/bits/limits.h"
+    "musl/arch/powerpc64/bits/mman.h"
+    "musl/arch/powerpc64/bits/msg.h"
+    "musl/arch/powerpc64/bits/posix.h"
+    "musl/arch/powerpc64/bits/ptrace.h"
+    "musl/arch/powerpc64/bits/reg.h"
+    "musl/arch/powerpc64/bits/sem.h"
+    "musl/arch/powerpc64/bits/setjmp.h"
+    "musl/arch/powerpc64/bits/shm.h"
+    "musl/arch/powerpc64/bits/signal.h"
+    "musl/arch/powerpc64/bits/socket.h"
+    "musl/arch/powerpc64/bits/stat.h"
+    "musl/arch/powerpc64/bits/stdint.h"
+    "musl/arch/powerpc64/bits/syscall.h.in"
+    "musl/arch/powerpc64/bits/termios.h"
+    "musl/arch/powerpc64/bits/user.h"
+    "musl/arch/powerpc64/crt_arch.h"
+    "musl/arch/powerpc64/pthread_arch.h"
+    "musl/arch/powerpc64/reloc.h"
+    "musl/arch/powerpc64/syscall_arch.h"
     "musl/arch/s390x/atomic_arch.h"
+    "musl/arch/s390x/bits/alltypes.h.in"
+    "musl/arch/s390x/bits/endian.h"
+    "musl/arch/s390x/bits/fcntl.h"
+    "musl/arch/s390x/bits/fenv.h"
     "musl/arch/s390x/bits/float.h"
-    "musl/arch/s390x/bits/stdint.h"
-    "musl/arch/s390x/bits/reg.h"
+    "musl/arch/s390x/bits/hwcap.h"
+    "musl/arch/s390x/bits/ioctl_fix.h"
     "musl/arch/s390x/bits/ipc.h"
-    "musl/arch/s390x/bits/fenv.h"
-    "musl/arch/s390x/bits/msg.h"
-    "musl/arch/s390x/bits/ptrace.h"
+    "musl/arch/s390x/bits/limits.h"
     "musl/arch/s390x/bits/link.h"
+    "musl/arch/s390x/bits/msg.h"
     "musl/arch/s390x/bits/posix.h"
+    "musl/arch/s390x/bits/ptrace.h"
+    "musl/arch/s390x/bits/reg.h"
+    "musl/arch/s390x/bits/sem.h"
     "musl/arch/s390x/bits/setjmp.h"
-    "musl/arch/s390x/bits/alltypes.h.in"
-    "musl/arch/s390x/bits/syscall.h.in"
     "musl/arch/s390x/bits/shm.h"
-    "musl/arch/s390x/bits/hwcap.h"
-    "musl/arch/s390x/bits/endian.h"
-    "musl/arch/s390x/bits/limits.h"
-    "musl/arch/s390x/bits/fcntl.h"
     "musl/arch/s390x/bits/signal.h"
-    "musl/arch/s390x/bits/stat.h"
-    "musl/arch/s390x/bits/user.h"
-    "musl/arch/s390x/bits/ioctl_fix.h"
-    "musl/arch/s390x/bits/sem.h"
     "musl/arch/s390x/bits/socket.h"
+    "musl/arch/s390x/bits/stat.h"
     "musl/arch/s390x/bits/statfs.h"
-    "musl/arch/mips/pthread_arch.h"
-    "musl/arch/mips/crt_arch.h"
-    "musl/arch/mips/ksigaction.h"
-    "musl/arch/mips/reloc.h"
-    "musl/arch/mips/syscall_arch.h"
-    "musl/arch/mips/atomic_arch.h"
-    "musl/arch/mips/bits/float.h"
-    "musl/arch/mips/bits/errno.h"
-    "musl/arch/mips/bits/mman.h"
-    "musl/arch/mips/bits/stdint.h"
-    "musl/arch/mips/bits/termios.h"
-    "musl/arch/mips/bits/reg.h"
-    "musl/arch/mips/bits/fenv.h"
-    "musl/arch/mips/bits/msg.h"
-    "musl/arch/mips/bits/ptrace.h"
-    "musl/arch/mips/bits/resource.h"
-    "musl/arch/mips/bits/posix.h"
-    "musl/arch/mips/bits/setjmp.h"
-    "musl/arch/mips/bits/alltypes.h.in"
-    "musl/arch/mips/bits/syscall.h.in"
-    "musl/arch/mips/bits/shm.h"
-    "musl/arch/mips/bits/hwcap.h"
-    "musl/arch/mips/bits/endian.h"
-    "musl/arch/mips/bits/limits.h"
-    "musl/arch/mips/bits/poll.h"
-    "musl/arch/mips/bits/ioctl.h"
-    "musl/arch/mips/bits/fcntl.h"
-    "musl/arch/mips/bits/signal.h"
-    "musl/arch/mips/bits/stat.h"
-    "musl/arch/mips/bits/user.h"
-    "musl/arch/mips/bits/sem.h"
-    "musl/arch/mips/bits/socket.h"
-    "musl/arch/mips/bits/statfs.h"
-    "musl/arch/x86_64/pthread_arch.h"
-    "musl/arch/x86_64/crt_arch.h"
-    "musl/arch/x86_64/ksigaction.h"
-    "musl/arch/x86_64/reloc.h"
-    "musl/arch/x86_64/syscall_arch.h"
+    "musl/arch/s390x/bits/stdint.h"
+    "musl/arch/s390x/bits/syscall.h.in"
+    "musl/arch/s390x/bits/user.h"
+    "musl/arch/s390x/crt_arch.h"
+    "musl/arch/s390x/pthread_arch.h"
+    "musl/arch/s390x/reloc.h"
+    "musl/arch/s390x/syscall_arch.h"
     "musl/arch/x86_64/atomic_arch.h"
+    "musl/arch/x86_64/bits/alltypes.h.in"
+    "musl/arch/x86_64/bits/endian.h"
+    "musl/arch/x86_64/bits/fcntl.h"
+    "musl/arch/x86_64/bits/fenv.h"
     "musl/arch/x86_64/bits/float.h"
-    "musl/arch/x86_64/bits/mman.h"
-    "musl/arch/x86_64/bits/stdint.h"
-    "musl/arch/x86_64/bits/reg.h"
+    "musl/arch/x86_64/bits/io.h"
     "musl/arch/x86_64/bits/ipc.h"
-    "musl/arch/x86_64/bits/fenv.h"
+    "musl/arch/x86_64/bits/limits.h"
+    "musl/arch/x86_64/bits/mman.h"
     "musl/arch/x86_64/bits/msg.h"
-    "musl/arch/x86_64/bits/ptrace.h"
-    "musl/arch/x86_64/bits/io.h"
     "musl/arch/x86_64/bits/posix.h"
+    "musl/arch/x86_64/bits/ptrace.h"
+    "musl/arch/x86_64/bits/reg.h"
     "musl/arch/x86_64/bits/setjmp.h"
-    "musl/arch/x86_64/bits/alltypes.h.in"
-    "musl/arch/x86_64/bits/syscall.h.in"
     "musl/arch/x86_64/bits/shm.h"
-    "musl/arch/x86_64/bits/endian.h"
-    "musl/arch/x86_64/bits/limits.h"
-    "musl/arch/x86_64/bits/fcntl.h"
     "musl/arch/x86_64/bits/signal.h"
+    "musl/arch/x86_64/bits/socket.h"
     "musl/arch/x86_64/bits/stat.h"
+    "musl/arch/x86_64/bits/stdint.h"
+    "musl/arch/x86_64/bits/syscall.h.in"
     "musl/arch/x86_64/bits/user.h"
-    "musl/arch/x86_64/bits/socket.h"
-    "musl/arch/i386/pthread_arch.h"
-    "musl/arch/i386/crt_arch.h"
-    "musl/arch/i386/reloc.h"
-    "musl/arch/i386/syscall_arch.h"
-    "musl/arch/i386/atomic_arch.h"
-    "musl/arch/i386/bits/float.h"
-    "musl/arch/i386/bits/mman.h"
-    "musl/arch/i386/bits/stdint.h"
-    "musl/arch/i386/bits/reg.h"
-    "musl/arch/i386/bits/fenv.h"
-    "musl/arch/i386/bits/ptrace.h"
-    "musl/arch/i386/bits/io.h"
-    "musl/arch/i386/bits/posix.h"
-    "musl/arch/i386/bits/setjmp.h"
-    "musl/arch/i386/bits/alltypes.h.in"
-    "musl/arch/i386/bits/syscall.h.in"
-    "musl/arch/i386/bits/endian.h"
-    "musl/arch/i386/bits/limits.h"
-    "musl/arch/i386/bits/signal.h"
-    "musl/arch/i386/bits/stat.h"
-    "musl/arch/i386/bits/user.h"
-    "musl/arch/aarch64/pthread_arch.h"
-    "musl/arch/aarch64/crt_arch.h"
-    "musl/arch/aarch64/reloc.h"
-    "musl/arch/aarch64/syscall_arch.h"
-    "musl/arch/aarch64/atomic_arch.h"
-    "musl/arch/aarch64/bits/float.h"
-    "musl/arch/aarch64/bits/stdint.h"
-    "musl/arch/aarch64/bits/reg.h"
-    "musl/arch/aarch64/bits/ipc.h"
-    "musl/arch/aarch64/bits/fenv.h"
-    "musl/arch/aarch64/bits/msg.h"
-    "musl/arch/aarch64/bits/posix.h"
-    "musl/arch/aarch64/bits/setjmp.h"
-    "musl/arch/aarch64/bits/alltypes.h.in"
-    "musl/arch/aarch64/bits/syscall.h.in"
-    "musl/arch/aarch64/bits/shm.h"
-    "musl/arch/aarch64/bits/hwcap.h"
-    "musl/arch/aarch64/bits/endian.h"
-    "musl/arch/aarch64/bits/limits.h"
-    "musl/arch/aarch64/bits/fcntl.h"
-    "musl/arch/aarch64/bits/signal.h"
-    "musl/arch/aarch64/bits/stat.h"
-    "musl/arch/aarch64/bits/user.h"
-    "musl/arch/aarch64/bits/sem.h"
-    "musl/arch/aarch64/bits/socket.h"
-    "musl/arch/powerpc/pthread_arch.h"
-    "musl/arch/powerpc/crt_arch.h"
-    "musl/arch/powerpc/reloc.h"
-    "musl/arch/powerpc/syscall_arch.h"
-    "musl/arch/powerpc/atomic_arch.h"
-    "musl/arch/powerpc/bits/float.h"
-    "musl/arch/powerpc/bits/errno.h"
-    "musl/arch/powerpc/bits/mman.h"
-    "musl/arch/powerpc/bits/stdint.h"
-    "musl/arch/powerpc/bits/termios.h"
-    "musl/arch/powerpc/bits/reg.h"
-    "musl/arch/powerpc/bits/ipc.h"
-    "musl/arch/powerpc/bits/fenv.h"
-    "musl/arch/powerpc/bits/msg.h"
-    "musl/arch/powerpc/bits/ptrace.h"
-    "musl/arch/powerpc/bits/posix.h"
-    "musl/arch/powerpc/bits/setjmp.h"
-    "musl/arch/powerpc/bits/alltypes.h.in"
-    "musl/arch/powerpc/bits/syscall.h.in"
-    "musl/arch/powerpc/bits/shm.h"
-    "musl/arch/powerpc/bits/hwcap.h"
-    "musl/arch/powerpc/bits/endian.h"
-    "musl/arch/powerpc/bits/limits.h"
-    "musl/arch/powerpc/bits/ioctl.h"
-    "musl/arch/powerpc/bits/fcntl.h"
-    "musl/arch/powerpc/bits/signal.h"
-    "musl/arch/powerpc/bits/stat.h"
-    "musl/arch/powerpc/bits/user.h"
-    "musl/arch/powerpc/bits/sem.h"
-    "musl/arch/powerpc/bits/socket.h"
+    "musl/arch/x86_64/crt_arch.h"
+    "musl/arch/x86_64/ksigaction.h"
+    "musl/arch/x86_64/pthread_arch.h"
+    "musl/arch/x86_64/reloc.h"
+    "musl/arch/x86_64/syscall_arch.h"
+    "musl/crt/Scrt1.c"
+    "musl/crt/aarch64/crti.s"
+    "musl/crt/aarch64/crtn.s"
+    "musl/crt/arm/crti.s"
+    "musl/crt/arm/crtn.s"
+    "musl/crt/crt1.c"
+    "musl/crt/crti.c"
+    "musl/crt/crtn.c"
+    "musl/crt/i386/crti.s"
+    "musl/crt/i386/crtn.s"
+    "musl/crt/microblaze/crti.s"
+    "musl/crt/microblaze/crtn.s"
+    "musl/crt/mips/crti.s"
+    "musl/crt/mips/crtn.s"
+    "musl/crt/mips64/crti.s"
+    "musl/crt/mips64/crtn.s"
+    "musl/crt/mipsn32/crti.s"
+    "musl/crt/mipsn32/crtn.s"
+    "musl/crt/or1k/crti.s"
+    "musl/crt/or1k/crtn.s"
+    "musl/crt/powerpc/crti.s"
+    "musl/crt/powerpc/crtn.s"
+    "musl/crt/powerpc64/crti.s"
+    "musl/crt/powerpc64/crtn.s"
+    "musl/crt/rcrt1.c"
+    "musl/crt/s390x/crti.s"
+    "musl/crt/s390x/crtn.s"
+    "musl/crt/sh/crti.s"
+    "musl/crt/sh/crtn.s"
+    "musl/crt/x32/crti.s"
+    "musl/crt/x32/crtn.s"
+    "musl/crt/x86_64/crti.s"
+    "musl/crt/x86_64/crtn.s"
+    ${ZIG_MUSL_SRC_FILES}
 )
 
 set(ZIG_LIBUNWIND_FILES
@@ -4836,10 +6636,13 @@ set(LIBC_FILES_DEST "${ZIG_LIB_DIR}/libc")
 set(LIBUNWIND_FILES_DEST "${ZIG_LIB_DIR}/libunwind")
 set(LIBCXX_FILES_DEST "${ZIG_LIB_DIR}/libcxx")
 set(ZIG_STD_DEST "${ZIG_LIB_DIR}/std")
-set(CONFIGURE_OUT_FILE "${CMAKE_BINARY_DIR}/config.h")
 configure_file (
     "${CMAKE_SOURCE_DIR}/src/config.h.in"
-    ${CONFIGURE_OUT_FILE}
+    "${CMAKE_BINARY_DIR}/config.h"
+)
+configure_file (
+    "${CMAKE_SOURCE_DIR}/src/install_files.h.in"
+    "${CMAKE_BINARY_DIR}/install_files.h"
 )
 
 include_directories(