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/amd64/_fpmath.h b/libm/amd64/_fpmath.h
index c2a7384..f8d5c85 100755
--- a/libm/amd64/_fpmath.h
+++ b/libm/amd64/_fpmath.h
@@ -26,30 +26,35 @@
* $FreeBSD$
*/
+// ANDROID changed
+// Android uses 128 bits long doubles for LP64, so the structure and macros
+// were reworked for the quad precision ieee representation.
+
union IEEEl2bits {
long double e;
struct {
- unsigned int manl :32;
- unsigned int manh :32;
- unsigned int exp :15;
+ unsigned long manl :64;
+ unsigned long manh :48;
+ unsigned int exp :15;
unsigned int sign :1;
- unsigned int junkl :16;
- unsigned int junkh :32;
} bits;
struct {
- unsigned long man :64;
+ unsigned long manl :64;
+ unsigned long manh :48;
unsigned int expsign :16;
- unsigned long junk :48;
} xbits;
};
-#define LDBL_NBIT 0x80000000
-#define mask_nbit_l(u) ((u).bits.manh &= ~LDBL_NBIT)
+#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; \
-} while (0)
+ (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)