blob: 49eb1f1a2bb4f5a240ff45a0d807bae129718155 [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"
16#ifdef CONFIG_PPC64
17 .align 3
18#define EXTBL .llong
19#else
20 .align 2
21#define EXTBL .long
22#endif
23 .text
24
25_GLOBAL(strcpy)
26 addi r5,r3,-1
27 addi r4,r4,-1
281: lbzu r0,1(r4)
29 cmpwi 0,r0,0
30 stbu r0,1(r5)
31 bne 1b
32 blr
33
34/* This clears out any unused part of the destination buffer,
35 just as the libc version does. -- paulus */
36_GLOBAL(strncpy)
37 cmpwi 0,r5,0
38 beqlr
39 mtctr r5
40 addi r6,r3,-1
41 addi r4,r4,-1
421: lbzu r0,1(r4)
43 cmpwi 0,r0,0
44 stbu r0,1(r6)
45 bdnzf 2,1b /* dec ctr, branch if ctr != 0 && !cr0.eq */
46 bnelr /* if we didn't hit a null char, we're done */
47 mfctr r5
48 cmpwi 0,r5,0 /* any space left in destination buffer? */
49 beqlr /* we know r0 == 0 here */
502: stbu r0,1(r6) /* clear it out if so */
51 bdnz 2b
52 blr
53
54_GLOBAL(strcat)
55 addi r5,r3,-1
56 addi r4,r4,-1
571: lbzu r0,1(r5)
58 cmpwi 0,r0,0
59 bne 1b
60 addi r5,r5,-1
611: lbzu r0,1(r4)
62 cmpwi 0,r0,0
63 stbu r0,1(r5)
64 bne 1b
65 blr
66
67_GLOBAL(strcmp)
68 addi r5,r3,-1
69 addi r4,r4,-1
701: lbzu r3,1(r5)
71 cmpwi 1,r3,0
72 lbzu r0,1(r4)
73 subf. r3,r0,r3
74 beqlr 1
75 beq 1b
76 blr
77
Steven Rostedt01195362008-03-01 03:04:57 +110078_GLOBAL(strncmp)
79 PPC_LCMPI r5,0
80 beqlr
81 mtctr r5
82 addi r5,r3,-1
83 addi r4,r4,-1
841: lbzu r3,1(r5)
85 cmpwi 1,r3,0
86 lbzu r0,1(r4)
87 subf. r3,r0,r3
88 beqlr 1
89 bdnzt eq,1b
90 blr
91
Paul Mackerras14cf11a2005-09-26 16:04:21 +100092_GLOBAL(strlen)
93 addi r4,r3,-1
941: lbzu r0,1(r4)
95 cmpwi 0,r0,0
96 bne 1b
97 subf r3,r3,r4
98 blr
99
100_GLOBAL(memcmp)
101 cmpwi 0,r5,0
102 ble- 2f
103 mtctr r5
104 addi r6,r3,-1
105 addi r4,r4,-1
1061: lbzu r3,1(r6)
107 lbzu r0,1(r4)
108 subf. r3,r0,r3
109 bdnzt 2,1b
110 blr
1112: li r3,0
112 blr
113
114_GLOBAL(memchr)
115 cmpwi 0,r5,0
116 ble- 2f
117 mtctr r5
118 addi r3,r3,-1
1191: lbzu r0,1(r3)
120 cmpw 0,r0,r4
121 bdnzf 2,1b
122 beqlr
1232: li r3,0
124 blr
125
126_GLOBAL(__clear_user)
127 addi r6,r3,-4
128 li r3,0
129 li r5,0
130 cmplwi 0,r4,4
131 blt 7f
132 /* clear a single word */
13311: stwu r5,4(r6)
134 beqlr
135 /* clear word sized chunks */
136 andi. r0,r6,3
137 add r4,r0,r4
138 subf r6,r0,r6
139 srwi r0,r4,2
140 andi. r4,r4,3
141 mtctr r0
142 bdz 7f
1431: stwu r5,4(r6)
144 bdnz 1b
145 /* clear byte sized chunks */
1467: cmpwi 0,r4,0
147 beqlr
148 mtctr r4
149 addi r6,r6,3
1508: stbu r5,1(r6)
151 bdnz 8b
152 blr
15390: mr r3,r4
154 blr
15591: mfctr r3
156 slwi r3,r3,2
157 add r3,r3,r4
158 blr
15992: mfctr r3
160 blr
161
162 .section __ex_table,"a"
163 EXTBL 11b,90b
164 EXTBL 1b,91b
165 EXTBL 8b,92b
166 .text
167
168_GLOBAL(__strncpy_from_user)
169 addi r6,r3,-1
170 addi r4,r4,-1
171 cmpwi 0,r5,0
172 beq 2f
173 mtctr r5
1741: lbzu r0,1(r4)
175 cmpwi 0,r0,0
176 stbu r0,1(r6)
177 bdnzf 2,1b /* dec ctr, branch if ctr != 0 && !cr0.eq */
178 beq 3f
1792: addi r6,r6,1
1803: subf r3,r3,r6
181 blr
18299: li r3,-EFAULT
183 blr
184
185 .section __ex_table,"a"
186 EXTBL 1b,99b
187 .text
188
189/* r3 = str, r4 = len (> 0), r5 = top (highest addr) */
190_GLOBAL(__strnlen_user)
191 addi r7,r3,-1
192 subf r6,r7,r5 /* top+1 - str */
193 cmplw 0,r4,r6
194 bge 0f
195 mr r6,r4
1960: mtctr r6 /* ctr = min(len, top - str) */
1971: lbzu r0,1(r7) /* get next byte */
198 cmpwi 0,r0,0
199 bdnzf 2,1b /* loop if --ctr != 0 && byte != 0 */
200 addi r7,r7,1
201 subf r3,r3,r7 /* number of bytes we have looked at */
202 beqlr /* return if we found a 0 byte */
203 cmpw 0,r3,r4 /* did we look at all len bytes? */
204 blt 99f /* if not, must have hit top */
205 addi r3,r4,1 /* return len + 1 to indicate no null found */
206 blr
20799: li r3,0 /* bad address, return 0 */
208 blr
209
210 .section __ex_table,"a"
211 EXTBL 1b,99b