Commit aebd1fb4 authored by Nicholas Piggin's avatar Nicholas Piggin Committed by Michael Ellerman
Browse files

powerpc: flexible GPR range save/restore macros



Introduce macros that operate on a (start, end) range of GPRs, which
reduces lines of code and need to do mental arithmetic while reading the
code.

Signed-off-by: default avatarNicholas Piggin <npiggin@gmail.com>
Reviewed-by: default avatarSegher Boessenkool <segher@kernel.crashing.org>
Reviewed-by: default avatarChristophe Leroy <christophe.leroy@csgroup.eu>
Signed-off-by: default avatarMichael Ellerman <mpe@ellerman.id.au>
Link: https://lore.kernel.org/r/20211022061322.2671178-1-npiggin@gmail.com
parent e012c499
Loading
Loading
Loading
Loading
+15 −16
Original line number Diff line number Diff line
@@ -226,16 +226,19 @@ p_base: mflr r10 /* r10 now points to runtime addr of p_base */
#ifdef __powerpc64__

#define PROM_FRAME_SIZE 512
#define SAVE_GPR(n, base)       std     n,8*(n)(base)
#define REST_GPR(n, base)       ld      n,8*(n)(base)
#define SAVE_2GPRS(n, base)     SAVE_GPR(n, base); SAVE_GPR(n+1, base)
#define SAVE_4GPRS(n, base)     SAVE_2GPRS(n, base); SAVE_2GPRS(n+2, base)
#define SAVE_8GPRS(n, base)     SAVE_4GPRS(n, base); SAVE_4GPRS(n+4, base)
#define SAVE_10GPRS(n, base)    SAVE_8GPRS(n, base); SAVE_2GPRS(n+8, base)
#define REST_2GPRS(n, base)     REST_GPR(n, base); REST_GPR(n+1, base)
#define REST_4GPRS(n, base)     REST_2GPRS(n, base); REST_2GPRS(n+2, base)
#define REST_8GPRS(n, base)     REST_4GPRS(n, base); REST_4GPRS(n+4, base)
#define REST_10GPRS(n, base)    REST_8GPRS(n, base); REST_2GPRS(n+8, base)

.macro OP_REGS op, width, start, end, base, offset
	.Lreg=\start
	.rept (\end - \start + 1)
	\op	.Lreg,\offset+\width*.Lreg(\base)
	.Lreg=.Lreg+1
	.endr
.endm

#define SAVE_GPRS(start, end, base)	OP_REGS std, 8, start, end, base, 0
#define REST_GPRS(start, end, base)	OP_REGS ld, 8, start, end, base, 0
#define SAVE_GPR(n, base)		SAVE_GPRS(n, n, base)
#define REST_GPR(n, base)		REST_GPRS(n, n, base)

/* prom handles the jump into and return from firmware.  The prom args pointer
   is loaded in r3. */
@@ -246,9 +249,7 @@ prom:
	stdu	r1,-PROM_FRAME_SIZE(r1) /* Save SP and create stack space */

	SAVE_GPR(2, r1)
	SAVE_GPR(13, r1)
	SAVE_8GPRS(14, r1)
	SAVE_10GPRS(22, r1)
	SAVE_GPRS(13, 31, r1)
	mfcr    r10
	std     r10,8*32(r1)
	mfmsr   r10
@@ -283,9 +284,7 @@ prom:

	/* Restore other registers */
	REST_GPR(2, r1)
	REST_GPR(13, r1)
	REST_8GPRS(14, r1)
	REST_10GPRS(22, r1)
	REST_GPRS(13, 31, r1)
	ld      r10,8*32(r1)
	mtcr	r10

+3 −7
Original line number Diff line number Diff line
@@ -38,15 +38,11 @@

#define INITIALIZE \
	PPC_STLU r1,-INT_FRAME_SIZE(r1); \
	SAVE_8GPRS(14, r1);		/* push registers onto stack	*/ \
	SAVE_4GPRS(22, r1);						   \
	SAVE_GPR(26, r1)
	SAVE_GPRS(14, 26, r1)		/* push registers onto stack	*/

