18c2ecf20Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0-or-later */
28c2ecf20Sopenharmony_ci/*
38c2ecf20Sopenharmony_ci * Copyright (C) Paul Mackerras 1997.
48c2ecf20Sopenharmony_ci *
58c2ecf20Sopenharmony_ci * NOTE: this code runs in 32 bit mode and is packaged as ELF32.
68c2ecf20Sopenharmony_ci */
78c2ecf20Sopenharmony_ci
88c2ecf20Sopenharmony_ci#include "ppc_asm.h"
98c2ecf20Sopenharmony_ci
108c2ecf20Sopenharmony_ci	.text
118c2ecf20Sopenharmony_ci	.globl	strcpy
128c2ecf20Sopenharmony_cistrcpy:
138c2ecf20Sopenharmony_ci	addi	r5,r3,-1
148c2ecf20Sopenharmony_ci	addi	r4,r4,-1
158c2ecf20Sopenharmony_ci1:	lbzu	r0,1(r4)
168c2ecf20Sopenharmony_ci	cmpwi	0,r0,0
178c2ecf20Sopenharmony_ci	stbu	r0,1(r5)
188c2ecf20Sopenharmony_ci	bne	1b
198c2ecf20Sopenharmony_ci	blr
208c2ecf20Sopenharmony_ci
218c2ecf20Sopenharmony_ci	.globl	strncpy
228c2ecf20Sopenharmony_cistrncpy:
238c2ecf20Sopenharmony_ci	cmpwi	0,r5,0
248c2ecf20Sopenharmony_ci	beqlr
258c2ecf20Sopenharmony_ci	mtctr	r5
268c2ecf20Sopenharmony_ci	addi	r6,r3,-1
278c2ecf20Sopenharmony_ci	addi	r4,r4,-1
288c2ecf20Sopenharmony_ci1:	lbzu	r0,1(r4)
298c2ecf20Sopenharmony_ci	cmpwi	0,r0,0
308c2ecf20Sopenharmony_ci	stbu	r0,1(r6)
318c2ecf20Sopenharmony_ci	bdnzf	2,1b		/* dec ctr, branch if ctr != 0 && !cr0.eq */
328c2ecf20Sopenharmony_ci	blr
338c2ecf20Sopenharmony_ci
348c2ecf20Sopenharmony_ci	.globl	strcat
358c2ecf20Sopenharmony_cistrcat:
368c2ecf20Sopenharmony_ci	addi	r5,r3,-1
378c2ecf20Sopenharmony_ci	addi	r4,r4,-1
388c2ecf20Sopenharmony_ci1:	lbzu	r0,1(r5)
398c2ecf20Sopenharmony_ci	cmpwi	0,r0,0
408c2ecf20Sopenharmony_ci	bne	1b
418c2ecf20Sopenharmony_ci	addi	r5,r5,-1
428c2ecf20Sopenharmony_ci1:	lbzu	r0,1(r4)
438c2ecf20Sopenharmony_ci	cmpwi	0,r0,0
448c2ecf20Sopenharmony_ci	stbu	r0,1(r5)
458c2ecf20Sopenharmony_ci	bne	1b
468c2ecf20Sopenharmony_ci	blr
478c2ecf20Sopenharmony_ci
488c2ecf20Sopenharmony_ci	.globl	strchr
498c2ecf20Sopenharmony_cistrchr:
508c2ecf20Sopenharmony_ci	addi	r3,r3,-1
518c2ecf20Sopenharmony_ci1:	lbzu	r0,1(r3)
528c2ecf20Sopenharmony_ci	cmpw	0,r0,r4
538c2ecf20Sopenharmony_ci	beqlr
548c2ecf20Sopenharmony_ci	cmpwi	0,r0,0
558c2ecf20Sopenharmony_ci	bne	1b
568c2ecf20Sopenharmony_ci	li	r3,0
578c2ecf20Sopenharmony_ci	blr
588c2ecf20Sopenharmony_ci
598c2ecf20Sopenharmony_ci	.globl	strcmp
608c2ecf20Sopenharmony_cistrcmp:
618c2ecf20Sopenharmony_ci	addi	r5,r3,-1
628c2ecf20Sopenharmony_ci	addi	r4,r4,-1
638c2ecf20Sopenharmony_ci1:	lbzu	r3,1(r5)
648c2ecf20Sopenharmony_ci	cmpwi	1,r3,0
658c2ecf20Sopenharmony_ci	lbzu	r0,1(r4)
668c2ecf20Sopenharmony_ci	subf.	r3,r0,r3
678c2ecf20Sopenharmony_ci	beqlr	1
688c2ecf20Sopenharmony_ci	beq	1b
698c2ecf20Sopenharmony_ci	blr
708c2ecf20Sopenharmony_ci
718c2ecf20Sopenharmony_ci	.globl	strncmp
728c2ecf20Sopenharmony_cistrncmp:
738c2ecf20Sopenharmony_ci	mtctr	r5
748c2ecf20Sopenharmony_ci	addi	r5,r3,-1
758c2ecf20Sopenharmony_ci	addi	r4,r4,-1
768c2ecf20Sopenharmony_ci1:	lbzu	r3,1(r5)
778c2ecf20Sopenharmony_ci	cmpwi	1,r3,0
788c2ecf20Sopenharmony_ci	lbzu	r0,1(r4)
798c2ecf20Sopenharmony_ci	subf.	r3,r0,r3
808c2ecf20Sopenharmony_ci	beqlr	1
818c2ecf20Sopenharmony_ci	bdnzt	eq,1b
828c2ecf20Sopenharmony_ci	blr
838c2ecf20Sopenharmony_ci
848c2ecf20Sopenharmony_ci	.globl	strlen
858c2ecf20Sopenharmony_cistrlen:
868c2ecf20Sopenharmony_ci	addi	r4,r3,-1
878c2ecf20Sopenharmony_ci1:	lbzu	r0,1(r4)
888c2ecf20Sopenharmony_ci	cmpwi	0,r0,0
898c2ecf20Sopenharmony_ci	bne	1b
908c2ecf20Sopenharmony_ci	subf	r3,r3,r4
918c2ecf20Sopenharmony_ci	blr
928c2ecf20Sopenharmony_ci
938c2ecf20Sopenharmony_ci	.globl	memset
948c2ecf20Sopenharmony_cimemset:
958c2ecf20Sopenharmony_ci	rlwimi	r4,r4,8,16,23
968c2ecf20Sopenharmony_ci	rlwimi	r4,r4,16,0,15
978c2ecf20Sopenharmony_ci	addi	r6,r3,-4
988c2ecf20Sopenharmony_ci	cmplwi	0,r5,4
998c2ecf20Sopenharmony_ci	blt	7f
1008c2ecf20Sopenharmony_ci	stwu	r4,4(r6)
1018c2ecf20Sopenharmony_ci	beqlr
1028c2ecf20Sopenharmony_ci	andi.	r0,r6,3
1038c2ecf20Sopenharmony_ci	add	r5,r0,r5
1048c2ecf20Sopenharmony_ci	subf	r6,r0,r6
1058c2ecf20Sopenharmony_ci	rlwinm	r0,r5,32-2,2,31
1068c2ecf20Sopenharmony_ci	mtctr	r0
1078c2ecf20Sopenharmony_ci	bdz	6f
1088c2ecf20Sopenharmony_ci1:	stwu	r4,4(r6)
1098c2ecf20Sopenharmony_ci	bdnz	1b
1108c2ecf20Sopenharmony_ci6:	andi.	r5,r5,3
1118c2ecf20Sopenharmony_ci7:	cmpwi	0,r5,0
1128c2ecf20Sopenharmony_ci	beqlr
1138c2ecf20Sopenharmony_ci	mtctr	r5
1148c2ecf20Sopenharmony_ci	addi	r6,r6,3
1158c2ecf20Sopenharmony_ci8:	stbu	r4,1(r6)
1168c2ecf20Sopenharmony_ci	bdnz	8b
1178c2ecf20Sopenharmony_ci	blr
1188c2ecf20Sopenharmony_ci
1198c2ecf20Sopenharmony_ci	.globl	memmove
1208c2ecf20Sopenharmony_cimemmove:
1218c2ecf20Sopenharmony_ci	cmplw	0,r3,r4
1228c2ecf20Sopenharmony_ci	bgt	backwards_memcpy
1238c2ecf20Sopenharmony_ci	/* fall through */
1248c2ecf20Sopenharmony_ci
1258c2ecf20Sopenharmony_ci	.globl	memcpy
1268c2ecf20Sopenharmony_cimemcpy:
1278c2ecf20Sopenharmony_ci	rlwinm.	r7,r5,32-3,3,31		/* r7 = r5 >> 3 */
1288c2ecf20Sopenharmony_ci	addi	r6,r3,-4
1298c2ecf20Sopenharmony_ci	addi	r4,r4,-4
1308c2ecf20Sopenharmony_ci	beq	3f			/* if less than 8 bytes to do */
1318c2ecf20Sopenharmony_ci	andi.	r0,r6,3			/* get dest word aligned */
1328c2ecf20Sopenharmony_ci	mtctr	r7
1338c2ecf20Sopenharmony_ci	bne	5f
1348c2ecf20Sopenharmony_ci	andi.	r0,r4,3			/* check src word aligned too */
1358c2ecf20Sopenharmony_ci	bne	3f
1368c2ecf20Sopenharmony_ci1:	lwz	r7,4(r4)
1378c2ecf20Sopenharmony_ci	lwzu	r8,8(r4)
1388c2ecf20Sopenharmony_ci	stw	r7,4(r6)
1398c2ecf20Sopenharmony_ci	stwu	r8,8(r6)
1408c2ecf20Sopenharmony_ci	bdnz	1b
1418c2ecf20Sopenharmony_ci	andi.	r5,r5,7
1428c2ecf20Sopenharmony_ci2:	cmplwi	0,r5,4
1438c2ecf20Sopenharmony_ci	blt	3f
1448c2ecf20Sopenharmony_ci	lwzu	r0,4(r4)
1458c2ecf20Sopenharmony_ci	addi	r5,r5,-4
1468c2ecf20Sopenharmony_ci	stwu	r0,4(r6)
1478c2ecf20Sopenharmony_ci3:	cmpwi	0,r5,0
1488c2ecf20Sopenharmony_ci	beqlr
1498c2ecf20Sopenharmony_ci	mtctr	r5
1508c2ecf20Sopenharmony_ci	addi	r4,r4,3
1518c2ecf20Sopenharmony_ci	addi	r6,r6,3
1528c2ecf20Sopenharmony_ci4:	lbzu	r0,1(r4)
1538c2ecf20Sopenharmony_ci	stbu	r0,1(r6)
1548c2ecf20Sopenharmony_ci	bdnz	4b
1558c2ecf20Sopenharmony_ci	blr
1568c2ecf20Sopenharmony_ci5:	subfic	r0,r0,4
1578c2ecf20Sopenharmony_ci	cmpw	cr1,r0,r5
1588c2ecf20Sopenharmony_ci	add	r7,r0,r4
1598c2ecf20Sopenharmony_ci	andi.	r7,r7,3			/* will source be word-aligned too? */
1608c2ecf20Sopenharmony_ci	ble	cr1,3b
1618c2ecf20Sopenharmony_ci	bne	3b			/* do byte-by-byte if not */
1628c2ecf20Sopenharmony_ci	mtctr	r0
1638c2ecf20Sopenharmony_ci6:	lbz	r7,4(r4)
1648c2ecf20Sopenharmony_ci	addi	r4,r4,1
1658c2ecf20Sopenharmony_ci	stb	r7,4(r6)
1668c2ecf20Sopenharmony_ci	addi	r6,r6,1
1678c2ecf20Sopenharmony_ci	bdnz	6b
1688c2ecf20Sopenharmony_ci	subf	r5,r0,r5
1698c2ecf20Sopenharmony_ci	rlwinm.	r7,r5,32-3,3,31
1708c2ecf20Sopenharmony_ci	beq	2b
1718c2ecf20Sopenharmony_ci	mtctr	r7
1728c2ecf20Sopenharmony_ci	b	1b
1738c2ecf20Sopenharmony_ci
1748c2ecf20Sopenharmony_ci	.globl	backwards_memcpy
1758c2ecf20Sopenharmony_cibackwards_memcpy:
1768c2ecf20Sopenharmony_ci	rlwinm.	r7,r5,32-3,3,31		/* r7 = r5 >> 3 */
1778c2ecf20Sopenharmony_ci	add	r6,r3,r5
1788c2ecf20Sopenharmony_ci	add	r4,r4,r5
1798c2ecf20Sopenharmony_ci	beq	3f
1808c2ecf20Sopenharmony_ci	andi.	r0,r6,3
1818c2ecf20Sopenharmony_ci	mtctr	r7
1828c2ecf20Sopenharmony_ci	bne	5f
1838c2ecf20Sopenharmony_ci	andi.	r0,r4,3
1848c2ecf20Sopenharmony_ci	bne	3f
1858c2ecf20Sopenharmony_ci1:	lwz	r7,-4(r4)
1868c2ecf20Sopenharmony_ci	lwzu	r8,-8(r4)
1878c2ecf20Sopenharmony_ci	stw	r7,-4(r6)
1888c2ecf20Sopenharmony_ci	stwu	r8,-8(r6)
1898c2ecf20Sopenharmony_ci	bdnz	1b
1908c2ecf20Sopenharmony_ci	andi.	r5,r5,7
1918c2ecf20Sopenharmony_ci2:	cmplwi	0,r5,4
1928c2ecf20Sopenharmony_ci	blt	3f
1938c2ecf20Sopenharmony_ci	lwzu	r0,-4(r4)
1948c2ecf20Sopenharmony_ci	subi	r5,r5,4
1958c2ecf20Sopenharmony_ci	stwu	r0,-4(r6)
1968c2ecf20Sopenharmony_ci3:	cmpwi	0,r5,0
1978c2ecf20Sopenharmony_ci	beqlr
1988c2ecf20Sopenharmony_ci	mtctr	r5
1998c2ecf20Sopenharmony_ci4:	lbzu	r0,-1(r4)
2008c2ecf20Sopenharmony_ci	stbu	r0,-1(r6)
2018c2ecf20Sopenharmony_ci	bdnz	4b
2028c2ecf20Sopenharmony_ci	blr
2038c2ecf20Sopenharmony_ci5:	cmpw	cr1,r0,r5
2048c2ecf20Sopenharmony_ci	subf	r7,r0,r4
2058c2ecf20Sopenharmony_ci	andi.	r7,r7,3
2068c2ecf20Sopenharmony_ci	ble	cr1,3b
2078c2ecf20Sopenharmony_ci	bne	3b
2088c2ecf20Sopenharmony_ci	mtctr	r0
2098c2ecf20Sopenharmony_ci6:	lbzu	r7,-1(r4)
2108c2ecf20Sopenharmony_ci	stbu	r7,-1(r6)
2118c2ecf20Sopenharmony_ci	bdnz	6b
2128c2ecf20Sopenharmony_ci	subf	r5,r0,r5
2138c2ecf20Sopenharmony_ci	rlwinm.	r7,r5,32-3,3,31
2148c2ecf20Sopenharmony_ci	beq	2b
2158c2ecf20Sopenharmony_ci	mtctr	r7
2168c2ecf20Sopenharmony_ci	b	1b
2178c2ecf20Sopenharmony_ci
2188c2ecf20Sopenharmony_ci	.globl	memchr
2198c2ecf20Sopenharmony_cimemchr:
2208c2ecf20Sopenharmony_ci	cmpwi	0,r5,0
2218c2ecf20Sopenharmony_ci	blelr
2228c2ecf20Sopenharmony_ci	mtctr	r5
2238c2ecf20Sopenharmony_ci	addi	r3,r3,-1
2248c2ecf20Sopenharmony_ci1:	lbzu	r0,1(r3)
2258c2ecf20Sopenharmony_ci	cmpw	r0,r4
2268c2ecf20Sopenharmony_ci	beqlr
2278c2ecf20Sopenharmony_ci	bdnz	1b
2288c2ecf20Sopenharmony_ci	li	r3,0
2298c2ecf20Sopenharmony_ci	blr
2308c2ecf20Sopenharmony_ci
2318c2ecf20Sopenharmony_ci	.globl	memcmp
2328c2ecf20Sopenharmony_cimemcmp:
2338c2ecf20Sopenharmony_ci	cmpwi	0,r5,0
2348c2ecf20Sopenharmony_ci	ble	2f
2358c2ecf20Sopenharmony_ci	mtctr	r5
2368c2ecf20Sopenharmony_ci	addi	r6,r3,-1
2378c2ecf20Sopenharmony_ci	addi	r4,r4,-1
2388c2ecf20Sopenharmony_ci1:	lbzu	r3,1(r6)
2398c2ecf20Sopenharmony_ci	lbzu	r0,1(r4)
2408c2ecf20Sopenharmony_ci	subf.	r3,r0,r3
2418c2ecf20Sopenharmony_ci	bdnzt	2,1b
2428c2ecf20Sopenharmony_ci	blr
2438c2ecf20Sopenharmony_ci2:	li	r3,0
2448c2ecf20Sopenharmony_ci	blr
2458c2ecf20Sopenharmony_ci
2468c2ecf20Sopenharmony_ci
2478c2ecf20Sopenharmony_ci/*
2488c2ecf20Sopenharmony_ci * Flush the dcache and invalidate the icache for a range of addresses.
2498c2ecf20Sopenharmony_ci *
2508c2ecf20Sopenharmony_ci * flush_cache(addr, len)
2518c2ecf20Sopenharmony_ci */
2528c2ecf20Sopenharmony_ci	.global	flush_cache
2538c2ecf20Sopenharmony_ciflush_cache:
2548c2ecf20Sopenharmony_ci	addi	4,4,0x1f	/* len = (len + 0x1f) / 0x20 */
2558c2ecf20Sopenharmony_ci	rlwinm.	4,4,27,5,31
2568c2ecf20Sopenharmony_ci	mtctr	4
2578c2ecf20Sopenharmony_ci	beqlr
2588c2ecf20Sopenharmony_ci1:	dcbf	0,3
2598c2ecf20Sopenharmony_ci	icbi	0,3
2608c2ecf20Sopenharmony_ci	addi	3,3,0x20
2618c2ecf20Sopenharmony_ci	bdnz	1b
2628c2ecf20Sopenharmony_ci	sync
2638c2ecf20Sopenharmony_ci	isync
2648c2ecf20Sopenharmony_ci	blr
2658c2ecf20Sopenharmony_ci
266