Fix LP64 libm for 128-bit long doubles

* reworked amd64/_fpmath.h and arm64/_fpmath.h to support 128-bit long
doubles.
* improved tests to cover long double cases
* made modfl an alias for LP32

Tests pass on x86, x86_64, arm, arm64 and mips.

Bug: 12921273

Change-Id: Ibe39acde57972447a8950fa45b1e702acc68ebeb
diff --git a/libm/arm64/_fpmath.h b/libm/arm64/_fpmath.h
index a24632a..9f46640 100644
--- a/libm/arm64/_fpmath.h
+++ b/libm/arm64/_fpmath.h
@@ -26,31 +26,48 @@
  * $FreeBSD: src/lib/libc/aarch64/_fpmath.h $
  */
 
+// ANDROID changed
+// Android uses 128 bits long doubles for LP64, so the structure and the macros
+// were reworked for the quad precision ieee representation.
+
 union IEEEl2bits {
 	long double	e;
 	struct {
 #ifndef __AARCH64EB__
-		unsigned int	manl	:32;
-		unsigned int	manh	:20;
-		unsigned int	exp	:11;
+		unsigned long	manl	:64;
+		unsigned long	manh	:48;
+		unsigned int	exp	  :15;
 		unsigned int	sign	:1;
 #else
-		unsigned int		sign	:1;
-		unsigned int		exp	:11;
-		unsigned int		manh	:20;
-		unsigned int		manl	:32;
+		unsigned int	sign	:1;
+		unsigned int	exp	  :15;
+		unsigned long	manh	:48;
+		unsigned long	manl	:64;
 #endif
 	} bits;
+	struct {
+#ifndef __AARCH64EB__
+		unsigned long	manl	:64;
+		unsigned long	manh	:48;
+		unsigned int	expsign	:16;
+#else
+		unsigned int	expsign	:16;
+		unsigned long	manh	:48;
+		unsigned long	manl	:64;
+#endif
+	} xbits;
 };
 
 #define	LDBL_NBIT	0
 #define	LDBL_IMPLICIT_NBIT
 #define	mask_nbit_l(u)	((void)0)
 
-#define	LDBL_MANH_SIZE	32
-#define	LDBL_MANL_SIZE	32
+#define	LDBL_MANH_SIZE	48
+#define	LDBL_MANL_SIZE	64
 
 #define	LDBL_TO_ARRAY32(u, a) do {			\
 	(a)[0] = (uint32_t)(u).bits.manl;		\
-	(a)[1] = (uint32_t)(u).bits.manh;		\
+	(a)[1] = (uint32_t)((u).bits.manl >> 32);      	\
+	(a)[2] = (uint32_t)(u).bits.manh;		\
+	(a)[3] = (uint32_t)((u).bits.manh >> 32);	\
 } while(0)