[PATCH resend 1/2] arm64: assembler: add utility macros to push/pop stack frames
Dave Martin
Dave.Martin at arm.com
Wed Mar 28 09:34:53 PDT 2018
On Wed, Mar 28, 2018 at 02:41:28PM +0200, Ard Biesheuvel wrote:
> We are going to add code to all the NEON crypto routines that will
> turn them into non-leaf functions, so we need to manage the stack
> frames. To make this less tedious and error prone, add some macros
> that take the number of callee saved registers to preserve and the
Apologies for the delay in looking at these patches...
Anyway:
Nit: for all instances of "callee saved" in this patch, do you mean "caller saved"?
A few stylistic comments below, but I don't consider them essential to
address unless someone feels like it.
Otherwise,
Reviewed-by: Dave Martin <Dave.Martin at arm.com>
> extra size to allocate in the stack frame (for locals) and emit
> the ldp/stp sequences.
>
> Signed-off-by: Ard Biesheuvel <ard.biesheuvel at linaro.org>
> ---
> arch/arm64/include/asm/assembler.h | 58 ++++++++++++++++++++
> 1 file changed, 58 insertions(+)
>
> diff --git a/arch/arm64/include/asm/assembler.h b/arch/arm64/include/asm/assembler.h
> index 053d83e8db6f..d354eb7f2f0c 100644
> --- a/arch/arm64/include/asm/assembler.h
> +++ b/arch/arm64/include/asm/assembler.h
> @@ -565,4 +565,62 @@ USER(\label, ic ivau, \tmp2) // invalidate I line PoU
> #endif
> .endm
>
> + /*
> + * frame_push - Push @regcount callee saved registers to the stack,
> + * starting at x19, as well as x29/x30, and set x29 to
> + * the new value of sp. Add @extra bytes of stack space
> + * for locals.
> + */
> + .macro frame_push, regcount:req, extra
> + __frame st, \regcount, \extra
> + .endm
> +
> + /*
> + * frame_pop - Pop the callee saved registers from the stack that were
> + * pushed in the most recent call to frame_push, as well
> + * as x29/x30 and any extra stack space that may have been
> + * allocated.
> + */
> + .macro frame_pop
> + __frame ld
> + .endm
> +
> + .macro __frame_regs, reg1, reg2, op, num
> + .if .Lframe_regcount == \num
> + \op\()r \reg1, [sp, #(\num + 1) * 8]
> + .elseif .Lframe_regcount > \num
> + \op\()p \reg1, \reg2, [sp, #(\num + 1) * 8]
> + .endif
> + .endm
> +
> + .macro __frame, op, regcount, extra=0
> + .ifc \op, st
> + .if (\regcount) < 0 || (\regcount) > 10
> + .error "regcount should be in the range [0 ... 10]"
> + .endif
> + .if ((\extra) % 16) != 0
> + .error "extra should be a multiple of 16 bytes"
> + .endif
> + .set .Lframe_regcount, \regcount
> + .set .Lframe_extra, \extra
> + .set .Lframe_local_offset, ((\regcount + 3) / 2) * 16
> + stp x29, x30, [sp, #-.Lframe_local_offset - .Lframe_extra]!
> + mov x29, sp
> + .endif
> +
> + __frame_regs x19, x20, \op, 1
> + __frame_regs x21, x22, \op, 3
> + __frame_regs x23, x24, \op, 5
> + __frame_regs x25, x26, \op, 7
> + __frame_regs x27, x28, \op, 9
> +
> + .ifc \op, ld
> + .if .Lframe_regcount == -1
We could also have
.ifc \op, st
.ifdef .Lframe_regcount
.if .Lframe_regcount != -1
.error [...]
on the push side, which would trip on the first nested frame_push
rather than waiting until a frame_pop appears.
Your existing code could be retained to guard against a double pop.
> + .error "frame_push/frame_pop may not be nested"
> + .endif
> + ldp x29, x30, [sp], #.Lframe_local_offset + .Lframe_extra
> + .set .Lframe_regcount, -1
> + .endif
> + .endm
> +
> #endif /* __ASM_ASSEMBLER_H */
> --
> 2.11.0
>
>
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
More information about the linux-arm-kernel
mailing list