Parcourir la source

[ARM] 3118/1: fix and reenable nwfpe extended precision emulation for big-endian

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>
Lennert Buytenhek il y a 19 ans
Parent
commit
bedf142b8b
4 fichiers modifiés avec 22 ajouts et 7 suppressions
  1. 1 1
      arch/arm/Kconfig
  2. 1 1
      arch/arm/nwfpe/fpa11.h
  3. 10 0
      arch/arm/nwfpe/fpa11_cpdt.c
  4. 10 5
      arch/arm/nwfpe/softfloat.h

+ 1 - 1
arch/arm/Kconfig

@@ -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.

+ 1 - 1
arch/arm/nwfpe/fpa11.h

@@ -60,7 +60,7 @@ typedef union tagFPREG {
 #ifdef CONFIG_FPE_NWFPE_XP
 	floatx80 fExtended;
 #else
-	int padding[3];
+	u32 padding[3];
 #endif
 } FPREG;
 

+ 10 - 0
arch/arm/nwfpe/fpa11_cpdt.c

@@ -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
 

+ 10 - 5
arch/arm/nwfpe/softfloat.h

@@ -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;
 
 /*