blob: 64e2e499e32a6fecacf81cb6eba2d03a32c8e50d [file] [log] [blame]
Paul Mackerras14cf11a2005-09-26 16:04:21 +10001/*
2 * String handling functions for PowerPC.
3 *
4 * Copyright (C) 1996 Paul Mackerras.
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version
9 * 2 of the License, or (at your option) any later version.
10 */
Paul Mackerras14cf11a2005-09-26 16:04:21 +100011#include <asm/processor.h>
12#include <asm/errno.h>
13#include <asm/ppc_asm.h>
14
Paul Mackerras14cf11a2005-09-26 16:04:21 +100015 .section __ex_table,"a"
Michael Ellerman76bfdcf2008-07-17 17:17:52 +100016 PPC_LONG_ALIGN
Paul Mackerras14cf11a2005-09-26 16:04:21 +100017 .text
18
19_GLOBAL(strcpy)
20 addi r5,r3,-1
21 addi r4,r4,-1
221: lbzu r0,1(r4)
23 cmpwi 0,r0,0
24 stbu r0,1(r5)
25 bne 1b
26 blr
27
28/* This clears out any unused part of the destination buffer,
29 just as the libc version does. -- paulus */
30_GLOBAL(strncpy)
31 cmpwi 0,r5,0
32 beqlr
33 mtctr r5
34 addi r6,r3,-1
35 addi r4,r4,-1
361: lbzu r0,1(r4)
37 cmpwi 0,r0,0
38 stbu r0,1(r6)
39 bdnzf 2,1b /* dec ctr, branch if ctr != 0 && !cr0.eq */
40 bnelr /* if we didn't hit a null char, we're done */
41 mfctr r5
42 cmpwi 0,r5,0 /* any space left in destination buffer? */
43 beqlr /* we know r0 == 0 here */
442: stbu r0,1(r6) /* clear it out if so */
45 bdnz 2b
46 blr
47
48_GLOBAL(strcat)
49 addi r5,r3,-1
50 addi r4,r4,-1
511: lbzu r0,1(r5)
52 cmpwi 0,r0,0
53 bne 1b
54 addi r5,r5,-1
551: lbzu r0,1(r4)
56 cmpwi 0,r0,0
57 stbu r0,1(r5)
58 bne 1b
59 blr
60
61_GLOBAL(strcmp)
62 addi r5,r3,-1
63 addi r4,r4,-1
641: lbzu r3,1(r5)
65 cmpwi 1,r3,0
66 lbzu r0,1(r4)
67 subf. r3,r0,r3
68 beqlr 1
69 beq 1b
70 blr
71
Steven Rostedt01195362008-03-01 03:04:57 +110072_GLOBAL(strncmp)
73 PPC_LCMPI r5,0
74 beqlr
75 mtctr r5
76 addi r5,r3,-1
77 addi r4,r4,-1
781: lbzu r3,1(r5)
79 cmpwi 1,r3,0
80 lbzu r0,1(r4)
81 subf. r3,r0,r3
82 beqlr 1
83 bdnzt eq,1b
84 blr
85
Paul Mackerras14cf11a2005-09-26 16:04:21 +100086_GLOBAL(strlen)
87 addi r4,r3,-1
881: lbzu r0,1(r4)
89 cmpwi 0,r0,0
90 bne 1b
91 subf r3,r3,r4
92 blr
93
94_GLOBAL(memcmp)
95 cmpwi 0,r5,0
96 ble- 2f
97 mtctr r5
98 addi r6,r3,-1
99 addi r4,r4,-1
1001: lbzu r3,1(r6)
101 lbzu r0,1(r4)
102 subf. r3,r0,r3
103 bdnzt 2,1b
104 blr
1052: li r3,0
106 blr
107
108_GLOBAL(memchr)
109 cmpwi 0,r5,0
110 ble- 2f
111 mtctr r5
112 addi r3,r3,-1
1131: lbzu r0,1(r3)
114 cmpw 0,r0,r4
115 bdnzf 2,1b
116 beqlr
1172: li r3,0
118 blr
119
120_GLOBAL(__clear_user)
121 addi r6,r3,-4
122 li r3,0
123 li r5,0
124 cmplwi 0,r4,4
125 blt 7f
126 /* clear a single word */
12711: stwu r5,4(r6)
128 beqlr
129 /* clear word sized chunks */
130 andi. r0,r6,3
131 add r4,r0,r4
132 subf r6,r0,r6
133 srwi r0,r4,2
134 andi. r4,r4,3
135 mtctr r0
136 bdz 7f
1371: stwu r5,4(r6)
138 bdnz 1b
139 /* clear byte sized chunks */
1407: cmpwi 0,r4,0
141 beqlr
142 mtctr r4
143 addi r6,r6,3
1448: stbu r5,1(r6)
145 bdnz 8b
146 blr
14790: mr r3,r4
148 blr
14991: mfctr r3
150 slwi r3,r3,2
151 add r3,r3,r4
152 blr
15392: mfctr r3
154 blr
155
156 .section __ex_table,"a"
Michael Ellerman76bfdcf2008-07-17 17:17:52 +1000157 PPC_LONG 11b,90b
158 PPC_LONG 1b,91b
159 PPC_LONG 8b,92b
Paul Mackerras14cf11a2005-09-26 16:04:21 +1000160 .text
161
162_GLOBAL(__strncpy_from_user)
163 addi r6,r3,-1
164 addi r4,r4,-1
165 cmpwi 0,r5,0
166 beq 2f
167 mtctr r5
1681: lbzu r0,1(r4)
169 cmpwi 0,r0,0
170 stbu r0,1(r6)
171 bdnzf 2,1b /* dec ctr, branch if ctr != 0 && !cr0.eq */
172 beq 3f
1732: addi r6,r6,1
1743: subf r3,r3,r6
175 blr
17699: li r3,-EFAULT
177 blr
178
179 .section __ex_table,"a"
Michael Ellerman76bfdcf2008-07-17 17:17:52 +1000180 PPC_LONG 1b,99b
Paul Mackerras14cf11a2005-09-26 16:04:21 +1000181 .text
182
183/* r3 = str, r4 = len (> 0), r5 = top (highest addr) */
184_GLOBAL(__strnlen_user)
185 addi r7,r3,-1
186 subf r6,r7,r5 /* top+1 - str */
187 cmplw 0,r4,r6
188 bge 0f
189 mr r6,r4
1900: mtctr r6 /* ctr = min(len, top - str) */
1911: lbzu r0,1(r7) /* get next byte */
192 cmpwi 0,r0,0
193 bdnzf 2,1b /* loop if --ctr != 0 && byte != 0 */
194 addi r7,r7,1
195 subf r3,r3,r7 /* number of bytes we have looked at */
196 beqlr /* return if we found a 0 byte */
197 cmpw 0,r3,r4 /* did we look at all len bytes? */
198 blt 99f /* if not, must have hit top */
199 addi r3,r4,1 /* return len + 1 to indicate no null found */
200 blr
20199: li r3,0 /* bad address, return 0 */
202 blr
203
204 .section __ex_table,"a"
Michael Ellerman76bfdcf2008-07-17 17:17:52 +1000205 PPC_LONG 1b,99b