Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

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

[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
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -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
Original line number Diff line number Diff line
@@ -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
Original line number Diff line number Diff line
@@ -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
Original line number Diff line number Diff line
@@ -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;

/*