[ARM] 3118/1: fix and reenable nwfpe extended precision emulation for big-endian
authorLennert Buytenhek <buytenh@wantstofly.org>
Mon, 7 Nov 2005 21:12:08 +0000 (21:12 +0000)
committerRussell King <rmk+kernel@arm.linux.org.uk>
Mon, 7 Nov 2005 21:12:08 +0000 (21:12 +0000)
Patch from Lennert Buytenhek

nwfpe extended precision emulation used to be broken on big-endian
and was therefore disabled.  This patch fixes nwfpe so that it copies
extended precision floats to/from userspace in the proper word order
(similar to patch #2046, see the description of that patch for an
explanation) and reenables the Kconfig option.

Signed-off-by: Lennert Buytenhek <buytenh@wantstofly.org>
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
arch/arm/Kconfig
arch/arm/nwfpe/fpa11.h
arch/arm/nwfpe/fpa11_cpdt.c
arch/arm/nwfpe/softfloat.h

index 296bc03..056adc8 100644 (file)
@@ -585,7 +585,7 @@ config FPE_NWFPE
 
 config FPE_NWFPE_XP
        bool "Support extended precision"
-       depends on FPE_NWFPE && !CPU_BIG_ENDIAN
+       depends on FPE_NWFPE
        help
          Say Y to include 80-bit support in the kernel floating-point
          emulator.  Otherwise, only 32 and 64-bit support is compiled in.
index 9677ae8..da4c616 100644 (file)
@@ -60,7 +60,7 @@ typedef union tagFPREG {
 #ifdef CONFIG_FPE_NWFPE_XP
        floatx80 fExtended;
 #else
-       int padding[3];
+       u32 padding[3];
 #endif
 } FPREG;
 
index b0db5cb..32859fa 100644 (file)
@@ -59,8 +59,13 @@ static inline void loadExtended(const unsigned int Fn, const unsigned int __user
        p = (unsigned int *) &fpa11->fpreg[Fn].fExtended;
        fpa11->fType[Fn] = typeExtended;
        get_user(p[0], &pMem[0]);       /* sign & exponent */
+#ifdef __ARMEB__
+       get_user(p[1], &pMem[1]);       /* ms bits */
+       get_user(p[2], &pMem[2]);       /* ls bits */
+#else
        get_user(p[1], &pMem[2]);       /* ls bits */
        get_user(p[2], &pMem[1]);       /* ms bits */
+#endif
 }
 #endif
 
@@ -177,8 +182,13 @@ static inline void storeExtended(const unsigned int Fn, unsigned int __user *pMe
        }
 
        put_user(val.i[0], &pMem[0]);   /* sign & exp */
+#ifdef __ARMEB__
+       put_user(val.i[1], &pMem[1]);   /* msw */
+       put_user(val.i[2], &pMem[2]);
+#else
        put_user(val.i[1], &pMem[2]);
        put_user(val.i[2], &pMem[1]);   /* msw */
+#endif
 }
 #endif
 
index 1301d97..978c699 100644 (file)
@@ -51,12 +51,17 @@ input or output the `floatx80' type will be defined.
 Software IEC/IEEE floating-point types.
 -------------------------------------------------------------------------------
 */
-typedef unsigned long int float32;
-typedef unsigned long long float64;
+typedef u32 float32;
+typedef u64 float64;
 typedef struct {
-    unsigned short high;
-    unsigned short __padding;
-    unsigned long long low;
+#ifdef __ARMEB__
+    u16 __padding;
+    u16 high;
+#else
+    u16 high;
+    u16 __padding;
+#endif
+    u64 low;
 } floatx80;
 
 /*