1/* SPDX-License-Identifier: GPL-2.0+ */
2/*
3 * String handling functions for PowerPC.
4 *
5 * Copyright (C) 1996 Paul Mackerras.
6 */
7#include <ppc_asm.tmpl>
8#include <linux/errno.h>
9
10	.globl	strcpy
11strcpy:
12	addi	r5,r3,-1
13	addi	r4,r4,-1
141:	lbzu	r0,1(r4)
15	cmpwi	0,r0,0
16	stbu	r0,1(r5)
17	bne	1b
18	blr
19
20	.globl	strncpy
21strncpy:
22	cmpwi	0,r5,0
23	beqlr
24	mtctr	r5
25	addi	r6,r3,-1
26	addi	r4,r4,-1
271:	lbzu	r0,1(r4)
28	cmpwi	0,r0,0
29	stbu	r0,1(r6)
30	bdnzf	2,1b		/* dec ctr, branch if ctr != 0 && !cr0.eq */
31	blr
32
33	.globl	strcat
34strcat:
35	addi	r5,r3,-1
36	addi	r4,r4,-1
371:	lbzu	r0,1(r5)
38	cmpwi	0,r0,0
39	bne	1b
40	addi	r5,r5,-1
411:	lbzu	r0,1(r4)
42	cmpwi	0,r0,0
43	stbu	r0,1(r5)
44	bne	1b
45	blr
46
47	.globl	strcmp
48strcmp:
49	addi	r5,r3,-1
50	addi	r4,r4,-1
511:	lbzu	r3,1(r5)
52	cmpwi	1,r3,0
53	lbzu	r0,1(r4)
54	subf.	r3,r0,r3
55	beqlr	1
56	beq	1b
57	blr
58
59	.globl	strlen
60strlen:
61	addi	r4,r3,-1
621:	lbzu	r0,1(r4)
63	cmpwi	0,r0,0
64	bne	1b
65	subf	r3,r3,r4
66	blr
67
68	.globl	memset
69memset:
70	rlwimi	r4,r4,8,16,23
71	rlwimi	r4,r4,16,0,15
72	addi	r6,r3,-4
73	cmplwi	0,r5,4
74	blt	7f
75	stwu	r4,4(r6)
76	beqlr
77	andi.	r0,r6,3
78	add	r5,r0,r5
79	subf	r6,r0,r6
80	rlwinm	r0,r5,32-2,2,31
81	mtctr	r0
82	bdz	6f
831:	stwu	r4,4(r6)
84	bdnz	1b
856:	andi.	r5,r5,3
867:	cmpwi	0,r5,0
87	beqlr
88	mtctr	r5
89	addi	r6,r6,3
908:	stbu	r4,1(r6)
91	bdnz	8b
92	blr
93
94	.globl	memmove
95memmove:
96	cmplw	0,r3,r4
97	bgt	backwards_memcpy
98	/* fall through */
99
100	.globl	memcpy
101memcpy:
102	rlwinm.	r7,r5,32-3,3,31		/* r0 = r5 >> 3 */
103	addi	r6,r3,-4
104	addi	r4,r4,-4
105	beq	2f			/* if less than 8 bytes to do */
106	andi.	r0,r6,3			/* get dest word aligned */
107	mtctr	r7
108	bne	5f
1091:	lwz	r7,4(r4)
110	lwzu	r8,8(r4)
111	stw	r7,4(r6)
112	stwu	r8,8(r6)
113	bdnz	1b
114	andi.	r5,r5,7
1152:	cmplwi	0,r5,4
116	blt	3f
117	lwzu	r0,4(r4)
118	addi	r5,r5,-4
119	stwu	r0,4(r6)
1203:	cmpwi	0,r5,0
121	beqlr
122	mtctr	r5
123	addi	r4,r4,3
124	addi	r6,r6,3
1254:	lbzu	r0,1(r4)
126	stbu	r0,1(r6)
127	bdnz	4b
128	blr
1295:	subfic	r0,r0,4
130	mtctr	r0
1316:	lbz	r7,4(r4)
132	addi	r4,r4,1
133	stb	r7,4(r6)
134	addi	r6,r6,1
135	bdnz	6b
136	subf	r5,r0,r5
137	rlwinm.	r7,r5,32-3,3,31
138	beq	2b
139	mtctr	r7
140	b	1b
141
142	.globl	backwards_memcpy
143backwards_memcpy:
144	rlwinm.	r7,r5,32-3,3,31		/* r0 = r5 >> 3 */
145	add	r6,r3,r5
146	add	r4,r4,r5
147	beq	2f
148	andi.	r0,r6,3
149	mtctr	r7
150	bne	5f
1511:	lwz	r7,-4(r4)
152	lwzu	r8,-8(r4)
153	stw	r7,-4(r6)
154	stwu	r8,-8(r6)
155	bdnz	1b
156	andi.	r5,r5,7
1572:	cmplwi	0,r5,4
158	blt	3f
159	lwzu	r0,-4(r4)
160	subi	r5,r5,4
161	stwu	r0,-4(r6)
1623:	cmpwi	0,r5,0
163	beqlr
164	mtctr	r5
1654:	lbzu	r0,-1(r4)
166	stbu	r0,-1(r6)
167	bdnz	4b
168	blr
1695:	mtctr	r0
1706:	lbzu	r7,-1(r4)
171	stbu	r7,-1(r6)
172	bdnz	6b
173	subf	r5,r0,r5
174	rlwinm.	r7,r5,32-3,3,31
175	beq	2b
176	mtctr	r7
177	b	1b
178
179	.globl	memcmp
180memcmp:
181	cmpwi	0,r5,0
182	ble-	2f
183	mtctr	r5
184	addi	r6,r3,-1
185	addi	r4,r4,-1
1861:	lbzu	r3,1(r6)
187	lbzu	r0,1(r4)
188	subf.	r3,r0,r3
189	bdnzt	2,1b
190	blr
1912:	li	r3,0
192	blr
193
194	.global	memchr
195memchr:
196	cmpwi	0,r5,0
197	ble-	2f
198	mtctr	r5
199	addi	r3,r3,-1
2001:	lbzu	r0,1(r3)
201	cmpw	0,r0,r4
202	bdnzf	2,1b
203	beqlr
2042:	li	r3,0
205	blr
206