arm64: add macros for common adrp usages
authorArd Biesheuvel <ard.biesheuvel@linaro.org>
Wed, 4 Mar 2015 18:45:38 +0000 (19:45 +0100)
committerWill Deacon <will.deacon@arm.com>
Thu, 19 Mar 2015 19:46:01 +0000 (19:46 +0000)
The adrp instruction is mostly used in combination with either
an add, a ldr or a str instruction with the low bits of the
referenced symbol in the 12-bit immediate of the followup
instruction.

Introduce the macros adr_l, ldr_l and str_l that encapsulate
these common patterns.

Tested-by: Mark Rutland <mark.rutland@arm.com>
Reviewed-by: Mark Rutland <mark.rutland@arm.com>
Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Signed-off-by: Will Deacon <will.deacon@arm.com>
arch/arm64/include/asm/assembler.h

index 750bac4e637e5323f29bd4859b6e655b3a035d95..144b64ad96c33bc80904ed053abdef2c6b5cf791 100644 (file)
@@ -159,4 +159,52 @@ lr .req    x30             // link register
        orr     \rd, \lbits, \hbits, lsl #32
        .endm
 
+/*
+ * Pseudo-ops for PC-relative adr/ldr/str <reg>, <symbol> where
+ * <symbol> is within the range +/- 4 GB of the PC.
+ */
+       /*
+        * @dst: destination register (64 bit wide)
+        * @sym: name of the symbol
+        * @tmp: optional scratch register to be used if <dst> == sp, which
+        *       is not allowed in an adrp instruction
+        */
+       .macro  adr_l, dst, sym, tmp=
+       .ifb    \tmp
+       adrp    \dst, \sym
+       add     \dst, \dst, :lo12:\sym
+       .else
+       adrp    \tmp, \sym
+       add     \dst, \tmp, :lo12:\sym
+       .endif
+       .endm
+
+       /*
+        * @dst: destination register (32 or 64 bit wide)
+        * @sym: name of the symbol
+        * @tmp: optional 64-bit scratch register to be used if <dst> is a
+        *       32-bit wide register, in which case it cannot be used to hold
+        *       the address
+        */
+       .macro  ldr_l, dst, sym, tmp=
+       .ifb    \tmp
+       adrp    \dst, \sym
+       ldr     \dst, [\dst, :lo12:\sym]
+       .else
+       adrp    \tmp, \sym
+       ldr     \dst, [\tmp, :lo12:\sym]
+       .endif
+       .endm
+
+       /*
+        * @src: source register (32 or 64 bit wide)
+        * @sym: name of the symbol
+        * @tmp: mandatory 64-bit scratch register to calculate the address
+        *       while <src> needs to be preserved.
+        */
+       .macro  str_l, src, sym, tmp
+       adrp    \tmp, \sym
+       str     \src, [\tmp, :lo12:\sym]
+       .endm
+
 #endif /* __ASM_ASSEMBLER_H */