From mboxrd@z Thu Jan 1 00:00:00 1970 From: mark.rutland@arm.com (Mark Rutland) Date: Wed, 6 Jan 2016 12:21:04 +0000 Subject: [PATCH 1/2] arm64: add macro to handle large immediates In-Reply-To: References: <1452078327-9635-1-git-send-email-mark.rutland@arm.com> Message-ID: <20160106122104.GF563@leverpostej> To: linux-arm-kernel@lists.infradead.org List-Id: linux-arm-kernel.lists.infradead.org On Wed, Jan 06, 2016 at 12:15:14PM +0100, Ard Biesheuvel wrote: > On 6 January 2016 at 12:05, Mark Rutland 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 > > Cc: Ard Biesheuvel > > Cc: Catalin Marinas > > Cc: Marc Zyngier > > Cc: Will Deacon > > --- > > 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 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? 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. Thanks, Mark.