Commit bedf142b authored by Lennert Buytenhek's avatar Lennert Buytenhek Committed by Russell King

[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: default avatarLennert Buytenhek <buytenh@wantstofly.org>
Signed-off-by: default avatarRussell King <rmk+kernel@arm.linux.org.uk>
parent 06c03cac
...@@ -585,7 +585,7 @@ config FPE_NWFPE ...@@ -585,7 +585,7 @@ config FPE_NWFPE
config FPE_NWFPE_XP config FPE_NWFPE_XP
bool "Support extended precision" bool "Support extended precision"
depends on FPE_NWFPE && !CPU_BIG_ENDIAN depends on FPE_NWFPE
help help
Say Y to include 80-bit support in the kernel floating-point Say Y to include 80-bit support in the kernel floating-point
emulator. Otherwise, only 32 and 64-bit support is compiled in. emulator. Otherwise, only 32 and 64-bit support is compiled in.
......
...@@ -60,7 +60,7 @@ typedef union tagFPREG { ...@@ -60,7 +60,7 @@ typedef union tagFPREG {
#ifdef CONFIG_FPE_NWFPE_XP #ifdef CONFIG_FPE_NWFPE_XP
floatx80 fExtended; floatx80 fExtended;
#else #else
int padding[3]; u32 padding[3];
#endif #endif
} FPREG; } FPREG;
......
...@@ -59,8 +59,13 @@ static inline void loadExtended(const unsigned int Fn, const unsigned int __user ...@@ -59,8 +59,13 @@ static inline void loadExtended(const unsigned int Fn, const unsigned int __user
p = (unsigned int *) &fpa11->fpreg[Fn].fExtended; p = (unsigned int *) &fpa11->fpreg[Fn].fExtended;
fpa11->fType[Fn] = typeExtended; fpa11->fType[Fn] = typeExtended;
get_user(p[0], &pMem[0]); /* sign & exponent */ 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[1], &pMem[2]); /* ls bits */
get_user(p[2], &pMem[1]); /* ms bits */ get_user(p[2], &pMem[1]); /* ms bits */
#endif
} }
#endif #endif
...@@ -177,8 +182,13 @@ static inline void storeExtended(const unsigned int Fn, unsigned int __user *pMe ...@@ -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 */ 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[1], &pMem[2]);
put_user(val.i[2], &pMem[1]); /* msw */ put_user(val.i[2], &pMem[1]); /* msw */
#endif
} }
#endif #endif
......
...@@ -51,12 +51,17 @@ input or output the `floatx80' type will be defined. ...@@ -51,12 +51,17 @@ input or output the `floatx80' type will be defined.
Software IEC/IEEE floating-point types. Software IEC/IEEE floating-point types.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
*/ */
typedef unsigned long int float32; typedef u32 float32;
typedef unsigned long long float64; typedef u64 float64;
typedef struct { typedef struct {
unsigned short high; #ifdef __ARMEB__
unsigned short __padding; u16 __padding;
unsigned long long low; u16 high;
#else
u16 high;
u16 __padding;
#endif
u64 low;
} floatx80; } floatx80;
/* /*
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment