e21a0038a4d67829451b6c44f9ffab8d74a8a9d5
[linux-2.6.git] / arch / ppc64 / lib / string.S
1 /*
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  */
11 #include <asm/processor.h>
12 #include <asm/errno.h>
13 #include <asm/ppc_asm.h>
14
15 _GLOBAL(strcpy)
16         addi    r5,r3,-1
17         addi    r4,r4,-1
18 1:      lbzu    r0,1(r4)
19         cmpwi   0,r0,0
20         stbu    r0,1(r5)
21         bne     1b
22         blr
23
24 _GLOBAL(strncpy)
25         cmpwi   0,r5,0
26         beqlr
27         mtctr   r5
28         addi    r6,r3,-1
29         addi    r4,r4,-1
30 1:      lbzu    r0,1(r4)
31         cmpwi   0,r0,0
32         stbu    r0,1(r6)
33         bdnzf   2,1b            /* dec ctr, branch if ctr != 0 && !cr0.eq */
34         blr
35
36 _GLOBAL(strcat)
37         addi    r5,r3,-1
38         addi    r4,r4,-1
39 1:      lbzu    r0,1(r5)
40         cmpwi   0,r0,0
41         bne     1b
42         addi    r5,r5,-1
43 1:      lbzu    r0,1(r4)
44         cmpwi   0,r0,0
45         stbu    r0,1(r5)
46         bne     1b
47         blr
48
49 _GLOBAL(strcmp)
50         addi    r5,r3,-1
51         addi    r4,r4,-1
52 1:      lbzu    r3,1(r5)
53         cmpwi   1,r3,0
54         lbzu    r0,1(r4)
55         subf.   r3,r0,r3
56         beqlr   1
57         beq     1b
58         blr
59
60 _GLOBAL(strlen)
61         addi    r4,r3,-1
62 1:      lbzu    r0,1(r4)
63         cmpwi   0,r0,0
64         bne     1b
65         subf    r3,r3,r4
66         blr
67
68 _GLOBAL(memcmp)
69         cmpwi   0,r5,0
70         ble-    2f
71         mtctr   r5
72         addi    r6,r3,-1
73         addi    r4,r4,-1
74 1:      lbzu    r3,1(r6)
75         lbzu    r0,1(r4)
76         subf.   r3,r0,r3
77         bdnzt   2,1b
78         blr
79 2:      li      r3,0
80         blr
81
82 _GLOBAL(memchr)
83         cmpwi   0,r5,0
84         ble-    2f
85         mtctr   r5
86         addi    r3,r3,-1
87 1:      lbzu    r0,1(r3)
88         cmpw    0,r0,r4
89         bdnzf   2,1b
90         beqlr
91 2:      li      r3,0
92         blr
93
94 _GLOBAL(__clear_user)
95         addi    r6,r3,-4
96         li      r3,0
97         li      r5,0
98         cmplwi  0,r4,4
99         blt     7f
100         /* clear a single word */
101 11:     stwu    r5,4(r6)
102         beqlr
103         /* clear word sized chunks */
104         andi.   r0,r6,3
105         add     r4,r0,r4
106         subf    r6,r0,r6
107         srwi    r0,r4,2
108         andi.   r4,r4,3
109         mtctr   r0
110         bdz     7f
111 1:      stwu    r5,4(r6)
112         bdnz    1b
113         /* clear byte sized chunks */
114 7:      cmpwi   0,r4,0
115         beqlr
116         mtctr   r4
117         addi    r6,r6,3
118 8:      stbu    r5,1(r6)
119         bdnz    8b
120         blr
121 90:     mr      r3,r4
122         blr
123 91:     mfctr   r3
124         slwi    r3,r3,2
125         add     r3,r3,r4
126         blr
127 92:     mfctr   r3
128         blr
129
130         .section __ex_table,"a"
131         .align  3
132         .llong  11b,90b
133         .llong  1b,91b
134         .llong  8b,92b
135         .text
136
137 /* r3 = dst, r4 = src, r5 = count */
138 _GLOBAL(__strncpy_from_user)
139         addi    r6,r3,-1
140         addi    r4,r4,-1
141         cmpwi   0,r5,0
142         beq     2f
143         mtctr   r5
144 1:      lbzu    r0,1(r4)
145         cmpwi   0,r0,0
146         stbu    r0,1(r6)
147         bdnzf   2,1b            /* dec ctr, branch if ctr != 0 && !cr0.eq */
148         beq     3f
149 2:      addi    r6,r6,1
150 3:      subf    r3,r3,r6
151         blr
152 99:     li      r3,-EFAULT
153         blr
154
155         .section __ex_table,"a"
156         .align  3
157         .llong  1b,99b
158         .text
159
160 /* r3 = str, r4 = len (> 0) */
161 _GLOBAL(__strnlen_user)
162         addi    r7,r3,-1
163         mtctr   r4              /* ctr = len */
164 1:      lbzu    r0,1(r7)        /* get next byte */
165         cmpwi   0,r0,0
166         bdnzf   2,1b            /* loop if --ctr != 0 && byte != 0 */
167         addi    r7,r7,1
168         subf    r3,r3,r7        /* number of bytes we have looked at */
169         beqlr                   /* return if we found a 0 byte */
170         cmpw    0,r3,r4         /* did we look at all len bytes? */
171         blt     99f             /* if not, must have hit top */
172         addi    r3,r4,1         /* return len + 1 to indicate no null found */
173         blr
174 99:     li      r3,0            /* bad address, return 0 */
175         blr
176
177         .section __ex_table,"a"
178         .align  3
179         .llong  1b,99b