[PATCH 1/2] arm64: add macro to handle large immediates
Ard Biesheuvel
ard.biesheuvel at linaro.org
Wed Jan 6 04:26:40 PST 2016
On 6 January 2016 at 13:21, Mark Rutland <mark.rutland at arm.com> wrote:
> On Wed, Jan 06, 2016 at 12:15:14PM +0100, Ard Biesheuvel wrote:
>> On 6 January 2016 at 12:05, Mark Rutland <mark.rutland at arm.com> wrote:
>> > Sometimes we want to be able to load values greater than 0xff into a
>> > register, without placing said values in a literal pool. Arranging for
>> > the value to be split up across a number of movz and movk instructions
>> > is tedious and error-prone.
>> >
>> > Following the example of {adr,str,ldr}_l, this patch adds a new mov_l
>> > macro which can be used to load immediate values of up to 64 bits into a
>> > register.
>> >
>> > Signed-off-by: Mark Rutland <mark.rutland at arm.com>
>> > Cc: Ard Biesheuvel <ard.biesheuvel at linaro.org>
>> > Cc: Catalin Marinas <catalin.marinas at arm.com>
>> > Cc: Marc Zyngier <marc.zyngier at arm.com>
>> > Cc: Will Deacon <will.deacon at arm.com>
>> > ---
>> > arch/arm64/include/asm/assembler.h | 13 +++++++++++++
>> > 1 file changed, 13 insertions(+)
>> >
>> > diff --git a/arch/arm64/include/asm/assembler.h b/arch/arm64/include/asm/assembler.h
>> > index 12eff92..64fd0a2 100644
>> > --- a/arch/arm64/include/asm/assembler.h
>> > +++ b/arch/arm64/include/asm/assembler.h
>> > @@ -193,6 +193,19 @@ lr .req x30 // link register
>> > str \src, [\tmp, :lo12:\sym]
>> > .endm
>> >
>> > + /*
>> > + * Move a large immediate up to 64-bits.
>> > + *
>> > + * @dst: destination register (64 bit wide)
>> > + * @val: value
>> > + */
>> > + .macro mov_l, dst, val
>> > + movz \dst, :abs_g0_nc:\val
>> > + movk \dst, :abs_g1_nc:\val
>> > + movk \dst, :abs_g2_nc:\val
>> > + movk \dst, :abs_g3:\val
>> > + .endm
>> > +
>>
>> Ack for the general idea, but for correctness, you should pair the
>> movk instructions with the _nc relocations (i.e., keep movz first, but
>> invert the order of the relocs)
>
> Ah, I hadn't spotted the restriction. I'll change that to:
>
> movz \dst, :abs_g3:\val
> movk \dst, :abs_g2:\val
> movk \dst, :abs_g1:\val
> movk \dst, :abs_g0:\val
>
Yes, but with the _nc suffix on the latter three.
> That raises a related question. Is it the linker's responsibility to
> fill in the shift encoding in the hw field as part of the g{3,2,1}
> relocs?
>
This
movz x0, :abs_g3:val
movk x0, :abs_g2_nc:val
movk x0, :abs_g1_nc:val
movk x0, :abs_g0_nc:val
assembles to
0000000000000000 <.text>:
0: d2e00000 movz x0, #0x0, lsl #48
4: f2c00000 movk x0, #0x0, lsl #32
8: f2a00000 movk x0, #0x0, lsl #16
c: f2800000 movk x0, #0x0
so it is in fact the assembler that sets the hw field.
> Mine seems to, but I don't know if that's strictly required or correct
> as the AArrch64 ELF spec only mentions the immediate field for *ABS_G*,
> and the shift is encoded in hw rather than imm16.
>
More information about the linux-arm-kernel
mailing list