Commit e0d8b2ec authored by Yousong Zhou's avatar Yousong Zhou Committed by Ralf Baechle

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: default avatarYousong 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: default avatarRalf Baechle <ralf@linux-mips.org>
parent 1cfa8de2
...@@ -16,11 +16,13 @@ ...@@ -16,11 +16,13 @@
#if (defined(__mips_isa_rev) && (__mips_isa_rev >= 2)) || \ #if (defined(__mips_isa_rev) && (__mips_isa_rev >= 2)) || \
defined(_MIPS_ARCH_LOONGSON3A) defined(_MIPS_ARCH_LOONGSON3A)
static inline __attribute_const__ __u16 __arch_swab16(__u16 x) static inline __attribute__((nomips16)) __attribute_const__
__u16 __arch_swab16(__u16 x)
{ {
__asm__( __asm__(
" .set push \n" " .set push \n"
" .set arch=mips32r2 \n" " .set arch=mips32r2 \n"
" .set nomips16 \n"
" wsbh %0, %1 \n" " wsbh %0, %1 \n"
" .set pop \n" " .set pop \n"
: "=r" (x) : "=r" (x)
...@@ -30,11 +32,13 @@ static inline __attribute_const__ __u16 __arch_swab16(__u16 x) ...@@ -30,11 +32,13 @@ static inline __attribute_const__ __u16 __arch_swab16(__u16 x)
} }
#define __arch_swab16 __arch_swab16 #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__( __asm__(
" .set push \n" " .set push \n"
" .set arch=mips32r2 \n" " .set arch=mips32r2 \n"
" .set nomips16 \n"
" wsbh %0, %1 \n" " wsbh %0, %1 \n"
" rotr %0, %0, 16 \n" " rotr %0, %0, 16 \n"
" .set pop \n" " .set pop \n"
...@@ -50,11 +54,13 @@ static inline __attribute_const__ __u32 __arch_swab32(__u32 x) ...@@ -50,11 +54,13 @@ static inline __attribute_const__ __u32 __arch_swab32(__u32 x)
* 64-bit kernel on r2 CPUs. * 64-bit kernel on r2 CPUs.
*/ */
#ifdef __mips64 #ifdef __mips64
static inline __attribute_const__ __u64 __arch_swab64(__u64 x) static inline __attribute__((nomips16)) __attribute_const__
__u64 __arch_swab64(__u64 x)
{ {
__asm__( __asm__(
" .set push \n" " .set push \n"
" .set arch=mips64r2 \n" " .set arch=mips64r2 \n"
" .set nomips16 \n"
" dsbh %0, %1 \n" " dsbh %0, %1 \n"
" dshd %0, %0 \n" " dshd %0, %0 \n"
" .set pop \n" " .set pop \n"
......
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