aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorYousong Zhou <yszhou4tech@gmail.com>2015-09-03 17:47:45 +0800
committerRalf Baechle <ralf@linux-mips.org>2015-09-03 12:30:19 +0200
commit0b41d69ac8d9350710e92448104f9665d6260a28 (patch)
tree196c2c426be61be503b4212b6b4212416bbda2a2
parent4cfb02fe1a4ad46aaf262a2653d9301c0119997d (diff)
downloadlinux-0b41d69ac8d9350710e92448104f9665d6260a28.tar.gz
MIPS: UAPI: Fix unrecognized opcode WSBH/DSBH/DSHD when using MIPS16.
The nomips16 has to be added both as function attribute and assembler directive. When only function attribute is specified, the compiler will inline the function with -Os optimization. The generated assembly code cannot be correctly assembled because ISA mode switch has to be done through jump instruction. When only ".set nomips16" directive is used, the generated assembly code will use MIPS32 code for the inline assembly template and MIPS16 for the function return. The compiled binary is invalid: 00403100 <__arch_swab16>: 403100: 7c0410a0 wsbh v0,a0 403104: e820ea31 swc2 $0,-5583(at) while correct code should be: 00402650 <__arch_swab16>: 402650: 7c0410a0 wsbh v0,a0 402654: 03e00008 jr ra 402658: 3042ffff andi v0,v0,0xffff Signed-off-by: Yousong Zhou <yszhou4tech@gmail.com> Cc: Chen Jie <chenj@lemote.com> Cc: linux-mips@linux-mips.org Cc: linux-kernel@vger.kernel.org Patchwork: https://patchwork.linux-mips.org/patch/11087/ Signed-off-by: Ralf Baechle <ralf@linux-mips.org> (cherry picked from commit 106c612ac609f72051fe6962c32cef80f49bbd27)
-rw-r--r--arch/mips/include/uapi/asm/swab.h24
1 files changed, 19 insertions, 5 deletions
diff --git a/arch/mips/include/uapi/asm/swab.h b/arch/mips/include/uapi/asm/swab.h
index ac9a8f9cd1fbf..4c03d6e63a394 100644
--- a/arch/mips/include/uapi/asm/swab.h
+++ b/arch/mips/include/uapi/asm/swab.h
@@ -15,10 +15,15 @@
#if defined(__mips_isa_rev) && (__mips_isa_rev >= 2)
-static inline __attribute_const__ __u16 __arch_swab16(__u16 x)
+static inline __attribute__((nomips16)) __attribute_const__
+ __u16 __arch_swab16(__u16 x)
{
__asm__(
+ " .set push \n"
+ " .set arch=mips32r2 \n"
+ " .set nomips16 \n"
" wsbh %0, %1 \n"
+ " .set pop \n"
: "=r" (x)
: "r" (x));
@@ -26,11 +31,16 @@ static inline __attribute_const__ __u16 __arch_swab16(__u16 x)
}
#define __arch_swab16 __arch_swab16
-static inline __attribute_const__ __u32 __arch_swab32(__u32 x)
+static inline __attribute__((nomips16)) __attribute_const__
+ __u32 __arch_swab32(__u32 x)
{
__asm__(
+ " .set push \n"
+ " .set arch=mips32r2 \n"
+ " .set nomips16 \n"
" wsbh %0, %1 \n"
" rotr %0, %0, 16 \n"
+ " .set pop \n"
: "=r" (x)
: "r" (x));
@@ -43,11 +53,15 @@ static inline __attribute_const__ __u32 __arch_swab32(__u32 x)
* 64-bit kernel on r2 CPUs.
*/
#ifdef __mips64
-static inline __attribute_const__ __u64 __arch_swab64(__u64 x)
+static inline __attribute__((nomips16)) __attribute_const__
+ __u64 __arch_swab64(__u64 x)
{
__asm__(
- " dsbh %0, %1\n"
- " dshd %0, %0"
+ " .set push \n"
+ " .set nomips16 \n"
+ " dsbh %0, %1 \n"
+ " dshd %0, %0 \n"
+ " .set pop \n"
: "=r" (x)
: "r" (x));