[PATCH v3 02/10] ARM: assembler: introduce bl_r and bl_m macros
Ard Biesheuvel
ardb at kernel.org
Sun Oct 17 06:17:15 PDT 2021
Add some macros that abstract the difference between the ways indirect
calls are performed on older and newer ARM architecture revisions.
The main difference is to prefer blx instructions over explicit LR
assignments when possible, as these tend to confuse the prediction logic
in out-of-order cores when speculating across a function return.
Signed-off-by: Ard Biesheuvel <ardb at kernel.org>
Reviewed-by: Arnd Bergmann <arnd at arndb.de>
Acked-by: Linus Walleij <linus.walleij at linaro.org>
Tested-by: Keith Packard <keithpac at amazon.com>
---
arch/arm/include/asm/assembler.h | 37 ++++++++++++++++++++
1 file changed, 37 insertions(+)
diff --git a/arch/arm/include/asm/assembler.h b/arch/arm/include/asm/assembler.h
index 7d23d4bb2168..abb8202ef0da 100644
--- a/arch/arm/include/asm/assembler.h
+++ b/arch/arm/include/asm/assembler.h
@@ -624,4 +624,41 @@ THUMB( orr \reg , \reg , #PSR_T_BIT )
.endif
.endm
+ /*
+ * bl_r - branch and link to register
+ *
+ * @dst: target to branch to
+ * @c: conditional opcode suffix
+ */
+ .macro bl_r, dst:req, c
+ .if __LINUX_ARM_ARCH__ < 6
+ mov\c lr, pc
+ mov\c pc, \dst
+ .else
+ blx\c \dst
+ .endif
+ .endm
+
+ /*
+ * bl_m - branch and link to address held in memory
+ *
+ * @dst: memory reference to load the branch target from
+ *
+ * This uses the same syntax as ldr instructions, including things like
+ * register writeback (where it makes sense). For example,
+ *
+ * bl_m [ip, #<offset>]
+ *
+ * Note that @dst should not reference lr as it may be clobbered early.
+ */
+ .macro bl_m, dst:vararg
+ .if __LINUX_ARM_ARCH__ < 6
+ mov lr, pc
+ ldr pc, \dst
+ .else
+ ldr lr, \dst
+ blx lr
+ .endif
+ .endm
+
#endif /* __ASM_ASSEMBLER_H__ */
--
2.30.2
More information about the linux-arm-kernel
mailing list