diff options
author | Ard Biesheuvel <ard.biesheuvel@linaro.org> | 2015-03-04 13:45:38 -0500 |
---|---|---|
committer | Will Deacon <will.deacon@arm.com> | 2015-03-19 15:46:01 -0400 |
commit | b784a5d97d0af4835dd0125a3e0e5d0fd48128d6 (patch) | |
tree | ce43b950581eef534c087c024e9ba07b55cbc42f /arch | |
parent | a591ede4cd1cac02d3398a9ad332bd0bba460efe (diff) |
arm64: add macros for common adrp usages
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>
Diffstat (limited to 'arch')
-rw-r--r-- | arch/arm64/include/asm/assembler.h | 48 |
1 files changed, 48 insertions, 0 deletions
diff --git a/arch/arm64/include/asm/assembler.h b/arch/arm64/include/asm/assembler.h index 750bac4e637e..144b64ad96c3 100644 --- a/arch/arm64/include/asm/assembler.h +++ b/arch/arm64/include/asm/assembler.h | |||
@@ -159,4 +159,52 @@ lr .req x30 // link register | |||
159 | orr \rd, \lbits, \hbits, lsl #32 | 159 | orr \rd, \lbits, \hbits, lsl #32 |
160 | .endm | 160 | .endm |
161 | 161 | ||
162 | /* | ||
163 | * Pseudo-ops for PC-relative adr/ldr/str <reg>, <symbol> where | ||
164 | * <symbol> is within the range +/- 4 GB of the PC. | ||
165 | */ | ||
166 | /* | ||
167 | * @dst: destination register (64 bit wide) | ||
168 | * @sym: name of the symbol | ||
169 | * @tmp: optional scratch register to be used if <dst> == sp, which | ||
170 | * is not allowed in an adrp instruction | ||
171 | */ | ||
172 | .macro adr_l, dst, sym, tmp= | ||
173 | .ifb \tmp | ||
174 | adrp \dst, \sym | ||
175 | add \dst, \dst, :lo12:\sym | ||
176 | .else | ||
177 | adrp \tmp, \sym | ||
178 | add \dst, \tmp, :lo12:\sym | ||
179 | .endif | ||
180 | .endm | ||
181 | |||
182 | /* | ||
183 | * @dst: destination register (32 or 64 bit wide) | ||
184 | * @sym: name of the symbol | ||
185 | * @tmp: optional 64-bit scratch register to be used if <dst> is a | ||
186 | * 32-bit wide register, in which case it cannot be used to hold | ||
187 | * the address | ||
188 | */ | ||
189 | .macro ldr_l, dst, sym, tmp= | ||
190 | .ifb \tmp | ||
191 | adrp \dst, \sym | ||
192 | ldr \dst, [\dst, :lo12:\sym] | ||
193 | .else | ||
194 | adrp \tmp, \sym | ||
195 | ldr \dst, [\tmp, :lo12:\sym] | ||
196 | .endif | ||
197 | .endm | ||
198 | |||
199 | /* | ||
200 | * @src: source register (32 or 64 bit wide) | ||
201 | * @sym: name of the symbol | ||
202 | * @tmp: mandatory 64-bit scratch register to calculate the address | ||
203 | * while <src> needs to be preserved. | ||
204 | */ | ||
205 | .macro str_l, src, sym, tmp | ||
206 | adrp \tmp, \sym | ||
207 | str \src, [\tmp, :lo12:\sym] | ||
208 | .endm | ||
209 | |||
162 | #endif /* __ASM_ASSEMBLER_H */ | 210 | #endif /* __ASM_ASSEMBLER_H */ |