162306a36Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0 */
262306a36Sopenharmony_ci/*
362306a36Sopenharmony_ci * Copyright (C) IBM Corporation, 2011
462306a36Sopenharmony_ci * Derived from copyuser_power7.s by Anton Blanchard <anton@au.ibm.com>
562306a36Sopenharmony_ci * Author - Balbir Singh <bsingharora@gmail.com>
662306a36Sopenharmony_ci */
762306a36Sopenharmony_ci#include <linux/export.h>
862306a36Sopenharmony_ci#include <asm/ppc_asm.h>
962306a36Sopenharmony_ci#include <asm/errno.h>
1062306a36Sopenharmony_ci
1162306a36Sopenharmony_ci	.macro err1
1262306a36Sopenharmony_ci100:
1362306a36Sopenharmony_ci	EX_TABLE(100b,.Ldo_err1)
1462306a36Sopenharmony_ci	.endm
1562306a36Sopenharmony_ci
1662306a36Sopenharmony_ci	.macro err2
1762306a36Sopenharmony_ci200:
1862306a36Sopenharmony_ci	EX_TABLE(200b,.Ldo_err2)
1962306a36Sopenharmony_ci	.endm
2062306a36Sopenharmony_ci
2162306a36Sopenharmony_ci	.macro err3
2262306a36Sopenharmony_ci300:	EX_TABLE(300b,.Ldone)
2362306a36Sopenharmony_ci	.endm
2462306a36Sopenharmony_ci
2562306a36Sopenharmony_ci.Ldo_err2:
2662306a36Sopenharmony_ci	ld	r22,STK_REG(R22)(r1)
2762306a36Sopenharmony_ci	ld	r21,STK_REG(R21)(r1)
2862306a36Sopenharmony_ci	ld	r20,STK_REG(R20)(r1)
2962306a36Sopenharmony_ci	ld	r19,STK_REG(R19)(r1)
3062306a36Sopenharmony_ci	ld	r18,STK_REG(R18)(r1)
3162306a36Sopenharmony_ci	ld	r17,STK_REG(R17)(r1)
3262306a36Sopenharmony_ci	ld	r16,STK_REG(R16)(r1)
3362306a36Sopenharmony_ci	ld	r15,STK_REG(R15)(r1)
3462306a36Sopenharmony_ci	ld	r14,STK_REG(R14)(r1)
3562306a36Sopenharmony_ci	addi	r1,r1,STACKFRAMESIZE
3662306a36Sopenharmony_ci.Ldo_err1:
3762306a36Sopenharmony_ci	/* Do a byte by byte copy to get the exact remaining size */
3862306a36Sopenharmony_ci	mtctr	r7
3962306a36Sopenharmony_ci46:
4062306a36Sopenharmony_cierr3;	lbz	r0,0(r4)
4162306a36Sopenharmony_ci	addi	r4,r4,1
4262306a36Sopenharmony_cierr3;	stb	r0,0(r3)
4362306a36Sopenharmony_ci	addi	r3,r3,1
4462306a36Sopenharmony_ci	bdnz	46b
4562306a36Sopenharmony_ci	li	r3,0
4662306a36Sopenharmony_ci	blr
4762306a36Sopenharmony_ci
4862306a36Sopenharmony_ci.Ldone:
4962306a36Sopenharmony_ci	mfctr	r3
5062306a36Sopenharmony_ci	blr
5162306a36Sopenharmony_ci
5262306a36Sopenharmony_ci
5362306a36Sopenharmony_ci_GLOBAL(copy_mc_generic)
5462306a36Sopenharmony_ci	mr	r7,r5
5562306a36Sopenharmony_ci	cmpldi	r5,16
5662306a36Sopenharmony_ci	blt	.Lshort_copy
5762306a36Sopenharmony_ci
5862306a36Sopenharmony_ci.Lcopy:
5962306a36Sopenharmony_ci	/* Get the source 8B aligned */
6062306a36Sopenharmony_ci	neg	r6,r4
6162306a36Sopenharmony_ci	mtocrf	0x01,r6
6262306a36Sopenharmony_ci	clrldi	r6,r6,(64-3)
6362306a36Sopenharmony_ci
6462306a36Sopenharmony_ci	bf	cr7*4+3,1f
6562306a36Sopenharmony_cierr1;	lbz	r0,0(r4)
6662306a36Sopenharmony_ci	addi	r4,r4,1
6762306a36Sopenharmony_cierr1;	stb	r0,0(r3)
6862306a36Sopenharmony_ci	addi	r3,r3,1
6962306a36Sopenharmony_ci	subi	r7,r7,1
7062306a36Sopenharmony_ci
7162306a36Sopenharmony_ci1:	bf	cr7*4+2,2f
7262306a36Sopenharmony_cierr1;	lhz	r0,0(r4)
7362306a36Sopenharmony_ci	addi	r4,r4,2
7462306a36Sopenharmony_cierr1;	sth	r0,0(r3)
7562306a36Sopenharmony_ci	addi	r3,r3,2
7662306a36Sopenharmony_ci	subi	r7,r7,2
7762306a36Sopenharmony_ci
7862306a36Sopenharmony_ci2:	bf	cr7*4+1,3f
7962306a36Sopenharmony_cierr1;	lwz	r0,0(r4)
8062306a36Sopenharmony_ci	addi	r4,r4,4
8162306a36Sopenharmony_cierr1;	stw	r0,0(r3)
8262306a36Sopenharmony_ci	addi	r3,r3,4
8362306a36Sopenharmony_ci	subi	r7,r7,4
8462306a36Sopenharmony_ci
8562306a36Sopenharmony_ci3:	sub	r5,r5,r6
8662306a36Sopenharmony_ci	cmpldi	r5,128
8762306a36Sopenharmony_ci
8862306a36Sopenharmony_ci	mflr	r0
8962306a36Sopenharmony_ci	stdu	r1,-STACKFRAMESIZE(r1)
9062306a36Sopenharmony_ci	std	r14,STK_REG(R14)(r1)
9162306a36Sopenharmony_ci	std	r15,STK_REG(R15)(r1)
9262306a36Sopenharmony_ci	std	r16,STK_REG(R16)(r1)
9362306a36Sopenharmony_ci	std	r17,STK_REG(R17)(r1)
9462306a36Sopenharmony_ci	std	r18,STK_REG(R18)(r1)
9562306a36Sopenharmony_ci	std	r19,STK_REG(R19)(r1)
9662306a36Sopenharmony_ci	std	r20,STK_REG(R20)(r1)
9762306a36Sopenharmony_ci	std	r21,STK_REG(R21)(r1)
9862306a36Sopenharmony_ci	std	r22,STK_REG(R22)(r1)
9962306a36Sopenharmony_ci	std	r0,STACKFRAMESIZE+16(r1)
10062306a36Sopenharmony_ci
10162306a36Sopenharmony_ci	blt	5f
10262306a36Sopenharmony_ci	srdi	r6,r5,7
10362306a36Sopenharmony_ci	mtctr	r6
10462306a36Sopenharmony_ci
10562306a36Sopenharmony_ci	/* Now do cacheline (128B) sized loads and stores. */
10662306a36Sopenharmony_ci	.align	5
10762306a36Sopenharmony_ci4:
10862306a36Sopenharmony_cierr2;	ld	r0,0(r4)
10962306a36Sopenharmony_cierr2;	ld	r6,8(r4)
11062306a36Sopenharmony_cierr2;	ld	r8,16(r4)
11162306a36Sopenharmony_cierr2;	ld	r9,24(r4)
11262306a36Sopenharmony_cierr2;	ld	r10,32(r4)
11362306a36Sopenharmony_cierr2;	ld	r11,40(r4)
11462306a36Sopenharmony_cierr2;	ld	r12,48(r4)
11562306a36Sopenharmony_cierr2;	ld	r14,56(r4)
11662306a36Sopenharmony_cierr2;	ld	r15,64(r4)
11762306a36Sopenharmony_cierr2;	ld	r16,72(r4)
11862306a36Sopenharmony_cierr2;	ld	r17,80(r4)
11962306a36Sopenharmony_cierr2;	ld	r18,88(r4)
12062306a36Sopenharmony_cierr2;	ld	r19,96(r4)
12162306a36Sopenharmony_cierr2;	ld	r20,104(r4)
12262306a36Sopenharmony_cierr2;	ld	r21,112(r4)
12362306a36Sopenharmony_cierr2;	ld	r22,120(r4)
12462306a36Sopenharmony_ci	addi	r4,r4,128
12562306a36Sopenharmony_cierr2;	std	r0,0(r3)
12662306a36Sopenharmony_cierr2;	std	r6,8(r3)
12762306a36Sopenharmony_cierr2;	std	r8,16(r3)
12862306a36Sopenharmony_cierr2;	std	r9,24(r3)
12962306a36Sopenharmony_cierr2;	std	r10,32(r3)
13062306a36Sopenharmony_cierr2;	std	r11,40(r3)
13162306a36Sopenharmony_cierr2;	std	r12,48(r3)
13262306a36Sopenharmony_cierr2;	std	r14,56(r3)
13362306a36Sopenharmony_cierr2;	std	r15,64(r3)
13462306a36Sopenharmony_cierr2;	std	r16,72(r3)
13562306a36Sopenharmony_cierr2;	std	r17,80(r3)
13662306a36Sopenharmony_cierr2;	std	r18,88(r3)
13762306a36Sopenharmony_cierr2;	std	r19,96(r3)
13862306a36Sopenharmony_cierr2;	std	r20,104(r3)
13962306a36Sopenharmony_cierr2;	std	r21,112(r3)
14062306a36Sopenharmony_cierr2;	std	r22,120(r3)
14162306a36Sopenharmony_ci	addi	r3,r3,128
14262306a36Sopenharmony_ci	subi	r7,r7,128
14362306a36Sopenharmony_ci	bdnz	4b
14462306a36Sopenharmony_ci
14562306a36Sopenharmony_ci	clrldi	r5,r5,(64-7)
14662306a36Sopenharmony_ci
14762306a36Sopenharmony_ci	/* Up to 127B to go */
14862306a36Sopenharmony_ci5:	srdi	r6,r5,4
14962306a36Sopenharmony_ci	mtocrf	0x01,r6
15062306a36Sopenharmony_ci
15162306a36Sopenharmony_ci6:	bf	cr7*4+1,7f
15262306a36Sopenharmony_cierr2;	ld	r0,0(r4)
15362306a36Sopenharmony_cierr2;	ld	r6,8(r4)
15462306a36Sopenharmony_cierr2;	ld	r8,16(r4)
15562306a36Sopenharmony_cierr2;	ld	r9,24(r4)
15662306a36Sopenharmony_cierr2;	ld	r10,32(r4)
15762306a36Sopenharmony_cierr2;	ld	r11,40(r4)
15862306a36Sopenharmony_cierr2;	ld	r12,48(r4)
15962306a36Sopenharmony_cierr2;	ld	r14,56(r4)
16062306a36Sopenharmony_ci	addi	r4,r4,64
16162306a36Sopenharmony_cierr2;	std	r0,0(r3)
16262306a36Sopenharmony_cierr2;	std	r6,8(r3)
16362306a36Sopenharmony_cierr2;	std	r8,16(r3)
16462306a36Sopenharmony_cierr2;	std	r9,24(r3)
16562306a36Sopenharmony_cierr2;	std	r10,32(r3)
16662306a36Sopenharmony_cierr2;	std	r11,40(r3)
16762306a36Sopenharmony_cierr2;	std	r12,48(r3)
16862306a36Sopenharmony_cierr2;	std	r14,56(r3)
16962306a36Sopenharmony_ci	addi	r3,r3,64
17062306a36Sopenharmony_ci	subi	r7,r7,64
17162306a36Sopenharmony_ci
17262306a36Sopenharmony_ci7:	ld	r14,STK_REG(R14)(r1)
17362306a36Sopenharmony_ci	ld	r15,STK_REG(R15)(r1)
17462306a36Sopenharmony_ci	ld	r16,STK_REG(R16)(r1)
17562306a36Sopenharmony_ci	ld	r17,STK_REG(R17)(r1)
17662306a36Sopenharmony_ci	ld	r18,STK_REG(R18)(r1)
17762306a36Sopenharmony_ci	ld	r19,STK_REG(R19)(r1)
17862306a36Sopenharmony_ci	ld	r20,STK_REG(R20)(r1)
17962306a36Sopenharmony_ci	ld	r21,STK_REG(R21)(r1)
18062306a36Sopenharmony_ci	ld	r22,STK_REG(R22)(r1)
18162306a36Sopenharmony_ci	addi	r1,r1,STACKFRAMESIZE
18262306a36Sopenharmony_ci
18362306a36Sopenharmony_ci	/* Up to 63B to go */
18462306a36Sopenharmony_ci	bf	cr7*4+2,8f
18562306a36Sopenharmony_cierr1;	ld	r0,0(r4)
18662306a36Sopenharmony_cierr1;	ld	r6,8(r4)
18762306a36Sopenharmony_cierr1;	ld	r8,16(r4)
18862306a36Sopenharmony_cierr1;	ld	r9,24(r4)
18962306a36Sopenharmony_ci	addi	r4,r4,32
19062306a36Sopenharmony_cierr1;	std	r0,0(r3)
19162306a36Sopenharmony_cierr1;	std	r6,8(r3)
19262306a36Sopenharmony_cierr1;	std	r8,16(r3)
19362306a36Sopenharmony_cierr1;	std	r9,24(r3)
19462306a36Sopenharmony_ci	addi	r3,r3,32
19562306a36Sopenharmony_ci	subi	r7,r7,32
19662306a36Sopenharmony_ci
19762306a36Sopenharmony_ci	/* Up to 31B to go */
19862306a36Sopenharmony_ci8:	bf	cr7*4+3,9f
19962306a36Sopenharmony_cierr1;	ld	r0,0(r4)
20062306a36Sopenharmony_cierr1;	ld	r6,8(r4)
20162306a36Sopenharmony_ci	addi	r4,r4,16
20262306a36Sopenharmony_cierr1;	std	r0,0(r3)
20362306a36Sopenharmony_cierr1;	std	r6,8(r3)
20462306a36Sopenharmony_ci	addi	r3,r3,16
20562306a36Sopenharmony_ci	subi	r7,r7,16
20662306a36Sopenharmony_ci
20762306a36Sopenharmony_ci9:	clrldi	r5,r5,(64-4)
20862306a36Sopenharmony_ci
20962306a36Sopenharmony_ci	/* Up to 15B to go */
21062306a36Sopenharmony_ci.Lshort_copy:
21162306a36Sopenharmony_ci	mtocrf	0x01,r5
21262306a36Sopenharmony_ci	bf	cr7*4+0,12f
21362306a36Sopenharmony_cierr1;	lwz	r0,0(r4)	/* Less chance of a reject with word ops */
21462306a36Sopenharmony_cierr1;	lwz	r6,4(r4)
21562306a36Sopenharmony_ci	addi	r4,r4,8
21662306a36Sopenharmony_cierr1;	stw	r0,0(r3)
21762306a36Sopenharmony_cierr1;	stw	r6,4(r3)
21862306a36Sopenharmony_ci	addi	r3,r3,8
21962306a36Sopenharmony_ci	subi	r7,r7,8
22062306a36Sopenharmony_ci
22162306a36Sopenharmony_ci12:	bf	cr7*4+1,13f
22262306a36Sopenharmony_cierr1;	lwz	r0,0(r4)
22362306a36Sopenharmony_ci	addi	r4,r4,4
22462306a36Sopenharmony_cierr1;	stw	r0,0(r3)
22562306a36Sopenharmony_ci	addi	r3,r3,4
22662306a36Sopenharmony_ci	subi	r7,r7,4
22762306a36Sopenharmony_ci
22862306a36Sopenharmony_ci13:	bf	cr7*4+2,14f
22962306a36Sopenharmony_cierr1;	lhz	r0,0(r4)
23062306a36Sopenharmony_ci	addi	r4,r4,2
23162306a36Sopenharmony_cierr1;	sth	r0,0(r3)
23262306a36Sopenharmony_ci	addi	r3,r3,2
23362306a36Sopenharmony_ci	subi	r7,r7,2
23462306a36Sopenharmony_ci
23562306a36Sopenharmony_ci14:	bf	cr7*4+3,15f
23662306a36Sopenharmony_cierr1;	lbz	r0,0(r4)
23762306a36Sopenharmony_cierr1;	stb	r0,0(r3)
23862306a36Sopenharmony_ci
23962306a36Sopenharmony_ci15:	li	r3,0
24062306a36Sopenharmony_ci	blr
24162306a36Sopenharmony_ci
24262306a36Sopenharmony_ciEXPORT_SYMBOL_GPL(copy_mc_generic);
243