MIPS: uasm: Handle low values in uasm_in_compat_space_p()
authorJames Hogan <james.hogan@imgtec.com>
Fri, 8 Jul 2016 13:05:26 +0000 (14:05 +0100)
committerRalf Baechle <ralf@linux-mips.org>
Sun, 24 Jul 2016 11:15:28 +0000 (13:15 +0200)
uasm_in_compat_space_p() determines whether the given value is in the
32-bit compatibility part of the 64-bit address space, i.e. is in 32-bit
sign-extended form, however it only handles the top half of the value
space (corresponding to the kernel compatibility segments in the upper
half of the address space). Since values < 2^31 (corresponding to the
low 2GiB of the address space) can also be handled using 32-bit
instructions (e.g. a LUI and ADDIU) rather than convoluted 64-bit
immediate generation, rewrite it with a cast to check whether the
address matches its 32-bit sign extended form.

This allows UASM_i_LA to be used to generate arbitrary 32-bit immediates
more efficiently on 64-bit CPUs, i.e. more like the li (load immediate)
pseudo-instruction.

For example this code to load the immediate (ST0_EXL | KSU_USER |
ST0_BEV | ST0_KX) into k0 with UASM_i_LA():

 lui        k0,0x0
 dsll       k0,k0,0x10
 daddiu     k0,k0,64
 dsll       k0,k0,0x10
 daddiu     k0,k0,146

Changes to this more efficient version:

 lui        k0,0x40
 addiu      k0,k0,146

Signed-off-by: James Hogan <james.hogan@imgtec.com>
Cc: linux-mips@linux-mips.org
Patchwork: https://patchwork.linux-mips.org/patch/13778/
Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
arch/mips/mm/uasm.c

index ad718debc35a74d62c2d0b532420b2711a5c4416..0b373405766a74aa3c4916866fd471720e282c6f 100644 (file)
@@ -370,11 +370,7 @@ UASM_EXPORT_SYMBOL(ISAFUNC(uasm_build_label));
 int ISAFUNC(uasm_in_compat_space_p)(long addr)
 {
        /* Is this address in 32bit compat space? */
-#ifdef CONFIG_64BIT
-       return (((addr) & 0xffffffff00000000L) == 0xffffffff00000000L);
-#else
-       return 1;
-#endif
+       return addr == (int)addr;
 }
 UASM_EXPORT_SYMBOL(ISAFUNC(uasm_in_compat_space_p));