[PATCH 1/8] ARM: assembler: introduce adr_l, ldr_l and str_l macros

Ard Biesheuvel ard.biesheuvel at linaro.org
Thu Aug 4 06:58:25 PDT 2016


On 4 August 2016 at 14:16, Russell King - ARM Linux
<linux at armlinux.org.uk> wrote:
> On Thu, Aug 04, 2016 at 12:22:29PM +0100, Dave Martin wrote:
>> The more conventional literal-.long approach could still be macro-ised
>> along the same lines, which might make the affected code more readable,
>> but the idiom you'd be replacing is well-understood and not very common.
>
> I don't see how it could be.  You can't efficiently place the literal
> data alongside the instructions dealing with it.
>
> The only alternative is to use ldr rd, =foo, but that gets very stupid
> when you want to calculate the relative offset, and you end up with
> something like this for every relative load:
>
>         ldr rd, =.
>         sub rd, rd, #. - 4
>         ldr r1, =foo
>         add r1, r1, rd
>

This does the trick

#ifdef CONFIG_THUMB2_KERNEL
#define PC_BIAS 4
#else
#define PC_BIAS 8
#endif

/*
* @dst: destination register
* @sym: name of the symbol
*/
.macro adr_l, dst, sym, tmp:req
#if __LINUX_ARM_ARCH__ >= 7
movw \dst, #:lower16:(\sym) - (. + 8 + PC_BIAS)
movt \dst, #:upper16:(\sym) - (. + 4 + PC_BIAS)
add \dst, \dst, pc
#else
ldr \tmp, =\sym
ldr \dst, =. + 12
sub \dst, \dst, pc
sub \dst, \tmp, \dst
#endif
.endm

but it is suboptimal for v6 and earlier, and now the macro requires a
temp register.

> As I've already said, I prefer the existing solution.  It works, it's
> been known to work for the last 22 years.
>
> If it isn't broken, don't try to fix it.
>

It seemed like low hanging fruit, but obviously not ...

Thanks for your time,
Ard.



More information about the linux-arm-kernel mailing list