#define FINALIZE \
	REST_8GPRS(14, r1);		/* pop registers from stack	*/ \
	REST_4GPRS(22, r1);						   \
	REST_GPR(26, r1);						   \
	addi	r1,r1,INT_FRAME_SIZE;
	REST_GPRS(14, 26, r1);		/* pop registers from stack	*/ \
	addi	r1,r1,INT_FRAME_SIZE

#ifdef __BIG_ENDIAN__
#define LOAD_DATA(reg, off) \
+2 −4
Original line number Diff line number Diff line
@@ -125,8 +125,7 @@

_GLOBAL(powerpc_sha_transform)
	PPC_STLU r1,-INT_FRAME_SIZE(r1)
	SAVE_8GPRS(14, r1)
	SAVE_10GPRS(22, r1)
	SAVE_GPRS(14, 31, r1)

	/* Load up A - E */
	lwz	RA(0),0(r3)	/* A */
@@ -184,7 +183,6 @@ _GLOBAL(powerpc_sha_transform)
	stw	RD(0),12(r3)
	stw	RE(0),16(r3)

	REST_8GPRS(14, r1)
	REST_10GPRS(22, r1)
	REST_GPRS(14, 31, r1)
	addi	r1,r1,INT_FRAME_SIZE
	blr
+27 −16
Original line number Diff line number Diff line
@@ -16,30 +16,41 @@

#define SZL			(BITS_PER_LONG/8)

/*
 * This expands to a sequence of operations with reg incrementing from
 * start to end inclusive, of this form:
 *
 *   op  reg, (offset + (width * reg))(base)
 *
 * Note that offset is not the offset of the first operation unless start
 * is zero (or width is zero).
 */
.macro OP_REGS op, width, start, end, base, offset
	.Lreg=\start
	.rept (\end - \start + 1)
	\op	.Lreg, \offset + \width * .Lreg(\base)
	.Lreg=.Lreg+1
	.endr
.endm

/*
 * Macros for storing registers into and loading registers from
 * exception frames.
 */
#ifdef __powerpc64__
#define SAVE_GPR(n, base)	std	n,GPR0+8*(n)(base)
#define REST_GPR(n, base)	ld	n,GPR0+8*(n)(base)
#define SAVE_NVGPRS(base)	SAVE_8GPRS(14, base); SAVE_10GPRS(22, base)
#define REST_NVGPRS(base)	REST_8GPRS(14, base); REST_10GPRS(22, base)
#define SAVE_GPRS(start, end, base)	OP_REGS std, 8, start, end, base, GPR0
#define REST_GPRS(start, end, base)	OP_REGS ld, 8, start, end, base, GPR0
#define SAVE_NVGPRS(base)		SAVE_GPRS(14, 31, base)
#define REST_NVGPRS(base)		REST_GPRS(14, 31, base)
#else
#define SAVE_GPR(n, base)	stw	n,GPR0+4*(n)(base)
#define REST_GPR(n, base)	lwz	n,GPR0+4*(n)(base)
#define SAVE_NVGPRS(base)	SAVE_GPR(13, base); SAVE_8GPRS(14, base); SAVE_10GPRS(22, base)
#define REST_NVGPRS(base)	REST_GPR(13, base); REST_8GPRS(14, base); REST_10GPRS(22, base)
#define SAVE_GPRS(start, end, base)	OP_REGS stw, 4, start, end, base, GPR0
#define REST_GPRS(start, end, base)	OP_REGS lwz, 4, start, end, base, GPR0
#define SAVE_NVGPRS(base)		SAVE_GPRS(13, 31, base)
#define REST_NVGPRS(base)		REST_GPRS(13, 31, base)
#endif

