瀏覽代碼

bus error on mips/mipsel is fixed now. thx to Rich Felker, added musl-git patch from today

Waldemar Brodkorb 12 年之前
父節點
當前提交
c59a74ce65
共有 1 個文件被更改,包括 8837 次插入0 次删除
  1. 8837 0
      toolchain/musl/patches/0.9.13/musl-git.patch

+ 8837 - 0
toolchain/musl/patches/0.9.13/musl-git.patch

@@ -0,0 +1,8837 @@
+diff -Nur musl-0.9.13/.gitignore musl-git/.gitignore
+--- musl-0.9.13/.gitignore	1970-01-01 01:00:00.000000000 +0100
++++ musl-git/.gitignore	2013-09-16 20:31:39.000000000 +0200
+@@ -0,0 +1,10 @@
++*.o
++*.lo
++*.a
++*.so
++*.so.1
++arch/*/bits/alltypes.h
++config.mak
++include/bits
++tools/musl-gcc
++lib/musl-gcc.specs
+diff -Nur musl-0.9.13/Makefile musl-git/Makefile
+--- musl-0.9.13/Makefile	2013-08-30 23:30:53.000000000 +0200
++++ musl-git/Makefile	2013-09-16 20:31:39.000000000 +0200
+@@ -157,7 +157,7 @@
+ 	$(INSTALL) -D -m 644 $< $@
+ 
+ $(DESTDIR)$(LDSO_PATHNAME): $(DESTDIR)$(libdir)/libc.so
+-	$(INSTALL) -D -l $< $@ || true
++	$(INSTALL) -D -l $(libdir)/libc.so $@ || true
+ 
+ install-libs: $(ALL_LIBS:lib/%=$(DESTDIR)$(libdir)/%) $(if $(SHARED_LIBS),$(DESTDIR)$(LDSO_PATHNAME),)
+ 
+diff -Nur musl-0.9.13/arch/microblaze/bits/limits.h musl-git/arch/microblaze/bits/limits.h
+--- musl-0.9.13/arch/microblaze/bits/limits.h	2013-08-30 23:30:53.000000000 +0200
++++ musl-git/arch/microblaze/bits/limits.h	2013-09-16 20:31:39.000000000 +0200
+@@ -1,6 +1,5 @@
+ #if defined(_POSIX_SOURCE) || defined(_POSIX_C_SOURCE) \
+  || defined(_XOPEN_SOURCE) || defined(_GNU_SOURCE) || defined(_BSD_SOURCE)
+-#define PAGE_SIZE 4096
+ #define LONG_BIT 32
+ #endif
+ 
+diff -Nur musl-0.9.13/arch/microblaze/reloc.h musl-git/arch/microblaze/reloc.h
+--- musl-0.9.13/arch/microblaze/reloc.h	2013-08-30 23:30:53.000000000 +0200
++++ musl-git/arch/microblaze/reloc.h	2013-09-16 20:31:39.000000000 +0200
+@@ -49,7 +49,7 @@
+ 	for (a+=c+1; *a; a++);
+ 	for (a++; *a; a+=2) if (*a<20) t[*a] = a[1];
+ 	base = (char *)t[AT_BASE];
+-	if (!base) base = (char *)(t[AT_PHDR] & -4096);
++	if (!base) base = (char *)(t[AT_PHDR] & -t[AT_PAGESZ]);
+ 	for (a=dynv; *a; a+=2) if (*a<20) t[*a] = a[1];
+ 	n = t[DT_RELASZ];
+ 	for (a=(void *)(base+t[DT_RELA]); n; a+=3, n-=12)
+diff -Nur musl-0.9.13/arch/mips/bits/limits.h musl-git/arch/mips/bits/limits.h
+--- musl-0.9.13/arch/mips/bits/limits.h	2013-08-30 23:30:53.000000000 +0200
++++ musl-git/arch/mips/bits/limits.h	2013-09-16 20:31:39.000000000 +0200
+@@ -1,6 +1,5 @@
+ #if defined(_POSIX_SOURCE) || defined(_POSIX_C_SOURCE) \
+  || defined(_XOPEN_SOURCE) || defined(_GNU_SOURCE) || defined(_BSD_SOURCE)
+-#define PAGE_SIZE 4096
+ #define LONG_BIT 32
+ #endif
+ 
+diff -Nur musl-0.9.13/arch/mips/bits/msg.h musl-git/arch/mips/bits/msg.h
+--- musl-0.9.13/arch/mips/bits/msg.h	2013-08-30 23:30:53.000000000 +0200
++++ musl-git/arch/mips/bits/msg.h	2013-09-16 20:31:39.000000000 +0200
+@@ -1,12 +1,21 @@
+ struct msqid_ds
+ {
+ 	struct ipc_perm msg_perm;
++#if _MIPSEL || __MIPSEL || __MIPSEL__
+ 	time_t msg_stime;
+ 	int __unused1;
+ 	time_t msg_rtime;
+ 	int __unused2;
+ 	time_t msg_ctime;
+ 	int __unused3;
++#else
++	int __unused1;
++	time_t msg_stime;
++	int __unused2;
++	time_t msg_rtime;
++	int __unused3;
++	time_t msg_ctime;
++#endif
+ 	unsigned long msg_cbytes;
+ 	msgqnum_t msg_qnum;
+ 	msglen_t msg_qbytes;
+diff -Nur musl-0.9.13/arch/mips/bits/shm.h musl-git/arch/mips/bits/shm.h
+--- musl-0.9.13/arch/mips/bits/shm.h	2013-08-30 23:30:53.000000000 +0200
++++ musl-git/arch/mips/bits/shm.h	2013-09-16 20:31:39.000000000 +0200
+@@ -5,11 +5,8 @@
+ 	struct ipc_perm shm_perm;
+ 	size_t shm_segsz;
+ 	time_t shm_atime;
+-	int __unused1;
+ 	time_t shm_dtime;
+-	int __unused2;
+ 	time_t shm_ctime;
+-	int __unused3;
+ 	pid_t shm_cpid;
+ 	pid_t shm_lpid;
+ 	unsigned long shm_nattch;
+diff -Nur musl-0.9.13/arch/mips/reloc.h musl-git/arch/mips/reloc.h
+--- musl-0.9.13/arch/mips/reloc.h	2013-08-30 23:30:53.000000000 +0200
++++ musl-git/arch/mips/reloc.h	2013-09-16 20:31:39.000000000 +0200
+@@ -51,7 +51,7 @@
+ 	for (a+=c+1; *a; a++);
+ 	for (a++; *a; a+=2) if (*a<20) t[*a] = a[1];
+ 	base = (char *)t[AT_BASE];
+-	if (!base) base = (char *)(t[AT_PHDR] & -4096);
++	if (!base) base = (char *)(t[AT_PHDR] & -t[AT_PAGESZ]);
+ 	for (a=dynv; *a; a+=2) if (*a-0x70000000UL<20) t[*a&31] = a[1];
+ 	n = t[DT_MIPS_LOCAL_GOTNO - 0x70000000];
+ 	for (a=got; n; a++, n--) *a += (size_t)base;
+diff -Nur musl-0.9.13/arch/powerpc/bits/limits.h musl-git/arch/powerpc/bits/limits.h
+--- musl-0.9.13/arch/powerpc/bits/limits.h	2013-08-30 23:30:53.000000000 +0200
++++ musl-git/arch/powerpc/bits/limits.h	2013-09-16 20:31:39.000000000 +0200
+@@ -1,6 +1,5 @@
+ #if defined(_POSIX_SOURCE) || defined(_POSIX_C_SOURCE) \
+  || defined(_XOPEN_SOURCE) || defined(_GNU_SOURCE) || defined(_BSD_SOURCE)
+-#define PAGE_SIZE 4096
+ #define LONG_BIT 32
+ #endif
+ 
+diff -Nur musl-0.9.13/arch/powerpc/reloc.h musl-git/arch/powerpc/reloc.h
+--- musl-0.9.13/arch/powerpc/reloc.h	2013-08-30 23:30:53.000000000 +0200
++++ musl-git/arch/powerpc/reloc.h	2013-09-16 20:31:39.000000000 +0200
+@@ -46,7 +46,7 @@
+ 	for (a+=c+1; *a; a++);
+ 	for (a++; *a; a+=2) if (*a<20) t[*a] = a[1];
+ 	base = (char *)t[AT_BASE];
+-	if (!base) base = (char *)(t[AT_PHDR] & -4096);
++	if (!base) base = (char *)(t[AT_PHDR] & -t[AT_PAGESZ]);
+ 	for (a=dynv; *a; a+=2) if (*a<20) t[*a] = a[1];
+ 	n = t[DT_RELASZ];
+ 	for (a=(void *)(base+t[DT_RELA]); n; a+=3, n-=12)
+diff -Nur musl-0.9.13/include/elf.h musl-git/include/elf.h
+--- musl-0.9.13/include/elf.h	2013-08-30 23:30:53.000000000 +0200
++++ musl-git/include/elf.h	2013-09-16 20:31:39.000000000 +0200
+@@ -105,6 +105,7 @@
+ #define ELFOSABI_HPUX		1
+ #define ELFOSABI_NETBSD		2
+ #define ELFOSABI_LINUX		3
++#define ELFOSABI_GNU		3
+ #define ELFOSABI_SOLARIS	6
+ #define ELFOSABI_AIX		7
+ #define ELFOSABI_IRIX		8
+@@ -211,7 +212,11 @@
+ #define EM_OPENRISC	92
+ #define EM_ARC_A5	93
+ #define EM_XTENSA	94
+-#define EM_NUM		95
++#define EM_AARCH64	183
++#define EM_TILEPRO	188
++#define EM_MICROBLAZE	189
++#define EM_TILEGX	191
++#define EM_NUM		192
+ #define EM_ALPHA	0x9026
+ 
+ #define EV_NONE		0
+@@ -487,6 +492,8 @@
+ #define PT_HIPROC	0x7fffffff
+ 
+ 
++#define PN_XNUM 0xffff
++
+ 
+ #define PF_X		(1 << 0)
+ #define PF_W		(1 << 1)
+@@ -512,12 +519,31 @@
+ #define NT_LWPSTATUS	16
+ #define NT_LWPSINFO	17
+ #define NT_PRFPXREG	20
++#define NT_SIGINFO	0x53494749
++#define NT_FILE		0x46494c45
+ #define NT_PRXFPREG	0x46e62b7f
+ #define NT_PPC_VMX	0x100
+ #define NT_PPC_SPE	0x101
+ #define NT_PPC_VSX	0x102
+ #define NT_386_TLS	0x200
+ #define NT_386_IOPERM	0x201
++#define NT_X86_XSTATE	0x202
++#define NT_S390_HIGH_GPRS	0x300
++#define NT_S390_TIMER	0x301
++#define NT_S390_TODCMP	0x302
++#define NT_S390_TODPREG	0x303
++#define NT_S390_CTRS	0x304
++#define NT_S390_PREFIX	0x305
++#define NT_S390_LAST_BREAK	0x306
++#define NT_S390_SYSTEM_CALL	0x307
++#define NT_S390_TDB	0x308
++#define NT_ARM_VFP	0x400
++#define NT_ARM_TLS	0x401
++#define NT_ARM_HW_BREAK	0x402
++#define NT_ARM_HW_WATCH	0x403
++#define NT_METAG_CBUF	0x500
++#define NT_METAG_RPIPE	0x501
++#define NT_METAG_TLS	0x502
+ #define NT_VERSION	1
+ 
+ 
+@@ -666,7 +692,15 @@
+ #define DF_1_ENDFILTEE	0x00004000
+ #define	DF_1_DISPRELDNE	0x00008000
+ #define	DF_1_DISPRELPND	0x00010000
+-
++#define	DF_1_NODIRECT	0x00020000
++#define	DF_1_IGNMULDEF	0x00040000
++#define	DF_1_NOKSYMS	0x00080000
++#define	DF_1_NOHDR	0x00100000
++#define	DF_1_EDITED	0x00200000
++#define	DF_1_NORELOC	0x00400000
++#define	DF_1_SYMINTPOSE	0x00800000
++#define	DF_1_GLOBAUDIT	0x01000000
++#define	DF_1_SINGLETON	0x02000000
+ 
+ #define DTF_1_PARINIT	0x00000001
+ #define DTF_1_CONFEXP	0x00000002
+@@ -832,6 +866,8 @@
+ 
+ #define AT_RANDOM	25
+ 
++#define AT_HWCAP2	26
++
+ #define AT_EXECFN	31
+ 
+ 
+@@ -979,6 +1015,7 @@
+ #define R_386_TLS_DTPMOD32 35
+ #define R_386_TLS_DTPOFF32 36
+ #define R_386_TLS_TPOFF32  37
++#define R_386_SIZE32       38
+ #define R_386_TLS_GOTDESC  39
+ #define R_386_TLS_DESC_CALL 40
+ #define R_386_TLS_DESC     41
+@@ -1109,20 +1146,6 @@
+ #define DT_SPARC_NUM	2
+ 
+ 
+-
+-#define HWCAP_SPARC_FLUSH	1
+-#define HWCAP_SPARC_STBAR	2
+-#define HWCAP_SPARC_SWAP	4
+-#define HWCAP_SPARC_MULDIV	8
+-#define HWCAP_SPARC_V9		16
+-#define HWCAP_SPARC_ULTRA3	32
+-#define HWCAP_SPARC_BLKINIT	64
+-#define HWCAP_SPARC_N2		128
+-
+-
+-
+-
+-
+ #define EF_MIPS_NOREORDER   1
+ #define EF_MIPS_PIC	    2
+ #define EF_MIPS_CPIC	    4
+@@ -1139,9 +1162,10 @@
+ #define EF_MIPS_ARCH_3	    0x20000000
+ #define EF_MIPS_ARCH_4	    0x30000000
+ #define EF_MIPS_ARCH_5	    0x40000000
+-#define EF_MIPS_ARCH_32	    0x60000000
+-#define EF_MIPS_ARCH_64	    0x70000000
+-
++#define EF_MIPS_ARCH_32     0x50000000
++#define EF_MIPS_ARCH_64     0x60000000
++#define EF_MIPS_ARCH_32R2   0x70000000
++#define EF_MIPS_ARCH_64R2   0x80000000
+ 
+ 
+ #define E_MIPS_ARCH_1	  0x00000000
+@@ -1149,8 +1173,8 @@
+ #define E_MIPS_ARCH_3	  0x20000000
+ #define E_MIPS_ARCH_4	  0x30000000
+ #define E_MIPS_ARCH_5	  0x40000000
+-#define E_MIPS_ARCH_32	  0x60000000
+-#define E_MIPS_ARCH_64	  0x70000000
++#define E_MIPS_ARCH_32	  0x50000000
++#define E_MIPS_ARCH_64	  0x60000000
+ 
+ 
+ 
+@@ -2020,7 +2044,8 @@
+ #define EF_ARM_VFP_FLOAT	0x400
+ #define EF_ARM_MAVERICK_FLOAT	0x800
+ 
+-
++#define EF_ARM_ABI_FLOAT_SOFT	0x200
++#define EF_ARM_ABI_FLOAT_HARD	0x400
+ 
+ 
+ #define EF_ARM_SYMSARESORTED	0x04
+@@ -2064,6 +2089,17 @@
+ #define SHT_ARM_ATTRIBUTES	(SHT_LOPROC + 3)
+ 
+ 
++#define R_AARCH64_NONE            0
++#define R_AARCH64_ABS64         257
++#define R_AARCH64_ABS32         258
++#define R_AARCH64_COPY         1024
++#define R_AARCH64_GLOB_DAT     1025
++#define R_AARCH64_JUMP_SLOT    1026
++#define R_AARCH64_RELATIVE     1027
++#define R_AARCH64_TLS_DTPMOD64 1028
++#define R_AARCH64_TLS_DTPREL64 1029
++#define R_AARCH64_TLS_TPREL64  1030
++#define R_AARCH64_TLSDESC      1031
+ 
+ 
+ #define R_ARM_NONE		0
+@@ -2079,7 +2115,7 @@
+ #define R_ARM_THM_PC22		10
+ #define R_ARM_THM_PC8		11
+ #define R_ARM_AMP_VCALL9	12
+-#define R_ARM_SWI24		13
++#define R_ARM_TLS_DESC		13
+ #define R_ARM_THM_SWI8		14
+ #define R_ARM_XPC25		15
+ #define R_ARM_THM_XPC22		16
+@@ -2094,12 +2130,78 @@
+ #define R_ARM_GOTPC		25
+ #define R_ARM_GOT32		26
+ #define R_ARM_PLT32		27
++#define R_ARM_CALL		28
++#define R_ARM_JUMP24		29
++#define R_ARM_THM_JUMP24	30
++#define R_ARM_BASE_ABS		31
+ #define R_ARM_ALU_PCREL_7_0	32
+ #define R_ARM_ALU_PCREL_15_8	33
+ #define R_ARM_ALU_PCREL_23_15	34
+ #define R_ARM_LDR_SBREL_11_0	35
+ #define R_ARM_ALU_SBREL_19_12	36
+ #define R_ARM_ALU_SBREL_27_20	37
++#define R_ARM_TARGET1		38
++#define R_ARM_SBREL31		39
++#define R_ARM_V4BX		40
++#define R_ARM_TARGET2		41
++#define R_ARM_PREL31		42
++#define R_ARM_MOVW_ABS_NC	43
++#define R_ARM_MOVT_ABS		44
++#define R_ARM_MOVW_PREL_NC	45
++#define R_ARM_MOVT_PREL		46
++#define R_ARM_THM_MOVW_ABS_NC	47
++#define R_ARM_THM_MOVT_ABS	48
++#define R_ARM_THM_MOVW_PREL_NC	49
++#define R_ARM_THM_MOVT_PREL	50
++#define R_ARM_THM_JUMP19	51
++#define R_ARM_THM_JUMP6		52
++#define R_ARM_THM_ALU_PREL_11_0	53
++#define R_ARM_THM_PC12		54
++#define R_ARM_ABS32_NOI		55
++#define R_ARM_REL32_NOI		56
++#define R_ARM_ALU_PC_G0_NC	57
++#define R_ARM_ALU_PC_G0		58
++#define R_ARM_ALU_PC_G1_NC	59
++#define R_ARM_ALU_PC_G1		60
++#define R_ARM_ALU_PC_G2		61
++#define R_ARM_LDR_PC_G1		62
++#define R_ARM_LDR_PC_G2		63
++#define R_ARM_LDRS_PC_G0	64
++#define R_ARM_LDRS_PC_G1	65
++#define R_ARM_LDRS_PC_G2	66
++#define R_ARM_LDC_PC_G0		67
++#define R_ARM_LDC_PC_G1		68
++#define R_ARM_LDC_PC_G2		69
++#define R_ARM_ALU_SB_G0_NC	70
++#define R_ARM_ALU_SB_G0		71
++#define R_ARM_ALU_SB_G1_NC	72
++#define R_ARM_ALU_SB_G1		73
++#define R_ARM_ALU_SB_G2		74
++#define R_ARM_LDR_SB_G0		75
++#define R_ARM_LDR_SB_G1		76
++#define R_ARM_LDR_SB_G2		77
++#define R_ARM_LDRS_SB_G0	78
++#define R_ARM_LDRS_SB_G1	79
++#define R_ARM_LDRS_SB_G2	80
++#define R_ARM_LDC_SB_G0		81
++#define R_ARM_LDC_SB_G1		82
++#define R_ARM_LDC_SB_G2		83
++#define R_ARM_MOVW_BREL_NC	84
++#define R_ARM_MOVT_BREL		85
++#define R_ARM_MOVW_BREL		86
++#define R_ARM_THM_MOVW_BREL_NC	87
++#define R_ARM_THM_MOVT_BREL	88
++#define R_ARM_THM_MOVW_BREL	89
++#define R_ARM_TLS_GOTDESC	90
++#define R_ARM_TLS_CALL		91
++#define R_ARM_TLS_DESCSEQ	92
++#define R_ARM_THM_TLS_CALL	93
++#define R_ARM_PLT32_ABS		94
++#define R_ARM_GOT_ABS		95
++#define R_ARM_GOT_PREL		96
++#define R_ARM_GOT_BREL12	97
++#define R_ARM_GOTOFF12		98
++#define R_ARM_GOTRELAX		99
+ #define R_ARM_GNU_VTENTRY	100
+ #define R_ARM_GNU_VTINHERIT	101
+ #define R_ARM_THM_PC11		102
+@@ -2113,7 +2215,15 @@
+ #define R_ARM_TLS_IE32		107
+ 
+ #define R_ARM_TLS_LE32		108
+-
++#define R_ARM_TLS_LDO12		109
++#define R_ARM_TLS_LE12		110
++#define R_ARM_TLS_IE12GP	111
++#define R_ARM_ME_TOO		128
++#define R_ARM_THM_TLS_DESCSEQ	129
++#define R_ARM_THM_TLS_DESCSEQ16	129
++#define R_ARM_THM_TLS_DESCSEQ32	130
++#define R_ARM_THM_GOT_BREL12	131
++#define R_ARM_IRELATIVE		160
+ #define R_ARM_RXPC25		249
+ #define R_ARM_RSBREL32		250
+ #define R_ARM_THM_RPC22		251
+@@ -2421,15 +2531,21 @@
+ #define R_X86_64_PC64		24
+ #define R_X86_64_GOTOFF64	25
+ #define R_X86_64_GOTPC32	26
+-
++#define R_X86_64_GOT64		27
++#define R_X86_64_GOTPCREL64	28
++#define R_X86_64_GOTPC64	29
++#define R_X86_64_GOTPLT64	30
++#define R_X86_64_PLTOFF64	31
++#define R_X86_64_SIZE32		32
++#define R_X86_64_SIZE64		33
+ 
+ #define R_X86_64_GOTPC32_TLSDESC 34
+ #define R_X86_64_TLSDESC_CALL   35
+ 
+ #define R_X86_64_TLSDESC        36
+ #define R_X86_64_IRELATIVE	37
+-
+-#define R_X86_64_NUM		38
++#define R_X86_64_RELATIVE64	38
++#define R_X86_64_NUM		39
+ 
+ 
+ 
+diff -Nur musl-0.9.13/include/limits.h musl-git/include/limits.h
+--- musl-0.9.13/include/limits.h	2013-08-30 23:30:53.000000000 +0200
++++ musl-git/include/limits.h	2013-09-16 20:31:39.000000000 +0200
+@@ -40,7 +40,9 @@
+  || defined(_XOPEN_SOURCE) || defined(_GNU_SOURCE) || defined(_BSD_SOURCE)
+ 
+ #define PIPE_BUF 4096
++#ifdef PAGE_SIZE
+ #define PAGESIZE PAGE_SIZE
++#endif
+ #define FILESIZEBITS 64
+ #define NAME_MAX 255
+ #define SYMLINK_MAX 255
+diff -Nur musl-0.9.13/include/net/if_arp.h musl-git/include/net/if_arp.h
+--- musl-0.9.13/include/net/if_arp.h	2013-08-30 23:30:53.000000000 +0200
++++ musl-git/include/net/if_arp.h	2013-09-16 20:31:39.000000000 +0200
+@@ -52,6 +52,7 @@
+ #define ARPHRD_ROSE	270
+ #define ARPHRD_X25	271
+ #define ARPHRD_HWX25	272
++#define ARPHRD_CAN	280
+ #define ARPHRD_PPP	512
+ #define ARPHRD_CISCO	513
+ #define ARPHRD_HDLC	ARPHRD_CISCO
+@@ -84,7 +85,12 @@
+ #define ARPHRD_IEEE80211_PRISM 802
+ #define ARPHRD_IEEE80211_RADIOTAP 803
+ #define ARPHRD_IEEE802154 804
+-#define ARPHRD_IEEE802154_PHY 805
++#define ARPHRD_IEEE802154_MONITOR 805
++#define ARPHRD_PHONET 820
++#define ARPHRD_PHONET_PIPE 821
++#define ARPHRD_CAIF 822
++#define ARPHRD_IP6GRE 823
++#define ARPHRD_NETLINK 824
+ 
+ #define ARPHRD_VOID	  0xFFFF
+ #define ARPHRD_NONE	  0xFFFE
+diff -Nur musl-0.9.13/include/netinet/in.h musl-git/include/netinet/in.h
+--- musl-0.9.13/include/netinet/in.h	2013-08-30 23:30:53.000000000 +0200
++++ musl-git/include/netinet/in.h	2013-09-16 20:31:39.000000000 +0200
+@@ -91,10 +91,12 @@
+ #define IPPROTO_NONE     59
+ #define IPPROTO_DSTOPTS  60
+ #define IPPROTO_MTP      92
++#define IPPROTO_BEETPH   94
+ #define IPPROTO_ENCAP    98
+ #define IPPROTO_PIM      103
+ #define IPPROTO_COMP     108
+ #define IPPROTO_SCTP     132
++#define IPPROTO_MH       135
+ #define IPPROTO_UDPLITE  136
+ #define IPPROTO_RAW      255
+ #define IPPROTO_MAX      256
+diff -Nur musl-0.9.13/include/sys/ptrace.h musl-git/include/sys/ptrace.h
+--- musl-0.9.13/include/sys/ptrace.h	2013-08-30 23:30:53.000000000 +0200
++++ musl-git/include/sys/ptrace.h	2013-09-16 20:31:39.000000000 +0200
+@@ -37,6 +37,8 @@
+ #define PTRACE_INTERRUPT 0x4207
+ #define PTRACE_LISTEN 0x4208
+ #define PTRACE_PEEKSIGINFO 0x4209
++#define PTRACE_GETSIGMASK 0x420a
++#define PTRACE_SETSIGMASK 0x420b
+ 
+ #define PT_READ_I PTRACE_PEEKTEXT
+ #define PT_READ_D PTRACE_PEEKDATA
+diff -Nur musl-0.9.13/include/sys/resource.h musl-git/include/sys/resource.h
+--- musl-0.9.13/include/sys/resource.h	2013-08-30 23:30:53.000000000 +0200
++++ musl-git/include/sys/resource.h	2013-09-16 20:31:39.000000000 +0200
+@@ -59,6 +59,9 @@
+ #define prlimit64 prlimit
+ #endif
+ 
++#define PRIO_MIN (-20)
++#define PRIO_MAX 20
++
+ #define PRIO_PROCESS 0
+ #define PRIO_PGRP    1
+ #define PRIO_USER    2
+diff -Nur musl-0.9.13/include/sys/socket.h musl-git/include/sys/socket.h
+--- musl-0.9.13/include/sys/socket.h	2013-08-30 23:30:53.000000000 +0200
++++ musl-git/include/sys/socket.h	2013-09-16 20:31:39.000000000 +0200
+@@ -199,6 +199,7 @@
+ #define SO_NOFCS                43
+ #define SO_LOCK_FILTER          44
+ #define SO_SELECT_ERR_QUEUE     45
++#define SO_BUSY_POLL            46
+ 
+ #ifndef SOL_SOCKET
+ #define SOL_SOCKET      1
+diff -Nur musl-0.9.13/include/wait.h musl-git/include/wait.h
+--- musl-0.9.13/include/wait.h	1970-01-01 01:00:00.000000000 +0100
++++ musl-git/include/wait.h	2013-09-16 20:31:39.000000000 +0200
+@@ -0,0 +1,2 @@
++#warning redirecting incorrect #include <wait.h> to <sys/wait.h>
++#include <sys/wait.h>
+diff -Nur musl-0.9.13/src/aio/aio_readwrite.c musl-git/src/aio/aio_readwrite.c
+--- musl-0.9.13/src/aio/aio_readwrite.c	2013-08-30 23:30:53.000000000 +0200
++++ musl-git/src/aio/aio_readwrite.c	2013-09-16 20:31:39.000000000 +0200
+@@ -2,8 +2,8 @@
+ #include <fcntl.h>
+ #include <errno.h>
+ #include <unistd.h>
+-#include <limits.h>
+ #include "pthread_impl.h"
++#include "libc.h"
+ 
+ static void dummy(void)
+ {
+diff -Nur musl-0.9.13/src/aio/lio_listio.c musl-git/src/aio/lio_listio.c
+--- musl-0.9.13/src/aio/lio_listio.c	2013-08-30 23:30:53.000000000 +0200
++++ musl-git/src/aio/lio_listio.c	2013-09-16 20:31:39.000000000 +0200
+@@ -1,9 +1,9 @@
+ #include <aio.h>
+ #include <errno.h>
+-#include <limits.h>
+ #include <unistd.h>
+ #include <string.h>
+ #include "pthread_impl.h"
++#include "libc.h"
+ 
+ struct lio_state {
+ 	struct sigevent *sev;
+diff -Nur musl-0.9.13/src/conf/fpathconf.c musl-git/src/conf/fpathconf.c
+--- musl-0.9.13/src/conf/fpathconf.c	2013-08-30 23:30:53.000000000 +0200
++++ musl-git/src/conf/fpathconf.c	2013-09-16 20:31:39.000000000 +0200
+@@ -19,11 +19,11 @@
+ 		[_PC_PRIO_IO] = -1,
+ 		[_PC_SOCK_MAXBUF] = -1,
+ 		[_PC_FILESIZEBITS] = FILESIZEBITS,
+-		[_PC_REC_INCR_XFER_SIZE] = PAGE_SIZE,
+-		[_PC_REC_MAX_XFER_SIZE] = PAGE_SIZE,
+-		[_PC_REC_MIN_XFER_SIZE] = PAGE_SIZE,
+-		[_PC_REC_XFER_ALIGN] = PAGE_SIZE,
+-		[_PC_ALLOC_SIZE_MIN] = PAGE_SIZE,
++		[_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] = SYMLINK_MAX,
+ 		[_PC_2_SYMLINKS] = 1
+ 	};
+diff -Nur musl-0.9.13/src/conf/sysconf.c musl-git/src/conf/sysconf.c
+--- musl-0.9.13/src/conf/sysconf.c	2013-08-30 23:30:53.000000000 +0200
++++ musl-git/src/conf/sysconf.c	2013-09-16 20:31:39.000000000 +0200
+@@ -3,6 +3,7 @@
+ #include <errno.h>
+ #include <sys/resource.h>
+ #include "syscall.h"
++#include "libc.h"
+ 
+ #define VER (-2)
+ #define OFLOW (-3)
+@@ -40,9 +41,9 @@
+ 		[_SC_AIO_PRIO_DELTA_MAX] = 0, /* ?? */
+ 		[_SC_DELAYTIMER_MAX] = _POSIX_DELAYTIMER_MAX,
+ 		[_SC_MQ_OPEN_MAX] = -1,
+-		[_SC_MQ_PRIO_MAX] = MQ_PRIO_MAX,
++		[_SC_MQ_PRIO_MAX] = OFLOW,
+ 		[_SC_VERSION] = VER,
+-		[_SC_PAGE_SIZE] = PAGE_SIZE,
++		[_SC_PAGE_SIZE] = OFLOW,
+ 		[_SC_RTSIG_MAX] = 63, /* ?? */
+ 		[_SC_SEM_NSEMS_MAX] = SEM_NSEMS_MAX,
+ 		[_SC_SEM_VALUE_MAX] = OFLOW,
+@@ -221,6 +222,9 @@
+ 	} else if (values[name] == OFLOW) {
+ 		if (name == _SC_ARG_MAX) return ARG_MAX;
+ 		if (name == _SC_SEM_VALUE_MAX) return SEM_VALUE_MAX;
++		if (name == _SC_MQ_PRIO_MAX) return MQ_PRIO_MAX;
++		/* name == _SC_PAGE_SIZE */
++		return PAGE_SIZE;
+ 	} else if (values[name] == CPUCNT) {
+ 		unsigned char set[128] = {1};
+ 		int i, cnt;
+diff -Nur musl-0.9.13/src/env/__libc_start_main.c musl-git/src/env/__libc_start_main.c
+--- musl-0.9.13/src/env/__libc_start_main.c	2013-08-30 23:30:53.000000000 +0200
++++ musl-git/src/env/__libc_start_main.c	2013-09-16 20:31:39.000000000 +0200
+@@ -26,6 +26,7 @@
+ 	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) {
+ 		__progname = __progname_full = pn;
+diff -Nur musl-0.9.13/src/internal/libc.h musl-git/src/internal/libc.h
+--- musl-0.9.13/src/internal/libc.h	2013-08-30 23:30:53.000000000 +0200
++++ musl-git/src/internal/libc.h	2013-09-16 20:31:39.000000000 +0200
+@@ -3,6 +3,7 @@
+ 
+ #include <stdlib.h>
+ #include <stdio.h>
++#include <limits.h>
+ 
+ struct __libc {
+ 	void *main_thread;
+@@ -14,10 +15,15 @@
+ 	FILE *ofl_head;
+ 	int ofl_lock[2];
+ 	size_t tls_size;
++	size_t page_size;
+ };
+ 
+ extern size_t __hwcap;
+ 
++#ifndef PAGE_SIZE
++#define PAGE_SIZE libc.page_size
++#endif
++
+ #if !defined(__PIC__) || (100*__GNUC__+__GNUC_MINOR__ >= 303 && !defined(__PCC__))
+ 
+ #ifdef __PIC__
+diff -Nur musl-0.9.13/src/internal/libm.h musl-git/src/internal/libm.h
+--- musl-0.9.13/src/internal/libm.h	2013-08-30 23:30:53.000000000 +0200
++++ musl-git/src/internal/libm.h	2013-09-16 20:31:39.000000000 +0200
+@@ -17,117 +17,115 @@
+ #include <float.h>
+ #include <math.h>
+ #include <complex.h>
++#include <endian.h>
+ 
+-#include "longdbl.h"
+-
+-#include "libc.h"
+-
+-union fshape {
+-	float value;
+-	uint32_t bits;
++#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;
+ };
+-
+-union dshape {
+-	double value;
+-	uint64_t bits;
++#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;
+ };
++#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);                          \
+-	}                                           \
++#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 dshape __u;                                             \
+-  __u.value = (d);                                              \
+-  (hi) = __u.bits >> 32;                                        \
+-  (lo) = (uint32_t)__u.bits;                                    \
+-} while (0)
+-
+-/* Get a 64 bit int from a double.  */
+-#define EXTRACT_WORD64(i,d)                                     \
+-do {                                                            \
+-  union dshape __u;                                             \
+-  __u.value = (d);                                              \
+-  (i) = __u.bits;                                               \
++#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(i,d)                                      \
+-do {                                                            \
+-  union dshape __u;                                             \
+-  __u.value = (d);                                              \
+-  (i) = __u.bits >> 32;                                         \
++#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(i,d)                                       \
+-do {                                                            \
+-  union dshape __u;                                             \
+-  __u.value = (d);                                              \
+-  (i) = (uint32_t)__u.bits;                                     \
++#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 dshape __u;                                             \
+-  __u.bits = ((uint64_t)(hi) << 32) | (uint32_t)(lo);           \
+-  (d) = __u.value;                                              \
+-} while (0)
+-
+-/* Set a double from a 64 bit int.  */
+-#define INSERT_WORD64(d,i)                                      \
+-do {                                                            \
+-  union dshape __u;                                             \
+-  __u.bits = (i);                                               \
+-  (d) = __u.value;                                              \
++#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 dshape __u;                                             \
+-  __u.value = (d);                                              \
+-  __u.bits &= 0xffffffff;                                       \
+-  __u.bits |= (uint64_t)(hi) << 32;                             \
+-  (d) = __u.value;                                              \
++#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 dshape __u;                                             \
+-  __u.value = (d);                                              \
+-  __u.bits &= 0xffffffff00000000ull;                            \
+-  __u.bits |= (uint32_t)(lo);                                   \
+-  (d) = __u.value;                                              \
++#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(i,d)                                     \
+-do {                                                            \
+-  union fshape __u;                                             \
+-  __u.value = (d);                                              \
+-  (i) = __u.bits;                                               \
++#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,i)                                     \
+-do {                                                            \
+-  union fshape __u;                                             \
+-  __u.bits = (i);                                               \
+-  (d) = __u.value;                                              \
++#define SET_FLOAT_WORD(d,w)                       \
++do {                                              \
++  union {float f; uint32_t i;} __u;               \
++  __u.i = (w);                                    \
++  (d) = __u.f;                                    \
+ } while (0)
+ 
+ /* fdlibm kernel functions */
+@@ -157,15 +155,4 @@
+ long double __polevll(long double, const long double *, int);
+ long double __p1evll(long double, const long double *, int);
+ 
+-#if 0
+-/* Attempt to get strict C99 semantics for assignment with non-C99 compilers. */
+-#define STRICT_ASSIGN(type, lval, rval) do {    \
+-        volatile type __v = (rval);             \
+-        (lval) = __v;                           \
+-} while (0)
+-#else
+-/* Should work with -fexcess-precision=standard (>=gcc-4.5) or -ffloat-store */
+-#define STRICT_ASSIGN(type, lval, rval) ((lval) = (type)(rval))
+-#endif
+-
+ #endif
+diff -Nur musl-0.9.13/src/internal/longdbl.h musl-git/src/internal/longdbl.h
+--- musl-0.9.13/src/internal/longdbl.h	2013-08-30 23:30:53.000000000 +0200
++++ musl-git/src/internal/longdbl.h	1970-01-01 01:00:00.000000000 +0100
+@@ -1,137 +0,0 @@
+-#ifndef _LDHACK_H
+-#define _LDHACK_H
+-
+-#include <float.h>
+-#include <stdint.h>
+-
+-#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024
+-#elif LDBL_MANT_DIG == 64 && LDBL_MAX_EXP == 16384
+-union ldshape {
+-	long double value;
+-	struct {
+-		uint64_t m;
+-		uint16_t exp:15;
+-		uint16_t sign:1;
+-		uint16_t pad;
+-	} bits;
+-};
+-#elif LDBL_MANT_DIG == 113 && LDBL_MAX_EXP == 16384
+-union ldshape {
+-	long double value;
+-	struct {
+-		uint64_t mlo;
+-		uint64_t mhi:48;
+-		uint16_t exp:15;
+-		uint16_t sign:1;
+-	} bits;
+-};
+-#else
+-#error Unsupported long double representation
+-#endif
+-
+-
+-// FIXME: hacks to make freebsd+openbsd long double code happy
+-
+-// union and macros for freebsd
+-
+-#if LDBL_MANT_DIG == 64 && LDBL_MAX_EXP == 16384
+-
+-union IEEEl2bits {
+-	long double e;
+-	struct {
+-		uint32_t manl:32;
+-		uint32_t manh:32;
+-		uint32_t exp:15;
+-		uint32_t sign:1;
+-		uint32_t pad:16;
+-	} bits;
+-	struct {
+-		uint64_t man:64;
+-		uint32_t expsign:16;
+-		uint32_t pad:16;
+-	} xbits;
+-};
+-
+-#define LDBL_MANL_SIZE 32
+-#define LDBL_MANH_SIZE 32
+-#define LDBL_NBIT (1ull << LDBL_MANH_SIZE-1)
+-#undef LDBL_IMPLICIT_NBIT
+-#define mask_nbit_l(u) ((u).bits.manh &= ~LDBL_NBIT)
+-
+-#elif LDBL_MANT_DIG == 113 && LDBL_MAX_EXP == 16384
+-/*
+-// ld128 float.h
+-//#define LDBL_MAX 1.189731495357231765085759326628007016E+4932L
+-#define LDBL_MAX 0x1.ffffffffffffffffffffffffffffp+16383
+-#define LDBL_MAX_EXP 16384
+-#define LDBL_HAS_INFINITY 1
+-//#define LDBL_MIN 3.362103143112093506262677817321752603E-4932L
+-#define LDBL_MIN 0x1p-16382
+-#define LDBL_HAS_QUIET_NAN 1
+-#define LDBL_HAS_DENORM 1
+-//#define LDBL_EPSILON 1.925929944387235853055977942584927319E-34L
+-#define LDBL_EPSILON 0x1p-112
+-#define LDBL_MANT_DIG 113
+-#define LDBL_MIN_EXP (-16381)
+-#define LDBL_MAX_10_EXP 4932
+-#define LDBL_DENORM_MIN 0x0.0000000000000000000000000001p-16381
+-#define LDBL_MIN_10_EXP (-4931)
+-#define LDBL_DIG 33
+-*/
+-
+-union IEEEl2bits {
+-	long double e;
+-	struct {
+-		uint64_t manl:64;
+-		uint64_t manh:48;
+-		uint32_t exp:15;
+-		uint32_t sign:1;
+-	} bits;
+-	struct {
+-		uint64_t unused0:64;
+-		uint64_t unused1:48;
+-		uint32_t expsign:16;
+-	} xbits;
+-};
+-
+-#define LDBL_MANL_SIZE 64
+-#define LDBL_MANH_SIZE 48
+-#define LDBL_NBIT (1ull << LDBL_MANH_SIZE)
+-#define LDBL_IMPLICIT_NBIT 1
+-#define mask_nbit_l(u)
+-
+-#endif
+-
+-
+-// macros for openbsd
+-
+-#define GET_LDOUBLE_WORDS(se,mh,ml, f) do{ \
+-	union IEEEl2bits u; \
+-	u.e = (f); \
+-	(se) = u.xbits.expsign; \
+-	(mh) = u.bits.manh; \
+-	(ml) = u.bits.manl; \
+-}while(0)
+-
+-#define SET_LDOUBLE_WORDS(f,  se,mh,ml) do{ \
+-	union IEEEl2bits u; \
+-	u.xbits.expsign = (se); \
+-	u.bits.manh = (mh); \
+-	u.bits.manl = (ml); \
+-	(f) = u.e; \
+-}while(0)
+-
+-#define GET_LDOUBLE_EXP(se, f) do{ \
+-	union IEEEl2bits u; \
+-	u.e = (f); \
+-	(se) = u.xbits.expsign; \
+-}while(0)
+-
+-#define SET_LDOUBLE_EXP(f, se) do{ \
+-	union IEEEl2bits u; \
+-	u.e = (f); \
+-	u.xbits.expsign = (se); \
+-	(f) = u.e; \
+-}while(0)
+-
+-#endif
+diff -Nur musl-0.9.13/src/ldso/dynlink.c musl-git/src/ldso/dynlink.c
+--- musl-0.9.13/src/ldso/dynlink.c	2013-08-30 23:30:53.000000000 +0200
++++ musl-git/src/ldso/dynlink.c	2013-09-16 20:31:39.000000000 +0200
+@@ -614,6 +614,8 @@
+ 						sys_path = "";
+ 					}
+ 					fclose(f);
++				} else if (errno != ENOENT) {
++					sys_path = "";
+ 				}
+ 			}
+ 			if (!sys_path) sys_path = "/lib:/usr/local/lib:/usr/lib";
+@@ -978,6 +980,7 @@
+ 		env_preload = 0;
+ 		libc.secure = 1;
+ 	}
++	libc.page_size = aux[AT_PAGESZ];
+ 
+ 	/* If the dynamic linker was invoked as a program itself, AT_BASE
+ 	 * will not be set. In that case, we assume the base address is
+diff -Nur musl-0.9.13/src/legacy/getpagesize.c musl-git/src/legacy/getpagesize.c
+--- musl-0.9.13/src/legacy/getpagesize.c	2013-08-30 23:30:53.000000000 +0200
++++ musl-git/src/legacy/getpagesize.c	2013-09-16 20:31:39.000000000 +0200
+@@ -1,5 +1,5 @@
+ #include <unistd.h>
+-#include <limits.h>
++#include "libc.h"
+ 
+ int getpagesize(void)
+ {
+diff -Nur musl-0.9.13/src/legacy/valloc.c musl-git/src/legacy/valloc.c
+--- musl-0.9.13/src/legacy/valloc.c	2013-08-30 23:30:53.000000000 +0200
++++ musl-git/src/legacy/valloc.c	2013-09-16 20:31:39.000000000 +0200
+@@ -1,6 +1,6 @@
+ #define _BSD_SOURCE
+ #include <stdlib.h>
+-#include <limits.h>
++#include "libc.h"
+ 
+ void *valloc(size_t size)
+ {
+diff -Nur musl-0.9.13/src/math/__cosl.c musl-git/src/math/__cosl.c
+--- musl-0.9.13/src/math/__cosl.c	2013-08-30 23:30:53.000000000 +0200
++++ musl-git/src/math/__cosl.c	2013-09-16 20:31:39.000000000 +0200
+@@ -1,4 +1,5 @@
+ /* 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.
+@@ -14,7 +15,8 @@
+ 
+ #include "libm.h"
+ 
+-#if LDBL_MANT_DIG == 64 && LDBL_MAX_EXP == 16384
++#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.
+  */
+@@ -43,7 +45,6 @@
+  */
+ 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 */
+@@ -51,13 +52,43 @@
+ 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  = z*(C1+z*(C2+z*(C3+z*(C4+z*(C5+z*(C6+z*C7))))));
++	r  = POLY(z);
+ 	hz = 0.5*z;
+ 	w  = 1.0-hz;
+ 	return w + (((1.0-w)-hz) + (z*r-x*y));
+diff -Nur musl-0.9.13/src/math/__fpclassify.c musl-git/src/math/__fpclassify.c
+--- musl-0.9.13/src/math/__fpclassify.c	2013-08-30 23:30:53.000000000 +0200
++++ musl-git/src/math/__fpclassify.c	2013-09-16 20:31:39.000000000 +0200
+@@ -1,10 +1,11 @@
+-#include "libm.h"
++#include <math.h>
++#include <stdint.h>
+ 
+ int __fpclassify(double x)
+ {
+-	union dshape u = { x };
+-	int e = u.bits>>52 & 0x7ff;
+-	if (!e) return u.bits<<1 ? FP_SUBNORMAL : FP_ZERO;
+-	if (e==0x7ff) return u.bits<<12 ? FP_NAN : FP_INFINITE;
++	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;
+ }
+diff -Nur musl-0.9.13/src/math/__fpclassifyf.c musl-git/src/math/__fpclassifyf.c
+--- musl-0.9.13/src/math/__fpclassifyf.c	2013-08-30 23:30:53.000000000 +0200
++++ musl-git/src/math/__fpclassifyf.c	2013-09-16 20:31:39.000000000 +0200
+@@ -1,10 +1,11 @@
+-#include "libm.h"
++#include <math.h>
++#include <stdint.h>
+ 
+ int __fpclassifyf(float x)
+ {
+-	union fshape u = { x };
+-	int e = u.bits>>23 & 0xff;
+-	if (!e) return u.bits<<1 ? FP_SUBNORMAL : FP_ZERO;
+-	if (e==0xff) return u.bits<<9 ? FP_NAN : FP_INFINITE;
++	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;
+ }
+diff -Nur musl-0.9.13/src/math/__fpclassifyl.c musl-git/src/math/__fpclassifyl.c
+--- musl-0.9.13/src/math/__fpclassifyl.c	2013-08-30 23:30:53.000000000 +0200
++++ musl-git/src/math/__fpclassifyl.c	2013-09-16 20:31:39.000000000 +0200
+@@ -5,26 +5,28 @@
+ #elif LDBL_MANT_DIG == 64 && LDBL_MAX_EXP == 16384
+ int __fpclassifyl(long double x)
+ {
+-	union ldshape u = { x };
+-	int e = u.bits.exp;
+-	if (!e) {
+-		if (u.bits.m >> 63) return FP_NAN;
+-		else if (u.bits.m) return FP_SUBNORMAL;
+-		else return FP_ZERO;
+-	}
++	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 (!msb)
++		return FP_NAN;
+ 	if (e == 0x7fff)
+-		return u.bits.m & (uint64_t)-1>>1 ? FP_NAN : FP_INFINITE;
+-	return u.bits.m & (uint64_t)1<<63 ? FP_NORMAL : FP_NAN;
++		return u.i.m << 1 ? FP_NAN : FP_INFINITE;
++	return FP_NORMAL;
+ }
+ #elif LDBL_MANT_DIG == 113 && LDBL_MAX_EXP == 16384
+ int __fpclassifyl(long double x)
+ {
+-	union ldshape u = { x };
+-	int e = u.bits.exp;
++	union ldshape u = {x};
++	int e = u.i.se & 0x7fff;
+ 	if (!e)
+-		return u.bits.mlo | u.bits.mhi ? FP_SUBNORMAL : FP_ZERO;
+-	if (e == 0x7fff)
+-		return u.bits.mlo | u.bits.mhi ? FP_NAN : FP_INFINITE;
++		return u.i2.lo | u.i2.hi ? FP_SUBNORMAL : FP_ZERO;
++	if (e == 0x7fff) {
++		u.i.se = 0;
++		return u.i2.lo | u.i2.hi ? FP_NAN : FP_INFINITE;
++	}
+ 	return FP_NORMAL;
+ }
+ #endif
+diff -Nur musl-0.9.13/src/math/__invtrigl.c musl-git/src/math/__invtrigl.c
+--- musl-0.9.13/src/math/__invtrigl.c	2013-08-30 23:30:53.000000000 +0200
++++ musl-git/src/math/__invtrigl.c	2013-09-16 20:31:39.000000000 +0200
+@@ -1,7 +1,7 @@
++#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,
+@@ -28,4 +28,36 @@
+ 	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*(pS6+z*(pS7+z*(pS8+z*pS9))))))));
++	return p/q;
++}
+ #endif
+diff -Nur musl-0.9.13/src/math/__invtrigl.h musl-git/src/math/__invtrigl.h
+--- musl-0.9.13/src/math/__invtrigl.h	2013-08-30 23:30:53.000000000 +0200
++++ musl-git/src/math/__invtrigl.h	2013-09-16 20:31:39.000000000 +0200
+@@ -1,10 +1,6 @@
+-#include <float.h>
+-
+-#if LDBL_MANT_DIG == 64 && LDBL_MAX_EXP == 16384
+ /* shared by acosl, asinl and atan2l */
+ #define pio2_hi __pio2_hi
+ #define pio2_lo __pio2_lo
+ extern const long double pio2_hi, pio2_lo;
+ 
+ long double __invtrigl_R(long double z);
+-#endif
+diff -Nur musl-0.9.13/src/math/__rem_pio2.c musl-git/src/math/__rem_pio2.c
+--- musl-0.9.13/src/math/__rem_pio2.c	2013-08-30 23:30:53.000000000 +0200
++++ musl-git/src/math/__rem_pio2.c	2013-09-16 20:31:39.000000000 +0200
+@@ -112,7 +112,7 @@
+ 		uint32_t high;
+ medium:
+ 		/* Use a specialized rint() to get fn.  Assume round-to-nearest. */
+-		STRICT_ASSIGN(double, fn, x*invpio2 + 0x1.8p52);
++		fn = x*invpio2 + 0x1.8p52;
+ 		fn = fn - 0x1.8p52;
+ // FIXME
+ #ifdef HAVE_EFFICIENT_IRINT
+diff -Nur musl-0.9.13/src/math/__rem_pio2_large.c musl-git/src/math/__rem_pio2_large.c
+--- musl-0.9.13/src/math/__rem_pio2_large.c	2013-08-30 23:30:53.000000000 +0200
++++ musl-git/src/math/__rem_pio2_large.c	2013-09-16 20:31:39.000000000 +0200
+@@ -415,7 +415,8 @@
+ 		fw = 0.0;
+ 		for (i=jz; i>=0; i--)
+ 			fw += fq[i];
+-		STRICT_ASSIGN(double,fw,fw);
++		// 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++)
+diff -Nur musl-0.9.13/src/math/__rem_pio2f.c musl-git/src/math/__rem_pio2f.c
+--- musl-0.9.13/src/math/__rem_pio2f.c	2013-08-30 23:30:53.000000000 +0200
++++ musl-git/src/math/__rem_pio2f.c	2013-09-16 20:31:39.000000000 +0200
+@@ -44,7 +44,7 @@
+ 	/* 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. */
+-		STRICT_ASSIGN(double, fn, x*invpio2 + 0x1.8p52);
++		fn = x*invpio2 + 0x1.8p52;
+ 		fn = fn - 0x1.8p52;
+ // FIXME
+ #ifdef HAVE_EFFICIENT_IRINT
+diff -Nur musl-0.9.13/src/math/__rem_pio2l.c musl-git/src/math/__rem_pio2l.c
+--- musl-0.9.13/src/math/__rem_pio2l.c	2013-08-30 23:30:53.000000000 +0200
++++ musl-git/src/math/__rem_pio2l.c	2013-09-16 20:31:39.000000000 +0200
+@@ -13,15 +13,22 @@
+  * Optimized by Bruce D. Evans.
+  */
+ #include "libm.h"
+-#if LDBL_MANT_DIG == 64 && LDBL_MAX_EXP == 16384
+-/* ld80 version of __rem_pio2(x,y)
++#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
+  */
+ 
+-#define BIAS    (LDBL_MAX_EXP - 1)
+-
++#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 TOINT 0x1.8p63
++#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
+@@ -32,60 +39,61 @@
+  * pio2_3t:  pi/2 - (pio2_1+pio2_2+pio2_3)
+  */
+ static const double
+-two24  =  1.67772160000000000000e+07, /* 0x41700000, 0x00000000 */
+ 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 TOINT 0x1.8p112
++#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 IEEEl2bits u,u1;
++	union ldshape u,uz;
+ 	long double z,w,t,r,fn;
+-	double tx[3],ty[2];
+-	int e0,ex,i,j,nx,n;
+-	int16_t expsign;
+-
+-	u.e = x;
+-	expsign = u.xbits.expsign;
+-	ex = expsign & 0x7fff;
+-	if (ex < BIAS + 25 || (ex == BIAS + 25 && u.bits.manh < 0xc90fdaa2)) {
+-		union IEEEl2bits u2;
+-		int ex1;
++	double tx[NX],ty[NY];
++	int ex,ey,n,i;
+ 
+-		/* |x| ~< 2^25*(pi/2), medium size */
+-		/* Use a specialized rint() to get fn.  Assume round-to-nearest. */
+-		fn = x*invpio2 + 0x1.8p63;
+-		fn = fn - 0x1.8p63;
+-// FIXME
+-//#ifdef HAVE_EFFICIENT_IRINT
+-//		n = irint(fn);
+-//#else
+-		n = fn;
+-//#endif
++	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 bit */
+-		j = ex;
++		w = fn*pio2_1t;  /* 1st round good to 102/180 bits (ld80/ld128) */
+ 		y[0] = r-w;
+-		u2.e = y[0];
+-		ex1 = u2.xbits.expsign & 0x7fff;
+-		i = j-ex1;
+-		if (i > 22) {  /* 2nd iteration needed, good to 141 */
++		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;
+-			u2.e = y[0];
+-			ex1 = u2.xbits.expsign & 0x7fff;
+-			i = j-ex1;
+-			if (i > 61) {  /* 3rd iteration need, 180 bits acc */
+-				t = r; /* will cover all possible cases */
++			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);
+@@ -102,23 +110,26 @@
+ 		y[0] = y[1] = x - x;
+ 		return 0;
+ 	}
+-	/* set z = scalbn(|x|,ilogb(x)-23) */
+-	u1.e = x;
+-	e0 = ex - BIAS - 23;            /* e0 = ilogb(|x|)-23; */
+-	u1.xbits.expsign = ex - e0;
+-	z = u1.e;
+-	for (i=0; i<2; i++) {
++	/* 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])*two24;
++		z     = (z-tx[i])*0x1p24;
+ 	}
+-	tx[2] = z;
+-	nx = 3;
+-	while (tx[nx-1] == 0.0)
+-		nx--;     /* skip zero term */
+-	n = __rem_pio2_large(tx,ty,e0,nx,2);
+-	r = (long double)ty[0] + ty[1];
+-	w = ty[1] - (r - ty[0]);
+-	if (expsign < 0) {
++	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;
+diff -Nur musl-0.9.13/src/math/__signbitl.c musl-git/src/math/__signbitl.c
+--- musl-0.9.13/src/math/__signbitl.c	2013-08-30 23:30:53.000000000 +0200
++++ musl-git/src/math/__signbitl.c	2013-09-16 20:31:39.000000000 +0200
+@@ -1,11 +1,9 @@
+ #include "libm.h"
+ 
+-// FIXME: should be a macro
+ #if (LDBL_MANT_DIG == 64 || LDBL_MANT_DIG == 113) && LDBL_MAX_EXP == 16384
+ int __signbitl(long double x)
+ {
+ 	union ldshape u = {x};
+-
+-	return u.bits.sign;
++	return u.i.se >> 15;
+ }
+ #endif
+diff -Nur musl-0.9.13/src/math/__sinl.c musl-git/src/math/__sinl.c
+--- musl-0.9.13/src/math/__sinl.c	2013-08-30 23:30:53.000000000 +0200
++++ musl-git/src/math/__sinl.c	2013-09-16 20:31:39.000000000 +0200
+@@ -1,4 +1,5 @@
+ /* 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.
+@@ -13,7 +14,8 @@
+ 
+ #include "libm.h"
+ 
+-#if LDBL_MANT_DIG == 64 && LDBL_MAX_EXP == 16384
++#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.
+  */
+@@ -23,10 +25,8 @@
+  *
+  * 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 */
+@@ -35,6 +35,34 @@
+ 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)
+ {
+@@ -42,7 +70,7 @@
+ 
+ 	z = x*x;
+ 	v = z*x;
+-	r = S2+z*(S3+z*(S4+z*(S5+z*(S6+z*(S7+z*S8)))));
++	r = POLY(z);
+ 	if (iy == 0)
+ 		return x+v*(S1+z*r);
+ 	return x-((z*(0.5*y-v*r)-y)-v*S1);
+diff -Nur musl-0.9.13/src/math/__tanl.c musl-git/src/math/__tanl.c
+--- musl-0.9.13/src/math/__tanl.c	2013-08-30 23:30:53.000000000 +0200
++++ musl-git/src/math/__tanl.c	2013-09-16 20:31:39.000000000 +0200
+@@ -1,4 +1,5 @@
+ /* 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.
+@@ -12,7 +13,8 @@
+ 
+ #include "libm.h"
+ 
+-#if LDBL_MANT_DIG == 64 && LDBL_MAX_EXP == 16384
++#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.
+  */
+@@ -22,14 +24,12 @@
+  *
+  * 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 */
+@@ -44,6 +44,59 @@
+ 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;
+@@ -62,10 +115,8 @@
+ 	}
+ 	z = x * x;
+ 	w = z * z;
+-	r = T5 + w * (T9 + w * (T13 + w * (T17 + w * (T21 +
+-	     w * (T25 + w * (T29 + w * T33))))));
+-	v = z * (T7 + w * (T11 + w * (T15 + w * (T19 + w * (T23 +
+-	     w * (T27 + w * T31))))));
++	r = RPOLY(w);
++	v = z * VPOLY(w);
+ 	s = z * x;
+ 	r = y + z * (s * (r + v) + y) + T3 * s;
+ 	w = x + r;
+@@ -76,7 +127,6 @@
+ 	}
+ 	if (!odd)
+ 		return w;
+-
+ 	/*
+ 	 * if allow error up to 2 ulp, simply return
+ 	 * -1.0 / (x+r) here
+diff -Nur musl-0.9.13/src/math/acoshf.c musl-git/src/math/acoshf.c
+--- musl-0.9.13/src/math/acoshf.c	2013-08-30 23:30:53.000000000 +0200
++++ musl-git/src/math/acoshf.c	2013-09-16 20:31:39.000000000 +0200
+@@ -3,14 +3,15 @@
+ /* acosh(x) = log(x + sqrt(x*x-1)) */
+ float acoshf(float x)
+ {
+-	union {float f; int32_t i;} u = {.f = x};
++	union {float f; uint32_t i;} u = {x};
++	uint32_t a = u.i & 0x7fffffff;
+ 
+-	if (u.i < 0x3f800000+(1<<23))
+-		/* x < 2, invalid if x < 1 or nan */
++	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 (u.i < 0x3f800000+(12<<23))
+-		/* x < 0x1p12 */
++	if (a < 0x3f800000+(12<<23))
++		/* |x| < 0x1p12 */
+ 		return logf(2*x - 1/(x+sqrtf(x*x-1)));
+ 	/* x >= 0x1p12 */
+ 	return logf(x) + 0.693147180559945309417232121458176568f;
+diff -Nur musl-0.9.13/src/math/acoshl.c musl-git/src/math/acoshl.c
+--- musl-0.9.13/src/math/acoshl.c	2013-08-30 23:30:53.000000000 +0200
++++ musl-git/src/math/acoshl.c	2013-09-16 20:31:39.000000000 +0200
+@@ -9,16 +9,14 @@
+ /* acosh(x) = log(x + sqrt(x*x-1)) */
+ long double acoshl(long double x)
+ {
+-	union {
+-		long double f;
+-		struct{uint64_t m; int16_t se; uint16_t pad;} i;
+-	} u = {.f = x};
++	union ldshape u = {x};
++	int e = u.i.se & 0x7fff;
+ 
+-	if (u.i.se < 0x3fff + 1)
+-		/* x < 2, invalid if x < 1 or nan */
++	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 (u.i.se < 0x3fff + 32)
+-		/* x < 0x1p32 */
++	if (e < 0x3fff + 32)
++		/* |x| < 0x1p32 */
+ 		return logl(2*x - 1/(x+sqrtl(x*x-1)));
+ 	return logl(x) + 0.693147180559945309417232121458176568L;
+ }
+diff -Nur musl-0.9.13/src/math/acosl.c musl-git/src/math/acosl.c
+--- musl-0.9.13/src/math/acosl.c	2013-08-30 23:30:53.000000000 +0200
++++ musl-git/src/math/acosl.c	2013-09-16 20:31:39.000000000 +0200
+@@ -23,46 +23,45 @@
+ }
+ #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 IEEEl2bits u;
+-	long double z, w, s, c, df;
+-	int16_t expsign, expt;
+-	u.e = x;
+-	expsign = u.xbits.expsign;
+-	expt = expsign & 0x7fff;
++	union ldshape u = {x};
++	long double z, s, c, f;
++	uint16_t e = u.i.se & 0x7fff;
++
+ 	/* |x| >= 1 or nan */
+-	if (expt >= 0x3fff) {
+-		if (expt == 0x3fff &&
+-			((u.bits.manh & ~LDBL_NBIT) | u.bits.manl) == 0) {
+-			if (expsign > 0)
+-				return 0;  /* acos(1) = 0 */
+-			return 2*pio2_hi + 0x1p-120f;  /* acos(-1)= pi */
+-		}
+-		return 0/(x-x);  /* acos(|x|>1) is 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 (expt < 0x3fff - 1) {
+-		if (expt < 0x3fff - 65)
+-			return pio2_hi + 0x1p-120f;  /* x < 0x1p-65: acosl(x)=pi/2 */
+-		return pio2_hi - (x - (pio2_lo - x * __invtrigl_R(x*x)));
++	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 (expsign < 0) {
+-		z = (1.0 + x) * 0.5;
++	if (u.i.se >> 15) {
++		z = (1 + x)*0.5;
+ 		s = sqrtl(z);
+-		w = __invtrigl_R(z) * s - pio2_lo;
+-		return 2*(pio2_hi - (s + w));
++		return 2*(pio2_hi - (__invtrigl_R(z)*s - pio2_lo + s));
+ 	}
+ 	/* x > 0.5 */
+-	z = (1.0 - x) * 0.5;
++	z = (1 - x)*0.5;
+ 	s = sqrtl(z);
+-	u.e = s;
+-	u.bits.manl = 0;
+-	df = u.e;
+-	c = (z - df * df) / (s + df);
+-	w = __invtrigl_R(z) * s + c;
+-	return 2*(df + w);
++	u.f = s;
++	CLEARBOTTOM(u);
++	f = u.f;
++	c = (z - f*f)/(s + f);
++	return 2*(__invtrigl_R(z)*s + c + f);
+ }
+ #endif
+diff -Nur musl-0.9.13/src/math/asinhl.c musl-git/src/math/asinhl.c
+--- musl-0.9.13/src/math/asinhl.c	2013-08-30 23:30:53.000000000 +0200
++++ musl-git/src/math/asinhl.c	2013-09-16 20:31:39.000000000 +0200
+@@ -9,10 +9,7 @@
+ /* asinh(x) = sign(x)*log(|x|+sqrt(x*x+1)) ~= x - x^3/6 + o(x^5) */
+ long double asinhl(long double x)
+ {
+-	union {
+-		long double f;
+-		struct{uint64_t m; uint16_t se; uint16_t pad;} i;
+-	} u = {.f = x};
++	union ldshape u = {x};
+ 	unsigned e = u.i.se & 0x7fff;
+ 	unsigned s = u.i.se >> 15;
+ 
+diff -Nur musl-0.9.13/src/math/asinl.c musl-git/src/math/asinl.c
+--- musl-0.9.13/src/math/asinl.c	2013-08-30 23:30:53.000000000 +0200
++++ musl-git/src/math/asinl.c	2013-09-16 20:31:39.000000000 +0200
+@@ -23,27 +23,29 @@
+ }
+ #elif (LDBL_MANT_DIG == 64 || LDBL_MANT_DIG == 113) && LDBL_MAX_EXP == 16384
+ #include "__invtrigl.h"
+-/* 0.95 */
+-#define THRESH  ((0xe666666666666666ULL>>(64-(LDBL_MANH_SIZE-1)))|LDBL_NBIT)
++#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 IEEEl2bits u;
+-	long double z,r,s;
+-	uint16_t expsign, expt;
++	union ldshape u = {x};
++	long double z, r, s;
++	uint16_t e = u.i.se & 0x7fff;
++	int sign = u.i.se >> 15;
+ 
+-	u.e = x;
+-	expsign = u.xbits.expsign;
+-	expt = expsign & 0x7fff;
+-	if (expt >= 0x3fff) {   /* |x| >= 1 or nan */
+-		if (expt == 0x3fff &&
+-		    ((u.bits.manh&~LDBL_NBIT)|u.bits.manl) == 0)
+-			/* asin(+-1)=+-pi/2 with inexact */
++	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 (expt < 0x3fff - 1) {  /* |x| < 0.5 */
+-		if (expt < 0x3fff - 32) {  /* |x|<0x1p-32, asinl(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;
+@@ -54,18 +56,16 @@
+ 	z = (1.0 - fabsl(x))*0.5;
+ 	s = sqrtl(z);
+ 	r = __invtrigl_R(z);
+-	if (u.bits.manh >= THRESH) { /* if |x| is close to 1 */
++	if (CLOSETO1(u)) {
+ 		x = pio2_hi - (2*(s+s*r)-pio2_lo);
+ 	} else {
+ 		long double f, c;
+-		u.e = s;
+-		u.bits.manl = 0;
+-		f = u.e;
+-		c = (z-f*f)/(s+f);
++		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));
+ 	}
+-	if (expsign>>15)
+-		return -x;
+-	return x;
++	return sign ? -x : x;
+ }
+ #endif
+diff -Nur musl-0.9.13/src/math/atan2l.c musl-git/src/math/atan2l.c
+--- musl-0.9.13/src/math/atan2l.c	2013-08-30 23:30:53.000000000 +0200
++++ musl-git/src/math/atan2l.c	2013-09-16 20:31:39.000000000 +0200
+@@ -27,56 +27,50 @@
+ 
+ long double atan2l(long double y, long double x)
+ {
+-	union IEEEl2bits ux, uy;
++	union ldshape ux, uy;
+ 	long double z;
+-	int m;
+-	uint16_t exptx, expsignx, expty, expsigny;
++	int m, ex, ey;
+ 
+ 	if (isnan(x) || isnan(y))
+ 		return x+y;
+ 	if (x == 1)
+ 		return atanl(y);
+-	uy.e = y;
+-	expsigny = uy.xbits.expsign;
+-	expty = expsigny & 0x7fff;
+-	ux.e = x;
+-	expsignx = ux.xbits.expsign;
+-	exptx = expsignx & 0x7fff;
+-	m = ((expsigny>>15)&1) | ((expsignx>>14)&2);  /* 2*sign(x)+sign(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+0x1p-120f; /* atan(+0,-anything) = pi */
+-		case 3: return -2*pio2_hi-0x1p-120f; /* atan(-0,-anything) =-pi */
++		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-0x1p-120f : pio2_hi+0x1p-120f;
+-	/* when x is INF */
+-	if (exptx == 0x7fff) {
+-		if (expty == 0x7fff) {
++		return m&1 ? -pio2_hi : pio2_hi;
++	if (ex == 0x7fff) {
++		if (ey == 0x7fff) {
+ 			switch(m) {
+-			case 0: return  pio2_hi*0.5+0x1p-120f; /* atan(+INF,+INF) */
+-			case 1: return -pio2_hi*0.5-0x1p-120f; /* atan(-INF,+INF) */
+-			case 2: return  1.5*pio2_hi+0x1p-120f; /* atan(+INF,-INF) */
+-			case 3: return -1.5*pio2_hi-0x1p-120f; /* atan(-INF,-INF) */
++			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+0x1p-120f; /* atan(+...,-INF) */
+-			case 3: return -2*pio2_hi-0x1p-120f; /* atan(-...,-INF) */
++			case 2: return  2*pio2_hi;  /* atan(+...,-INF) */
++			case 3: return -2*pio2_hi;  /* atan(-...,-INF) */
+ 			}
+ 		}
+ 	}
+-	/* when y is INF */
+-	if (exptx+120 < expty || expty == 0x7fff)
+-		return m&1 ? -pio2_hi-0x1p-120f : pio2_hi+0x1p-120f;
+-
+-	if ((m&2) && expty+120 < exptx) /* |y/x| tiny, x<0 */
++	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));
+diff -Nur musl-0.9.13/src/math/atanh.c musl-git/src/math/atanh.c
+--- musl-0.9.13/src/math/atanh.c	2013-08-30 23:30:53.000000000 +0200
++++ musl-git/src/math/atanh.c	2013-09-16 20:31:39.000000000 +0200
+@@ -6,16 +6,24 @@
+ 	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;
+-	x = u.f;
++	y = u.f;
+ 
+ 	if (e < 0x3ff - 1) {
+-		/* |x| < 0.5, up to 1.7ulp error */
+-		x = 0.5*log1p(2*x + 2*x*x/(1-x));
++		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 {
+-		x = 0.5*log1p(2*x/(1-x));
++		/* avoid overflow */
++		y = 0.5*log1p(2*(y/(1-y)));
+ 	}
+-	return s ? -x : x;
++	return s ? -y : y;
+ }
+diff -Nur musl-0.9.13/src/math/atanhf.c musl-git/src/math/atanhf.c
+--- musl-0.9.13/src/math/atanhf.c	2013-08-30 23:30:53.000000000 +0200
++++ musl-git/src/math/atanhf.c	2013-09-16 20:31:39.000000000 +0200
+@@ -5,16 +5,24 @@
+ {
+ 	union {float f; uint32_t i;} u = {.f = x};
+ 	unsigned s = u.i >> 31;
++	float_t y;
+ 
+ 	/* |x| */
+ 	u.i &= 0x7fffffff;
+-	x = u.f;
++	y = u.f;
+ 
+ 	if (u.i < 0x3f800000 - (1<<23)) {
+-		/* |x| < 0.5, up to 1.7ulp error */
+-		x = 0.5f*log1pf(2*x + 2*x*x/(1-x));
++		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 {
+-		x = 0.5f*log1pf(2*x/(1-x));
++		/* avoid overflow */
++		y = 0.5f*log1pf(2*(y/(1-y)));
+ 	}
+-	return s ? -x : x;
++	return s ? -y : y;
+ }
+diff -Nur musl-0.9.13/src/math/atanhl.c musl-git/src/math/atanhl.c
+--- musl-0.9.13/src/math/atanhl.c	2013-08-30 23:30:53.000000000 +0200
++++ musl-git/src/math/atanhl.c	2013-09-16 20:31:39.000000000 +0200
+@@ -9,10 +9,7 @@
+ /* 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 {
+-		long double f;
+-		struct{uint64_t m; uint16_t se; uint16_t pad;} i;
+-	} u = {.f = x};
++	union ldshape u = {x};
+ 	unsigned e = u.i.se & 0x7fff;
+ 	unsigned s = u.i.se >> 15;
+ 
+@@ -20,11 +17,18 @@
+ 	u.i.se = e;
+ 	x = u.f;
+ 
+-	if (e < 0x3fff - 1) {
+-		/* |x| < 0.5, up to 1.7ulp error */
+-		x = 0.5*log1pl(2*x + 2*x*x/(1-x));
++	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 {
+-		x = 0.5*log1pl(2*x/(1-x));
++		/* avoid overflow */
++		x = 0.5*log1pl(2*(x/(1-x)));
+ 	}
+ 	return s ? -x : x;
+ }
+diff -Nur musl-0.9.13/src/math/atanl.c musl-git/src/math/atanl.c
+--- musl-0.9.13/src/math/atanl.c	2013-08-30 23:30:53.000000000 +0200
++++ musl-git/src/math/atanl.c	2013-09-16 20:31:39.000000000 +0200
+@@ -23,6 +23,9 @@
+ }
+ #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,
+@@ -64,32 +67,85 @@
+ 	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 IEEEl2bits u;
+-	long double w,s1,s2,z;
++	union ldshape u = {x};
++	long double w, s1, s2, z;
+ 	int id;
+-	uint16_t expsign, expt;
+-	uint32_t expman;
++	unsigned e = u.i.se & 0x7fff;
++	unsigned sign = u.i.se >> 15;
++	unsigned expman;
+ 
+-	u.e = x;
+-	expsign = u.xbits.expsign;
+-	expt = expsign & 0x7fff;
+-	if (expt >= 0x3fff + 65) { /* if |x| is large, atan(x)~=pi/2 */
+-		if (expt == 0x7fff &&
+-		    ((u.bits.manh&~LDBL_NBIT)|u.bits.manl)!=0)  /* NaN */
+-			return x+x;
+-		z = atanhi[3] + 0x1p-120f;
+-		return expsign>>15 ? -z : z;
++	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. */
+-	/* XXX There should be a more convenient way to do this. */
+-	expman = (expt << 8) | ((u.bits.manh >> (LDBL_MANH_SIZE - 9)) & 0xff);
++	expman = EXPMAN(u);
+ 	if (expman < ((0x3fff - 2) << 8) + 0xc0) {  /* |x| < 0.4375 */
+-		if (expt < 0x3fff - 32) {   /* if |x| is small, atanl(x)~=x */
++		if (e < 0x3fff - (LDBL_MANT_DIG+1)/2) {   /* if |x| is small, atanl(x)~=x */
+ 			/* raise underflow if subnormal */
+-			if (expt == 0)
++			if (e == 0)
+ 				FORCE_EVAL((float)x);
+ 			return x;
+ 		}
+@@ -108,7 +164,7 @@
+ 			if (expman < ((0x3fff + 1) << 8) + 0x38) { /* |x| < 2.4375 */
+ 				id = 2;
+ 				x = (x-1.5)/(1.0+1.5*x);
+-			} else {                                 /* 2.4375 <= |x| < 2^ATAN_CONST */
++			} else {                                 /* 2.4375 <= |x| */
+ 				id = 3;
+ 				x = -1.0/x;
+ 			}
+@@ -123,6 +179,6 @@
+ 	if (id < 0)
+ 		return x - x*(s1+s2);
+ 	z = atanhi[id] - ((x*(s1+s2) - atanlo[id]) - x);
+-	return expsign>>15 ? -z : z;
++	return sign ? -z : z;
+ }
+ #endif
+diff -Nur musl-0.9.13/src/math/cbrt.c musl-git/src/math/cbrt.c
+--- musl-0.9.13/src/math/cbrt.c	2013-08-30 23:30:53.000000000 +0200
++++ musl-git/src/math/cbrt.c	2013-09-16 20:31:39.000000000 +0200
+@@ -15,7 +15,8 @@
+  * Return cube root of x
+  */
+ 
+-#include "libm.h"
++#include <math.h>
++#include <stdint.h>
+ 
+ static const uint32_t
+ B1 = 715094163, /* B1 = (1023-1023/3-0.03306235651)*2**20 */
+@@ -31,15 +32,10 @@
+ 
+ double cbrt(double x)
+ {
+-	int32_t hx;
+-	union dshape u;
+-	double r,s,t=0.0,w;
+-	uint32_t sign;
+-	uint32_t high,low;
+-
+-	EXTRACT_WORDS(hx, low, x);
+-	sign = hx & 0x80000000;
+-	hx ^= sign;
++	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;
+ 
+@@ -59,14 +55,16 @@
+ 	 * division rounds towards minus infinity; this is also efficient.
+ 	 */
+ 	if (hx < 0x00100000) { /* zero or subnormal? */
+-		if ((hx|low) == 0)
++		u.f = x*0x1p54;
++		hx = u.i>>32 & 0x7fffffff;
++		if (hx == 0)
+ 			return x;  /* cbrt(0) is itself */
+-		SET_HIGH_WORD(t, 0x43500000); /* set t = 2**54 */
+-		t *= x;
+-		GET_HIGH_WORD(high, t);
+-		INSERT_WORDS(t, sign|((high&0x7fffffff)/3+B2), 0);
++		hx = hx/3 + B2;
+ 	} else
+-		INSERT_WORDS(t, sign|(hx/3+B1), 0);
++		hx = hx/3 + B1;
++	u.i &= 1ULL<<63;
++	u.i |= (uint64_t)hx << 32;
++	t = u.f;
+ 
+ 	/*
+ 	 * New cbrt to 23 bits:
+@@ -76,7 +74,7 @@
+ 	 * 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 k_tanf.c.
++	 * 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));
+@@ -91,9 +89,9 @@
+ 	 * 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.value = t;
+-	u.bits = (u.bits + 0x80000000) & 0xffffffffc0000000ULL;
+-	t = u.value;
++	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 */
+diff -Nur musl-0.9.13/src/math/cbrtf.c musl-git/src/math/cbrtf.c
+--- musl-0.9.13/src/math/cbrtf.c	2013-08-30 23:30:53.000000000 +0200
++++ musl-git/src/math/cbrtf.c	2013-09-16 20:31:39.000000000 +0200
+@@ -17,7 +17,8 @@
+  * Return cube root of x
+  */
+ 
+-#include "libm.h"
++#include <math.h>
++#include <stdint.h>
+ 
+ static const unsigned
+ B1 = 709958130, /* B1 = (127-127.0/3-0.03306235651)*2**23 */
+@@ -25,15 +26,10 @@
+ 
+ float cbrtf(float x)
+ {
+-	double r,T;
+-	float t;
+-	int32_t hx;
+-	uint32_t sign;
+-	uint32_t high;
+-
+-	GET_FLOAT_WORD(hx, x);
+-	sign = hx & 0x80000000;
+-	hx ^= sign;
++	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;
+ 
+@@ -41,28 +37,29 @@
+ 	if (hx < 0x00800000) {  /* zero or subnormal? */
+ 		if (hx == 0)
+ 			return x;  /* cbrt(+-0) is itself */
+-		SET_FLOAT_WORD(t, 0x4b800000);  /* set t = 2**24 */
+-		t *= x;
+-		GET_FLOAT_WORD(high, t);
+-		SET_FLOAT_WORD(t, sign|((high&0x7fffffff)/3+B2));
++		u.f = x*0x1p24f;
++		hx = u.i & 0x7fffffff;
++		hx = hx/3 + B2;
+ 	} else
+-		SET_FLOAT_WORD(t, sign|(hx/3+B1));
++		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 = t;
++	T = u.f;
+ 	r = T*T*T;
+-	T = T*((double)x+x+r)/(x+r+r);
++	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)x+x+r)/(x+r+r);
++	T = T*((double_t)x+x+r)/(x+r+r);
+ 
+ 	/* rounding to 24 bits is perfect in round-to-nearest mode */
+ 	return T;
+diff -Nur musl-0.9.13/src/math/cbrtl.c musl-git/src/math/cbrtl.c
+--- musl-0.9.13/src/math/cbrtl.c	2013-08-30 23:30:53.000000000 +0200
++++ musl-git/src/math/cbrtl.c	2013-09-16 20:31:39.000000000 +0200
+@@ -23,58 +23,50 @@
+ 	return cbrt(x);
+ }
+ #elif (LDBL_MANT_DIG == 64 || LDBL_MANT_DIG == 113) && LDBL_MAX_EXP == 16384
+-
+-#define BIAS (LDBL_MAX_EXP - 1)
+ static const unsigned B1 = 709958130; /* B1 = (127-127.0/3-0.03306235651)*2**23 */
+ 
+ long double cbrtl(long double x)
+ {
+-	union IEEEl2bits u, v;
++	union ldshape u = {x}, v;
++	union {float f; uint32_t i;} uft;
+ 	long double r, s, t, w;
+-	double dr, dt, dx;
+-	float ft, fx;
+-	uint32_t hx;
+-	uint16_t expsign;
+-	int k;
+-
+-	u.e = x;
+-	expsign = u.xbits.expsign;
+-	k = expsign & 0x7fff;
++	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 (k == BIAS + LDBL_MAX_EXP)
++	if (e == 0x7fff)
+ 		return x + x;
+-
+-	if (k == 0) {
++	if (e == 0) {
++		/* Adjust subnormal numbers. */
++		u.f *= 0x1p120;
++		e = u.i.se & 0x7fff;
+ 		/* If x = +-0, then cbrt(x) = +-0. */
+-		if ((u.bits.manh | u.bits.manl) == 0)
++		if (e == 0)
+ 			return x;
+-		/* Adjust subnormal numbers. */
+-		u.e *= 0x1.0p514;
+-		k = u.bits.exp;
+-		k -= BIAS + 514;
+-	} else
+-		k -= BIAS;
+-	u.xbits.expsign = BIAS;
+-	v.e = 1;
+-
+-	x = u.e;
+-	switch (k % 3) {
++		e -= 120;
++	}
++	e -= 0x3fff;
++	u.i.se = 0x3fff;
++	x = u.f;
++	switch (e % 3) {
+ 	case 1:
+ 	case -2:
+-		x = 2*x;
+-		k--;
++		x *= 2;
++		e--;
+ 		break;
+ 	case 2:
+ 	case -1:
+-		x = 4*x;
+-		k -= 2;
++		x *= 4;
++		e -= 2;
+ 		break;
+ 	}
+-	v.xbits.expsign = (expsign & 0x8000) | (BIAS + k / 3);
++	v.f = 1.0;
++	v.i.se = sign | (0x3fff + e/3);
+ 
+ 	/*
+ 	 * The following is the guts of s_cbrtf, with the handling of
+@@ -83,9 +75,9 @@
+ 	 */
+ 
+ 	/* ~5-bit estimate: */
+-	fx = x;
+-	GET_FLOAT_WORD(hx, fx);
+-	SET_FLOAT_WORD(ft, ((hx & 0x7fffffff) / 3 + B1));
++	uft.f = x;
++	uft.i = (uft.i & 0x7fffffff)/3 + B1;
++	ft = uft.f;
+ 
+ 	/* ~16-bit estimate: */
+ 	dx = x;
+@@ -126,7 +118,7 @@
+ 	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.e;
++	t *= v.f;
+ 	return t;
+ }
+ #endif
+diff -Nur musl-0.9.13/src/math/ceil.c musl-git/src/math/ceil.c
+--- musl-0.9.13/src/math/ceil.c	2013-08-30 23:30:53.000000000 +0200
++++ musl-git/src/math/ceil.c	2013-09-16 20:31:39.000000000 +0200
+@@ -1,82 +1,24 @@
+-/* origin: FreeBSD /usr/src/lib/msun/src/s_ceil.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.
+- * ====================================================
+- */
+-/*
+- * ceil(x)
+- * Return x rounded toward -inf to integral value
+- * Method:
+- *      Bit twiddling.
+- * Exception:
+- *      Inexact flag raised if x not equal to ceil(x).
+- */
+-
+ #include "libm.h"
+ 
+-static const double huge = 1.0e300;
+-
+ double ceil(double x)
+ {
+-	int32_t i0,i1,j0;
+-	uint32_t i,j;
++	union {double f; uint64_t i;} u = {x};
++	int e = u.i >> 52 & 0x7ff;
++	double_t y;
+ 
+-	EXTRACT_WORDS(i0, i1, x);
+-	// FIXME signed shift
+-	j0 = ((i0>>20)&0x7ff) - 0x3ff;
+-	if (j0 < 20) {
+-		if (j0 < 0) {
+-			 /* raise inexact if x != 0 */
+-			if (huge+x > 0.0) {
+-				if (i0 < 0) {
+-					i0 = 0x80000000;
+-					i1=0;
+-				} else if ((i0|i1) != 0) {
+-					i0=0x3ff00000;
+-					i1=0;
+-				}
+-			}
+-		} else {
+-			i = 0x000fffff>>j0;
+-			if (((i0&i)|i1) == 0) /* x is integral */
+-				return x;
+-			/* raise inexact flag */
+-			if (huge+x > 0.0) {
+-				if (i0 > 0)
+-					i0 += 0x00100000>>j0;
+-				i0 &= ~i;
+-				i1 = 0;
+-			}
+-		}
+-	} else if (j0 > 51) {
+-		if (j0 == 0x400)  /* inf or NaN */
+-			return x+x;
+-		return x;         /* x is integral */
+-	} else {
+-		i = (uint32_t)0xffffffff>>(j0-20);
+-		if ((i1&i) == 0)
+-			return x; /* x is integral */
+-		/* raise inexact flag */
+-		if (huge+x > 0.0) {
+-			if (i0 > 0) {
+-				if (j0 == 20)
+-					i0 += 1;
+-				else {
+-					j = i1 + (1<<(52-j0));
+-					if (j < i1)  /* got a carry */
+-						i0 += 1;
+-					i1 = j;
+-				}
+-			}
+-			i1 &= ~i;
+-		}
++	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 = (double)(x - 0x1p52) + 0x1p52 - x;
++	else
++		y = (double)(x + 0x1p52) - 0x1p52 - x;
++	/* special case because of non-nearest rounding modes */
++	if (e <= 0x3ff-1) {
++		FORCE_EVAL(y);
++		return u.i >> 63 ? -0.0 : 1;
+ 	}
+-	INSERT_WORDS(x, i0, i1);
+-	return x;
++	if (y < 0)
++		return x + y + 1;
++	return x + y;
+ }
+diff -Nur musl-0.9.13/src/math/ceilf.c musl-git/src/math/ceilf.c
+--- musl-0.9.13/src/math/ceilf.c	2013-08-30 23:30:53.000000000 +0200
++++ musl-git/src/math/ceilf.c	2013-09-16 20:31:39.000000000 +0200
+@@ -1,54 +1,27 @@
+-/* origin: FreeBSD /usr/src/lib/msun/src/s_ceilf.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 huge = 1.0e30;
+-
+ float ceilf(float x)
+ {
+-	int32_t i0,j0;
+-	uint32_t i;
++	union {float f; uint32_t i;} u = {x};
++	int e = (int)(u.i >> 23 & 0xff) - 0x7f;
++	uint32_t m;
+ 
+-	GET_FLOAT_WORD(i0, x);
+-	j0 = ((i0>>23)&0xff) - 0x7f;
+-	if (j0 < 23) {
+-		if (j0 < 0) {
+-			/* raise inexact if x != 0 */
+-			if (huge+x > 0.0f) {
+-				if (i0 < 0)
+-					i0 = 0x80000000;
+-				else if(i0 != 0)
+-					i0 = 0x3f800000;
+-			}
+-		} else {
+-			i = 0x007fffff>>j0;
+-			if ((i0&i) == 0)
+-				return x; /* x is integral */
+-			/* raise inexact flag */
+-			if (huge+x > 0.0f) {
+-				if (i0 > 0)
+-					i0 += 0x00800000>>j0;
+-				i0 &= ~i;
+-			}
+-		}
++	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 {
+-		if (j0 == 0x80)  /* inf or NaN */
+-			return x+x;
+-		return x; /* x is integral */
++		FORCE_EVAL(x + 0x1p120f);
++		if (u.i >> 31)
++			u.f = -0.0;
++		else if (u.i << 1)
++			u.f = 1.0;
+ 	}
+-	SET_FLOAT_WORD(x, i0);
+-	return x;
++	return u.f;
+ }
+diff -Nur musl-0.9.13/src/math/ceill.c musl-git/src/math/ceill.c
+--- musl-0.9.13/src/math/ceill.c	2013-08-30 23:30:53.000000000 +0200
++++ musl-git/src/math/ceill.c	2013-09-16 20:31:39.000000000 +0200
+@@ -1,23 +1,3 @@
+-/* origin: FreeBSD /usr/src/lib/msun/src/s_ceill.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.
+- * ====================================================
+- */
+-/*
+- * ceill(x)
+- * Return x rounded toward -inf to integral value
+- * Method:
+- *      Bit twiddling.
+- * Exception:
+- *      Inexact flag raised if x not equal to ceill(x).
+- */
+-
+ #include "libm.h"
+ 
+ #if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024
+@@ -26,77 +6,31 @@
+ 	return ceil(x);
+ }
+ #elif (LDBL_MANT_DIG == 64 || LDBL_MANT_DIG == 113) && LDBL_MAX_EXP == 16384
+-
+-#ifdef LDBL_IMPLICIT_NBIT
+-#define MANH_SIZE       (LDBL_MANH_SIZE + 1)
+-#define INC_MANH(u, c)  do {                                    \
+-	uint64_t o = u.bits.manh;                               \
+-	u.bits.manh += (c);                                     \
+-	if (u.bits.manh < o)                                    \
+-		u.bits.exp++;                                   \
+-} while (0)
+-#else
+-#define MANH_SIZE       LDBL_MANH_SIZE
+-#define INC_MANH(u, c)  do {                                    \
+-	uint64_t o = u.bits.manh;                               \
+-	u.bits.manh += (c);                                     \
+-	if (u.bits.manh < o) {                                  \
+-		u.bits.exp++;                                   \
+-		u.bits.manh |= 1llu << (LDBL_MANH_SIZE - 1);    \
+-	}                                                       \
+-} while (0)
++#if LDBL_MANT_DIG == 64
++#define TOINT 0x1p63
++#elif LDBL_MANT_DIG == 113
++#define TOINT 0x1p112
+ #endif
+-
+-static const long double huge = 1.0e300;
+-
+ long double ceill(long double x)
+ {
+-	union IEEEl2bits u = { .e = x };
+-	int e = u.bits.exp - LDBL_MAX_EXP + 1;
+-
+-	if (e < MANH_SIZE - 1) {
+-		if (e < 0) {
+-			/* raise inexact if x != 0 */
+-			if (huge + x > 0.0)
+-				if (u.bits.exp > 0 ||
+-					(u.bits.manh | u.bits.manl) != 0)
+-					u.e = u.bits.sign ? -0.0 : 1.0;
+-		} else {
+-			uint64_t m = ((1llu << MANH_SIZE) - 1) >> (e + 1);
+-			if (((u.bits.manh & m) | u.bits.manl) == 0)
+-				return x;  /* x is integral */
+-			if (!u.bits.sign) {
+-#ifdef LDBL_IMPLICIT_NBIT
+-				if (e == 0)
+-					u.bits.exp++;
+-				else
+-#endif
+-				INC_MANH(u, 1llu << (MANH_SIZE - e - 1));
+-			}
+-			/* raise inexact flag */
+-			if (huge + x > 0.0) {
+-				u.bits.manh &= ~m;
+-				u.bits.manl = 0;
+-			}
+-		}
+-	} else if (e < LDBL_MANT_DIG - 1) {
+-		uint64_t m = (uint64_t)-1 >> (64 - LDBL_MANT_DIG + e + 1);
+-		if ((u.bits.manl & m) == 0)
+-			return x;  /* x is integral */
+-		if (!u.bits.sign) {
+-			if (e == MANH_SIZE - 1)
+-				INC_MANH(u, 1);
+-			else {
+-				uint64_t o = u.bits.manl;
+-				u.bits.manl += 1llu << (LDBL_MANT_DIG - e - 1);
+-				if (u.bits.manl < o)    /* got a carry */
+-					INC_MANH(u, 1);
+-			}
+-		}
+-		/* raise inexact flag */
+-		if (huge + x > 0.0)
+-			u.bits.manl &= ~m;
++	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;
+ 	}
+-	return u.e;
++	if (y < 0)
++		return x + y + 1;
++	return x + y;
+ }
+ #endif
+diff -Nur musl-0.9.13/src/math/copysign.c musl-git/src/math/copysign.c
+--- musl-0.9.13/src/math/copysign.c	2013-08-30 23:30:53.000000000 +0200
++++ musl-git/src/math/copysign.c	2013-09-16 20:31:39.000000000 +0200
+@@ -1,11 +1,8 @@
+ #include "libm.h"
+ 
+ double copysign(double x, double y) {
+-	union dshape ux, uy;
+-
+-	ux.value = x;
+-	uy.value = y;
+-	ux.bits &= (uint64_t)-1>>1;
+-	ux.bits |= uy.bits & (uint64_t)1<<63;
+-	return ux.value;
++	union {double f; uint64_t i;} ux={x}, uy={y};
++	ux.i &= -1ULL/2;
++	ux.i |= uy.i & 1ULL<<63;
++	return ux.f;
+ }
+diff -Nur musl-0.9.13/src/math/copysignf.c musl-git/src/math/copysignf.c
+--- musl-0.9.13/src/math/copysignf.c	2013-08-30 23:30:53.000000000 +0200
++++ musl-git/src/math/copysignf.c	2013-09-16 20:31:39.000000000 +0200
+@@ -1,11 +1,10 @@
+-#include "libm.h"
++#include <math.h>
++#include <stdint.h>
+ 
+-float copysignf(float x, float y) {
+-	union fshape ux, uy;
+-
+-	ux.value = x;
+-	uy.value = y;
+-	ux.bits &= (uint32_t)-1>>1;
+-	ux.bits |= uy.bits & (uint32_t)1<<31;
+-	return ux.value;
++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;
+ }
+diff -Nur musl-0.9.13/src/math/copysignl.c musl-git/src/math/copysignl.c
+--- musl-0.9.13/src/math/copysignl.c	2013-08-30 23:30:53.000000000 +0200
++++ musl-git/src/math/copysignl.c	2013-09-16 20:31:39.000000000 +0200
+@@ -9,8 +9,8 @@
+ long double copysignl(long double x, long double y)
+ {
+ 	union ldshape ux = {x}, uy = {y};
+-
+-	ux.bits.sign = uy.bits.sign;
+-	return ux.value;
++	ux.i.se &= 0x7fff;
++	ux.i.se |= uy.i.se & 0x8000;
++	return ux.f;
+ }
+ #endif
+diff -Nur musl-0.9.13/src/math/coshl.c musl-git/src/math/coshl.c
+--- musl-0.9.13/src/math/coshl.c	2013-08-30 23:30:53.000000000 +0200
++++ musl-git/src/math/coshl.c	2013-09-16 20:31:39.000000000 +0200
+@@ -8,10 +8,7 @@
+ #elif LDBL_MANT_DIG == 64 && LDBL_MAX_EXP == 16384
+ long double coshl(long double x)
+ {
+-	union {
+-		long double f;
+-		struct{uint64_t m; uint16_t se; uint16_t pad;} i;
+-	} u = {.f = x};
++	union ldshape u = {x};
+ 	unsigned ex = u.i.se & 0x7fff;
+ 	uint32_t w;
+ 	long double t;
+diff -Nur musl-0.9.13/src/math/cosl.c musl-git/src/math/cosl.c
+--- musl-0.9.13/src/math/cosl.c	2013-08-30 23:30:53.000000000 +0200
++++ musl-git/src/math/cosl.c	2013-09-16 20:31:39.000000000 +0200
+@@ -1,34 +1,3 @@
+-/* origin: FreeBSD /usr/src/lib/msun/src/s_cosl.c */
+-/*-
+- * Copyright (c) 2007 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.
+- */
+-/*
+- * Limited testing on pseudorandom numbers drawn within [-2e8:4e8] shows
+- * an accuracy of <= 0.7412 ULP.
+- */
+-
+ #include "libm.h"
+ 
+ #if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024
+@@ -38,44 +7,33 @@
+ #elif (LDBL_MANT_DIG == 64 || LDBL_MANT_DIG == 113) && LDBL_MAX_EXP == 16384
+ long double cosl(long double x)
+ {
+-	union IEEEl2bits z;
++	union ldshape u = {x};
+ 	unsigned n;
+-	long double y[2];
+-	long double hi, lo;
+-
+-	z.e = x;
+-	z.bits.sign = 0;
++	long double y[2], hi, lo;
+ 
+-	/* If x = NaN or Inf, then cos(x) = NaN. */
+-	if (z.bits.exp == 0x7fff)
+-		return (x - x) / (x - x);
+-
+-	/* |x| < (double)pi/4 */
+-	if (z.e < M_PI_4) {
+-		/* |x| < 0x1p-64 */
+-		if (z.bits.exp < 0x3fff - 64)
++	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(z.e, 0);
++		return __cosl(x, 0);
+ 	}
+-
+ 	n = __rem_pio2l(x, y);
+ 	hi = y[0];
+ 	lo = y[1];
+ 	switch (n & 3) {
+ 	case 0:
+-		hi = __cosl(hi, lo);
+-		break;
++		return __cosl(hi, lo);
+ 	case 1:
+-		hi = -__sinl(hi, lo, 1);
+-		break;
++		return -__sinl(hi, lo, 1);
+ 	case 2:
+-		hi = -__cosl(hi, lo);
+-		break;
++		return -__cosl(hi, lo);
+ 	case 3:
+-		hi = __sinl(hi, lo, 1);
+-		break;
++	default:
++		return __sinl(hi, lo, 1);
+ 	}
+-	return hi;
+ }
+ #endif
+diff -Nur musl-0.9.13/src/math/erfl.c musl-git/src/math/erfl.c
+--- musl-0.9.13/src/math/erfl.c	2013-08-30 23:30:53.000000000 +0200
++++ musl-git/src/math/erfl.c	2013-09-16 20:31:39.000000000 +0200
+@@ -253,8 +253,8 @@
+ 
+ static long double erfc2(uint32_t ix, long double x)
+ {
++	union ldshape u;
+ 	long double s,z,R,S;
+-	uint32_t i0,i1;
+ 
+ 	if (ix < 0x3fffa000)  /* 0.84375 <= |x| < 1.25 */
+ 		return erfc1(x);
+@@ -288,28 +288,22 @@
+ 		S = sc[0] + s * (sc[1] + s * (sc[2] + s * (sc[3] +
+ 		     s * (sc[4] + s))));
+ 	}
+-	z = x;
+-	GET_LDOUBLE_WORDS(ix, i0, i1, z);
+-	i1 = 0;
+-	i0 &= 0xffffff00;
+-	SET_LDOUBLE_WORDS(z, ix, i0, i1);
++	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;
+-	uint32_t i0, i1, ix;
+-	int sign;
++	union ldshape u = {x};
++	uint32_t ix = (u.i.se & 0x7fffU)<<16 | u.i.m>>48;
++	int sign = u.i.se >> 15;
+ 
+-	GET_LDOUBLE_WORDS(ix, i0, i1, x);
+-	sign = ix >> 15;
+-	ix &= 0x7fff;
+-	if (ix == 0x7fff) {
++	if (ix >= 0x7fff0000)
+ 		/* erf(nan)=nan, erf(+-inf)=+-1 */
+ 		return 1 - 2*sign + 1/x;
+-	}
+-	ix = (ix << 16) | (i0 >> 16);
+ 	if (ix < 0x3ffed800) {  /* |x| < 0.84375 */
+ 		if (ix < 0x3fde8000) {  /* |x| < 2**-33 */
+ 			return 0.125 * (8 * x + efx8 * x);  /* avoid underflow */
+@@ -332,17 +326,13 @@
+ long double erfcl(long double x)
+ {
+ 	long double r, s, z, y;
+-	uint32_t i0, i1, ix;
+-	int sign;
++	union ldshape u = {x};
++	uint32_t ix = (u.i.se & 0x7fffU)<<16 | u.i.m>>48;
++	int sign = u.i.se >> 15;
+ 
+-	GET_LDOUBLE_WORDS(ix, i0, i1, x);
+-	sign = ix>>15;
+-	ix &= 0x7fff;
+-	if (ix == 0x7fff)
++	if (ix >= 0x7fff0000)
+ 		/* erfc(nan) = nan, erfc(+-inf) = 0,2 */
+ 		return 2*sign + 1/x;
+-
+-	ix = (ix << 16) | (i0 >> 16);
+ 	if (ix < 0x3ffed800) {  /* |x| < 0.84375 */
+ 		if (ix < 0x3fbe0000)  /* |x| < 2**-65 */
+ 			return 1.0 - x;
+@@ -358,6 +348,7 @@
+ 	}
+ 	if (ix < 0x4005d600)  /* |x| < 107 */
+ 		return sign ? 2 - erfc2(ix,x) : erfc2(ix,x);
+-	return sign ? 2 - 0x1p-16382L : 0x1p-16382L*0x1p-16382L;
++	y = 0x1p-16382L;
++	return sign ? 2 - y : y*y;
+ }
+ #endif
+diff -Nur musl-0.9.13/src/math/exp.c musl-git/src/math/exp.c
+--- musl-0.9.13/src/math/exp.c	2013-08-30 23:30:53.000000000 +0200
++++ musl-git/src/math/exp.c	2013-09-16 20:31:39.000000000 +0200
+@@ -80,7 +80,7 @@
+ 
+ double exp(double x)
+ {
+-	double hi, lo, c, xx;
++	double_t hi, lo, c, xx, y;
+ 	int k, sign;
+ 	uint32_t hx;
+ 
+@@ -89,20 +89,19 @@
+ 	hx &= 0x7fffffff;  /* high word of |x| */
+ 
+ 	/* special cases */
+-	if (hx >= 0x40862e42) {  /* if |x| >= 709.78... */
++	if (hx >= 0x4086232b) {  /* if |x| >= 708.39... */
+ 		if (isnan(x))
+ 			return x;
+-		if (hx == 0x7ff00000 && sign) /* -inf */
+-			return 0;
+ 		if (x > 709.782712893383973096) {
+ 			/* overflow if x!=inf */
+-			STRICT_ASSIGN(double, x, 0x1p1023 * x);
++			x *= 0x1p1023;
+ 			return x;
+ 		}
+-		if (x < -745.13321910194110842) {
+-			/* underflow */
+-			STRICT_ASSIGN(double, x, 0x1p-1000 * 0x1p-1000);
+-			return x;
++		if (x < -708.39641853226410622) {
++			/* underflow if x!=-inf */
++			FORCE_EVAL((float)(-0x1p-149/x));
++			if (x < -745.13321910194110842)
++				return 0;
+ 		}
+ 	}
+ 
+@@ -114,7 +113,7 @@
+ 			k = 1 - sign - sign;
+ 		hi = x - k*ln2hi;  /* k*ln2hi is exact here */
+ 		lo = k*ln2lo;
+-		STRICT_ASSIGN(double, x, hi - lo);
++		x = hi - lo;
+ 	} else if (hx > 0x3e300000)  {  /* if |x| > 2**-28 */
+ 		k = 0;
+ 		hi = x;
+@@ -128,8 +127,8 @@
+ 	/* x is now in primary range */
+ 	xx = x*x;
+ 	c = x - xx*(P1+xx*(P2+xx*(P3+xx*(P4+xx*P5))));
+-	x = 1 + (x*c/(2-c) - lo + hi);
++	y = 1 + (x*c/(2-c) - lo + hi);
+ 	if (k == 0)
+-		return x;
+-	return scalbn(x, k);
++		return y;
++	return scalbn(y, k);
+ }
+diff -Nur musl-0.9.13/src/math/exp2.c musl-git/src/math/exp2.c
+--- musl-0.9.13/src/math/exp2.c	2013-08-30 23:30:53.000000000 +0200
++++ musl-git/src/math/exp2.c	2013-09-16 20:31:39.000000000 +0200
+@@ -305,7 +305,7 @@
+  * Method: (accurate tables)
+  *
+  *   Reduce x:
+- *     x = 2**k + y, for integer k and |y| <= 1/2.
++ *     x = k + y, for integer k and |y| <= 1/2.
+  *     Thus we have exp2(x) = 2**k * exp2(y).
+  *
+  *   Reduce y:
+@@ -330,41 +330,41 @@
+  */
+ double exp2(double x)
+ {
+-	double r, t, z;
+-	uint32_t hx, ix, i0;
++	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. */
+-	GET_HIGH_WORD(hx, x);
+-	ix = hx & 0x7fffffff;
+-	if (ix >= 0x40900000) {        /* |x| >= 1024 */
+-		if (ix >= 0x7ff00000) {
+-			GET_LOW_WORD(ix, x);
+-			if (hx == 0xfff00000 && ix == 0) /* -inf */
+-				return 0;
+-			return x;
+-		}
+-		if (x >= 1024) {
+-			STRICT_ASSIGN(double, x, x * 0x1p1023);
++	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 (x <= -1075) {
+-			STRICT_ASSIGN(double, x, 0x1p-1000*0x1p-1000);
+-			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. */
+-	STRICT_ASSIGN(double, t, x + redux);
+-	GET_LOW_WORD(i0, t);
++	u.f = x + redux;
++	i0 = u.i;
+ 	i0 += TBLSIZE / 2;
+ 	k.u = i0 / TBLSIZE * TBLSIZE;
+ 	k.i /= TBLSIZE;
+ 	i0 %= TBLSIZE;
+-	t -= redux;
+-	z = x - t;
++	u.f -= redux;
++	z = x - u.f;
+ 
+ 	/* Compute r = exp2(y) = exp2t[i0] * p(z - eps[i]). */
+ 	t = tbl[2*i0];       /* exp2t[i0] */
+diff -Nur musl-0.9.13/src/math/exp2f.c musl-git/src/math/exp2f.c
+--- musl-0.9.13/src/math/exp2f.c	2013-08-30 23:30:53.000000000 +0200
++++ musl-git/src/math/exp2f.c	2013-09-16 20:31:39.000000000 +0200
+@@ -63,7 +63,7 @@
+  * Method: (equally-spaced tables)
+  *
+  *   Reduce x:
+- *     x = 2**k + y, for integer k and |y| <= 1/2.
++ *     x = k + y, for integer k and |y| <= 1/2.
+  *     Thus we have exp2f(x) = 2**k * exp2(y).
+  *
+  *   Reduce y:
+@@ -83,46 +83,42 @@
+  */
+ float exp2f(float x)
+ {
+-	double tv, twopk, u, z;
+-	float t;
+-	uint32_t hx, ix, i0, k;
++	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. */
+-	GET_FLOAT_WORD(hx, x);
+-	ix = hx & 0x7fffffff;
+-	if (ix >= 0x43000000) {  /* |x| >= 128 */
+-		if (ix >= 0x7f800000) {
+-			if (hx == 0xff800000) /* -inf */
+-				return 0;
+-			return x;
+-		}
+-		if (x >= 128) {
+-			STRICT_ASSIGN(float, x, x * 0x1p127f);
++	ix = u.i & 0x7fffffff;
++	if (ix > 0x42fc0000) {  /* |x| > 126 */
++		if (u.i >= 0x43000000 && u.i < 0x80000000) {  /* x >= 128 */
++			x *= 0x1p127f;
+ 			return x;
+ 		}
+-		if (x <= -150) {
+-			STRICT_ASSIGN(float, x, 0x1p-100f*0x1p-100f);
+-			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. */
+-	STRICT_ASSIGN(float, t, x + redux);
+-	GET_FLOAT_WORD(i0, t);
++	u.f = x + redux;
++	i0 = u.i;
+ 	i0 += TBLSIZE / 2;
+-	k = (i0 / TBLSIZE) << 20;
++	k = i0 / TBLSIZE;
++	uk.i = (uint64_t)(0x3ff + k)<<52;
+ 	i0 &= TBLSIZE - 1;
+-	t -= redux;
+-	z = x - t;
+-	INSERT_WORDS(twopk, 0x3ff00000 + k, 0);
+-
++	u.f -= redux;
++	z = x - u.f;
+ 	/* Compute r = exp2(y) = exp2ft[i0] * p(z). */
+-	tv = exp2ft[i0];
+-	u = tv * z;
+-	tv = tv + u * (P1 + z * P2) + u * (z * z) * (P3 + z * P4);
++	r = exp2ft[i0];
++	t = r * z;
++	r = r + t * (P1 + z * P2) + t * (z * z) * (P3 + z * P4);
+ 
+-	/* Scale by 2**(k>>20). */
+-	return tv * twopk;
++	/* Scale by 2**k */
++	return r * uk.f;
+ }
+diff -Nur musl-0.9.13/src/math/exp2l.c musl-git/src/math/exp2l.c
+--- musl-0.9.13/src/math/exp2l.c	2013-08-30 23:30:53.000000000 +0200
++++ musl-git/src/math/exp2l.c	2013-09-16 20:31:39.000000000 +0200
+@@ -33,13 +33,9 @@
+ 	return exp2(x);
+ }
+ #elif LDBL_MANT_DIG == 64 && LDBL_MAX_EXP == 16384
+-
+ #define TBLBITS 7
+ #define TBLSIZE (1 << TBLBITS)
+ 
+-#define BIAS    (LDBL_MAX_EXP - 1)
+-#define EXPMASK (BIAS + LDBL_MAX_EXP)
+-
+ static const double
+ redux = 0x1.8p63 / TBLSIZE,
+ P1    = 0x1.62e42fefa39efp-1,
+@@ -203,29 +199,29 @@
+  */
+ long double exp2l(long double x)
+ {
+-	union IEEEl2bits u, v;
++	union ldshape u = {x};
++	int e = u.i.se & 0x7fff;
+ 	long double r, z;
+-	uint32_t hx, ix, i0;
++	uint32_t i0;
+ 	union {uint32_t u; int32_t i;} k;
+ 
+ 	/* Filter out exceptional cases. */
+-	u.e = x;
+-	hx = u.xbits.expsign;
+-	ix = hx & EXPMASK;
+-	if (ix >= BIAS + 14) {  /* |x| >= 16384 or x is NaN */
+-		if (ix == EXPMASK) {
+-			if (u.xbits.man == 1ULL << 63 && hx == 0xffff) /* -inf */
++	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;
+-			return x;
+-		}
+-		if (x >= 16384) {
+-			x *= 0x1p16383L;
+-			return x;
+ 		}
+-		if (x <= -16446)
+-			return 0x1p-10000L*0x1p-10000L;
+-	} else if (ix < BIAS - 64)  /* |x| < 0x1p-64 */
++	} else if (e < 0x3fff - 64) {
+ 		return 1 + x;
++	}
+ 
+ 	/*
+ 	 * Reduce x, computing z, i0, and k. The low bits of x + redux
+@@ -238,13 +234,13 @@
+ 	 * We split this into k = 0xabc and i0 = 0x12 (adjusted to
+ 	 * index into the table), then we compute z = 0x0.003456p0.
+ 	 */
+-	u.e = x + redux;
+-	i0 = u.bits.manl + TBLSIZE / 2;
++	u.f = x + redux;
++	i0 = u.i.m + TBLSIZE / 2;
+ 	k.u = i0 / TBLSIZE * TBLSIZE;
+ 	k.i /= TBLSIZE;
+ 	i0 %= TBLSIZE;
+-	u.e -= redux;
+-	z = x - u.e;
++	u.f -= redux;
++	z = x - u.f;
+ 
+ 	/* Compute r = exp2l(y) = exp2lt[i0] * p(z). */
+ 	long double t_hi = tbl[2*i0];
+diff -Nur musl-0.9.13/src/math/expf.c musl-git/src/math/expf.c
+--- musl-0.9.13/src/math/expf.c	2013-08-30 23:30:53.000000000 +0200
++++ musl-git/src/math/expf.c	2013-09-16 20:31:39.000000000 +0200
+@@ -29,7 +29,7 @@
+ 
+ float expf(float x)
+ {
+-	float hi, lo, c, xx;
++	float_t hi, lo, c, xx, y;
+ 	int k, sign;
+ 	uint32_t hx;
+ 
+@@ -38,20 +38,17 @@
+ 	hx &= 0x7fffffff;  /* high word of |x| */
+ 
+ 	/* special cases */
+-	if (hx >= 0x42b17218) {  /* if |x| >= 88.722839f or NaN */
+-		if (hx > 0x7f800000)  /* NaN */
+-			return x;
+-		if (!sign) {
+-			/* overflow if x!=inf */
+-			STRICT_ASSIGN(float, x, x * 0x1p127f);
++	if (hx >= 0x42aeac50) {  /* if |x| >= -87.33655f or NaN */
++		if (hx >= 0x42b17218 && !sign) {  /* x >= 88.722839f */
++			/* overflow */
++			x *= 0x1p127f;
+ 			return x;
+ 		}
+-		if (hx == 0x7f800000)  /* -inf */
+-			return 0;
+-		if (hx >= 0x42cff1b5) { /* x <= -103.972084f */
++		if (sign) {
+ 			/* underflow */
+-			STRICT_ASSIGN(float, x, 0x1p-100f*0x1p-100f);
+-			return x;
++			FORCE_EVAL(-0x1p-149f/x);
++			if (hx >= 0x42cff1b5)  /* x <= -103.972084f */
++				return 0;
+ 		}
+ 	}
+ 
+@@ -63,7 +60,7 @@
+ 			k = 1 - sign - sign;
+ 		hi = x - k*ln2hi;  /* k*ln2hi is exact here */
+ 		lo = k*ln2lo;
+-		STRICT_ASSIGN(float, x, hi - lo);
++		x = hi - lo;
+ 	} else if (hx > 0x39000000) {  /* |x| > 2**-14 */
+ 		k = 0;
+ 		hi = x;
+@@ -77,8 +74,8 @@
+ 	/* x is now in primary range */
+ 	xx = x*x;
+ 	c = x - xx*(P1+xx*P2);
+-	x = 1 + (x*c/(2-c) - lo + hi);
++	y = 1 + (x*c/(2-c) - lo + hi);
+ 	if (k == 0)
+-		return x;
+-	return scalbnf(x, k);
++		return y;
++	return scalbnf(y, k);
+ }
+diff -Nur musl-0.9.13/src/math/expl.c musl-git/src/math/expl.c
+--- musl-0.9.13/src/math/expl.c	2013-08-30 23:30:53.000000000 +0200
++++ musl-git/src/math/expl.c	2013-09-16 20:31:39.000000000 +0200
+@@ -100,7 +100,7 @@
+ 	if (x > 11356.5234062941439488L) /* x > ln(2^16384 - 0.5) */
+ 		return x * 0x1p16383L;
+ 	if (x < -11399.4985314888605581L) /* x < ln(2^-16446) */
+-		return 0x1p-10000L * 0x1p-10000L;
++		return -0x1p-16445L/x;
+ 
+ 	/* Express e**x = e**f 2**k
+ 	 *   = e**(f + k ln(2))
+diff -Nur musl-0.9.13/src/math/expm1.c musl-git/src/math/expm1.c
+--- musl-0.9.13/src/math/expm1.c	2013-08-30 23:30:53.000000000 +0200
++++ musl-git/src/math/expm1.c	2013-09-16 20:31:39.000000000 +0200
+@@ -31,7 +31,7 @@
+  *          R1(r**2) = 6/r *((exp(r)+1)/(exp(r)-1) - 2/r)
+  *                   = 6/r * ( 1 + 2.0*(1/(exp(r)-1) - 1/r))
+  *                   = 1 - r^2/60 + r^4/2520 - r^6/100800 + ...
+- *      We use a special Reme algorithm on [0,0.347] to generate
++ *      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,
+@@ -107,8 +107,6 @@
+ #include "libm.h"
+ 
+ static const double
+-huge        = 1.0e+300,
+-tiny        = 1.0e-300,
+ o_threshold = 7.09782712893383973096e+02, /* 0x40862E42, 0xFEFA39EF */
+ ln2_hi      = 6.93147180369123816490e-01, /* 0x3fe62e42, 0xfee00000 */
+ ln2_lo      = 1.90821492927058770002e-10, /* 0x3dea39ef, 0x35793c76 */
+@@ -122,39 +120,27 @@
+ 
+ double expm1(double x)
+ {
+-	double y,hi,lo,c,t,e,hxs,hfx,r1,twopk;
+-	int32_t k,xsb;
+-	uint32_t hx;
+-
+-	GET_HIGH_WORD(hx, x);
+-	xsb = hx&0x80000000;  /* sign bit of x */
+-	hx &= 0x7fffffff;     /* high word of |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 (hx >= 0x40862E42) {  /* if |x|>=709.78... */
+-			if (hx >= 0x7ff00000) {
+-				uint32_t low;
+-
+-				GET_LOW_WORD(low, x);
+-				if (((hx&0xfffff)|low) != 0) /* NaN */
+-					return x+x;
+-				return xsb==0 ? x : -1.0; /* exp(+-inf)={inf,-1} */
+-			}
+-			if(x > o_threshold)
+-				return huge*huge; /* overflow */
+-		}
+-		if (xsb != 0) { /* x < -56*ln2, return -1.0 with inexact */
+-			/* raise inexact */
+-			if(x+tiny<0.0)
+-				return tiny-1.0;  /* return -1 */
++		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 (xsb == 0) {
++			if (!sign) {
+ 				hi = x - ln2_hi;
+ 				lo = ln2_lo;
+ 				k =  1;
+@@ -164,17 +150,17 @@
+ 				k = -1;
+ 			}
+ 		} else {
+-			k  = invln2*x + (xsb==0 ? 0.5 : -0.5);
++			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;
+ 		}
+-		STRICT_ASSIGN(double, x, hi - lo);
++		x = hi-lo;
+ 		c = (hi-x)-lo;
+ 	} else if (hx < 0x3c900000) {  /* |x| < 2**-54, return x */
+-		/* raise inexact flags when x != 0 */
+-		t = huge+x;
+-		return x - (t-(huge+x));
++		if (hx < 0x00100000)
++			FORCE_EVAL((float)x);
++		return x;
+ 	} else
+ 		k = 0;
+ 
+@@ -186,9 +172,9 @@
+ 	e  = hxs*((r1-t)/(6.0 - x*t));
+ 	if (k == 0)   /* c is 0 */
+ 		return x - (x*e-hxs);
+-	INSERT_WORDS(twopk, 0x3ff00000+(k<<20), 0);  /* 2^k */
+ 	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) {
+@@ -196,24 +182,20 @@
+ 			return -2.0*(e-(x+0.5));
+ 		return 1.0+2.0*(x-e);
+ 	}
+-	if (k <= -2 || k > 56) {  /* suffice to return exp(x)-1 */
+-		y = 1.0 - (e-x);
++	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;
+ 	}
+-	t = 1.0;
+-	if (k < 20) {
+-		SET_HIGH_WORD(t, 0x3ff00000 - (0x200000>>k));  /* t=1-2^-k */
+-		y = t-(e-x);
+-		y = y*twopk;
+-	} else {
+-		SET_HIGH_WORD(t, ((0x3ff-k)<<20));  /* 2^-k */
+-		y = x-(e+t);
+-		y += 1.0;
+-		y = y*twopk;
+-	}
++	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;
+ }
+diff -Nur musl-0.9.13/src/math/expm1f.c musl-git/src/math/expm1f.c
+--- musl-0.9.13/src/math/expm1f.c	2013-08-30 23:30:53.000000000 +0200
++++ musl-git/src/math/expm1f.c	2013-09-16 20:31:39.000000000 +0200
+@@ -16,8 +16,6 @@
+ #include "libm.h"
+ 
+ static const float
+-huge        = 1.0e+30,
+-tiny        = 1.0e-30,
+ o_threshold = 8.8721679688e+01, /* 0x42b17180 */
+ ln2_hi      = 6.9313812256e-01, /* 0x3f317180 */
+ ln2_lo      = 9.0580006145e-06, /* 0x3717f7d1 */
+@@ -32,35 +30,27 @@
+ 
+ float expm1f(float x)
+ {
+-	float y,hi,lo,c,t,e,hxs,hfx,r1,twopk;
+-	int32_t k,xsb;
+-	uint32_t hx;
+-
+-	GET_FLOAT_WORD(hx, x);
+-	xsb = hx&0x80000000;  /* sign bit of x */
+-	hx &= 0x7fffffff;     /* high word of |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 >= 0x42b17218) {  /* if |x|>=88.721... */
+-			if (hx > 0x7f800000)  /* NaN */
+-				return x+x;
+-			if (hx == 0x7f800000) /* exp(+-inf)={inf,-1} */
+-				return xsb==0 ? x : -1.0;
+-			if (x > o_threshold)
+-				return huge*huge; /* overflow */
+-		}
+-		if (xsb != 0) {  /* x < -27*ln2 */
+-			/* raise inexact */
+-			if (x+tiny < 0.0f)
+-				return tiny-1.0f;  /* return -1 */
++		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 (xsb == 0) {
++			if (!sign) {
+ 				hi = x - ln2_hi;
+ 				lo = ln2_lo;
+ 				k =  1;
+@@ -70,16 +60,17 @@
+ 				k = -1;
+ 			}
+ 		} else {
+-			k  = invln2*x + (xsb==0 ? 0.5f : -0.5f);
++			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;
+ 		}
+-		STRICT_ASSIGN(float, x, hi - lo);
++		x = hi-lo;
+ 		c = (hi-x)-lo;
+ 	} else if (hx < 0x33000000) {  /* when |x|<2**-25, return x */
+-		t = huge+x; /* return x with inexact flags when x!=0 */
+-		return x - (t-(huge+x));
++		if (hx < 0x00800000)
++			FORCE_EVAL(x*x);
++		return x;
+ 	} else
+ 		k = 0;
+ 
+@@ -91,9 +82,9 @@
+ 	e  = hxs*((r1-t)/(6.0f - x*t));
+ 	if (k == 0)  /* c is 0 */
+ 		return x - (x*e-hxs);
+-	SET_FLOAT_WORD(twopk, 0x3f800000+(k<<23));   /* 2^k */
+ 	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) {
+@@ -101,24 +92,20 @@
+ 			return -2.0f*(e-(x+0.5f));
+ 		return 1.0f + 2.0f*(x-e);
+ 	}
+-	if (k <= -2 || k > 56) {   /* suffice to return exp(x)-1 */
+-		y = 1.0f - (e - x);
++	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;
+ 	}
+-	t = 1.0f;
+-	if (k < 23) {
+-		SET_FLOAT_WORD(t, 0x3f800000 - (0x1000000>>k)); /* t=1-2^-k */
+-		y = t - (e - x);
+-		y = y*twopk;
+-	} else {
+-		SET_FLOAT_WORD(t, (0x7f-k)<<23);  /* 2^-k */
+-		y = x - (e + t);
+-		y += 1.0f;
+-		y = y*twopk;
+-	}
++	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;
+ }
+diff -Nur musl-0.9.13/src/math/fabs.c musl-git/src/math/fabs.c
+--- musl-0.9.13/src/math/fabs.c	2013-08-30 23:30:53.000000000 +0200
++++ musl-git/src/math/fabs.c	2013-09-16 20:31:39.000000000 +0200
+@@ -1,10 +1,9 @@
+-#include "libm.h"
++#include <math.h>
++#include <stdint.h>
+ 
+ double fabs(double x)
+ {
+-	union dshape u;
+-
+-	u.value = x;
+-	u.bits &= (uint64_t)-1 / 2;
+-	return u.value;
++	union {double f; uint64_t i;} u = {x};
++	u.i &= -1ULL/2;
++	return u.f;
+ }
+diff -Nur musl-0.9.13/src/math/fabsf.c musl-git/src/math/fabsf.c
+--- musl-0.9.13/src/math/fabsf.c	2013-08-30 23:30:53.000000000 +0200
++++ musl-git/src/math/fabsf.c	2013-09-16 20:31:39.000000000 +0200
+@@ -1,10 +1,9 @@
+-#include "libm.h"
++#include <math.h>
++#include <stdint.h>
+ 
+ float fabsf(float x)
+ {
+-	union fshape u;
+-
+-	u.value = x;
+-	u.bits &= (uint32_t)-1 / 2;
+-	return u.value;
++	union {float f; uint32_t i;} u = {x};
++	u.i &= 0x7fffffff;
++	return u.f;
+ }
+diff -Nur musl-0.9.13/src/math/fabsl.c musl-git/src/math/fabsl.c
+--- musl-0.9.13/src/math/fabsl.c	2013-08-30 23:30:53.000000000 +0200
++++ musl-git/src/math/fabsl.c	2013-09-16 20:31:39.000000000 +0200
+@@ -9,7 +9,7 @@
+ {
+ 	union ldshape u = {x};
+ 
+-	u.bits.sign = 0;
+-	return u.value;
++	u.i.se &= 0x7fff;
++	return u.f;
+ }
+ #endif
+diff -Nur musl-0.9.13/src/math/floor.c musl-git/src/math/floor.c
+--- musl-0.9.13/src/math/floor.c	2013-08-30 23:30:53.000000000 +0200
++++ musl-git/src/math/floor.c	2013-09-16 20:31:39.000000000 +0200
+@@ -1,82 +1,24 @@
+-/* origin: FreeBSD /usr/src/lib/msun/src/s_floor.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.
+- * ====================================================
+- */
+-/*
+- * floor(x)
+- * Return x rounded toward -inf to integral value
+- * Method:
+- *      Bit twiddling.
+- * Exception:
+- *      Inexact flag raised if x not equal to floor(x).
+- */
+-
+ #include "libm.h"
+ 
+-static const double huge = 1.0e300;
+-
+ double floor(double x)
+ {
+-	int32_t i0,i1,j0;
+-	uint32_t i,j;
++	union {double f; uint64_t i;} u = {x};
++	int e = u.i >> 52 & 0x7ff;
++	double_t y;
+ 
+-	EXTRACT_WORDS(i0, i1, x);
+-	// FIXME: signed shift
+-	j0 = ((i0>>20)&0x7ff) - 0x3ff;
+-	if (j0 < 20) {
+-		if (j0 < 0) {  /* |x| < 1 */
+-			/* raise inexact if x != 0 */
+-			if (huge+x > 0.0) {
+-				if (i0 >= 0) {  /* x >= 0 */
+-					i0 = i1 = 0;
+-				} else if (((i0&0x7fffffff)|i1) != 0) {
+-					i0 = 0xbff00000;
+-					i1 = 0;
+-				}
+-			}
+-		} else {
+-			i = 0x000fffff>>j0;
+-			if (((i0&i)|i1) == 0)
+-				return x; /* x is integral */
+-			 /* raise inexact flag */
+-			if (huge+x > 0.0) {
+-				if (i0 < 0)
+-					i0 += 0x00100000>>j0;
+-				i0 &= ~i;
+-				i1 = 0;
+-			}
+-		}
+-	} else if (j0 > 51) {
+-		if (j0 == 0x400)
+-			return x+x; /* inf or NaN */
+-		else
+-			return x;   /* x is integral */
+-	} else {
+-		i = (uint32_t)0xffffffff>>(j0-20);
+-		if ((i1&i) == 0)
+-			return x;   /* x is integral */
+-		/* raise inexact flag */
+-		if (huge+x > 0.0) {
+-			if (i0 < 0) {
+-				if (j0 == 20)
+-					i0++;
+-				else {
+-					j = i1+(1<<(52-j0));
+-					if (j < i1)
+-						i0++; /* got a carry */
+-					i1 = j;
+-				}
+-			}
+-			i1 &= ~i;
+-		}
++	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 = (double)(x - 0x1p52) + 0x1p52 - x;
++	else
++		y = (double)(x + 0x1p52) - 0x1p52 - x;
++	/* special case because of non-nearest rounding modes */
++	if (e <= 0x3ff-1) {
++		FORCE_EVAL(y);
++		return u.i >> 63 ? -1 : 0;
+ 	}
+-	INSERT_WORDS(x, i0, i1);
+-	return x;
++	if (y > 0)
++		return x + y - 1;
++	return x + y;
+ }
+diff -Nur musl-0.9.13/src/math/floorf.c musl-git/src/math/floorf.c
+--- musl-0.9.13/src/math/floorf.c	2013-08-30 23:30:53.000000000 +0200
++++ musl-git/src/math/floorf.c	2013-09-16 20:31:39.000000000 +0200
+@@ -1,64 +1,27 @@
+-/* origin: FreeBSD /usr/src/lib/msun/src/s_floorf.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.
+- * ====================================================
+- */
+-/*
+- * floorf(x)
+- * Return x rounded toward -inf to integral value
+- * Method:
+- *      Bit twiddling.
+- * Exception:
+- *      Inexact flag raised if x not equal to floorf(x).
+- */
+-
+ #include "libm.h"
+ 
+-static const float huge = 1.0e30;
+-
+ float floorf(float x)
+ {
+-	int32_t i0,j0;
+-	uint32_t i;
++	union {float f; uint32_t i;} u = {x};
++	int e = (int)(u.i >> 23 & 0xff) - 0x7f;
++	uint32_t m;
+ 
+-	GET_FLOAT_WORD(i0, x);
+-	// FIXME: signed shift
+-	j0 = ((i0>>23)&0xff) - 0x7f;
+-	if (j0 < 23) {
+-		if (j0 < 0) {  /* |x| < 1 */
+-			/* raise inexact if x != 0 */
+-			if (huge+x > 0.0f) {
+-				if (i0 >= 0)  /* x >= 0 */
+-					i0 = 0;
+-				else if ((i0&0x7fffffff) != 0)
+-					i0 = 0xbf800000;
+-			}
+-		} else {
+-			i = 0x007fffff>>j0;
+-			if ((i0&i) == 0)
+-				return x; /* x is integral */
+-			/* raise inexact flag */
+-			if (huge+x > 0.0f) {
+-				if (i0 < 0)
+-					i0 += 0x00800000>>j0;
+-				i0 &= ~i;
+-			}
+-		}
++	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 {
+-		if (j0 == 0x80)  /* inf or NaN */
+-			return x+x;
+-		else
+-			return x;  /* x is integral */
++		FORCE_EVAL(x + 0x1p120f);
++		if (u.i >> 31 == 0)
++			u.i = 0;
++		else if (u.i << 1)
++			u.f = -1.0;
+ 	}
+-	SET_FLOAT_WORD(x, i0);
+-	return x;
++	return u.f;
+ }
+diff -Nur musl-0.9.13/src/math/floorl.c musl-git/src/math/floorl.c
+--- musl-0.9.13/src/math/floorl.c	2013-08-30 23:30:53.000000000 +0200
++++ musl-git/src/math/floorl.c	2013-09-16 20:31:39.000000000 +0200
+@@ -1,23 +1,3 @@
+-/* origin: FreeBSD /usr/src/lib/msun/src/s_floorl.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.
+- * ====================================================
+- */
+-/*
+- * floorl(x)
+- * Return x rounded toward -inf to integral value
+- * Method:
+- *      Bit twiddling.
+- * Exception:
+- *      Inexact flag raised if x not equal to floorl(x).
+- */
+-
+ #include "libm.h"
+ 
+ #if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024
+@@ -26,77 +6,31 @@
+ 	return floor(x);
+ }
+ #elif (LDBL_MANT_DIG == 64 || LDBL_MANT_DIG == 113) && LDBL_MAX_EXP == 16384
+-
+-#ifdef LDBL_IMPLICIT_NBIT
+-#define MANH_SIZE       (LDBL_MANH_SIZE + 1)
+-#define INC_MANH(u, c)  do {                                    \
+-	uint64_t o = u.bits.manh;                               \
+-	u.bits.manh += (c);                                     \
+-	if (u.bits.manh < o)                                    \
+-		u.bits.exp++;                                   \
+-} while (0)
+-#else
+-#define MANH_SIZE       LDBL_MANH_SIZE
+-#define INC_MANH(u, c)  do {                                    \
+-	uint64_t o = u.bits.manh;                               \
+-	u.bits.manh += (c);                                     \
+-	if (u.bits.manh < o) {                                  \
+-		u.bits.exp++;                                   \
+-		u.bits.manh |= 1llu << (LDBL_MANH_SIZE - 1);    \
+-	}                                                       \
+-} while (0)
++#if LDBL_MANT_DIG == 64
++#define TOINT 0x1p63
++#elif LDBL_MANT_DIG == 113
++#define TOINT 0x1p112
+ #endif
+-
+-static const long double huge = 1.0e300;
+-
+ long double floorl(long double x)
+ {
+-	union IEEEl2bits u = { .e = x };
+-	int e = u.bits.exp - LDBL_MAX_EXP + 1;
+-
+-	if (e < MANH_SIZE - 1) {
+-		if (e < 0) {
+-			/* raise inexact if x != 0 */
+-			if (huge + x > 0.0)
+-				if (u.bits.exp > 0 ||
+-				    (u.bits.manh | u.bits.manl) != 0)
+-					u.e = u.bits.sign ? -1.0 : 0.0;
+-		} else {
+-			uint64_t m = ((1llu << MANH_SIZE) - 1) >> (e + 1);
+-			if (((u.bits.manh & m) | u.bits.manl) == 0)
+-				return x;  /* x is integral */
+-			if (u.bits.sign) {
+-#ifdef LDBL_IMPLICIT_NBIT
+-				if (e == 0)
+-					u.bits.exp++;
+-				else
+-#endif
+-				INC_MANH(u, 1llu << (MANH_SIZE - e - 1));
+-			}
+-			/* raise inexact flag */
+-			if (huge + x > 0.0) {
+-				u.bits.manh &= ~m;
+-				u.bits.manl = 0;
+-			}
+-		}
+-	} else if (e < LDBL_MANT_DIG - 1) {
+-		uint64_t m = (uint64_t)-1 >> (64 - LDBL_MANT_DIG + e + 1);
+-		if ((u.bits.manl & m) == 0)
+-			return x;  /* x is integral */
+-		if (u.bits.sign) {
+-			if (e == MANH_SIZE - 1)
+-				INC_MANH(u, 1);
+-			else {
+-				uint64_t o = u.bits.manl;
+-				u.bits.manl += 1llu << (LDBL_MANT_DIG - e - 1);
+-				if (u.bits.manl < o)   /* got a carry */
+-					INC_MANH(u, 1);
+-			}
+-		}
+-		/* raise inexact flag */
+-		if (huge + x > 0.0)
+-			u.bits.manl &= ~m;
++	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;
+ 	}
+-	return u.e;
++	if (y > 0)
++		return x + y - 1;
++	return x + y;
+ }
+ #endif
+diff -Nur musl-0.9.13/src/math/fma.c musl-git/src/math/fma.c
+--- musl-0.9.13/src/math/fma.c	2013-08-30 23:30:53.000000000 +0200
++++ musl-git/src/math/fma.c	2013-09-16 20:31:39.000000000 +0200
+@@ -2,16 +2,6 @@
+ #include "libm.h"
+ 
+ #if LDBL_MANT_DIG==64 && LDBL_MAX_EXP==16384
+-union ld80 {
+-	long double x;
+-	struct {
+-		uint64_t m;
+-		uint16_t e : 15;
+-		uint16_t s : 1;
+-		uint16_t pad;
+-	} bits;
+-};
+-
+ /* exact add, assumes exponent_x >= exponent_y */
+ static void add(long double *hi, long double *lo, long double x, long double y)
+ {
+@@ -45,25 +35,25 @@
+ */
+ static long double adjust(long double hi, long double lo)
+ {
+-	union ld80 uhi, ulo;
++	union ldshape uhi, ulo;
+ 
+ 	if (lo == 0)
+ 		return hi;
+-	uhi.x = hi;
+-	if (uhi.bits.m & 0x3ff)
++	uhi.f = hi;
++	if (uhi.i.m & 0x3ff)
+ 		return hi;
+-	ulo.x = lo;
+-	if (uhi.bits.s == ulo.bits.s)
+-		uhi.bits.m++;
++	ulo.f = lo;
++	if ((uhi.i.se & 0x8000) == (ulo.i.se & 0x8000))
++		uhi.i.m++;
+ 	else {
+-		uhi.bits.m--;
+ 		/* handle underflow and take care of ld80 implicit msb */
+-		if (uhi.bits.m == (uint64_t)-1/2) {
+-			uhi.bits.m *= 2;
+-			uhi.bits.e--;
++		if (uhi.i.m << 1 == 0) {
++			uhi.i.m = 0;
++			uhi.i.se--;
+ 		}
++		uhi.i.m--;
+ 	}
+-	return uhi.x;
++	return uhi.f;
+ }
+ 
+ /* adjusted add so the result is correct when rounded to double (or less) precision */
+@@ -82,9 +72,9 @@
+ 
+ static int getexp(long double x)
+ {
+-	union ld80 u;
+-	u.x = x;
+-	return u.bits.e;
++	union ldshape u;
++	u.f = x;
++	return u.i.se & 0x7fff;
+ }
+ 
+ double fma(double x, double y, double z)
+@@ -242,16 +232,16 @@
+ static inline double add_adjusted(double a, double b)
+ {
+ 	struct dd sum;
+-	uint64_t hibits, lobits;
++	union {double f; uint64_t i;} uhi, ulo;
+ 
+ 	sum = dd_add(a, b);
+ 	if (sum.lo != 0) {
+-		EXTRACT_WORD64(hibits, sum.hi);
+-		if ((hibits & 1) == 0) {
++		uhi.f = sum.hi;
++		if ((uhi.i & 1) == 0) {
+ 			/* hibits += (int)copysign(1.0, sum.hi * sum.lo) */
+-			EXTRACT_WORD64(lobits, sum.lo);
+-			hibits += 1 - ((hibits ^ lobits) >> 62);
+-			INSERT_WORD64(sum.hi, hibits);
++			ulo.f = sum.lo;
++			uhi.i += 1 - ((uhi.i ^ ulo.i) >> 62);
++			sum.hi = uhi.f;
+ 		}
+ 	}
+ 	return (sum.hi);
+@@ -265,7 +255,7 @@
+ static inline double add_and_denormalize(double a, double b, int scale)
+ {
+ 	struct dd sum;
+-	uint64_t hibits, lobits;
++	union {double f; uint64_t i;} uhi, ulo;
+ 	int bits_lost;
+ 
+ 	sum = dd_add(a, b);
+@@ -281,13 +271,13 @@
+ 	 * break the ties manually.
+ 	 */
+ 	if (sum.lo != 0) {
+-		EXTRACT_WORD64(hibits, sum.hi);
+-		bits_lost = -((int)(hibits >> 52) & 0x7ff) - scale + 1;
+-		if (bits_lost != 1 ^ (int)(hibits & 1)) {
++		uhi.f = sum.hi;
++		bits_lost = -((int)(uhi.i >> 52) & 0x7ff) - scale + 1;
++		if (bits_lost != 1 ^ (int)(uhi.i & 1)) {
+ 			/* hibits += (int)copysign(1.0, sum.hi * sum.lo) */
+-			EXTRACT_WORD64(lobits, sum.lo);
+-			hibits += 1 - (((hibits ^ lobits) >> 62) & 2);
+-			INSERT_WORD64(sum.hi, hibits);
++			ulo.f = sum.lo;
++			uhi.i += 1 - (((uhi.i ^ ulo.i) >> 62) & 2);
++			sum.hi = uhi.f;
+ 		}
+ 	}
+ 	return scalbn(sum.hi, scale);
+diff -Nur musl-0.9.13/src/math/fmal.c musl-git/src/math/fmal.c
+--- musl-0.9.13/src/math/fmal.c	2013-08-30 23:30:53.000000000 +0200
++++ musl-git/src/math/fmal.c	2013-09-16 20:31:39.000000000 +0200
+@@ -34,6 +34,13 @@
+ }
+ #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
+@@ -75,12 +82,12 @@
+ static inline long double add_adjusted(long double a, long double b)
+ {
+ 	struct dd sum;
+-	union IEEEl2bits u;
++	union ldshape u;
+ 
+ 	sum = dd_add(a, b);
+ 	if (sum.lo != 0) {
+-		u.e = sum.hi;
+-		if ((u.bits.manl & 1) == 0)
++		u.f = sum.hi;
++		if (!LASTBIT(u))
+ 			sum.hi = nextafterl(sum.hi, INFINITY * sum.lo);
+ 	}
+ 	return (sum.hi);
+@@ -95,7 +102,7 @@
+ {
+ 	struct dd sum;
+ 	int bits_lost;
+-	union IEEEl2bits u;
++	union ldshape u;
+ 
+ 	sum = dd_add(a, b);
+ 
+@@ -110,9 +117,9 @@
+ 	 * break the ties manually.
+ 	 */
+ 	if (sum.lo != 0) {
+-		u.e = sum.hi;
+-		bits_lost = -u.bits.exp - scale + 1;
+-		if (bits_lost != 1 ^ (int)(u.bits.manl & 1))
++		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);
+@@ -125,20 +132,15 @@
+  */
+ static inline struct dd dd_mul(long double a, long double b)
+ {
+-#if LDBL_MANT_DIG == 64
+-	static const long double split = 0x1p32L + 1.0;
+-#elif LDBL_MANT_DIG == 113
+-	static const long double split = 0x1p57L + 1.0;
+-#endif
+ 	struct dd ret;
+ 	long double ha, hb, la, lb, p, q;
+ 
+-	p = a * split;
++	p = a * SPLIT;
+ 	ha = a - p;
+ 	ha += p;
+ 	la = a - ha;
+ 
+-	p = b * split;
++	p = b * SPLIT;
+ 	hb = b - p;
+ 	hb += p;
+ 	lb = b - hb;
+diff -Nur musl-0.9.13/src/math/fmod.c musl-git/src/math/fmod.c
+--- musl-0.9.13/src/math/fmod.c	2013-08-30 23:30:53.000000000 +0200
++++ musl-git/src/math/fmod.c	2013-09-16 20:31:39.000000000 +0200
+@@ -1,145 +1,68 @@
+-/* origin: FreeBSD /usr/src/lib/msun/src/e_fmod.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.
+- * ====================================================
+- */
+-/*
+- * fmod(x,y)
+- * Return x mod y in exact arithmetic
+- * Method: shift and subtract
+- */
+-
+-#include "libm.h"
+-
+-static const double Zero[] = {0.0, -0.0,};
++#include <math.h>
++#include <stdint.h>
+ 
+ double fmod(double x, double y)
+ {
+-	int32_t n,hx,hy,hz,ix,iy,sx,i;
+-	uint32_t lx,ly,lz;
++	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;
+ 
+-	EXTRACT_WORDS(hx, lx, x);
+-	EXTRACT_WORDS(hy, ly, y);
+-	sx = hx & 0x80000000;  /* sign of x */
+-	hx ^= sx;              /* |x| */
+-	hy &= 0x7fffffff;      /* |y| */
+-
+-	/* purge off exception values */
+-	if ((hy|ly) == 0 || hx >= 0x7ff00000 ||  /* y=0,or x not finite */
+-	    (hy|((ly|-ly)>>31)) > 0x7ff00000)    /* or y is NaN */
++	if (uy.i<<1 == 0 || isnan(y) || ex == 0x7ff)
+ 		return (x*y)/(x*y);
+-	if (hx <= hy) {
+-		if (hx < hy || lx < ly)  /* |x| < |y| */
+-			return x;
+-		if (lx == ly)            /* |x| = |y|, return x*0 */
+-			return Zero[(uint32_t)sx>>31];
+-	}
+-
+-	/* determine ix = ilogb(x) */
+-	if (hx < 0x00100000) {  /* subnormal x */
+-		if (hx == 0) {
+-			for (ix = -1043, i = lx; i > 0; i <<= 1)
+-				ix -= 1;
+-		} else {
+-			for (ix = -1022, i = hx<<11; i > 0; i <<= 1)
+-				ix -= 1;
+-		}
+-	} else
+-		ix = (hx>>20) - 1023;
+-
+-	/* determine iy = ilogb(y) */
+-	if (hy < 0x00100000) {  /* subnormal y */
+-		if (hy == 0) {
+-			for (iy = -1043, i = ly; i > 0; i <<= 1)
+-				iy -= 1;
+-		} else {
+-			for (iy = -1022, i = hy<<11; i > 0; i <<= 1)
+-				iy -= 1;
+-		}
+-	} else
+-		iy = (hy>>20) - 1023;
+-
+-	/* set up {hx,lx}, {hy,ly} and align y to x */
+-	if (ix >= -1022)
+-		hx = 0x00100000|(0x000fffff&hx);
+-	else {       /* subnormal x, shift x to normal */
+-		n = -1022-ix;
+-		if (n <= 31) {
+-			hx = (hx<<n)|(lx>>(32-n));
+-			lx <<= n;
+-		} else {
+-			hx = lx<<(n-32);
+-			lx = 0;
+-		}
+-	}
+-	if(iy >= -1022)
+-		hy = 0x00100000|(0x000fffff&hy);
+-	else {       /* subnormal y, shift y to normal */
+-		n = -1022-iy;
+-		if (n <= 31) {
+-			hy = (hy<<n)|(ly>>(32-n));
+-			ly <<= n;
+-		} else {
+-			hy = ly<<(n-32);
+-			ly = 0;
+-		}
+-	}
+-
+-	/* fix point fmod */
+-	n = ix - iy;
+-	while (n--) {
+-		hz = hx-hy;
+-		lz = lx-ly;
+-		if (lx < ly)
+-			hz -= 1;
+-		if (hz < 0) {
+-			hx = hx+hx+(lx>>31);
+-			lx = lx+lx;
+-		} else {
+-			if ((hz|lz) == 0)   /* return sign(x)*0 */
+-				return Zero[(uint32_t)sx>>31];
+-			hx = hz+hz+(lz>>31);
+-			lx = lz+lz;
+-		}
+-	}
+-	hz = hx-hy;
+-	lz = lx-ly;
+-	if (lx < ly)
+-		hz -= 1;
+-	if (hz >= 0) {
+-		hx = hz;
+-		lx = lz;
+-	}
+-
+-	/* convert back to floating value and restore the sign */
+-	if ((hx|lx) == 0)          /* return sign(x)*0 */
+-		return Zero[(uint32_t)sx>>31];
+-	while (hx < 0x00100000) {  /* normalize x */
+-		hx = hx+hx+(lx>>31);
+-		lx = lx+lx;
+-		iy -= 1;
+-	}
+-	if (iy >= -1022) {         /* normalize output */
+-		hx = ((hx-0x00100000)|((iy+1023)<<20));
+-		INSERT_WORDS(x, hx|sx, lx);
+-	} else {                   /* subnormal output */
+-		n = -1022 - iy;
+-		if (n <= 20) {
+-			lx = (lx>>n)|((uint32_t)hx<<(32-n));
+-			hx >>= n;
+-		} else if (n <= 31) {
+-			lx = (hx<<(32-n))|(lx>>n);
+-			hx = sx;
+-		} else {
+-			lx = hx>>(n-32); hx = sx;
+-		}
+-		INSERT_WORDS(x, hx|sx, lx);
+-	}
+-	return x;  /* exact output */
++	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;
+ }
+diff -Nur musl-0.9.13/src/math/fmodf.c musl-git/src/math/fmodf.c
+--- musl-0.9.13/src/math/fmodf.c	2013-08-30 23:30:53.000000000 +0200
++++ musl-git/src/math/fmodf.c	2013-09-16 20:31:39.000000000 +0200
+@@ -1,104 +1,65 @@
+-/* origin: FreeBSD /usr/src/lib/msun/src/e_fmodf.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.
+- * ====================================================
+- */
+-/*
+- * fmodf(x,y)
+- * Return x mod y in exact arithmetic
+- * Method: shift and subtract
+- */
+-
+-#include "libm.h"
+-
+-static const float Zero[] = {0.0, -0.0,};
++#include <math.h>
++#include <stdint.h>
+ 
+ float fmodf(float x, float y)
+ {
+-	int32_t n,hx,hy,hz,ix,iy,sx,i;
++	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;
+ 
+-	GET_FLOAT_WORD(hx, x);
+-	GET_FLOAT_WORD(hy, y);
+-	sx = hx & 0x80000000;  /* sign of x */
+-	hx ^= sx;              /* |x| */
+-	hy &= 0x7fffffff;      /* |y| */
+-
+-	/* purge off exception values */
+-	if (hy == 0 || hx >= 0x7f800000 ||  /* y=0,or x not finite */
+-	    hy > 0x7f800000)                /* or y is NaN */
++	if (uy.i<<1 == 0 || isnan(y) || ex == 0xff)
+ 		return (x*y)/(x*y);
+-	if (hx < hy)                        /* |x| < |y| */
++	if (uxi<<1 <= uy.i<<1) {
++		if (uxi<<1 == uy.i<<1)
++			return 0*x;
+ 		return x;
+-	if (hx == hy)                       /* |x| = |y|, return x*0 */
+-		return Zero[(uint32_t)sx>>31];
+-
+-	/* determine ix = ilogb(x) */
+-	if (hx < 0x00800000) {     /* subnormal x */
+-		for (ix = -126, i = hx<<8; i > 0; i <<= 1)
+-			ix -= 1;
+-	} else
+-		ix = (hx>>23) - 127;
+-
+-	/* determine iy = ilogb(y) */
+-	if (hy < 0x00800000) {     /* subnormal y */
+-		for (iy = -126, i = hy<<8; i >= 0; i <<= 1)
+-			iy -= 1;
+-	} else
+-		iy = (hy>>23) - 127;
++	}
+ 
+-	/* set up {hx,lx}, {hy,ly} and align y to x */
+-	if (ix >= -126)
+-		hx = 0x00800000|(0x007fffff&hx);
+-	else {          /* subnormal x, shift x to normal */
+-		n = -126-ix;
+-		hx = hx<<n;
+-	}
+-	if (iy >= -126)
+-		hy = 0x00800000|(0x007fffff&hy);
+-	else {          /* subnormal y, shift y to normal */
+-		n = -126-iy;
+-		hy = hy<<n;
++	/* 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;
+ 	}
+ 
+-	/* fix point fmod */
+-	n = ix - iy;
+-	while (n--) {
+-		hz = hx-hy;
+-		if (hz<0)
+-			hx = hx+hx;
+-		else {
+-			if(hz == 0)   /* return sign(x)*0 */
+-				return Zero[(uint32_t)sx>>31];
+-			hx = hz+hz;
++	/* 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;
+ 	}
+-	hz = hx-hy;
+-	if (hz >= 0)
+-		hx = hz;
++	for (; uxi>>23 == 0; uxi <<= 1, ex--);
+ 
+-	/* convert back to floating value and restore the sign */
+-	if (hx == 0)               /* return sign(x)*0 */
+-		return Zero[(uint32_t)sx>>31];
+-	while (hx < 0x00800000) {  /* normalize x */
+-		hx = hx+hx;
+-		iy -= 1;
+-	}
+-	if (iy >= -126) {          /* normalize output */
+-		hx = ((hx-0x00800000)|((iy+127)<<23));
+-		SET_FLOAT_WORD(x, hx|sx);
+-	} else {                   /* subnormal output */
+-		n = -126 - iy;
+-		hx >>= n;
+-		SET_FLOAT_WORD(x, hx|sx);
++	/* scale result up */
++	if (ex > 0) {
++		uxi -= 1U << 23;
++		uxi |= (uint32_t)ex << 23;
++	} else {
++		uxi >>= -ex + 1;
+ 	}
+-	return x;  /* exact output */
++	uxi |= sx;
++	ux.i = uxi;
++	return ux.f;
+ }
+diff -Nur musl-0.9.13/src/math/fmodl.c musl-git/src/math/fmodl.c
+--- musl-0.9.13/src/math/fmodl.c	2013-08-30 23:30:53.000000000 +0200
++++ musl-git/src/math/fmodl.c	2013-09-16 20:31:39.000000000 +0200
+@@ -1,15 +1,3 @@
+-/* origin: FreeBSD /usr/src/lib/msun/src/e_fmodl.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.
+- * ====================================================
+- */
+-
+ #include "libm.h"
+ 
+ #if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024
+@@ -18,141 +6,100 @@
+ 	return fmod(x, y);
+ }
+ #elif (LDBL_MANT_DIG == 64 || LDBL_MANT_DIG == 113) && LDBL_MAX_EXP == 16384
+-
+-#define BIAS (LDBL_MAX_EXP - 1)
+-
+-#if LDBL_MANL_SIZE > 32
+-typedef uint64_t manl_t;
+-#else
+-typedef uint32_t manl_t;
+-#endif
+-
+-#if LDBL_MANH_SIZE > 32
+-typedef uint64_t manh_t;
+-#else
+-typedef uint32_t manh_t;
+-#endif
+-
+-/*
+- * These macros add and remove an explicit integer bit in front of the
+- * fractional mantissa, if the architecture doesn't have such a bit by
+- * default already.
+- */
+-#ifdef LDBL_IMPLICIT_NBIT
+-#define SET_NBIT(hx)    ((hx) | (1ULL << LDBL_MANH_SIZE))
+-#define HFRAC_BITS      LDBL_MANH_SIZE
+-#else
+-#define SET_NBIT(hx)    (hx)
+-#define HFRAC_BITS      (LDBL_MANH_SIZE - 1)
+-#endif
+-
+-#define MANL_SHIFT      (LDBL_MANL_SIZE - 1)
+-
+-static const long double Zero[] = {0.0, -0.0,};
+-
+-/*
+- * fmodl(x,y)
+- * Return x mod y in exact arithmetic
+- * Method: shift and subtract
+- *
+- * Assumptions:
+- * - The low part of the mantissa fits in a manl_t exactly.
+- * - The high part of the mantissa fits in an int64_t with enough room
+- *   for an explicit integer bit in front of the fractional bits.
+- */
+ long double fmodl(long double x, long double y)
+ {
+-	union IEEEl2bits ux, uy;
+-	int64_t hx,hz;  /* We need a carry bit even if LDBL_MANH_SIZE is 32. */
+-	manh_t hy;
+-	manl_t lx,ly,lz;
+-	int ix,iy,n,sx;
+-
+-	ux.e = x;
+-	uy.e = y;
+-	sx = ux.bits.sign;
++	union ldshape ux = {x}, uy = {y};
++	int ex = ux.i.se & 0x7fff;
++	int ey = uy.i.se & 0x7fff;
++	int sx = ux.i.se & 0x8000;
+ 
+-	/* purge off exception values */
+-	if ((uy.bits.exp|uy.bits.manh|uy.bits.manl) == 0 || /* y=0 */
+-	    ux.bits.exp == BIAS + LDBL_MAX_EXP ||           /* or x not finite */
+-	    (uy.bits.exp == BIAS + LDBL_MAX_EXP &&
+-	     ((uy.bits.manh&~LDBL_NBIT)|uy.bits.manl) != 0)) /* or y is NaN */
++	if (y == 0 || isnan(y) || ex == 0x7fff)
+ 		return (x*y)/(x*y);
+-	if (ux.bits.exp <= uy.bits.exp) {
+-		if (ux.bits.exp < uy.bits.exp ||
+-		    (ux.bits.manh<=uy.bits.manh &&
+-		     (ux.bits.manh<uy.bits.manh ||
+-		      ux.bits.manl<uy.bits.manl)))  /* |x|<|y| return x or x-y */
+-			return x;
+-		if (ux.bits.manh==uy.bits.manh && ux.bits.manl==uy.bits.manl)
+-			return Zero[sx];  /* |x| = |y| return x*0 */
+-	}
+-
+-	/* determine ix = ilogb(x) */
+-	if (ux.bits.exp == 0) {  /* subnormal x */
+-		ux.e *= 0x1.0p512;
+-		ix = ux.bits.exp - (BIAS + 512);
+-	} else {
+-		ix = ux.bits.exp - BIAS;
+-	}
+-
+-	/* determine iy = ilogb(y) */
+-	if (uy.bits.exp == 0) {  /* subnormal y */
+-		uy.e *= 0x1.0p512;
+-		iy = uy.bits.exp - (BIAS + 512);
+-	} else {
+-		iy = uy.bits.exp - BIAS;
+-	}
+-
+-	/* set up {hx,lx}, {hy,ly} and align y to x */
+-	hx = SET_NBIT(ux.bits.manh);
+-	hy = SET_NBIT(uy.bits.manh);
+-	lx = ux.bits.manl;
+-	ly = uy.bits.manl;
+-
+-	/* fix point fmod */
+-	n = ix - iy;
+-
+-	while (n--) {
+-		hz = hx-hy;
+-		lz = lx-ly;
+-		if (lx < ly)
+-			hz -= 1;
+-		if (hz < 0) {
+-			hx = hx+hx+(lx>>MANL_SHIFT);
+-			lx = lx+lx;
++	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 {
+-			if ((hz|lz)==0)   /* return sign(x)*0 */
+-				return Zero[sx];
+-			hx = hz+hz+(lz>>MANL_SHIFT);
+-			lx = lz+lz;
++			mx = 2*mx;
+ 		}
+ 	}
+-	hz = hx-hy;
+-	lz = lx-ly;
+-	if (lx < ly)
+-		hz -= 1;
+-	if (hz >= 0) {
+-		hx = hz;
+-		lx = lz;
++	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 = ux.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
+ 
+-	/* convert back to floating value and restore the sign */
+-	if ((hx|lx) == 0)   /* return sign(x)*0 */
+-		return Zero[sx];
+-	while (hx < (1ULL<<HFRAC_BITS)) {  /* normalize x */
+-		hx = hx+hx+(lx>>MANL_SHIFT);
+-		lx = lx+lx;
+-		iy -= 1;
+-	}
+-	ux.bits.manh = hx; /* The mantissa is truncated here if needed. */
+-	ux.bits.manl = lx;
+-	if (iy < LDBL_MIN_EXP) {
+-		ux.bits.exp = iy + (BIAS + 512);
+-		ux.e *= 0x1p-512;
+-	} else {
+-		ux.bits.exp = iy + BIAS;
+-	}
+-	return ux.e;       /* exact output */
++	/* 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
+diff -Nur musl-0.9.13/src/math/frexpl.c musl-git/src/math/frexpl.c
+--- musl-0.9.13/src/math/frexpl.c	2013-08-30 23:30:53.000000000 +0200
++++ musl-git/src/math/frexpl.c	2013-09-16 20:31:39.000000000 +0200
+@@ -1,20 +1,20 @@
+-#include <math.h>
+-#include <stdint.h>
+-#include <float.h>
+-
+-#if LDBL_MANT_DIG == 64 && LDBL_MAX_EXP == 16384
+-
+-/* This version is for 80-bit little endian long double */
++#include "libm.h"
+ 
++#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024
+ long double frexpl(long double x, int *e)
+ {
+-	union { long double ld; uint16_t hw[5]; } y = { x };
+-	int ee = y.hw[4]&0x7fff;
++	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*0x1p64, e);
+-			*e -= 64;
++			x = frexpl(x*0x1p120, e);
++			*e -= 120;
+ 		} else *e = 0;
+ 		return x;
+ 	} else if (ee == 0x7fff) {
+@@ -22,16 +22,8 @@
+ 	}
+ 
+ 	*e = ee - 0x3ffe;
+-	y.hw[4] &= 0x8000;
+-	y.hw[4] |= 0x3ffe;
+-	return y.ld;
++	u.i.se &= 0x8000;
++	u.i.se |= 0x3ffe;
++	return u.f;
+ }
+-
+-#else
+-
+-long double frexpl(long double x, int *e)
+-{
+-	return frexp(x, e);
+-}
+-
+ #endif
+diff -Nur musl-0.9.13/src/math/hypot.c musl-git/src/math/hypot.c
+--- musl-0.9.13/src/math/hypot.c	2013-08-30 23:30:53.000000000 +0200
++++ musl-git/src/math/hypot.c	2013-09-16 20:31:39.000000000 +0200
+@@ -1,123 +1,67 @@
+-/* origin: FreeBSD /usr/src/lib/msun/src/e_hypot.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.
+- * ====================================================
+- */
+-/* hypot(x,y)
+- *
+- * Method :
+- *      If (assume round-to-nearest) z=x*x+y*y
+- *      has error less than sqrt(2)/2 ulp, then
+- *      sqrt(z) has error less than 1 ulp (exercise).
+- *
+- *      So, compute sqrt(x*x+y*y) with some care as
+- *      follows to get the error below 1 ulp:
+- *
+- *      Assume x>y>0;
+- *      (if possible, set rounding to round-to-nearest)
+- *      1. if x > 2y  use
+- *              x1*x1+(y*y+(x2*(x+x1))) for x*x+y*y
+- *      where x1 = x with lower 32 bits cleared, x2 = x-x1; else
+- *      2. if x <= 2y use
+- *              t1*y1+((x-y)*(x-y)+(t1*y2+t2*y))
+- *      where t1 = 2x with lower 32 bits cleared, t2 = 2x-t1,
+- *      y1= y with lower 32 bits chopped, y2 = y-y1.
+- *
+- *      NOTE: scaling may be necessary if some argument is too
+- *            large or too tiny
+- *
+- * Special cases:
+- *      hypot(x,y) is INF if x or y is +INF or -INF; else
+- *      hypot(x,y) is NAN if x or y is NAN.
+- *
+- * Accuracy:
+- *      hypot(x,y) returns sqrt(x^2+y^2) with error less
+- *      than 1 ulps (units in the last place)
+- */
++#include <math.h>
++#include <stdint.h>
++#include <float.h>
+ 
+-#include "libm.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 = x*SPLIT;
++	xh = x - xc + xc;
++	xl = x - xh;
++	*hi = x*x;
++	*lo = xh*xh - *hi + 2*xh*xl + xl*xl;
++}
+ 
+ double hypot(double x, double y)
+ {
+-	double a,b,t1,t2,y1,y2,w;
+-	int32_t j,k,ha,hb;
++	union {double f; uint64_t i;} ux = {x}, uy = {y}, ut;
++	int ex, ey;
++	double_t hx, lx, hy, ly, z;
+ 
+-	GET_HIGH_WORD(ha, x);
+-	ha &= 0x7fffffff;
+-	GET_HIGH_WORD(hb, y);
+-	hb &= 0x7fffffff;
+-	if (hb > ha) {
+-		a = y;
+-		b = x;
+-		j=ha; ha=hb; hb=j;
+-	} else {
+-		a = x;
+-		b = y;
++	/* arrange |x| >= |y| */
++	ux.i &= -1ULL>>1;
++	uy.i &= -1ULL>>1;
++	if (ux.i < uy.i) {
++		ut = ux;
++		ux = uy;
++		uy = ut;
+ 	}
+-	a = fabs(a);
+-	b = fabs(b);
+-	if (ha - hb > 0x3c00000)  /* x/y > 2**60 */
+-		return a+b;
+-	k = 0;
+-	if (ha > 0x5f300000) {    /* a > 2**500 */
+-		if(ha >= 0x7ff00000) {  /* Inf or NaN */
+-			uint32_t low;
+-			/* Use original arg order iff result is NaN; quieten sNaNs. */
+-			w = fabs(x+0.0) - fabs(y+0.0);
+-			GET_LOW_WORD(low, a);
+-			if (((ha&0xfffff)|low) == 0) w = a;
+-			GET_LOW_WORD(low, b);
+-			if (((hb^0x7ff00000)|low) == 0) w = b;
+-			return w;
+-		}
+-		/* scale a and b by 2**-600 */
+-		ha -= 0x25800000; hb -= 0x25800000;  k += 600;
+-		SET_HIGH_WORD(a, ha);
+-		SET_HIGH_WORD(b, hb);
+-	}
+-	if (hb < 0x20b00000) {    /* b < 2**-500 */
+-		if (hb <= 0x000fffff) {  /* subnormal b or 0 */
+-			uint32_t low;
+-			GET_LOW_WORD(low, b);
+-			if ((hb|low) == 0)
+-				return a;
+-			t1 = 0;
+-			SET_HIGH_WORD(t1, 0x7fd00000);  /* t1 = 2^1022 */
+-			b *= t1;
+-			a *= t1;
+-			k -= 1022;
+-		} else {            /* scale a and b by 2^600 */
+-			ha += 0x25800000;  /* a *= 2^600 */
+-			hb += 0x25800000;  /* b *= 2^600 */
+-			k -= 600;
+-			SET_HIGH_WORD(a, ha);
+-			SET_HIGH_WORD(b, hb);
+-		}
+-	}
+-	/* medium size a and b */
+-	w = a - b;
+-	if (w > b) {
+-		t1 = 0;
+-		SET_HIGH_WORD(t1, ha);
+-		t2 = a-t1;
+-		w  = sqrt(t1*t1-(b*(-b)-t2*(a+t1)));
+-	} else {
+-		a  = a + a;
+-		y1 = 0;
+-		SET_HIGH_WORD(y1, hb);
+-		y2 = b - y1;
+-		t1 = 0;
+-		SET_HIGH_WORD(t1, ha+0x00100000);
+-		t2 = a - t1;
+-		w  = sqrt(t1*y1-(w*(-w)-(t1*y2+t2*b)));
++
++	/* 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;
+ 	}
+-	if (k)
+-		w = scalbn(w, k);
+-	return w;
++	sq(&hx, &lx, x);
++	sq(&hy, &ly, y);
++	return z*sqrt(ly+lx+hy+hx);
+ }
+diff -Nur musl-0.9.13/src/math/hypotf.c musl-git/src/math/hypotf.c
+--- musl-0.9.13/src/math/hypotf.c	2013-08-30 23:30:53.000000000 +0200
++++ musl-git/src/math/hypotf.c	2013-09-16 20:31:39.000000000 +0200
+@@ -1,86 +1,35 @@
+-/* origin: FreeBSD /usr/src/lib/msun/src/e_hypotf.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"
++#include <math.h>
++#include <stdint.h>
+ 
+ float hypotf(float x, float y)
+ {
+-	float a,b,t1,t2,y1,y2,w;
+-	int32_t j,k,ha,hb;
++	union {float f; uint32_t i;} ux = {x}, uy = {y}, ut;
++	float_t z;
+ 
+-	GET_FLOAT_WORD(ha,x);
+-	ha &= 0x7fffffff;
+-	GET_FLOAT_WORD(hb,y);
+-	hb &= 0x7fffffff;
+-	if (hb > ha) {
+-		a = y;
+-		b = x;
+-		j=ha; ha=hb; hb=j;
+-	} else {
+-		a = x;
+-		b = y;
+-	}
+-	a = fabsf(a);
+-	b = fabsf(b);
+-	if (ha - hb > 0xf000000)  /* x/y > 2**30 */
+-		return a+b;
+-	k = 0;
+-	if (ha > 0x58800000) {    /* a > 2**50 */
+-		if(ha >= 0x7f800000) {  /* Inf or NaN */
+-			/* Use original arg order iff result is NaN; quieten sNaNs. */
+-			w = fabsf(x+0.0f) - fabsf(y+0.0f);
+-			if (ha == 0x7f800000) w = a;
+-			if (hb == 0x7f800000) w = b;
+-			return w;
+-		}
+-		/* scale a and b by 2**-68 */
+-		ha -= 0x22000000; hb -= 0x22000000; k += 68;
+-		SET_FLOAT_WORD(a, ha);
+-		SET_FLOAT_WORD(b, hb);
+-	}
+-	if (hb < 0x26800000) {    /* b < 2**-50 */
+-		if (hb <= 0x007fffff) {  /* subnormal b or 0 */
+-			if (hb == 0)
+-				return a;
+-			SET_FLOAT_WORD(t1, 0x7e800000);  /* t1 = 2^126 */
+-			b *= t1;
+-			a *= t1;
+-			k -= 126;
+-		} else {   /* scale a and b by 2^68 */
+-			ha += 0x22000000;  /* a *= 2^68 */
+-			hb += 0x22000000;  /* b *= 2^68 */
+-			k -= 68;
+-			SET_FLOAT_WORD(a, ha);
+-			SET_FLOAT_WORD(b, hb);
+-		}
++	ux.i &= -1U>>1;
++	uy.i &= -1U>>1;
++	if (ux.i < uy.i) {
++		ut = ux;
++		ux = uy;
++		uy = ut;
+ 	}
+-	/* medium size a and b */
+-	w = a - b;
+-	if (w > b) {
+-		SET_FLOAT_WORD(t1, ha&0xfffff000);
+-		t2 = a - t1;
+-		w  = sqrtf(t1*t1-(b*(-b)-t2*(a+t1)));
+-	} else {
+-		a  = a + a;
+-		SET_FLOAT_WORD(y1, hb&0xfffff000);
+-		y2 = b - y1;
+-		SET_FLOAT_WORD(t1,(ha+0x00800000)&0xfffff000);
+-		t2 = a - t1;
+-		w  = sqrtf(t1*y1-(w*(-w)-(t1*y2+t2*b)));
++
++	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;
+ 	}
+-	if (k)
+-		w = scalbnf(w, k);
+-	return w;
++	return z*sqrtf((double)x*x + (double)y*y);
+ }
+diff -Nur musl-0.9.13/src/math/hypotl.c musl-git/src/math/hypotl.c
+--- musl-0.9.13/src/math/hypotl.c	2013-08-30 23:30:53.000000000 +0200
++++ musl-git/src/math/hypotl.c	2013-09-16 20:31:39.000000000 +0200
+@@ -1,16 +1,3 @@
+-/* origin: FreeBSD /usr/src/lib/msun/src/e_hypotl.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.
+- * ====================================================
+- */
+-/* long double version of hypot().  See comments in hypot.c. */
+-
+ #include "libm.h"
+ 
+ #if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024
+@@ -19,130 +6,61 @@
+ 	return hypot(x, y);
+ }
+ #elif (LDBL_MANT_DIG == 64 || LDBL_MANT_DIG == 113) && LDBL_MAX_EXP == 16384
+-
+-#define GET_LDBL_EXPSIGN(i, v) do {     \
+-	union IEEEl2bits uv;            \
+-					\
+-	uv.e = v;                       \
+-	i = uv.xbits.expsign;           \
+-} while (0)
+-
+-#define GET_LDBL_MAN(h, l, v) do {      \
+-	union IEEEl2bits uv;            \
+-					\
+-	uv.e = v;                       \
+-	h = uv.bits.manh;               \
+-	l = uv.bits.manl;               \
+-} while (0)
+-
+-#define SET_LDBL_EXPSIGN(v, i) do {     \
+-	union IEEEl2bits uv;            \
+-					\
+-	uv.e = v;                       \
+-	uv.xbits.expsign = i;           \
+-	v = uv.e;                       \
+-} while (0)
+-
+-#undef GET_HIGH_WORD
+-#define GET_HIGH_WORD(i, v)     GET_LDBL_EXPSIGN(i, v)
+-#undef SET_HIGH_WORD
+-#define SET_HIGH_WORD(v, i)     SET_LDBL_EXPSIGN(v, i)
+-
+-#define DESW(exp)       (exp)           /* delta expsign word */
+-#define ESW(exp)        (MAX_EXP - 1 + (exp))   /* expsign word */
+-#define MANT_DIG        LDBL_MANT_DIG
+-#define MAX_EXP         LDBL_MAX_EXP
+-
+-#if LDBL_MANL_SIZE > 32
+-typedef uint64_t man_t;
+-#else
+-typedef uint32_t man_t;
++#if LDBL_MANT_DIG == 64
++#define SPLIT (0x1p32L+1)
++#elif LDBL_MANT_DIG == 113
++#define SPLIT (0x1p57L+1)
+ #endif
+ 
+-long double hypotl(long double x, long double y)
++static void sq(long double *hi, long double *lo, long double x)
+ {
+-	long double a=x,b=y,t1,t2,y1,y2,w;
+-	int32_t j,k,ha,hb;
++	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;
++}
+ 
+-	GET_HIGH_WORD(ha, x);
+-	ha &= 0x7fff;
+-	GET_HIGH_WORD(hb, y);
+-	hb &= 0x7fff;
+-	if (hb > ha) {
+-		a = y;
+-		b = x;
+-		j=ha; ha=hb; hb=j;
+-	} else {
+-		a = x;
+-		b = y;
+-	}
+-	a = fabsl(a);
+-	b = fabsl(b);
+-	if (ha - hb > DESW(MANT_DIG+7))  /* x/y > 2**(MANT_DIG+7) */
+-		return a+b;
+-	k = 0;
+-	if (ha > ESW(MAX_EXP/2-12)) {    /* a>2**(MAX_EXP/2-12) */
+-		if (ha >= ESW(MAX_EXP)) {  /* Inf or NaN */
+-			man_t manh, manl;
+-			/* Use original arg order iff result is NaN; quieten sNaNs. */
+-			w = fabsl(x+0.0)-fabsl(y+0.0);
+-			GET_LDBL_MAN(manh,manl,a);
+-			if (manh == LDBL_NBIT && manl == 0) w = a;
+-			GET_LDBL_MAN(manh,manl,b);
+-			if (hb >= ESW(MAX_EXP) && manh == LDBL_NBIT && manl == 0) w = b;
+-			return w;
+-		}
+-		/* scale a and b by 2**-(MAX_EXP/2+88) */
+-		ha -= DESW(MAX_EXP/2+88); hb -= DESW(MAX_EXP/2+88);
+-		k += MAX_EXP/2+88;
+-		SET_HIGH_WORD(a, ha);
+-		SET_HIGH_WORD(b, hb);
+-	}
+-	if (hb < ESW(-(MAX_EXP/2-12))) {  /* b < 2**-(MAX_EXP/2-12) */
+-		if (hb <= 0) {  /* subnormal b or 0 */
+-			man_t manh, manl;
+-			GET_LDBL_MAN(manh,manl,b);
+-			if ((manh|manl) == 0)
+-				return a;
+-			t1 = 0;
+-			SET_HIGH_WORD(t1, ESW(MAX_EXP-2));  /* t1 = 2^(MAX_EXP-2) */
+-			b *= t1;
+-			a *= t1;
+-			k -= MAX_EXP-2;
+-		} else {            /* scale a and b by 2^(MAX_EXP/2+88) */
+-			ha += DESW(MAX_EXP/2+88);
+-			hb += DESW(MAX_EXP/2+88);
+-			k -= MAX_EXP/2+88;
+-			SET_HIGH_WORD(a, ha);
+-			SET_HIGH_WORD(b, hb);
+-		}
+-	}
+-	/* medium size a and b */
+-	w = a - b;
+-	if (w > b) {
+-		t1 = a;
+-		union IEEEl2bits uv;
+-		uv.e = t1; uv.bits.manl = 0; t1 = uv.e;
+-		t2 = a-t1;
+-		w  = sqrtl(t1*t1-(b*(-b)-t2*(a+t1)));
++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 {
+-		a  = a+a;
+-		y1 = b;
+-		union IEEEl2bits uv;
+-		uv.e = y1; uv.bits.manl = 0; y1 = uv.e;
+-		y2 = b - y1;
+-		t1 = a;
+-		uv.e = t1; uv.bits.manl = 0; t1 = uv.e;
+-		t2 = a - t1;
+-		w  = sqrtl(t1*y1-(w*(-w)-(t1*y2+t2*b)));
++		ex = ux.i.se;
++		ey = uy.i.se;
++		x = ux.f;
++		y = uy.f;
+ 	}
+-	if(k!=0) {
+-		uint32_t high;
+-		t1 = 1.0;
+-		GET_HIGH_WORD(high, t1);
+-		SET_HIGH_WORD(t1, high+DESW(k));
+-		return t1*w;
++
++	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;
+ 	}
+-	return w;
++	sq(&hx, &lx, x);
++	sq(&hy, &ly, y);
++	return z*sqrtl(ly+lx+hy+hx);
+ }
+ #endif
+diff -Nur musl-0.9.13/src/math/i386/exp.s musl-git/src/math/i386/exp.s
+--- musl-0.9.13/src/math/i386/exp.s	2013-08-30 23:30:53.000000000 +0200
++++ musl-git/src/math/i386/exp.s	2013-09-16 20:31:39.000000000 +0200
+@@ -95,42 +95,32 @@
+ .type exp2,@function
+ exp2:
+ 	fldl 4(%esp)
+-1:	pushl $0x467ff000
+-	flds (%esp)       # 16380
+-	xorl %eax,%eax
+-	pushl $0x80000000
+-	push %eax
+-	fld %st(1)
+-	fabs
+-	fucomp %st(1)
+-	fnstsw
+-	fstp %st(0)
+-	sahf
+-	ja 3f             # |x| > 16380
+-	jp 2f             # x is nan (avoid invalid except in fistp)
++1:	sub $12,%esp
+ 	fld %st(0)
+-	fistpl 8(%esp)
+-	fildl 8(%esp)
+-	fxch %st(1)
+-	fsub %st(1)
+-	mov $0x3fff,%eax
+-	add %eax,8(%esp)
+-	f2xm1
+-	fld1
+-	faddp             # 2^(x-rint(x))
+-	fldt (%esp)       # 2^rint(x)
+-	fmulp
+-	fstp %st(1)
+-2:	add $12,%esp
+-	ret
+-
+-3:	fld %st(0)
+ 	fstpt (%esp)
+-	fld1
+ 	mov 8(%esp),%ax
+ 	and $0x7fff,%ax
+-	cmp $0x7fff,%ax
+-	je 1f             # x = +-inf
++	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)
+@@ -141,3 +131,19 @@
+ 	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
+diff -Nur musl-0.9.13/src/math/ilogb.c musl-git/src/math/ilogb.c
+--- musl-0.9.13/src/math/ilogb.c	2013-08-30 23:30:53.000000000 +0200
++++ musl-git/src/math/ilogb.c	2013-09-16 20:31:39.000000000 +0200
+@@ -3,22 +3,24 @@
+ 
+ int ilogb(double x)
+ {
+-	union dshape u = {x};
+-	int e = u.bits>>52 & 0x7ff;
++	#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) {
+-		u.bits <<= 12;
+-		if (u.bits == 0) {
++		i <<= 12;
++		if (i == 0) {
+ 			FORCE_EVAL(0/0.0f);
+ 			return FP_ILOGB0;
+ 		}
+ 		/* subnormal x */
+-		for (e = -0x3ff; u.bits < (uint64_t)1<<63; e--, u.bits<<=1);
++		for (e = -0x3ff; i>>63 == 0; e--, i<<=1);
+ 		return e;
+ 	}
+ 	if (e == 0x7ff) {
+ 		FORCE_EVAL(0/0.0f);
+-		return u.bits<<12 ? FP_ILOGBNAN : INT_MAX;
++		return i<<12 ? FP_ILOGBNAN : INT_MAX;
+ 	}
+ 	return e - 0x3ff;
+ }
+diff -Nur musl-0.9.13/src/math/ilogbf.c musl-git/src/math/ilogbf.c
+--- musl-0.9.13/src/math/ilogbf.c	2013-08-30 23:30:53.000000000 +0200
++++ musl-git/src/math/ilogbf.c	2013-09-16 20:31:39.000000000 +0200
+@@ -3,22 +3,24 @@
+ 
+ int ilogbf(float x)
+ {
+-	union fshape u = {x};
+-	int e = u.bits>>23 & 0xff;
++	#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) {
+-		u.bits <<= 9;
+-		if (u.bits == 0) {
++		i <<= 9;
++		if (i == 0) {
+ 			FORCE_EVAL(0/0.0f);
+ 			return FP_ILOGB0;
+ 		}
+ 		/* subnormal x */
+-		for (e = -0x7f; u.bits < (uint32_t)1<<31; e--, u.bits<<=1);
++		for (e = -0x7f; i>>31 == 0; e--, i<<=1);
+ 		return e;
+ 	}
+ 	if (e == 0xff) {
+ 		FORCE_EVAL(0/0.0f);
+-		return u.bits<<9 ? FP_ILOGBNAN : INT_MAX;
++		return i<<9 ? FP_ILOGBNAN : INT_MAX;
+ 	}
+ 	return e - 0x7f;
+ }
+diff -Nur musl-0.9.13/src/math/ilogbl.c musl-git/src/math/ilogbl.c
+--- musl-0.9.13/src/math/ilogbl.c	2013-08-30 23:30:53.000000000 +0200
++++ musl-git/src/math/ilogbl.c	2013-09-16 20:31:39.000000000 +0200
+@@ -9,9 +9,10 @@
+ #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.bits.m;
+-	int e = u.bits.exp;
++	uint64_t m = u.i.m;
++	int e = u.i.se & 0x7fff;
+ 
+ 	if (!e) {
+ 		if (m == 0) {
+@@ -19,13 +20,35 @@
+ 			return FP_ILOGB0;
+ 		}
+ 		/* subnormal x */
+-		for (e = -0x3fff+1; m < (uint64_t)1<<63; e--, m<<=1);
++		for (e = -0x3fff+1; m>>63 == 0; e--, m<<=1);
+ 		return e;
+ 	}
+ 	if (e == 0x7fff) {
+ 		FORCE_EVAL(0/0.0f);
+-		/* in ld80 msb is set in inf */
+-		return m & (uint64_t)-1>>1 ? FP_ILOGBNAN : INT_MAX;
++		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;
+ }
+diff -Nur musl-0.9.13/src/math/lgamma_r.c musl-git/src/math/lgamma_r.c
+--- musl-0.9.13/src/math/lgamma_r.c	2013-08-30 23:30:53.000000000 +0200
++++ musl-git/src/math/lgamma_r.c	2013-09-16 20:31:39.000000000 +0200
+@@ -79,6 +79,7 @@
+  */
+ 
+ #include "libm.h"
++#include "libc.h"
+ 
+ static const double
+ two52= 4.50359962737049600000e+15, /* 0x43300000, 0x00000000 */
+diff -Nur musl-0.9.13/src/math/lgammaf_r.c musl-git/src/math/lgammaf_r.c
+--- musl-0.9.13/src/math/lgammaf_r.c	2013-08-30 23:30:53.000000000 +0200
++++ musl-git/src/math/lgammaf_r.c	2013-09-16 20:31:39.000000000 +0200
+@@ -14,6 +14,7 @@
+  */
+ 
+ #include "libm.h"
++#include "libc.h"
+ 
+ static const float
+ two23= 8.3886080000e+06, /* 0x4b000000 */
+diff -Nur musl-0.9.13/src/math/lgammal.c musl-git/src/math/lgammal.c
+--- musl-0.9.13/src/math/lgammal.c	2013-08-30 23:30:53.000000000 +0200
++++ musl-git/src/math/lgammal.c	2013-09-16 20:31:39.000000000 +0200
+@@ -87,6 +87,7 @@
+ 
+ #define _GNU_SOURCE
+ #include "libm.h"
++#include "libc.h"
+ 
+ #if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024
+ double __lgamma_r(double x, int *sg);
+@@ -202,13 +203,11 @@
+ 
+ static long double sin_pi(long double x)
+ {
++	union ldshape u = {x};
++	uint32_t ix = (u.i.se & 0x7fffU)<<16 | u.i.m>>48;
+ 	long double y, z;
+-	int n, ix;
+-	uint32_t se, i0, i1;
++	int n;
+ 
+-	GET_LDOUBLE_WORDS(se, i0, i1, x);
+-	ix = se & 0x7fff;
+-	ix = (ix << 16) | (i0 >> 16);
+ 	if (ix < 0x3ffd8000)  /* 0.25 */
+ 		return sinl(pi * x);
+ 	y = -x;  /* x is assume negative */
+@@ -229,8 +228,8 @@
+ 		} else {
+ 			if (ix < 0x403e8000)  /* 2^63 */
+ 				z = y + two63;  /* exact */
+-			GET_LDOUBLE_WORDS(se, i0, i1, z);
+-			n = i1 & 1;
++			u.f = z;
++			n = u.i.m & 1;
+ 			y = n;
+ 			n <<= 2;
+ 		}
+@@ -261,33 +260,28 @@
+ 
+ long double __lgammal_r(long double x, int *sg) {
+ 	long double t, y, z, nadj, p, p1, p2, q, r, w;
+-	int i, ix;
+-	uint32_t se, i0, i1;
++	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;
+-	GET_LDOUBLE_WORDS(se, i0, i1, x);
+-	ix = se & 0x7fff;
+-
+-	if ((ix | i0 | i1) == 0) {
+-		if (se & 0x8000)
+-			*sg = -1;
+-		return 1.0 / fabsl(x);
+-	}
+-
+-	ix = (ix << 16) | (i0 >> 16);
+ 
+ 	/* purge off +-inf, NaN, +-0, and negative arguments */
+ 	if (ix >= 0x7fff0000)
+ 		return x * x;
+-
++	if (x == 0) {
++		*sg -= 2*sign;
++		return 1.0 / fabsl(x);
++	}
+ 	if (ix < 0x3fc08000) {  /* |x|<2**-63, return -log(|x|) */
+-		if (se & 0x8000) {
++		if (sign) {
+ 			*sg = -1;
+ 			return -logl(-x);
+ 		}
+ 		return -logl(x);
+ 	}
+-	if (se & 0x8000) {
++	if (sign) {
+ 		t = sin_pi (x);
+ 		if (t == 0.0)
+ 			return 1.0 / fabsl(t); /* -integer */
+@@ -297,11 +291,7 @@
+ 		x = -x;
+ 	}
+ 
+-	/* purge off 1 and 2 */
+-	if ((((ix - 0x3fff8000) | i0 | i1) == 0) ||
+-	    (((ix - 0x40008000) | i0 | i1) == 0))
+-		r = 0;
+-	else if (ix < 0x40008000) {  /* x < 2.0 */
++	if (ix < 0x40008000) {  /* x < 2.0 */
+ 		if (ix <= 0x3ffee666) {  /* 8.99993896484375e-1 */
+ 			/* lgamma(x) = lgamma(x+1) - log(x) */
+ 			r = -logl(x);
+@@ -380,7 +370,7 @@
+ 		r = (x - 0.5) * (t - 1.0) + w;
+ 	} else /* 2**66 <= x <= inf */
+ 		r = x * (logl(x) - 1.0);
+-	if (se & 0x8000)
++	if (sign)
+ 		r = nadj - r;
+ 	return r;
+ }
+diff -Nur musl-0.9.13/src/math/log1p.c musl-git/src/math/log1p.c
+--- musl-0.9.13/src/math/log1p.c	2013-08-30 23:30:53.000000000 +0200
++++ musl-git/src/math/log1p.c	2013-09-16 20:31:39.000000000 +0200
+@@ -122,7 +122,7 @@
+ 		return x+x;
+ 	if (k != 0) {
+ 		if (hx < 0x43400000) {
+-			STRICT_ASSIGN(double, u, 1.0 + x);
++			u = 1 + x;
+ 			GET_HIGH_WORD(hu, u);
+ 			k = (hu>>20) - 1023;
+ 			c = k > 0 ? 1.0-(u-x) : x-(u-1.0); /* correction term */
+diff -Nur musl-0.9.13/src/math/log1pf.c musl-git/src/math/log1pf.c
+--- musl-0.9.13/src/math/log1pf.c	2013-08-30 23:30:53.000000000 +0200
++++ musl-git/src/math/log1pf.c	2013-09-16 20:31:39.000000000 +0200
+@@ -61,7 +61,7 @@
+ 		return x+x;
+ 	if (k != 0) {
+ 		if (hx < 0x5a000000) {
+-			STRICT_ASSIGN(float, u, 1.0f + x);
++			u = 1 + x;
+ 			GET_FLOAT_WORD(hu, u);
+ 			k = (hu>>23) - 127;
+ 			/* correction term */
+diff -Nur musl-0.9.13/src/math/logb.c musl-git/src/math/logb.c
+--- musl-0.9.13/src/math/logb.c	2013-08-30 23:30:53.000000000 +0200
++++ musl-git/src/math/logb.c	2013-09-16 20:31:39.000000000 +0200
+@@ -1,4 +1,4 @@
+-#include "libm.h"
++#include <math.h>
+ 
+ /*
+ special cases:
+@@ -12,6 +12,6 @@
+ 	if (!isfinite(x))
+ 		return x * x;
+ 	if (x == 0)
+-		return -1/(x+0);
++		return -1/(x*x);
+ 	return ilogb(x);
+ }
+diff -Nur musl-0.9.13/src/math/logbf.c musl-git/src/math/logbf.c
+--- musl-0.9.13/src/math/logbf.c	2013-08-30 23:30:53.000000000 +0200
++++ musl-git/src/math/logbf.c	2013-09-16 20:31:39.000000000 +0200
+@@ -1,10 +1,10 @@
+-#include "libm.h"
++#include <math.h>
+ 
+ float logbf(float x)
+ {
+ 	if (!isfinite(x))
+ 		return x * x;
+ 	if (x == 0)
+-		return -1/(x+0);
++		return -1/(x*x);
+ 	return ilogbf(x);
+ }
+diff -Nur musl-0.9.13/src/math/logbl.c musl-git/src/math/logbl.c
+--- musl-0.9.13/src/math/logbl.c	2013-08-30 23:30:53.000000000 +0200
++++ musl-git/src/math/logbl.c	2013-09-16 20:31:39.000000000 +0200
+@@ -1,4 +1,4 @@
+-#include "libm.h"
++#include <math.h>
+ #if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024
+ long double logbl(long double x)
+ {
+@@ -10,7 +10,7 @@
+ 	if (!isfinite(x))
+ 		return x * x;
+ 	if (x == 0)
+-		return -1/(x+0);
++		return -1/(x*x);
+ 	return ilogbl(x);
+ }
+ #endif
+diff -Nur musl-0.9.13/src/math/modf.c musl-git/src/math/modf.c
+--- musl-0.9.13/src/math/modf.c	2013-08-30 23:30:53.000000000 +0200
++++ musl-git/src/math/modf.c	2013-09-16 20:31:39.000000000 +0200
+@@ -2,36 +2,33 @@
+ 
+ double modf(double x, double *iptr)
+ {
+-	union {double x; uint64_t n;} u = {x};
++	union {double f; uint64_t i;} u = {x};
+ 	uint64_t mask;
+-	int e;
+-
+-	e = (int)(u.n>>52 & 0x7ff) - 0x3ff;
++	int e = (int)(u.i>>52 & 0x7ff) - 0x3ff;
+ 
+ 	/* no fractional part */
+ 	if (e >= 52) {
+ 		*iptr = x;
+-		if (e == 0x400 && u.n<<12 != 0) /* nan */
++		if (e == 0x400 && u.i<<12 != 0) /* nan */
+ 			return x;
+-		u.n &= (uint64_t)1<<63;
+-		return u.x;
++		u.i &= 1ULL<<63;
++		return u.f;
+ 	}
+ 
+ 	/* no integral part*/
+ 	if (e < 0) {
+-		u.n &= (uint64_t)1<<63;
+-		*iptr = u.x;
++		u.i &= 1ULL<<63;
++		*iptr = u.f;
+ 		return x;
+ 	}
+ 
+-	mask = (uint64_t)-1>>12 >> e;
+-	if ((u.n & mask) == 0) {
++	mask = -1ULL>>12>>e;
++	if ((u.i & mask) == 0) {
+ 		*iptr = x;
+-		u.n &= (uint64_t)1<<63;
+-		return u.x;
++		u.i &= 1ULL<<63;
++		return u.f;
+ 	}
+-	u.n &= ~mask;
+-	*iptr = u.x;
+-	STRICT_ASSIGN(double, x, x - *iptr);
+-	return x;
++	u.i &= ~mask;
++	*iptr = u.f;
++	return x - u.f;
+ }
+diff -Nur musl-0.9.13/src/math/modff.c musl-git/src/math/modff.c
+--- musl-0.9.13/src/math/modff.c	2013-08-30 23:30:53.000000000 +0200
++++ musl-git/src/math/modff.c	2013-09-16 20:31:39.000000000 +0200
+@@ -2,36 +2,33 @@
+ 
+ float modff(float x, float *iptr)
+ {
+-	union {float x; uint32_t n;} u = {x};
++	union {float f; uint32_t i;} u = {x};
+ 	uint32_t mask;
+-	int e;
+-
+-	e = (int)(u.n>>23 & 0xff) - 0x7f;
++	int e = (int)(u.i>>23 & 0xff) - 0x7f;
+ 
+ 	/* no fractional part */
+ 	if (e >= 23) {
+ 		*iptr = x;
+-		if (e == 0x80 && u.n<<9 != 0) { /* nan */
++		if (e == 0x80 && u.i<<9 != 0) { /* nan */
+ 			return x;
+ 		}
+-		u.n &= 0x80000000;
+-		return u.x;
++		u.i &= 0x80000000;
++		return u.f;
+ 	}
+ 	/* no integral part */
+ 	if (e < 0) {
+-		u.n &= 0x80000000;
+-		*iptr = u.x;
++		u.i &= 0x80000000;
++		*iptr = u.f;
+ 		return x;
+ 	}
+ 
+ 	mask = 0x007fffff>>e;
+-	if ((u.n & mask) == 0) {
++	if ((u.i & mask) == 0) {
+ 		*iptr = x;
+-		u.n &= 0x80000000;
+-		return u.x;
++		u.i &= 0x80000000;
++		return u.f;
+ 	}
+-	u.n &= ~mask;
+-	*iptr = u.x;
+-	STRICT_ASSIGN(float, x, x - *iptr);
+-	return x;
++	u.i &= ~mask;
++	*iptr = u.f;
++	return x - u.f;
+ }
+diff -Nur musl-0.9.13/src/math/modfl.c musl-git/src/math/modfl.c
+--- musl-0.9.13/src/math/modfl.c	2013-08-30 23:30:53.000000000 +0200
++++ musl-git/src/math/modfl.c	2013-09-16 20:31:39.000000000 +0200
+@@ -1,40 +1,3 @@
+-/* origin: FreeBSD /usr/src/lib/msun/src/s_modfl.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.
+- *
+- * Derived from s_modf.c, which has the following Copyright:
+- * ====================================================
+- * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+- *
+- * Developed at 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"
+ 
+ #if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024
+@@ -43,58 +6,46 @@
+ 	return modf(x, (double *)iptr);
+ }
+ #elif (LDBL_MANT_DIG == 64 || LDBL_MANT_DIG == 113) && LDBL_MAX_EXP == 16384
+-
+-#if LDBL_MANL_SIZE > 32
+-#define MASK    ((uint64_t)-1)
+-#else
+-#define MASK    ((uint32_t)-1)
++#if LDBL_MANT_DIG == 64
++#define TOINT 0x1p63
++#elif LDBL_MANT_DIG == 113
++#define TOINT 0x1p112
+ #endif
+-/* Return the last n bits of a word, representing the fractional part. */
+-#define GETFRAC(bits, n)        ((bits) & ~(MASK << (n)))
+-/* The number of fraction bits in manh, not counting the integer bit */
+-#define HIBITS  (LDBL_MANT_DIG - LDBL_MANL_SIZE)
+-
+-static const long double zero[] = { 0.0, -0.0 };
+-
+ long double modfl(long double x, long double *iptr)
+ {
+-	union IEEEl2bits ux;
+-	int e;
++	union ldshape u = {x};
++	uint64_t mask;
++	int e = (u.i.se & 0x7fff) - 0x3fff;
++	int s = u.i.se >> 15;
++	long double absx;
++	long double y;
+ 
+-	ux.e = x;
+-	e = ux.bits.exp - LDBL_MAX_EXP + 1;
+-	if (e < HIBITS) {                       /* Integer part is in manh. */
+-		if (e < 0) {                    /* |x|<1 */
+-			*iptr = zero[ux.bits.sign];
+-			return x;
+-		}
+-		if ((GETFRAC(ux.bits.manh, HIBITS - 1 - e)|ux.bits.manl) == 0) {
+-			/* x is an integer. */
+-			*iptr = x;
+-			return zero[ux.bits.sign];
+-		}
+-		/* Clear all but the top e+1 bits. */
+-		ux.bits.manh >>= HIBITS - 1 - e;
+-		ux.bits.manh <<= HIBITS - 1 - e;
+-		ux.bits.manl = 0;
+-		*iptr = ux.e;
+-		return x - ux.e;
+-	} else if (e >= LDBL_MANT_DIG - 1) {    /* x has no fraction part. */
++	/* no fractional part */
++	if (e >= LDBL_MANT_DIG-1) {
+ 		*iptr = x;
+-		if (e == LDBL_MAX_EXP && ((ux.bits.manh&~LDBL_NBIT)|ux.bits.manl)) /* nan */
++		if (isnan(x))
+ 			return x;
+-		return zero[ux.bits.sign];
+-	} else {                                /* Fraction part is in manl. */
+-		if (GETFRAC(ux.bits.manl, LDBL_MANT_DIG - 1 - e) == 0) {
+-			/* x is integral. */
+-			*iptr = x;
+-			return zero[ux.bits.sign];
+-		}
+-		/* Clear all but the top e+1 bits. */
+-		ux.bits.manl >>= LDBL_MANT_DIG - 1 - e;
+-		ux.bits.manl <<= LDBL_MANT_DIG - 1 - e;
+-		*iptr = ux.e;
+-		return x - ux.e;
++		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
+diff -Nur musl-0.9.13/src/math/nextafter.c musl-git/src/math/nextafter.c
+--- musl-0.9.13/src/math/nextafter.c	2013-08-30 23:30:53.000000000 +0200
++++ musl-git/src/math/nextafter.c	2013-09-16 20:31:39.000000000 +0200
+@@ -1,35 +1,31 @@
+ #include "libm.h"
+ 
+-#define SIGN ((uint64_t)1<<63)
+-
+ double nextafter(double x, double y)
+ {
+-	union dshape ux, uy;
++	union {double f; uint64_t i;} ux={x}, uy={y};
+ 	uint64_t ax, ay;
+ 	int e;
+ 
+ 	if (isnan(x) || isnan(y))
+ 		return x + y;
+-	ux.value = x;
+-	uy.value = y;
+-	if (ux.bits == uy.bits)
++	if (ux.i == uy.i)
+ 		return y;
+-	ax = ux.bits & ~SIGN;
+-	ay = uy.bits & ~SIGN;
++	ax = ux.i & -1ULL/2;
++	ay = uy.i & -1ULL/2;
+ 	if (ax == 0) {
+ 		if (ay == 0)
+ 			return y;
+-		ux.bits = (uy.bits & SIGN) | 1;
+-	} else if (ax > ay || ((ux.bits ^ uy.bits) & SIGN))
+-		ux.bits--;
++		ux.i = (uy.i & 1ULL<<63) | 1;
++	} else if (ax > ay || ((ux.i ^ uy.i) & 1ULL<<63))
++		ux.i--;
+ 	else
+-		ux.bits++;
+-	e = ux.bits >> 52 & 0x7ff;
+-	/* raise overflow if ux.value is infinite and x is finite */
++		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.value is subnormal or zero */
++	/* raise underflow if ux.f is subnormal or zero */
+ 	if (e == 0)
+-		FORCE_EVAL(x*x + ux.value*ux.value);
+-	return ux.value;
++		FORCE_EVAL(x*x + ux.f*ux.f);
++	return ux.f;
+ }
+diff -Nur musl-0.9.13/src/math/nextafterf.c musl-git/src/math/nextafterf.c
+--- musl-0.9.13/src/math/nextafterf.c	2013-08-30 23:30:53.000000000 +0200
++++ musl-git/src/math/nextafterf.c	2013-09-16 20:31:39.000000000 +0200
+@@ -1,34 +1,30 @@
+ #include "libm.h"
+ 
+-#define SIGN 0x80000000
+-
+ float nextafterf(float x, float y)
+ {
+-	union fshape ux, uy;
++	union {float f; uint32_t i;} ux={x}, uy={y};
+ 	uint32_t ax, ay, e;
+ 
+ 	if (isnan(x) || isnan(y))
+ 		return x + y;
+-	ux.value = x;
+-	uy.value = y;
+-	if (ux.bits == uy.bits)
++	if (ux.i == uy.i)
+ 		return y;
+-	ax = ux.bits & ~SIGN;
+-	ay = uy.bits & ~SIGN;
++	ax = ux.i & 0x7fffffff;
++	ay = uy.i & 0x7fffffff;
+ 	if (ax == 0) {
+ 		if (ay == 0)
+ 			return y;
+-		ux.bits = (uy.bits & SIGN) | 1;
+-	} else if (ax > ay || ((ux.bits ^ uy.bits) & SIGN))
+-		ux.bits--;
++		ux.i = (uy.i & 0x80000000) | 1;
++	} else if (ax > ay || ((ux.i ^ uy.i) & 0x80000000))
++		ux.i--;
+ 	else
+-		ux.bits++;
+-	e = ux.bits & 0x7f800000;
+-	/* raise overflow if ux.value is infinite and x is finite */
++		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.value is subnormal or zero */
++	/* raise underflow if ux.f is subnormal or zero */
+ 	if (e == 0)
+-		FORCE_EVAL(x*x + ux.value*ux.value);
+-	return ux.value;
++		FORCE_EVAL(x*x + ux.f*ux.f);
++	return ux.f;
+ }
+diff -Nur musl-0.9.13/src/math/nextafterl.c musl-git/src/math/nextafterl.c
+--- musl-0.9.13/src/math/nextafterl.c	2013-08-30 23:30:53.000000000 +0200
++++ musl-git/src/math/nextafterl.c	2013-09-16 20:31:39.000000000 +0200
+@@ -6,7 +6,6 @@
+ 	return nextafter(x, y);
+ }
+ #elif LDBL_MANT_DIG == 64 && LDBL_MAX_EXP == 16384
+-#define MSB ((uint64_t)1<<63)
+ long double nextafterl(long double x, long double y)
+ {
+ 	union ldshape ux, uy;
+@@ -15,32 +14,32 @@
+ 		return x + y;
+ 	if (x == y)
+ 		return y;
+-	ux.value = x;
++	ux.f = x;
+ 	if (x == 0) {
+-		uy.value = y;
+-		ux.bits.m = 1;
+-		ux.bits.sign = uy.bits.sign;
+-	} else if (x < y ^ ux.bits.sign) {
+-		ux.bits.m++;
+-		if ((ux.bits.m & ~MSB) == 0) {
+-			ux.bits.m = MSB;
+-			ux.bits.exp++;
++		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.bits.m & ~MSB) == 0) {
+-			ux.bits.exp--;
+-			if (ux.bits.exp)
+-				ux.bits.m = 0;
++		if (ux.i.m << 1 == 0) {
++			ux.i.se--;
++			if (ux.i.se)
++				ux.i.m = 0;
+ 		}
+-		ux.bits.m--;
++		ux.i.m--;
+ 	}
+-	/* raise overflow if ux.value is infinite and x is finite */
+-	if (ux.bits.exp == 0x7fff)
++	/* raise overflow if ux is infinite and x is finite */
++	if ((ux.i.se & 0x7fff) == 0x7fff)
+ 		return x + x;
+-	/* raise underflow if ux.value is subnormal or zero */
+-	if (ux.bits.exp == 0)
+-		FORCE_EVAL(x*x + ux.value*ux.value);
+-	return ux.value;
++	/* 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)
+@@ -51,32 +50,26 @@
+ 		return x + y;
+ 	if (x == y)
+ 		return y;
+-	ux.value = x;
++	ux.f = x;
+ 	if (x == 0) {
+-		uy.value = y;
+-		ux.bits.mlo = 1;
+-		ux.bits.sign = uy.bits.sign;
+-	} else if (x < y ^ ux.bits.sign) {
+-		ux.bits.mlo++;
+-		if (ux.bits.mlo == 0) {
+-			ux.bits.mhi++;
+-			if (ux.bits.mhi == 0)
+-				ux.bits.exp++;
+-		}
++		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.bits.mlo == 0) {
+-			if (ux.bits.mhi == 0)
+-				ux.bits.exp--;
+-			ux.bits.mhi--;
+-		}
+-		ux.bits.mlo--;
++		if (ux.i2.lo == 0)
++			ux.i2.hi--;
++		ux.i2.lo--;
+ 	}
+-	/* raise overflow if ux.value is infinite and x is finite */
+-	if (ux.bits.exp == 0x7fff)
++	/* raise overflow if ux is infinite and x is finite */
++	if ((ux.i.se & 0x7fff) == 0x7fff)
+ 		return x + x;
+-	/* raise underflow if ux.value is subnormal or zero */
+-	if (ux.bits.exp == 0)
+-		FORCE_EVAL(x*x + ux.value*ux.value);
+-	return ux.value;
++	/* 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
+diff -Nur musl-0.9.13/src/math/nexttoward.c musl-git/src/math/nexttoward.c
+--- musl-0.9.13/src/math/nexttoward.c	2013-08-30 23:30:53.000000000 +0200
++++ musl-git/src/math/nexttoward.c	2013-09-16 20:31:39.000000000 +0200
+@@ -6,40 +6,37 @@
+ 	return nextafter(x, y);
+ }
+ #else
+-#define SIGN ((uint64_t)1<<63)
+-
+ double nexttoward(double x, long double y)
+ {
+-	union dshape ux;
++	union {double f; uint64_t i;} ux = {x};
+ 	int e;
+ 
+ 	if (isnan(x) || isnan(y))
+ 		return x + y;
+ 	if (x == y)
+ 		return y;
+-	ux.value = x;
+ 	if (x == 0) {
+-		ux.bits = 1;
++		ux.i = 1;
+ 		if (signbit(y))
+-			ux.bits |= SIGN;
++			ux.i |= 1ULL<<63;
+ 	} else if (x < y) {
+ 		if (signbit(x))
+-			ux.bits--;
++			ux.i--;
+ 		else
+-			ux.bits++;
++			ux.i++;
+ 	} else {
+ 		if (signbit(x))
+-			ux.bits++;
++			ux.i++;
+ 		else
+-			ux.bits--;
++			ux.i--;
+ 	}
+-	e = ux.bits>>52 & 0x7ff;
+-	/* raise overflow if ux.value is infinite and x is finite */
++	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.value is subnormal or zero */
++	/* raise underflow if ux.f is subnormal or zero */
+ 	if (e == 0)
+-		FORCE_EVAL(x*x + ux.value*ux.value);
+-	return ux.value;
++		FORCE_EVAL(x*x + ux.f*ux.f);
++	return ux.f;
+ }
+ #endif
+diff -Nur musl-0.9.13/src/math/nexttowardf.c musl-git/src/math/nexttowardf.c
+--- musl-0.9.13/src/math/nexttowardf.c	2013-08-30 23:30:53.000000000 +0200
++++ musl-git/src/math/nexttowardf.c	2013-09-16 20:31:39.000000000 +0200
+@@ -2,35 +2,34 @@
+ 
+ float nexttowardf(float x, long double y)
+ {
+-	union fshape ux;
++	union {float f; uint32_t i;} ux = {x};
+ 	uint32_t e;
+ 
+ 	if (isnan(x) || isnan(y))
+ 		return x + y;
+ 	if (x == y)
+ 		return y;
+-	ux.value = x;
+ 	if (x == 0) {
+-		ux.bits = 1;
++		ux.i = 1;
+ 		if (signbit(y))
+-			ux.bits |= 0x80000000;
++			ux.i |= 0x80000000;
+ 	} else if (x < y) {
+ 		if (signbit(x))
+-			ux.bits--;
++			ux.i--;
+ 		else
+-			ux.bits++;
++			ux.i++;
+ 	} else {
+ 		if (signbit(x))
+-			ux.bits++;
++			ux.i++;
+ 		else
+-			ux.bits--;
++			ux.i--;
+ 	}
+-	e = ux.bits & 0x7f800000;
+-	/* raise overflow if ux.value is infinite and x is finite */
++	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.value is subnormal or zero */
++	/* raise underflow if ux.f is subnormal or zero */
+ 	if (e == 0)
+-		FORCE_EVAL(x*x + ux.value*ux.value);
+-	return ux.value;
++		FORCE_EVAL(x*x + ux.f*ux.f);
++	return ux.f;
+ }
+diff -Nur musl-0.9.13/src/math/remainder.c musl-git/src/math/remainder.c
+--- musl-0.9.13/src/math/remainder.c	2013-08-30 23:30:53.000000000 +0200
++++ musl-git/src/math/remainder.c	2013-09-16 20:31:39.000000000 +0200
+@@ -1,66 +1,7 @@
+-/* origin: FreeBSD /usr/src/lib/msun/src/e_remainder.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.
+- * ====================================================
+- */
+-/* remainder(x,p)
+- * Return :
+- *      returns  x REM p  =  x - [x/p]*p as if in infinite
+- *      precise arithmetic, where [x/p] is the (infinite bit)
+- *      integer nearest x/p (in half way case choose the even one).
+- * Method :
+- *      Based on fmod() return x-[x/p]chopped*p exactlp.
+- */
++#include <math.h>
+ 
+-#include "libm.h"
+-
+-double remainder(double x, double p)
++double remainder(double x, double y)
+ {
+-	int32_t hx,hp;
+-	uint32_t sx,lx,lp;
+-	double p_half;
+-
+-	EXTRACT_WORDS(hx, lx, x);
+-	EXTRACT_WORDS(hp, lp, p);
+-	sx = hx & 0x80000000;
+-	hp &= 0x7fffffff;
+-	hx &= 0x7fffffff;
+-
+-	/* purge off exception values */
+-	if ((hp|lp) == 0 ||                                  /* p = 0 */
+-	    hx >= 0x7ff00000 ||                              /* x not finite */
+-	    (hp >= 0x7ff00000 && (hp-0x7ff00000 | lp) != 0)) /* p is NaN */
+-		return (x*p)/(x*p);
+-
+-	if (hp <= 0x7fdfffff)
+-		x = fmod(x, p+p);  /* now x < 2p */
+-	if (((hx-hp)|(lx-lp)) == 0)
+-		return 0.0*x;
+-	x = fabs(x);
+-	p = fabs(p);
+-	if (hp < 0x00200000) {
+-		if (x + x > p) {
+-			x -= p;
+-			if (x + x >= p)
+-				x -= p;
+-		}
+-	} else {
+-		p_half = 0.5*p;
+-		if (x > p_half) {
+-			x -= p;
+-			if (x >= p_half)
+-				x -= p;
+-		}
+-	}
+-	GET_HIGH_WORD(hx, x);
+-	if ((hx&0x7fffffff) == 0)
+-		hx = 0;
+-	SET_HIGH_WORD(x, hx^sx);
+-	return x;
++	int q;
++	return remquo(x, y, &q);
+ }
+diff -Nur musl-0.9.13/src/math/remainderf.c musl-git/src/math/remainderf.c
+--- musl-0.9.13/src/math/remainderf.c	2013-08-30 23:30:53.000000000 +0200
++++ musl-git/src/math/remainderf.c	2013-09-16 20:31:39.000000000 +0200
+@@ -1,59 +1,7 @@
+-/* origin: FreeBSD /usr/src/lib/msun/src/e_remainderf.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 "libm.h"
+-
+-float remainderf(float x, float p)
++float remainderf(float x, float y)
+ {
+-	int32_t hx,hp;
+-	uint32_t sx;
+-	float p_half;
+-
+-	GET_FLOAT_WORD(hx, x);
+-	GET_FLOAT_WORD(hp, p);
+-	sx = hx & 0x80000000;
+-	hp &= 0x7fffffff;
+-	hx &= 0x7fffffff;
+-
+-	/* purge off exception values */
+-	if (hp == 0 || hx >= 0x7f800000 || hp > 0x7f800000)  /* p = 0, x not finite, p is NaN */
+-		return (x*p)/(x*p);
+-
+-	if (hp <= 0x7effffff)
+-		x = fmodf(x, p + p);  /* now x < 2p */
+-	if (hx - hp == 0)
+-		return 0.0f*x;
+-	x = fabsf(x);
+-	p = fabsf(p);
+-	if (hp < 0x01000000) {
+-		if (x + x > p) {
+-			x -= p;
+-			if (x + x >= p)
+-				x -= p;
+-		}
+-	} else {
+-		p_half = 0.5f*p;
+-		if (x > p_half) {
+-			x -= p;
+-			if (x >= p_half)
+-				x -= p;
+-		}
+-	}
+-	GET_FLOAT_WORD(hx, x);
+-	if ((hx & 0x7fffffff) == 0)
+-		hx = 0;
+-	SET_FLOAT_WORD(x, hx ^ sx);
+-	return x;
++	int q;
++	return remquof(x, y, &q);
+ }
+diff -Nur musl-0.9.13/src/math/remquo.c musl-git/src/math/remquo.c
+--- musl-0.9.13/src/math/remquo.c	2013-08-30 23:30:53.000000000 +0200
++++ musl-git/src/math/remquo.c	2013-09-16 20:31:39.000000000 +0200
+@@ -1,171 +1,82 @@
+-/* origin: FreeBSD /usr/src/lib/msun/src/s_remquo.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 IEEE remainder and set *quo to the last n bits of the
+- * quotient, rounded to the nearest integer.  We choose n=31 because
+- * we wind up computing all the integer bits of the quotient anyway as
+- * a side-effect of computing the remainder by the shift and subtract
+- * method.  In practice, this is far more bits than are needed to use
+- * remquo in reduction algorithms.
+- */
+-
+-#include "libm.h"
+-
+-static const double Zero[] = {0.0, -0.0,};
++#include <math.h>
++#include <stdint.h>
+ 
+ double remquo(double x, double y, int *quo)
+ {
+-	int32_t n,hx,hy,hz,ix,iy,sx,i;
+-	uint32_t lx,ly,lz,q,sxy;
+-
+-	EXTRACT_WORDS(hx, lx, x);
+-	EXTRACT_WORDS(hy, ly, y);
+-	sxy = (hx ^ hy) & 0x80000000;
+-	sx = hx & 0x80000000;   /* sign of x */
+-	hx ^= sx;               /* |x| */
+-	hy &= 0x7fffffff;       /* |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;
++	int sy = uy.i>>63;
++	uint32_t q;
++	uint64_t i;
++	uint64_t uxi = ux.i;
+ 
+-	/* purge off exception values */
+-	if ((hy|ly) == 0 || hx >= 0x7ff00000 ||  /* y = 0, or x not finite */
+-	    (hy|((ly|-ly)>>31)) > 0x7ff00000)    /* or y is NaN */
++	*quo = 0;
++	if (uy.i<<1 == 0 || isnan(y) || ex == 0x7ff)
+ 		return (x*y)/(x*y);
+-	if (hx <= hy) {
+-		if (hx < hy || lx < ly) {  /* |x| < |y| return x or x-y */
+-			q = 0;
+-			goto fixup;
+-		}
+-		if (lx == ly) {            /* |x| = |y| return x*0 */
+-			*quo = sxy ? -1 : 1;
+-			return Zero[(uint32_t)sx>>31];
+-		}
+-	}
++	if (ux.i<<1 == 0)
++		return x;
+ 
+-	// FIXME: use ilogb?
+-
+-	/* determine ix = ilogb(x) */
+-	if (hx < 0x00100000) {  /* subnormal x */
+-		if (hx == 0) {
+-			for (ix = -1043, i=lx; i>0; i<<=1) ix--;
+-		} else {
+-			for (ix = -1022, i=hx<<11; i>0; i<<=1) ix--;
+-		}
+-	} else
+-		ix = (hx>>20) - 1023;
+-
+-	/* determine iy = ilogb(y) */
+-	if (hy < 0x00100000) {  /* subnormal y */
+-		if (hy == 0) {
+-			for (iy = -1043, i=ly; i>0; i<<=1) iy--;
+-		} else {
+-			for (iy = -1022, i=hy<<11; i>0; i<<=1) iy--;
+-		}
+-	} else
+-		iy = (hy>>20) - 1023;
+-
+-	/* set up {hx,lx}, {hy,ly} and align y to x */
+-	if (ix >= -1022)
+-		hx = 0x00100000|(0x000fffff&hx);
+-	else {  /* subnormal x, shift x to normal */
+-		n = -1022 - ix;
+-		if (n <= 31) {
+-			hx = (hx<<n)|(lx>>(32-n));
+-			lx <<= n;
+-		} else {
+-			hx = lx<<(n-32);
+-			lx = 0;
+-		}
+-	}
+-	if (iy >= -1022)
+-		hy = 0x00100000|(0x000fffff&hy);
+-	else {  /* subnormal y, shift y to normal */
+-		n = -1022 - iy;
+-		if (n <= 31) {
+-			hy = (hy<<n)|(ly>>(32-n));
+-			ly <<= n;
+-		} else {
+-			hy = ly<<(n-32);
+-			ly = 0;
+-		}
++	/* 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;
+ 	}
+ 
+-	/* fix point fmod */
+-	n = ix - iy;
+ 	q = 0;
+-	while (n--) {
+-		hz = hx - hy;
+-		lz = lx - ly;
+-		if (lx < ly)
+-			hz--;
+-		if (hz < 0) {
+-			hx = hx + hx + (lx>>31);
+-			lx = lx + lx;
+-		} else {
+-			hx = hz + hz + (lz>>31);
+-			lx = lz + lz;
++	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;
+ 	}
+-	hz = hx - hy;
+-	lz = lx - ly;
+-	if (lx < ly)
+-		hz--;
+-	if (hz >= 0) {
+-		hx = hz;
+-		lx = lz;
++	i = uxi - uy.i;
++	if (i >> 63 == 0) {
++		uxi = i;
+ 		q++;
+ 	}
+-
+-	/* convert back to floating value and restore the sign */
+-	if ((hx|lx) == 0) {  /* return sign(x)*0 */
+-		q &= 0x7fffffff;
+-		*quo = sxy ? -q : q;
+-		return Zero[(uint32_t)sx>>31];
+-	}
+-	while (hx < 0x00100000) {  /* normalize x */
+-		hx = hx + hx + (lx>>31);
+-		lx = lx + lx;
+-		iy--;
+-	}
+-	if (iy >= -1022) {         /* normalize output */
+-		hx = (hx-0x00100000)|((iy+1023)<<20);
+-	} else {                   /* subnormal output */
+-		n = -1022 - iy;
+-		if (n <= 20) {
+-			lx = (lx>>n)|((uint32_t)hx<<(32-n));
+-			hx >>= n;
+-		} else if (n <= 31) {
+-			lx = (hx<<(32-n))|(lx>>n);
+-			hx = 0;
+-		} else {
+-			lx = hx>>(n-32);
+-			hx = 0;
+-		}
+-	}
+-fixup:
+-	INSERT_WORDS(x, hx, lx);
+-	y = fabs(y);
+-	if (y < 0x1p-1021) {
+-		if (x + x > y || (x + x == y && (q & 1))) {
+-			q++;
+-			x -= y;
+-		}
+-	} else if (x > 0.5*y || (x == 0.5*y && (q & 1))) {
+-		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++;
+ 	}
+-	GET_HIGH_WORD(hx, x);
+-	SET_HIGH_WORD(x, hx ^ sx);
+ 	q &= 0x7fffffff;
+-	*quo = sxy ? -q : q;
+-	return x;
++	*quo = sx^sy ? -(int)q : (int)q;
++	return sx ? -x : x;
+ }
+diff -Nur musl-0.9.13/src/math/remquof.c musl-git/src/math/remquof.c
+--- musl-0.9.13/src/math/remquof.c	2013-08-30 23:30:53.000000000 +0200
++++ musl-git/src/math/remquof.c	2013-09-16 20:31:39.000000000 +0200
+@@ -1,126 +1,82 @@
+-/* origin: FreeBSD /usr/src/lib/msun/src/s_remquof.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 IEEE remainder and set *quo to the last n bits of the
+- * quotient, rounded to the nearest integer.  We choose n=31 because
+- * we wind up computing all the integer bits of the quotient anyway as
+- * a side-effect of computing the remainder by the shift and subtract
+- * method.  In practice, this is far more bits than are needed to use
+- * remquo in reduction algorithms.
+- */
+-
+-#include "libm.h"
+-
+-static const float Zero[] = {0.0, -0.0,};
++#include <math.h>
++#include <stdint.h>
+ 
+ float remquof(float x, float y, int *quo)
+ {
+-	int32_t n,hx,hy,hz,ix,iy,sx,i;
+-	uint32_t q,sxy;
++	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;
+ 
+-	GET_FLOAT_WORD(hx, x);
+-	GET_FLOAT_WORD(hy, y);
+-	sxy = (hx ^ hy) & 0x80000000;
+-	sx = hx & 0x80000000;   /* sign of x */
+-	hx ^= sx;               /* |x| */
+-	hy &= 0x7fffffff;       /* |y| */
+-
+-	/* purge off exception values */
+-	if (hy == 0 || hx >= 0x7f800000 || hy > 0x7f800000) /* y=0,NaN;or x not finite */
++	*quo = 0;
++	if (uy.i<<1 == 0 || isnan(y) || ex == 0xff)
+ 		return (x*y)/(x*y);
+-	if (hx < hy) {       /* |x| < |y| return x or x-y */
+-		q = 0;
+-		goto fixup;
+-	} else if(hx==hy) {  /* |x| = |y| return x*0*/
+-		*quo = sxy ? -1 : 1;
+-		return Zero[(uint32_t)sx>>31];
+-	}
++	if (ux.i<<1 == 0)
++		return x;
+ 
+-	/* determine ix = ilogb(x) */
+-	if (hx < 0x00800000) {  /* subnormal x */
+-		for (ix = -126, i=hx<<8; i>0; i<<=1) ix--;
+-	} else
+-		ix = (hx>>23) - 127;
+-
+-	/* determine iy = ilogb(y) */
+-	if (hy < 0x00800000) {  /* subnormal y */
+-		for (iy = -126, i=hy<<8; i>0; i<<=1) iy--;
+-	} else
+-		iy = (hy>>23) - 127;
+-
+-	/* set up {hx,lx}, {hy,ly} and align y to x */
+-	if (ix >= -126)
+-		hx = 0x00800000|(0x007fffff&hx);
+-	else {  /* subnormal x, shift x to normal */
+-		n = -126 - ix;
+-		hx <<= n;
+-	}
+-	if (iy >= -126)
+-		hy = 0x00800000|(0x007fffff&hy);
+-	else {  /* subnormal y, shift y to normal */
+-		n = -126 - iy;
+-		hy <<= n;
++	/* 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;
+ 	}
+ 
+-	/* fix point fmod */
+-	n = ix - iy;
+ 	q = 0;
+-	while (n--) {
+-		hz = hx - hy;
+-		if (hz < 0)
+-			hx = hx << 1;
+-		else {
+-			hx = hz << 1;
++	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;
+ 	}
+-	hz = hx - hy;
+-	if (hz >= 0) {
+-		hx = hz;
++	i = uxi - uy.i;
++	if (i >> 31 == 0) {
++		uxi = i;
+ 		q++;
+ 	}
+-
+-	/* convert back to floating value and restore the sign */
+-	if (hx == 0) {                             /* return sign(x)*0 */
+-		q &= 0x7fffffff;
+-		*quo = sxy ? -q : q;
+-		return Zero[(uint32_t)sx>>31];
+-	}
+-	while (hx < 0x00800000) {  /* normalize x */
+-		hx <<= 1;
+-		iy--;
+-	}
+-	if (iy >= -126) {          /* normalize output */
+-		hx = (hx-0x00800000)|((iy+127)<<23);
+-	} else {                   /* subnormal output */
+-		n = -126 - iy;
+-		hx >>= n;
+-	}
+-fixup:
+-	SET_FLOAT_WORD(x,hx);
+-	y = fabsf(y);
+-	if (y < 0x1p-125f) {
+-		if (x + x > y || (x + x == y && (q & 1))) {
+-			q++;
+-			x -= y;
+-		}
+-	} else if (x > 0.5f*y || (x == 0.5f*y && (q & 1))) {
+-		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++;
+ 	}
+-	GET_FLOAT_WORD(hx, x);
+-	SET_FLOAT_WORD(x, hx ^ sx);
+ 	q &= 0x7fffffff;
+-	*quo = sxy ? -q : q;
+-	return x;
++	*quo = sx^sy ? -(int)q : (int)q;
++	return sx ? -x : x;
+ }
+diff -Nur musl-0.9.13/src/math/remquol.c musl-git/src/math/remquol.c
+--- musl-0.9.13/src/math/remquol.c	2013-08-30 23:30:53.000000000 +0200
++++ musl-git/src/math/remquol.c	2013-09-16 20:31:39.000000000 +0200
+@@ -1,15 +1,3 @@
+-/* origin: FreeBSD /usr/src/lib/msun/src/s_remquol.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.
+- * ====================================================
+- */
+-
+ #include "libm.h"
+ 
+ #if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024
+@@ -18,177 +6,119 @@
+ 	return remquo(x, y, quo);
+ }
+ #elif (LDBL_MANT_DIG == 64 || LDBL_MANT_DIG == 113) && LDBL_MAX_EXP == 16384
+-
+-#define BIAS (LDBL_MAX_EXP - 1)
+-
+-#if LDBL_MANL_SIZE > 32
+-typedef uint64_t manl_t;
+-#else
+-typedef uint32_t manl_t;
+-#endif
+-
+-#if LDBL_MANH_SIZE > 32
+-typedef uint64_t manh_t;
+-#else
+-typedef uint32_t manh_t;
+-#endif
+-
+-/*
+- * These macros add and remove an explicit integer bit in front of the
+- * fractional mantissa, if the architecture doesn't have such a bit by
+- * default already.
+- */
+-#ifdef LDBL_IMPLICIT_NBIT
+-#define SET_NBIT(hx)    ((hx) | (1ULL << LDBL_MANH_SIZE))
+-#define HFRAC_BITS      LDBL_MANH_SIZE
+-#else
+-#define SET_NBIT(hx)    (hx)
+-#define HFRAC_BITS      (LDBL_MANH_SIZE - 1)
+-#endif
+-
+-#define MANL_SHIFT      (LDBL_MANL_SIZE - 1)
+-
+-static const long double Zero[] = {0.0, -0.0};
+-
+-/*
+- * Return the IEEE remainder and set *quo to the last n bits of the
+- * quotient, rounded to the nearest integer.  We choose n=31 because
+- * we wind up computing all the integer bits of the quotient anyway as
+- * a side-effect of computing the remainder by the shift and subtract
+- * method.  In practice, this is far more bits than are needed to use
+- * remquo in reduction algorithms.
+- *
+- * Assumptions:
+- * - The low part of the mantissa fits in a manl_t exactly.
+- * - The high part of the mantissa fits in an int64_t with enough room
+- *   for an explicit integer bit in front of the fractional bits.
+- */
+ long double remquol(long double x, long double y, int *quo)
+ {
+-	union IEEEl2bits ux, uy;
+-	int64_t hx,hz;  /* We need a carry bit even if LDBL_MANH_SIZE is 32. */
+-	manh_t hy;
+-	manl_t lx,ly,lz;
+-	int ix,iy,n,q,sx,sxy;
++	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;
+ 
+-	ux.e = x;
+-	uy.e = y;
+-	sx = ux.bits.sign;
+-	sxy = sx ^ uy.bits.sign;
+-	ux.bits.sign = 0;       /* |x| */
+-	uy.bits.sign = 0;       /* |y| */
+-	x = ux.e;
+-
+-	/* purge off exception values */
+-	if ((uy.bits.exp|uy.bits.manh|uy.bits.manl)==0 || /* y=0 */
+-	    (ux.bits.exp == BIAS + LDBL_MAX_EXP) ||       /* or x not finite */
+-	    (uy.bits.exp == BIAS + LDBL_MAX_EXP &&
+-		((uy.bits.manh&~LDBL_NBIT)|uy.bits.manl)!=0)) /* or y is NaN */
++	*quo = 0;
++	if (y == 0 || isnan(y) || ex == 0x7fff)
+ 		return (x*y)/(x*y);
+-	if (ux.bits.exp <= uy.bits.exp) {
+-		if ((ux.bits.exp < uy.bits.exp) ||
+-		    (ux.bits.manh <= uy.bits.manh &&
+-		     (ux.bits.manh < uy.bits.manh ||
+-		      ux.bits.manl < uy.bits.manl))) {
+-			q = 0;
+-			goto fixup;       /* |x|<|y| return x or x-y */
+-		}
+-		if (ux.bits.manh == uy.bits.manh && ux.bits.manl == uy.bits.manl) {
+-			*quo = sxy ? -1 : 1;
+-			return Zero[sx];  /* |x|=|y| return x*0*/
+-		}
+-	}
+-
+-	/* determine ix = ilogb(x) */
+-	if (ux.bits.exp == 0) {  /* subnormal x */
+-		ux.e *= 0x1.0p512;
+-		ix = ux.bits.exp - (BIAS + 512);
+-	} else {
+-		ix = ux.bits.exp - BIAS;
+-	}
++	if (x == 0)
++		return x;
+ 
+-	/* determine iy = ilogb(y) */
+-	if (uy.bits.exp == 0) {  /* subnormal y */
+-		uy.e *= 0x1.0p512;
+-		iy = uy.bits.exp - (BIAS + 512);
+-	} else {
+-		iy = uy.bits.exp - BIAS;
++	/* 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;
+ 	}
+ 
+-	/* set up {hx,lx}, {hy,ly} and align y to x */
+-	hx = SET_NBIT(ux.bits.manh);
+-	hy = SET_NBIT(uy.bits.manh);
+-	lx = ux.bits.manl;
+-	ly = uy.bits.manl;
+-
+-	/* fix point fmod */
+-	n = ix - iy;
+ 	q = 0;
+-
+-	while (n--) {
+-		hz = hx - hy;
+-		lz = lx - ly;
+-		if (lx < ly)
+-			hz -= 1;
+-		if (hz < 0) {
+-			hx = hx + hx + (lx>>MANL_SHIFT);
+-			lx = lx + lx;
+-		} else {
+-			hx = hz + hz + (lz>>MANL_SHIFT);
+-			lx = lz + lz;
++	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++;
+ 		}
+-		q <<= 1;
+-	}
+-	hz = hx - hy;
+-	lz = lx - ly;
+-	if (lx < ly)
+-		hz -= 1;
+-	if (hz >= 0) {
+-		hx = hz;
+-		lx = lz;
+-		q++;
+-	}
+-
+-	/* convert back to floating value and restore the sign */
+-	if ((hx|lx) == 0) {  /* return sign(x)*0 */
+-		q &= 0x7fffffff;
+-		*quo = sxy ? -q : q;
+-		return Zero[sx];
+-	}
+-	while (hx < (1ULL<<HFRAC_BITS)) {  /* normalize x */
+-		hx = hx + hx + (lx>>MANL_SHIFT);
+-		lx = lx + lx;
+-		iy -= 1;
+-	}
+-	ux.bits.manh = hx; /* The integer bit is truncated here if needed. */
+-	ux.bits.manl = lx;
+-	if (iy < LDBL_MIN_EXP) {
+-		ux.bits.exp = iy + (BIAS + 512);
+-		ux.e *= 0x1p-512;
+-	} else {
+-		ux.bits.exp = iy + BIAS;
+-	}
+-	ux.bits.sign = 0;
+-	x = ux.e;
+-fixup:
+-	y = fabsl(y);
+-	if (y < LDBL_MIN * 2) {
+-		if (x + x > y || (x + x == y && (q & 1))) {
++		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++;
+-			x-=y;
+ 		}
+-	} else if (x > 0.5*y || (x == 0.5*y && (q & 1))) {
+-		q++;
+-		x-=y;
++		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
+ 	}
+ 
+-	ux.e = x;
+-	ux.bits.sign ^= sx;
+-	x = ux.e;
+-
++	/* 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 = sxy ? -q : q;
+-	return x;
++	*quo = sx^sy ? -(int)q : (int)q;
++	return sx ? -x : x;
+ }
+ #endif
+diff -Nur musl-0.9.13/src/math/rint.c musl-git/src/math/rint.c
+--- musl-0.9.13/src/math/rint.c	2013-08-30 23:30:53.000000000 +0200
++++ musl-git/src/math/rint.c	2013-09-16 20:31:39.000000000 +0200
+@@ -1,90 +1,20 @@
+-/* origin: FreeBSD /usr/src/lib/msun/src/s_rint.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.
+- * ====================================================
+- */
+-/*
+- * rint(x)
+- * Return x rounded to integral value according to the prevailing
+- * rounding mode.
+- * Method:
+- *      Using floating addition.
+- * Exception:
+- *      Inexact flag raised if x not equal to rint(x).
+- */
+-
+-#include "libm.h"
+-
+-static const double
+-TWO52[2] = {
+-  4.50359962737049600000e+15, /* 0x43300000, 0x00000000 */
+- -4.50359962737049600000e+15, /* 0xC3300000, 0x00000000 */
+-};
++#include <math.h>
++#include <stdint.h>
+ 
+ double rint(double x)
+ {
+-	int32_t i0,j0,sx;
+-	uint32_t i,i1;
+-	double w,t;
++	union {double f; uint64_t i;} u = {x};
++	int e = u.i>>52 & 0x7ff;
++	int s = u.i>>63;
++	double_t y;
+ 
+-	EXTRACT_WORDS(i0, i1, x);
+-	// FIXME: signed shift
+-	sx = (i0>>31) & 1;
+-	j0 = ((i0>>20)&0x7ff) - 0x3ff;
+-	if (j0 < 20) {
+-		if (j0 < 0) {
+-			if (((i0&0x7fffffff)|i1) == 0)
+-				return x;
+-			i1 |= i0 & 0x0fffff;
+-			i0 &= 0xfffe0000;
+-			i0 |= ((i1|-i1)>>12) & 0x80000;
+-			SET_HIGH_WORD(x, i0);
+-			STRICT_ASSIGN(double, w, TWO52[sx] + x);
+-			t = w - TWO52[sx];
+-			GET_HIGH_WORD(i0, t);
+-			SET_HIGH_WORD(t, (i0&0x7fffffff)|(sx<<31));
+-			return t;
+-		} else {
+-			i = 0x000fffff>>j0;
+-			if (((i0&i)|i1) == 0)
+-				return x; /* x is integral */
+-			i >>= 1;
+-			if (((i0&i)|i1) != 0) {
+-				/*
+-				 * Some bit is set after the 0.5 bit.  To avoid the
+-				 * possibility of errors from double rounding in
+-				 * w = TWO52[sx]+x, adjust the 0.25 bit to a lower
+-				 * guard bit.  We do this for all j0<=51.  The
+-				 * adjustment is trickiest for j0==18 and j0==19
+-				 * since then it spans the word boundary.
+-				 */
+-				if (j0 == 19)
+-					i1 = 0x40000000;
+-				else if (j0 == 18)
+-					i1 = 0x80000000;
+-				else
+-					i0 = (i0 & ~i)|(0x20000>>j0);
+-			}
+-		}
+-	} else if (j0 > 51) {
+-		if (j0 == 0x400)
+-			return x+x;  /* inf or NaN */
+-		return x;            /* x is integral */
+-	} else {
+-		i = (uint32_t)0xffffffff>>(j0-20);
+-		if ((i1&i) == 0)
+-			return x;    /* x is integral */
+-		i >>= 1;
+-		if ((i1&i) != 0)
+-			i1 = (i1 & ~i)|(0x40000000>>(j0-20));
+-	}
+-	INSERT_WORDS(x, i0, i1);
+-	STRICT_ASSIGN(double, w, TWO52[sx] + x);
+-	return w - TWO52[sx];
++	if (e >= 0x3ff+52)
++		return x;
++	if (s)
++		y = (double)(x - 0x1p52) + 0x1p52;
++	else
++		y = (double)(x + 0x1p52) - 0x1p52;
++	if (y == 0)
++		return s ? -0.0 : 0;
++	return y;
+ }
+diff -Nur musl-0.9.13/src/math/rintf.c musl-git/src/math/rintf.c
+--- musl-0.9.13/src/math/rintf.c	2013-08-30 23:30:53.000000000 +0200
++++ musl-git/src/math/rintf.c	2013-09-16 20:31:39.000000000 +0200
+@@ -1,48 +1,20 @@
+-/* origin: FreeBSD /usr/src/lib/msun/src/s_rintf.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
+-TWO23[2] = {
+-  8.3886080000e+06, /* 0x4b000000 */
+- -8.3886080000e+06, /* 0xcb000000 */
+-};
++#include <math.h>
++#include <stdint.h>
+ 
+ float rintf(float x)
+ {
+-	int32_t i0,j0,sx;
+-	float w,t;
++	union {float f; uint32_t i;} u = {x};
++	int e = u.i>>23 & 0xff;
++	int s = u.i>>31;
++	float_t y;
+ 
+-	GET_FLOAT_WORD(i0, x);
+-	sx = (i0>>31) & 1;
+-	j0 = ((i0>>23)&0xff) - 0x7f;
+-	if (j0 < 23) {
+-		if (j0 < 0) {
+-			if ((i0&0x7fffffff) == 0)
+-				return x;
+-			STRICT_ASSIGN(float, w, TWO23[sx] + x);
+-			t = w - TWO23[sx];
+-			GET_FLOAT_WORD(i0, t);
+-			SET_FLOAT_WORD(t, (i0&0x7fffffff)|(sx<<31));
+-			return t;
+-		}
+-		STRICT_ASSIGN(float, w, TWO23[sx] + x);
+-		return w - TWO23[sx];
+-	}
+-	if (j0 == 0x80)
+-		return x+x;  /* inf or NaN */
+-	return x;            /* x is integral */
++	if (e >= 0x7f+23)
++		return x;
++	if (s)
++		y = (float)(x - 0x1p23f) + 0x1p23f;
++	else
++		y = (float)(x + 0x1p23f) - 0x1p23f;
++	if (y == 0)
++		return s ? -0.0f : 0.0f;
++	return y;
+ }
+diff -Nur musl-0.9.13/src/math/rintl.c musl-git/src/math/rintl.c
+--- musl-0.9.13/src/math/rintl.c	2013-08-30 23:30:53.000000000 +0200
++++ musl-git/src/math/rintl.c	2013-09-16 20:31:39.000000000 +0200
+@@ -1,30 +1,3 @@
+-/* origin: FreeBSD /usr/src/lib/msun/src/s_rintl.c */
+-/*-
+- * Copyright (c) 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
+@@ -33,53 +6,26 @@
+ 	return rint(x);
+ }
+ #elif (LDBL_MANT_DIG == 64 || LDBL_MANT_DIG == 113) && LDBL_MAX_EXP == 16384
+-
+-#define BIAS    (LDBL_MAX_EXP - 1)
+-
+-static const float
+-shift[2] = {
+ #if LDBL_MANT_DIG == 64
+-	0x1.0p63, -0x1.0p63
++#define TOINT 0x1p63
+ #elif LDBL_MANT_DIG == 113
+-	0x1.0p112, -0x1.0p112
++#define TOINT 0x1p112
+ #endif
+-};
+-static const float zero[2] = { 0.0, -0.0 };
+-
+ long double rintl(long double x)
+ {
+-	union IEEEl2bits u;
+-	uint32_t expsign;
+-	int ex, sign;
+-
+-	u.e = x;
+-	expsign = u.xbits.expsign;
+-	ex = expsign & 0x7fff;
+-
+-	if (ex >= BIAS + LDBL_MANT_DIG - 1) {
+-		if (ex == BIAS + LDBL_MAX_EXP)
+-			return x + x; /* Inf, NaN, or unsupported format */
+-		return x;             /* finite and already an integer */
+-	}
+-	sign = expsign >> 15;
+-
+-	/*
+-	 * The following code assumes that intermediate results are
+-	 * evaluated in long double precision. If they are evaluated in
+-	 * greater precision, double rounding may occur, and if they are
+-	 * evaluated in less precision (as on i386), results will be
+-	 * wildly incorrect.
+-	 */
+-	x += shift[sign];
+-	x -= shift[sign];
+-
+-	/*
+-	 * If the result is +-0, then it must have the same sign as x, but
+-	 * the above calculation doesn't always give this.  Fix up the sign.
+-	 */
+-	if (ex < BIAS && x == 0.0)
+-		return zero[sign];
+-
+-	return 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
+diff -Nur musl-0.9.13/src/math/round.c musl-git/src/math/round.c
+--- musl-0.9.13/src/math/round.c	2013-08-30 23:30:53.000000000 +0200
++++ musl-git/src/math/round.c	2013-09-16 20:31:39.000000000 +0200
+@@ -1,48 +1,28 @@
+-/* origin: FreeBSD /usr/src/lib/msun/src/s_round.c */
+-/*-
+- * Copyright (c) 2003, 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.
+- */
+-
+-#include <math.h>
++#include "libm.h"
+ 
+ double round(double x)
+ {
+-	double t;
++	union {double f; uint64_t i;} u = {x};
++	int e = u.i >> 52 & 0x7ff;
++	double_t y;
+ 
+-	if (!isfinite(x))
++	if (e >= 0x3ff+52)
+ 		return x;
+-
+-	if (x >= 0.0) {
+-		t = floor(x);
+-		if (t - x <= -0.5)
+-			t += 1.0;
+-		return t;
+-	} else {
+-		t = floor(-x);
+-		if (t + x <= -0.5)
+-			t += 1.0;
+-		return -t;
++	if (u.i >> 63)
++		x = -x;
++	if (e < 0x3ff-1) {
++		/* raise inexact if x!=0 */
++		FORCE_EVAL(x + 0x1p52);
++		return 0*u.f;
+ 	}
++	y = (double)(x + 0x1p52) - 0x1p52 - 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;
+ }
+diff -Nur musl-0.9.13/src/math/roundf.c musl-git/src/math/roundf.c
+--- musl-0.9.13/src/math/roundf.c	2013-08-30 23:30:53.000000000 +0200
++++ musl-git/src/math/roundf.c	2013-09-16 20:31:39.000000000 +0200
+@@ -1,48 +1,27 @@
+-/* origin: FreeBSD /usr/src/lib/msun/src/s_roundf.c */
+-/*-
+- * Copyright (c) 2003, 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.
+- */
+-
+-#include <math.h>
++#include "libm.h"
+ 
+ float roundf(float x)
+ {
+-	float t;
++	union {float f; uint32_t i;} u = {x};
++	int e = u.i >> 23 & 0xff;
++	float_t y;
+ 
+-	if (!isfinite(x))
++	if (e >= 0x7f+23)
+ 		return x;
+-
+-	if (x >= 0.0) {
+-		t = floorf(x);
+-		if (t - x <= -0.5)
+-			t += 1.0;
+-		return t;
+-	} else {
+-		t = floorf(-x);
+-		if (t + x <= -0.5)
+-			t += 1.0;
+-		return -t;
++	if (u.i >> 31)
++		x = -x;
++	if (e < 0x7f-1) {
++		FORCE_EVAL(x + 0x1p23f);
++		return 0*u.f;
+ 	}
++	y = (float)(x + 0x1p23f) - 0x1p23f - 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;
+ }
+diff -Nur musl-0.9.13/src/math/roundl.c musl-git/src/math/roundl.c
+--- musl-0.9.13/src/math/roundl.c	2013-08-30 23:30:53.000000000 +0200
++++ musl-git/src/math/roundl.c	2013-09-16 20:31:39.000000000 +0200
+@@ -1,56 +1,39 @@
+-/* origin: FreeBSD /usr/src/lib/msun/src/s_roundl.c */
+-/*-
+- * Copyright (c) 2003, 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.
+- */
+-
+-#include <math.h>
+-#include <float.h>
++#include "libm.h"
+ 
+ #if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024
+ long double roundl(long double x)
+ {
+ 	return round(x);
+ }
+-#else
++#elif (LDBL_MANT_DIG == 64 || LDBL_MANT_DIG == 113) && LDBL_MAX_EXP == 16384
++#if LDBL_MANT_DIG == 64
++#define TOINT 0x1p63
++#elif LDBL_MANT_DIG == 113
++#define TOINT 0x1p112
++#endif
+ long double roundl(long double x)
+ {
+-	long double t;
++	union ldshape u = {x};
++	int e = u.i.se & 0x7fff;
++	long double y;
+ 
+-	if (!isfinite(x))
++	if (e >= 0x3fff+LDBL_MANT_DIG-1)
+ 		return x;
+-
+-	if (x >= 0.0) {
+-		t = floorl(x);
+-		if (t - x <= -0.5)
+-			t += 1.0;
+-		return t;
+-	} else {
+-		t = floorl(-x);
+-		if (t + x <= -0.5)
+-			t += 1.0;
+-		return -t;
++	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
+diff -Nur musl-0.9.13/src/math/scalbn.c musl-git/src/math/scalbn.c
+--- musl-0.9.13/src/math/scalbn.c	2013-08-30 23:30:53.000000000 +0200
++++ musl-git/src/math/scalbn.c	2013-09-16 20:31:39.000000000 +0200
+@@ -1,29 +1,31 @@
+-#include "libm.h"
++#include <math.h>
++#include <stdint.h>
+ 
+ double scalbn(double x, int n)
+ {
+-	double scale;
++	union {double f; uint64_t i;} u;
++	double_t y = x;
+ 
+ 	if (n > 1023) {
+-		x *= 0x1p1023;
++		y *= 0x1p1023;
+ 		n -= 1023;
+ 		if (n > 1023) {
+-			x *= 0x1p1023;
++			y *= 0x1p1023;
+ 			n -= 1023;
+ 			if (n > 1023)
+ 				n = 1023;
+ 		}
+ 	} else if (n < -1022) {
+-		x *= 0x1p-1022;
++		y *= 0x1p-1022;
+ 		n += 1022;
+ 		if (n < -1022) {
+-			x *= 0x1p-1022;
++			y *= 0x1p-1022;
+ 			n += 1022;
+ 			if (n < -1022)
+ 				n = -1022;
+ 		}
+ 	}
+-	INSERT_WORDS(scale, (uint32_t)(0x3ff+n)<<20, 0);
+-	STRICT_ASSIGN(double, x, x * scale);
++	u.i = (uint64_t)(0x3ff+n)<<52;
++	x = y * u.f;
+ 	return x;
+ }
+diff -Nur musl-0.9.13/src/math/scalbnf.c musl-git/src/math/scalbnf.c
+--- musl-0.9.13/src/math/scalbnf.c	2013-08-30 23:30:53.000000000 +0200
++++ musl-git/src/math/scalbnf.c	2013-09-16 20:31:39.000000000 +0200
+@@ -1,29 +1,31 @@
+-#include "libm.h"
++#include <math.h>
++#include <stdint.h>
+ 
+ float scalbnf(float x, int n)
+ {
+-	float scale;
++	union {float f; uint32_t i;} u;
++	float_t y = x;
+ 
+ 	if (n > 127) {
+-		x *= 0x1p127f;
++		y *= 0x1p127f;
+ 		n -= 127;
+ 		if (n > 127) {
+-			x *= 0x1p127f;
++			y *= 0x1p127f;
+ 			n -= 127;
+ 			if (n > 127)
+ 				n = 127;
+ 		}
+ 	} else if (n < -126) {
+-		x *= 0x1p-126f;
++		y *= 0x1p-126f;
+ 		n += 126;
+ 		if (n < -126) {
+-			x *= 0x1p-126f;
++			y *= 0x1p-126f;
+ 			n += 126;
+ 			if (n < -126)
+ 				n = -126;
+ 		}
+ 	}
+-	SET_FLOAT_WORD(scale, (uint32_t)(0x7f+n)<<23);
+-	STRICT_ASSIGN(float, x, x * scale);
++	u.i = (uint32_t)(0x7f+n)<<23;
++	x = y * u.f;
+ 	return x;
+ }
+diff -Nur musl-0.9.13/src/math/scalbnl.c musl-git/src/math/scalbnl.c
+--- musl-0.9.13/src/math/scalbnl.c	2013-08-30 23:30:53.000000000 +0200
++++ musl-git/src/math/scalbnl.c	2013-09-16 20:31:39.000000000 +0200
+@@ -8,7 +8,7 @@
+ #elif (LDBL_MANT_DIG == 64 || LDBL_MANT_DIG == 113) && LDBL_MAX_EXP == 16384
+ long double scalbnl(long double x, int n)
+ {
+-	union IEEEl2bits scale;
++	union ldshape u;
+ 
+ 	if (n > 16383) {
+ 		x *= 0x1p16383L;
+@@ -29,8 +29,8 @@
+ 				n = -16382;
+ 		}
+ 	}
+-	scale.e = 1.0;
+-	scale.bits.exp = 0x3fff + n;
+-	return x * scale.e;
++	u.f = 1.0;
++	u.i.se = 0x3fff + n;
++	return x * u.f;
+ }
+ #endif
+diff -Nur musl-0.9.13/src/math/signgam.c musl-git/src/math/signgam.c
+--- musl-0.9.13/src/math/signgam.c	2013-08-30 23:30:53.000000000 +0200
++++ musl-git/src/math/signgam.c	2013-09-16 20:31:39.000000000 +0200
+@@ -1,4 +1,5 @@
+-#include "libm.h"
++#include <math.h>
++#include "libc.h"
+ 
+ int __signgam = 0;
+ 
+diff -Nur musl-0.9.13/src/math/sincosl.c musl-git/src/math/sincosl.c
+--- musl-0.9.13/src/math/sincosl.c	2013-08-30 23:30:53.000000000 +0200
++++ musl-git/src/math/sincosl.c	2013-09-16 20:31:39.000000000 +0200
+@@ -9,25 +9,19 @@
+ #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 IEEEl2bits u;
++	union ldshape u = {x};
+ 	unsigned n;
+ 	long double y[2], s, c;
+ 
+-	u.e = x;
+-	u.bits.sign = 0;
+-
+-	/* x = nan or inf */
+-	if (u.bits.exp == 0x7fff) {
++	u.i.se &= 0x7fff;
++	if (u.i.se == 0x7fff) {
+ 		*sin = *cos = x - x;
+ 		return;
+ 	}
+-
+-	/* |x| < (double)pi/4 */
+-	if (u.e < M_PI_4) {
+-		/* |x| < 0x1p-64 */
+-		if (u.bits.exp < 0x3fff - 64) {
++	if (u.f < M_PI_4) {
++		if (u.i.se < 0x3fff - LDBL_MANT_DIG) {
+ 			/* raise underflow if subnormal */
+-			if (u.bits.exp == 0) FORCE_EVAL(x*0x1p-120f);
++			if (u.i.se == 0) FORCE_EVAL(x*0x1p-120f);
+ 			*sin = x;
+ 			/* raise inexact if x!=0 */
+ 			*cos = 1.0 + x;
+@@ -37,7 +31,6 @@
+ 		*cos = __cosl(x, 0);
+ 		return;
+ 	}
+-
+ 	n = __rem_pio2l(x, y);
+ 	s = __sinl(y[0], y[1], 1);
+ 	c = __cosl(y[0], y[1]);
+diff -Nur musl-0.9.13/src/math/sinhl.c musl-git/src/math/sinhl.c
+--- musl-0.9.13/src/math/sinhl.c	2013-08-30 23:30:53.000000000 +0200
++++ musl-git/src/math/sinhl.c	2013-09-16 20:31:39.000000000 +0200
+@@ -8,10 +8,7 @@
+ #elif LDBL_MANT_DIG == 64 && LDBL_MAX_EXP == 16384
+ long double sinhl(long double x)
+ {
+-	union {
+-		long double f;
+-		struct{uint64_t m; uint16_t se; uint16_t pad;} i;
+-	} u = {.f = x};
++	union ldshape u = {x};
+ 	unsigned ex = u.i.se & 0x7fff;
+ 	long double h, t, absx;
+ 
+diff -Nur musl-0.9.13/src/math/sinl.c musl-git/src/math/sinl.c
+--- musl-0.9.13/src/math/sinl.c	2013-08-30 23:30:53.000000000 +0200
++++ musl-git/src/math/sinl.c	2013-09-16 20:31:39.000000000 +0200
+@@ -1,31 +1,3 @@
+-/* origin: FreeBSD /usr/src/lib/msun/src/s_sinl.c */
+-/*-
+- * Copyright (c) 2007 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.
+- */
+-
+-
+ #include "libm.h"
+ 
+ #if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024
+@@ -36,46 +8,34 @@
+ #elif (LDBL_MANT_DIG == 64 || LDBL_MANT_DIG == 113) && LDBL_MAX_EXP == 16384
+ long double sinl(long double x)
+ {
+-	union IEEEl2bits z;
++	union ldshape u = {x};
+ 	unsigned n;
+-	long double y[2];
+-	long double hi, lo;
+-
+-	z.e = x;
+-	z.bits.sign = 0;
++	long double y[2], hi, lo;
+ 
+-	/* If x = NaN or Inf, then sin(x) = NaN. */
+-	if (z.bits.exp == 0x7fff)
+-		return (x - x) / (x - x);
+-
+-	/* |x| < (double)pi/4 */
+-	if (z.e < M_PI_4) {
+-		/* |x| < 0x1p-64 */
+-		if (z.bits.exp < 0x3fff - 64) {
++	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(z.bits.exp == 0 ? x/0x1p120f : x+0x1p120f);
++			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:
+-		hi = __sinl(hi, lo, 1);
+-		break;
++		return __sinl(hi, lo, 1);
+ 	case 1:
+-		hi = __cosl(hi, lo);
+-		break;
++		return __cosl(hi, lo);
+ 	case 2:
+-		hi = -__sinl(hi, lo, 1);
+-		break;
++		return -__sinl(hi, lo, 1);
+ 	case 3:
+-		hi = -__cosl(hi, lo);
+-		break;
++	default:
++		return -__cosl(hi, lo);
+ 	}
+-	return hi;
+ }
+ #endif
+diff -Nur musl-0.9.13/src/math/sqrtl.c musl-git/src/math/sqrtl.c
+--- musl-0.9.13/src/math/sqrtl.c	2013-08-30 23:30:53.000000000 +0200
++++ musl-git/src/math/sqrtl.c	2013-09-16 20:31:39.000000000 +0200
+@@ -2,8 +2,6 @@
+ 
+ long double sqrtl(long double x)
+ {
+-	/* FIXME: implement sqrtl in C. At least this works for now on
+-	 * ARM (which uses ld64), the only arch without sqrtl asm
+-	 * that's supported so far. */
++	/* FIXME: implement in C, this is for LDBL_MANT_DIG == 64 only */
+ 	return sqrt(x);
+ }
+diff -Nur musl-0.9.13/src/math/tanhl.c musl-git/src/math/tanhl.c
+--- musl-0.9.13/src/math/tanhl.c	2013-08-30 23:30:53.000000000 +0200
++++ musl-git/src/math/tanhl.c	2013-09-16 20:31:39.000000000 +0200
+@@ -8,10 +8,7 @@
+ #elif LDBL_MANT_DIG == 64 && LDBL_MAX_EXP == 16384
+ long double tanhl(long double x)
+ {
+-	union {
+-		long double f;
+-		struct{uint64_t m; uint16_t se; uint16_t pad;} i;
+-	} u = {.f = x};
++	union ldshape u = {x};
+ 	unsigned ex = u.i.se & 0x7fff;
+ 	unsigned sign = u.i.se & 0x8000;
+ 	uint32_t w;
+diff -Nur musl-0.9.13/src/math/tanl.c musl-git/src/math/tanl.c
+--- musl-0.9.13/src/math/tanl.c	2013-08-30 23:30:53.000000000 +0200
++++ musl-git/src/math/tanl.c	2013-09-16 20:31:39.000000000 +0200
+@@ -1,35 +1,3 @@
+-/* origin: FreeBSD /usr/src/lib/msun/src/s_tanl.c */
+-/*-
+- * Copyright (c) 2007 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.
+- */
+-/*
+- * Limited testing on pseudorandom numbers drawn within [0:4e8] shows
+- * an accuracy of <= 1.5 ULP where 247024 values of x out of 40 million
+- * possibles resulted in tan(x) that exceeded 0.5 ULP (ie., 0.6%).
+- */
+-
+ #include "libm.h"
+ 
+ #if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024
+@@ -40,28 +8,21 @@
+ #elif (LDBL_MANT_DIG == 64 || LDBL_MANT_DIG == 113) && LDBL_MAX_EXP == 16384
+ long double tanl(long double x)
+ {
+-	union IEEEl2bits z;
++	union ldshape u = {x};
+ 	long double y[2];
+ 	unsigned n;
+ 
+-	z.e = x;
+-	z.bits.sign = 0;
+-
+-	/* If x = NaN or Inf, then tan(x) = NaN. */
+-	if (z.bits.exp == 0x7fff)
+-		return (x - x) / (x - x);
+-
+-	/* |x| < (double)pi/4 */
+-	if (z.e < M_PI_4) {
+-		/* |x| < 0x1p-64 */
+-		if (z.bits.exp < 0x3fff - 64) {
++	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(z.bits.exp == 0 ? x/0x1p120f : x+0x1p120f);
++			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);
+ }
+diff -Nur musl-0.9.13/src/math/trunc.c musl-git/src/math/trunc.c
+--- musl-0.9.13/src/math/trunc.c	2013-08-30 23:30:53.000000000 +0200
++++ musl-git/src/math/trunc.c	2013-09-16 20:31:39.000000000 +0200
+@@ -1,63 +1,19 @@
+-/* origin: FreeBSD /usr/src/lib/msun/src/s_trunc.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.
+- * ====================================================
+- */
+-/*
+- * trunc(x)
+- * Return x rounded toward 0 to integral value
+- * Method:
+- *      Bit twiddling.
+- * Exception:
+- *      Inexact flag raised if x not equal to trunc(x).
+- */
+-
+ #include "libm.h"
+ 
+-static const double huge = 1.0e300;
+-
+ double trunc(double x)
+ {
+-	int32_t i0,i1,j0;
+-	uint32_t i;
++	union {double f; uint64_t i;} u = {x};
++	int e = (int)(u.i >> 52 & 0x7ff) - 0x3ff + 12;
++	uint64_t m;
+ 
+-	EXTRACT_WORDS(i0, i1, x);
+-	j0 = ((i0>>20)&0x7ff) - 0x3ff;
+-	if (j0 < 20) {
+-		if (j0 < 0) { /* |x|<1, return 0*sign(x) */
+-			/* raise inexact if x != 0 */
+-			if (huge+x > 0.0) {
+-				i0 &= 0x80000000U;
+-				i1 = 0;
+-			}
+-		} else {
+-			i = 0x000fffff>>j0;
+-			if (((i0&i)|i1) == 0)
+-				return x; /* x is integral */
+-			/* raise inexact */
+-			if (huge+x > 0.0) {
+-				i0 &= ~i;
+-				i1 = 0;
+-			}
+-		}
+-	} else if (j0 > 51) {
+-		if (j0 == 0x400)
+-			return x + x;  /* inf or NaN */
+-		return x;              /* x is integral */
+-	} else {
+-		i = (uint32_t)0xffffffff>>(j0-20);
+-		if ((i1&i) == 0)
+-			return x;      /* x is integral */
+-		/* raise inexact */
+-		if (huge+x > 0.0)
+-			i1 &= ~i;
+-	}
+-	INSERT_WORDS(x, i0, i1);
+-	return x;
++	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;
+ }
+diff -Nur musl-0.9.13/src/math/truncf.c musl-git/src/math/truncf.c
+--- musl-0.9.13/src/math/truncf.c	2013-08-30 23:30:53.000000000 +0200
++++ musl-git/src/math/truncf.c	2013-09-16 20:31:39.000000000 +0200
+@@ -1,52 +1,19 @@
+-/* origin: FreeBSD /usr/src/lib/msun/src/s_truncf.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.
+- * ====================================================
+- */
+-/*
+- * truncf(x)
+- * Return x rounded toward 0 to integral value
+- * Method:
+- *      Bit twiddling.
+- * Exception:
+- *      Inexact flag raised if x not equal to truncf(x).
+- */
+-
+ #include "libm.h"
+ 
+-static const float huge = 1.0e30f;
+-
+ float truncf(float x)
+ {
+-	int32_t i0,j0;
+-	uint32_t i;
++	union {float f; uint32_t i;} u = {x};
++	int e = (int)(u.i >> 23 & 0xff) - 0x7f + 9;
++	uint32_t m;
+ 
+-	GET_FLOAT_WORD(i0, x);
+-	j0 = ((i0>>23)&0xff) - 0x7f;
+-	if (j0 < 23) {
+-		if (j0 < 0) {  /* |x|<1, return 0*sign(x) */
+-			/* raise inexact if x != 0 */
+-			if (huge+x > 0.0f)
+-				i0 &= 0x80000000;
+-		} else {
+-			i = 0x007fffff>>j0;
+-			if ((i0&i) == 0)
+-				return x; /* x is integral */
+-			/* raise inexact */
+-			if (huge+x > 0.0f)
+-				i0 &= ~i;
+-		}
+-	} else {
+-		if (j0 == 0x80)
+-			return x + x;  /* inf or NaN */
+-		return x;              /* x is integral */
+-	}
+-	SET_FLOAT_WORD(x, i0);
+-	return x;
++	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;
+ }
+diff -Nur musl-0.9.13/src/math/truncl.c musl-git/src/math/truncl.c
+--- musl-0.9.13/src/math/truncl.c	2013-08-30 23:30:53.000000000 +0200
++++ musl-git/src/math/truncl.c	2013-09-16 20:31:39.000000000 +0200
+@@ -1,23 +1,3 @@
+-/* origin: FreeBSD /usr/src/lib/msun/src/s_truncl.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.
+- * ====================================================
+- */
+-/*
+- * truncl(x)
+- * Return x rounded toward 0 to integral value
+- * Method:
+- *      Bit twiddling.
+- * Exception:
+- *      Inexact flag raised if x not equal to truncl(x).
+- */
+-
+ #include "libm.h"
+ 
+ #if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024
+@@ -26,43 +6,31 @@
+ 	return trunc(x);
+ }
+ #elif (LDBL_MANT_DIG == 64 || LDBL_MANT_DIG == 113) && LDBL_MAX_EXP == 16384
+-#ifdef LDBL_IMPLICIT_NBIT
+-#define MANH_SIZE       (LDBL_MANH_SIZE + 1)
+-#else
+-#define MANH_SIZE       LDBL_MANH_SIZE
++#if LDBL_MANT_DIG == 64
++#define TOINT 0x1p63
++#elif LDBL_MANT_DIG == 113
++#define TOINT 0x1p112
+ #endif
+-
+-static const long double huge = 1.0e300;
+-static const float zero[] = { 0.0, -0.0 };
+-
+ long double truncl(long double x)
+ {
+-	union IEEEl2bits u = { .e = x };
+-	int e = u.bits.exp - LDBL_MAX_EXP + 1;
++	union ldshape u = {x};
++	int e = u.i.se & 0x7fff;
++	int s = u.i.se >> 15;
++	long double y;
+ 
+-	if (e < MANH_SIZE - 1) {
+-		if (e < 0) {
+-			/* raise inexact if x != 0 */
+-			if (huge + x > 0.0)
+-				u.e = zero[u.bits.sign];
+-		} else {
+-			uint64_t m = ((1llu << MANH_SIZE) - 1) >> (e + 1);
+-			if (((u.bits.manh & m) | u.bits.manl) == 0)
+-				return x;     /* x is integral */
+-			/* raise inexact */
+-			if (huge + x > 0.0) {
+-				u.bits.manh &= ~m;
+-				u.bits.manl = 0;
+-			}
+-		}
+-	} else if (e < LDBL_MANT_DIG - 1) {
+-		uint64_t m = (uint64_t)-1 >> (64 - LDBL_MANT_DIG + e + 1);
+-		if ((u.bits.manl & m) == 0)
+-			return x;     /* x is integral */
+-		/* raise inexact */
+-		if (huge + x > 0.0)
+-			u.bits.manl &= ~m;
++	if (e >= 0x3fff+LDBL_MANT_DIG-1)
++		return x;
++	if (e <= 0x3fff-1) {
++		FORCE_EVAL(x + 0x1p120f);
++		return x*0;
+ 	}
+-	return u.e;
++	/* 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
+diff -Nur musl-0.9.13/src/math/x86_64/ceill.s musl-git/src/math/x86_64/ceill.s
+--- musl-0.9.13/src/math/x86_64/ceill.s	2013-08-30 23:30:53.000000000 +0200
++++ musl-git/src/math/x86_64/ceill.s	2013-09-16 20:31:39.000000000 +0200
+@@ -1 +1 @@
+-# see floor.s
++# see floorl.s
+diff -Nur musl-0.9.13/src/math/x86_64/exp2l.s musl-git/src/math/x86_64/exp2l.s
+--- musl-0.9.13/src/math/x86_64/exp2l.s	2013-08-30 23:30:53.000000000 +0200
++++ musl-git/src/math/x86_64/exp2l.s	2013-09-16 20:31:39.000000000 +0200
+@@ -4,8 +4,18 @@
+ 	fldt 8(%rsp)
+ 	fldl2e
+ 	fmulp
++	movl $0xc2820000,-4(%rsp)
++	flds -4(%rsp)
++	fucomp %st(1)
++	fnstsw %ax
++	sahf
+ 	fld1
+-	fld %st(1)
++	jb 1f
++		# x*log2e <= -65, return -1 without underflow
++	fstp %st(1)
++	fchs
++	ret
++1:	fld %st(1)
+ 	fabs
+ 	fucom %st(1)
+ 	fnstsw %ax
+@@ -26,44 +36,32 @@
+ .type exp2l,@function
+ exp2l:
+ 	fldt 8(%rsp)
+-1:	mov $0x467ff000,%eax
+-	mov %eax,-16(%rsp)
+-	mov $0x80000000,%eax
+-	mov %eax,-20(%rsp)
+-	xor %eax,%eax
+-	mov %eax,-24(%rsp)
+-	flds -16(%rsp)    # 16380
++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)
+-	fabs
+-	fucom %st(1)
++	fsub %st(1)
++	faddp
++	fucomp %st(1)
+ 	fnstsw
+-	fstp %st(0)
+-	fstp %st(0)
+ 	sahf
+-	ja 3f             # |x| > 16380
+-	jp 2f             # x is nan (avoid invalid except in fistp)
+-	fld %st(0)
+-	fistpl -16(%rsp)
+-	fildl -16(%rsp)
+-	fxch %st(1)
+-	fsub %st(1)
+-	mov $0x3fff,%eax
+-	add %eax,-16(%rsp)
+-	f2xm1
+-	fld1
+-	faddp             # 2^(x-rint(x))
+-	fldt -24(%rsp)    # 2^rint(x)
+-	fmulp
+-2:	fstp %st(1)
+-	ret
+-
+-3:	fld %st(0)
+-	fstpt -24(%rsp)
+-	fld1
+-	mov -15(%rsp),%ax
+-	and $0x7fff,%ax
+-	cmp $0x7fff,%ax
+-	je 1f             # x = +-inf
++	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)
+@@ -72,4 +70,21 @@
+ 	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
+diff -Nur musl-0.9.13/src/math/x86_64/lrintl.s musl-git/src/math/x86_64/lrintl.s
+--- musl-0.9.13/src/math/x86_64/lrintl.s	2013-08-30 23:30:53.000000000 +0200
++++ musl-git/src/math/x86_64/lrintl.s	2013-09-16 20:31:39.000000000 +0200
+@@ -2,6 +2,6 @@
+ .type lrintl,@function
+ lrintl:
+ 	fldt 8(%rsp)
+-	fistpl 8(%rsp)
+-	mov 8(%rsp),%eax
++	fistpll 8(%rsp)
++	mov 8(%rsp),%rax
+ 	ret
+diff -Nur musl-0.9.13/src/math/x86_64/truncl.s musl-git/src/math/x86_64/truncl.s
+--- musl-0.9.13/src/math/x86_64/truncl.s	2013-08-30 23:30:53.000000000 +0200
++++ musl-git/src/math/x86_64/truncl.s	2013-09-16 20:31:39.000000000 +0200
+@@ -1 +1 @@
+-# see floor.s
++# see floorl.s
+diff -Nur musl-0.9.13/src/misc/realpath.c musl-git/src/misc/realpath.c
+--- musl-0.9.13/src/misc/realpath.c	2013-08-30 23:30:53.000000000 +0200
++++ musl-git/src/misc/realpath.c	2013-09-16 20:31:39.000000000 +0200
+@@ -1,10 +1,11 @@
+ #include <stdlib.h>
+-#include <stdio.h>
+ #include <limits.h>
+ #include <sys/stat.h>
+ #include <fcntl.h>
+ #include <errno.h>
+ #include <unistd.h>
++#include <string.h>
++#include "syscall.h"
+ 
+ void __procfdname(char *, unsigned);
+ 
+@@ -14,38 +15,31 @@
+ 	ssize_t r;
+ 	struct stat st1, st2;
+ 	char buf[15+3*sizeof(int)];
+-	int alloc = 0;
++	char tmp[PATH_MAX];
+ 
+ 	if (!filename) {
+ 		errno = EINVAL;
+ 		return 0;
+ 	}
+ 
+-	fd = open(filename, O_RDONLY|O_NONBLOCK|O_CLOEXEC);
++	fd = syscall(SYS_open, filename, O_PATH|O_NONBLOCK|O_CLOEXEC|O_LARGEFILE);
+ 	if (fd < 0) return 0;
+ 	__procfdname(buf, fd);
+ 
+-	if (!resolved) {
+-		alloc = 1;
+-		resolved = malloc(PATH_MAX);
+-		if (!resolved) return 0;
+-	}
+-
+-	r = readlink(buf, resolved, PATH_MAX-1);
++	r = readlink(buf, tmp, sizeof tmp - 1);
+ 	if (r < 0) goto err;
+-	resolved[r] = 0;
++	tmp[r] = 0;
+ 
+ 	fstat(fd, &st1);
+-	r = stat(resolved, &st2);
++	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;
+ 	}
+ 
+-	close(fd);
+-	return resolved;
++	__syscall(SYS_close, fd);
++	return resolved ? strcpy(resolved, tmp) : strdup(tmp);
+ err:
+-	if (alloc) free(resolved);
+-	close(fd);
++	__syscall(SYS_close, fd);
+ 	return 0;
+ }
+diff -Nur musl-0.9.13/src/mman/mprotect.c musl-git/src/mman/mprotect.c
+--- musl-0.9.13/src/mman/mprotect.c	2013-08-30 23:30:53.000000000 +0200
++++ musl-git/src/mman/mprotect.c	2013-09-16 20:31:39.000000000 +0200
+@@ -1,5 +1,5 @@
+ #include <sys/mman.h>
+-#include <limits.h>
++#include "libc.h"
+ #include "syscall.h"
+ 
+ int mprotect(void *addr, size_t len, int prot)
+diff -Nur musl-0.9.13/src/signal/sigemptyset.c musl-git/src/signal/sigemptyset.c
+--- musl-0.9.13/src/signal/sigemptyset.c	2013-08-30 23:30:53.000000000 +0200
++++ musl-git/src/signal/sigemptyset.c	2013-09-16 20:31:39.000000000 +0200
+@@ -4,6 +4,10 @@
+ int sigemptyset(sigset_t *set)
+ {
+ 	set->__bits[0] = 0;
+-	if (sizeof(long)==4) set->__bits[1] = 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;
+ }
+diff -Nur musl-0.9.13/src/signal/sigfillset.c musl-git/src/signal/sigfillset.c
+--- musl-0.9.13/src/signal/sigfillset.c	2013-08-30 23:30:53.000000000 +0200
++++ musl-git/src/signal/sigfillset.c	2013-09-16 20:31:39.000000000 +0200
+@@ -7,8 +7,13 @@
+ #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;
+ }
+diff -Nur musl-0.9.13/src/signal/sigqueue.c musl-git/src/signal/sigqueue.c
+--- musl-0.9.13/src/signal/sigqueue.c	2013-08-30 23:30:53.000000000 +0200
++++ musl-git/src/signal/sigqueue.c	2013-09-16 20:31:39.000000000 +0200
+@@ -3,6 +3,7 @@
+ #include <unistd.h>
+ #include <stdint.h>
+ #include "syscall.h"
++#include "pthread_impl.h"
+ 
+ int sigqueue(pid_t pid, int sig, const union sigval value)
+ {
+@@ -14,9 +15,9 @@
+ 	si.si_code = SI_QUEUE;
+ 	si.si_value = value;
+ 	si.si_uid = getuid();
+-	pthread_sigmask(SIG_BLOCK, (void *)(uint64_t[1]){-1}, &set);
++	__block_app_sigs(&set);
+ 	si.si_pid = getpid();
+ 	r = syscall(SYS_rt_sigqueueinfo, pid, sig, &si);
+-	pthread_sigmask(SIG_SETMASK, &set, 0);
++	__restore_sigs(&set);
+ 	return r;
+ }
+diff -Nur musl-0.9.13/src/stdio/popen.c musl-git/src/stdio/popen.c
+--- musl-0.9.13/src/stdio/popen.c	2013-08-30 23:30:53.000000000 +0200
++++ musl-git/src/stdio/popen.c	2013-09-16 20:31:39.000000000 +0200
+@@ -39,7 +39,7 @@
+ 	 * 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(F_DUPFD_CLOEXEC, 1-op, 0);
++		int tmp = fcntl(1-op, F_DUPFD_CLOEXEC, 0);
+ 		if (tmp < 0) {
+ 			e = errno;
+ 			goto fail;
+diff -Nur musl-0.9.13/src/stdio/vfscanf.c musl-git/src/stdio/vfscanf.c
+--- musl-0.9.13/src/stdio/vfscanf.c	2013-08-30 23:30:53.000000000 +0200
++++ musl-git/src/stdio/vfscanf.c	2013-09-16 20:31:39.000000000 +0200
+@@ -118,6 +118,8 @@
+ 		}
+ 
+ 		if (*p=='m') {
++			wcs = 0;
++			s = 0;
+ 			alloc = !!dest;
+ 			p++;
+ 		} else {
+diff -Nur musl-0.9.13/src/stdio/vfwscanf.c musl-git/src/stdio/vfwscanf.c
+--- musl-0.9.13/src/stdio/vfwscanf.c	2013-08-30 23:30:53.000000000 +0200
++++ musl-git/src/stdio/vfwscanf.c	2013-09-16 20:31:39.000000000 +0200
+@@ -143,6 +143,8 @@
+ 		}
+ 
+ 		if (*p=='m') {
++			wcs = 0;
++			s = 0;
+ 			alloc = !!dest;
+ 			p++;
+ 		} else {
+diff -Nur musl-0.9.13/src/temp/__randname.c musl-git/src/temp/__randname.c
+--- musl-0.9.13/src/temp/__randname.c	2013-08-30 23:30:53.000000000 +0200
++++ musl-git/src/temp/__randname.c	2013-09-16 20:31:39.000000000 +0200
+@@ -5,7 +5,7 @@
+ int __clock_gettime(clockid_t, struct timespec *);
+ 
+ /* This assumes that a check for the
+-   template size has alrady been made */
++   template size has already been made */
+ char *__randname(char *template)
+ {
+ 	int i;
+diff -Nur musl-0.9.13/src/thread/mips/clone.s musl-git/src/thread/mips/clone.s
+--- musl-0.9.13/src/thread/mips/clone.s	2013-08-30 23:30:53.000000000 +0200
++++ musl-git/src/thread/mips/clone.s	2013-09-16 20:31:39.000000000 +0200
+@@ -3,6 +3,7 @@
+ .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)
+@@ -11,15 +12,18 @@
+ 	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)
+diff -Nur musl-0.9.13/src/thread/pthread_create.c musl-git/src/thread/pthread_create.c
+--- musl-0.9.13/src/thread/pthread_create.c	2013-08-30 23:30:53.000000000 +0200
++++ musl-git/src/thread/pthread_create.c	2013-09-16 20:31:39.000000000 +0200
+@@ -1,5 +1,7 @@
++#define _GNU_SOURCE
+ #include "pthread_impl.h"
+ #include "stdio_impl.h"
++#include "libc.h"
+ #include <sys/mman.h>
+ 
+ static void dummy_0()
+@@ -127,7 +129,9 @@
+ 	size_t size, guard;
+ 	struct pthread *self = pthread_self(), *new;
+ 	unsigned char *map = 0, *stack = 0, *tsd = 0, *stack_limit;
+-	unsigned flags = 0x7d8f00;
++	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};
+ 
+@@ -197,7 +201,7 @@
+ 	new->tsd = (void *)tsd;
+ 	if (attr._a_detach) {
+ 		new->detached = 1;
+-		flags -= 0x200000;
++		flags -= CLONE_CHILD_CLEARTID;
+ 	}
+ 	if (attr._a_sched) {
+ 		do_sched = new->startlock[0] = 1;
+diff -Nur musl-0.9.13/src/thread/pthread_getattr_np.c musl-git/src/thread/pthread_getattr_np.c
+--- musl-0.9.13/src/thread/pthread_getattr_np.c	2013-08-30 23:30:53.000000000 +0200
++++ musl-git/src/thread/pthread_getattr_np.c	2013-09-16 20:31:39.000000000 +0200
+@@ -1,5 +1,6 @@
+ #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)
+diff -Nur musl-0.9.13/src/thread/synccall.c musl-git/src/thread/synccall.c
+--- musl-0.9.13/src/thread/synccall.c	2013-08-30 23:30:53.000000000 +0200
++++ musl-git/src/thread/synccall.c	2013-09-16 20:31:39.000000000 +0200
+@@ -43,7 +43,7 @@
+ 	pthread_t self;
+ 	struct sigaction sa;
+ 	struct chain *next;
+-	uint64_t oldmask;
++	sigset_t oldmask;
+ 
+ 	if (!libc.threads_minus_1) {
+ 		func(ctx);
+@@ -52,12 +52,12 @@
+ 
+ 	__inhibit_ptc();
+ 
+-	__syscall(SYS_rt_sigprocmask, SIG_BLOCK, SIGALL_SET,
+-		&oldmask, _NSIG/8);
++	__block_all_sigs(&oldmask);
+ 
+ 	sem_init(&chaindone, 0, 0);
+ 	sem_init(&chainlock, 0, 1);
+ 	chainlen = 0;
++	head = 0;
+ 	callback = func;
+ 	context = ctx;
+ 
+@@ -70,6 +70,10 @@
+ 	sigqueue(self->pid, SIGSYNCCALL, (union sigval){0});
+ 	while (sem_wait(&chaindone));
+ 
++	sa.sa_flags = 0;
++	sa.sa_handler = SIG_IGN;
++	__libc_sigaction(SIGSYNCCALL, &sa, 0);
++
+ 	for (cur=head; cur; cur=cur->next) {
+ 		sem_post(&cur->sem);
+ 		while (sem_wait(&cur->sem2));
+@@ -81,12 +85,7 @@
+ 		sem_post(&cur->sem);
+ 	}
+ 
+-	sa.sa_flags = 0;
+-	sa.sa_handler = SIG_IGN;
+-	__libc_sigaction(SIGSYNCCALL, &sa, 0);
+-
+-	__syscall(SYS_rt_sigprocmask, SIG_SETMASK,
+-		&oldmask, 0, _NSIG/8);
++	__restore_sigs(&oldmask);
+ 
+ 	__release_ptc();
+ }
+diff -Nur musl-0.9.13/src/unistd/faccessat.c musl-git/src/unistd/faccessat.c
+--- musl-0.9.13/src/unistd/faccessat.c	2013-08-30 23:30:53.000000000 +0200
++++ musl-git/src/unistd/faccessat.c	2013-09-16 20:31:39.000000000 +0200
+@@ -19,7 +19,7 @@
+ 		__syscall(SYS_exit, 1);
+ 	ret = __syscall(SYS_faccessat, c->fd, c->filename, c->amode, 0);
+ 	__syscall(SYS_write, c->p, &ret, sizeof ret);
+-	__syscall(SYS_exit, 0);
++	return 0;
+ }
+ 
+ int faccessat(int fd, const char *filename, int amode, int flag)