summaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
authorJames Hogan <james.hogan@imgtec.com>2016-07-08 15:05:26 +0200
committerRalf Baechle <ralf@linux-mips.org>2016-07-24 13:15:28 +0200
commitf7d9afea6cfb344021359ddd6101deb8f6e9cc76 (patch)
tree93deae3f6831df7174e0d65644e9de56426cbc7f /arch
parentMIPS: Add default configuration for ath25 (diff)
downloadlinux-f7d9afea6cfb344021359ddd6101deb8f6e9cc76.tar.xz
linux-f7d9afea6cfb344021359ddd6101deb8f6e9cc76.zip
MIPS: uasm: Handle low values in uasm_in_compat_space_p()
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>
Diffstat (limited to 'arch')
-rw-r--r--arch/mips/mm/uasm.c6
1 files changed, 1 insertions, 5 deletions
diff --git a/arch/mips/mm/uasm.c b/arch/mips/mm/uasm.c
index ad718debc35a..0b373405766a 100644
--- a/arch/mips/mm/uasm.c
+++ b/arch/mips/mm/uasm.c
@@ -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));