#define SAVE_2GPRS(n, base)	SAVE_GPR(n, base); SAVE_GPR(n+1, base)
#define SAVE_4GPRS(n, base)	SAVE_2GPRS(n, base); SAVE_2GPRS(n+2, base)
#define SAVE_8GPRS(n, base)	SAVE_4GPRS(n, base); SAVE_4GPRS(n+4, base)
#define SAVE_10GPRS(n, base)	SAVE_8GPRS(n, base); SAVE_2GPRS(n+8, base)
#define REST_2GPRS(n, base)	REST_GPR(n, base); REST_GPR(n+1, base)
#define REST_4GPRS(n, base)	REST_2GPRS(n, base); REST_2GPRS(n+2, base)
#define REST_8GPRS(n, base)	REST_4GPRS(n, base); REST_4GPRS(n+4, base)
#define REST_10GPRS(n, base)	REST_8GPRS(n, base); REST_2GPRS(n+8, base)
#define SAVE_GPR(n, base)		SAVE_GPRS(n, n, base)
#define REST_GPR(n, base)		REST_GPRS(n, n, base)

#define SAVE_FPR(n, base)	stfd	n,8*TS_FPRWIDTH*(n)(base)
#define SAVE_2FPRS(n, base)	SAVE_FPR(n, base); SAVE_FPR(n+1, base)
+9 −14
Original line number Diff line number Diff line
@@ -90,8 +90,7 @@ transfer_to_syscall:
	stw	r12,8(r1)
	stw	r2,_TRAP(r1)
	SAVE_GPR(0, r1)
	SAVE_4GPRS(3, r1)
	SAVE_2GPRS(7, r1)
	SAVE_GPRS(3, 8, r1)
	addi	r2,r10,-THREAD
	SAVE_NVGPRS(r1)

@@ -139,7 +138,7 @@ syscall_exit_finish:
	mtxer	r5
	lwz	r0,GPR0(r1)
	lwz	r3,GPR3(r1)
	REST_8GPRS(4,r1)
	REST_GPRS(4, 11, r1)
	lwz	r12,GPR12(r1)
	b	1b

@@ -232,9 +231,9 @@ fast_exception_return:
	beq	3f			/* if not, we've got problems */
#endif

2:	REST_4GPRS(3, r11)
2:	REST_GPRS(3, 6, r11)
	lwz	r10,_CCR(r11)
	REST_2GPRS(1, r11)
	REST_GPRS(1, 2, r11)
	mtcr	r10
	lwz	r10,_LINK(r11)
	mtlr	r10
@@ -298,16 +297,14 @@ ALT_FTR_SECTION_END_IFCLR(CPU_FTR_STCX_CHECKS_ADDRESS)
	 * the reliable stack unwinder later on. Clear it.
	 */
	stw	r0,8(r1)
	REST_4GPRS(7, r1)
	REST_2GPRS(11, r1)
	REST_GPRS(7, 12, r1)

	mtcr	r3
	mtlr	r4
	mtctr	r5
	mtspr	SPRN_XER,r6

	REST_4GPRS(2, r1)
	REST_GPR(6, r1)
	REST_GPRS(2, 6, r1)
	REST_GPR(0, r1)
	REST_GPR(1, r1)
	rfi
@@ -341,8 +338,7 @@ ALT_FTR_SECTION_END_IFCLR(CPU_FTR_STCX_CHECKS_ADDRESS)
	lwz	r6,_CCR(r1)
	li	r0,0

	REST_4GPRS(7, r1)
	REST_2GPRS(11, r1)
	REST_GPRS(7, 12, r1)

	mtlr	r3
	mtctr	r4
@@ -354,7 +350,7 @@ ALT_FTR_SECTION_END_IFCLR(CPU_FTR_STCX_CHECKS_ADDRESS)
	 */
	stw	r0,8(r1)

	REST_4GPRS(2, r1)
	REST_GPRS(2, 5, r1)

	bne-	cr1,1f /* emulate stack store */
	mtcr	r6
@@ -430,8 +426,7 @@ _ASM_NOKPROBE_SYMBOL(interrupt_return)
	bne	interrupt_return;					\
	lwz	r0,GPR0(r1);						\
	lwz	r2,GPR2(r1);						\
	REST_4GPRS(3, r1);						\
	REST_2GPRS(7, r1);						\
	REST_GPRS(3, 8, r1);						\
	lwz	r10,_XER(r1);						\
	lwz	r11,_CTR(r1);						\
	mtspr	SPRN_XER,r10;						\
Loading