Update copyright dates with scripts/update-copyrights.
[glibc.git] / sysdeps / powerpc / powerpc64 / power4 / strncmp.S
blob6756ed217416dbcbed8019e05d0fd7ec07e09b1c
1 /* Optimized strcmp implementation for PowerPC64.
2    Copyright (C) 2003-2015 Free Software Foundation, Inc.
3    This file is part of the GNU C Library.
5    The GNU C Library is free software; you can redistribute it and/or
6    modify it under the terms of the GNU Lesser General Public
7    License as published by the Free Software Foundation; either
8    version 2.1 of the License, or (at your option) any later version.
10    The GNU C Library is distributed in the hope that it will be useful,
11    but WITHOUT ANY WARRANTY; without even the implied warranty of
12    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13    Lesser General Public License for more details.
15    You should have received a copy of the GNU Lesser General Public
16    License along with the GNU C Library; if not, see
17    <http://www.gnu.org/licenses/>.  */
19 #include <sysdep.h>
21 /* See strlen.s for comments on how the end-of-string testing works.  */
23 /* int [r3] strncmp (const char *s1 [r3], const char *s2 [r4], size_t size [r5])  */
25 EALIGN (strncmp, 4, 0)
26         CALL_MCOUNT 3
28 #define rTMP2   r0
29 #define rRTN    r3
30 #define rSTR1   r3      /* first string arg */
31 #define rSTR2   r4      /* second string arg */
32 #define rN      r5      /* max string length */
33 #define rWORD1  r6      /* current word in s1 */
34 #define rWORD2  r7      /* current word in s2 */
35 #define rWORD3  r10
36 #define rWORD4  r11
37 #define rFEFE   r8      /* constant 0xfefefefefefefeff (-0x0101010101010101) */
38 #define r7F7F   r9      /* constant 0x7f7f7f7f7f7f7f7f */
39 #define rNEG    r10     /* ~(word in s1 | 0x7f7f7f7f7f7f7f7f) */
40 #define rBITDIF r11     /* bits that differ in s1 & s2 words */
41 #define rTMP    r12
43         dcbt    0,rSTR1
44         or      rTMP, rSTR2, rSTR1
45         lis     r7F7F, 0x7f7f
46         dcbt    0,rSTR2
47         clrldi. rTMP, rTMP, 61
48         cmpldi  cr1, rN, 0
49         lis     rFEFE, -0x101
50         bne     L(unaligned)
51 /* We are doubleword aligned so set up for two loops.  first a double word
52    loop, then fall into the byte loop if any residual.  */
53         srdi.   rTMP, rN, 3
54         clrldi  rN, rN, 61
55         addi    rFEFE, rFEFE, -0x101
56         addi    r7F7F, r7F7F, 0x7f7f
57         cmpldi  cr1, rN, 0
58         beq     L(unaligned)
60         mtctr   rTMP    /* Power4 wants mtctr 1st in dispatch group.  */
61         ld      rWORD1, 0(rSTR1)
62         ld      rWORD2, 0(rSTR2)
63         sldi    rTMP, rFEFE, 32
64         insrdi  r7F7F, r7F7F, 32, 0
65         add     rFEFE, rFEFE, rTMP
66         b       L(g1)
68 L(g0):
69         ldu     rWORD1, 8(rSTR1)
70         bne-    cr1, L(different)
71         ldu     rWORD2, 8(rSTR2)
72 L(g1):  add     rTMP, rFEFE, rWORD1
73         nor     rNEG, r7F7F, rWORD1
74         bdz     L(tail)
75         and.    rTMP, rTMP, rNEG
76         cmpd    cr1, rWORD1, rWORD2
77         beq+    L(g0)
79 /* OK. We've hit the end of the string. We need to be careful that
80    we don't compare two strings as different because of gunk beyond
81    the end of the strings...  */
83 #ifdef __LITTLE_ENDIAN__
84 L(endstring):
85         addi    rTMP2, rTMP, -1
86         beq     cr1, L(equal)
87         andc    rTMP2, rTMP2, rTMP
88         rldimi  rTMP2, rTMP2, 1, 0
89         and     rWORD2, rWORD2, rTMP2   /* Mask off gunk.  */
90         and     rWORD1, rWORD1, rTMP2
91         cmpd    cr1, rWORD1, rWORD2
92         beq     cr1, L(equal)
93         xor     rBITDIF, rWORD1, rWORD2 /* rBITDIF has bits that differ.  */
94         neg     rNEG, rBITDIF
95         and     rNEG, rNEG, rBITDIF     /* rNEG has LS bit that differs.  */
96         cntlzd  rNEG, rNEG              /* bitcount of the bit.  */
97         andi.   rNEG, rNEG, 56          /* bitcount to LS byte that differs. */
98         sld     rWORD1, rWORD1, rNEG    /* shift left to clear MS bytes.  */
99         sld     rWORD2, rWORD2, rNEG
100         xor.    rBITDIF, rWORD1, rWORD2
101         sub     rRTN, rWORD1, rWORD2
102         blt-    L(highbit)
103         sradi   rRTN, rRTN, 63          /* must return an int.  */
104         ori     rRTN, rRTN, 1
105         blr
106 L(equal):
107         li      rRTN, 0
108         blr
110 L(different):
111         ld      rWORD1, -8(rSTR1)
112         xor     rBITDIF, rWORD1, rWORD2 /* rBITDIF has bits that differ.  */
113         neg     rNEG, rBITDIF
114         and     rNEG, rNEG, rBITDIF     /* rNEG has LS bit that differs.  */
115         cntlzd  rNEG, rNEG              /* bitcount of the bit.  */
116         andi.   rNEG, rNEG, 56          /* bitcount to LS byte that differs. */
117         sld     rWORD1, rWORD1, rNEG    /* shift left to clear MS bytes.  */
118         sld     rWORD2, rWORD2, rNEG
119         xor.    rBITDIF, rWORD1, rWORD2
120         sub     rRTN, rWORD1, rWORD2
121         blt-    L(highbit)
122         sradi   rRTN, rRTN, 63
123         ori     rRTN, rRTN, 1
124         blr
125 L(highbit):
126         sradi   rRTN, rWORD2, 63
127         ori     rRTN, rRTN, 1
128         blr
130 #else
131 L(endstring):
132         and     rTMP, r7F7F, rWORD1
133         beq     cr1, L(equal)
134         add     rTMP, rTMP, r7F7F
135         xor.    rBITDIF, rWORD1, rWORD2
136         andc    rNEG, rNEG, rTMP
137         blt-    L(highbit)
138         cntlzd  rBITDIF, rBITDIF
139         cntlzd  rNEG, rNEG
140         addi    rNEG, rNEG, 7
141         cmpd    cr1, rNEG, rBITDIF
142         sub     rRTN, rWORD1, rWORD2
143         blt-    cr1, L(equal)
144         sradi   rRTN, rRTN, 63          /* must return an int.  */
145         ori     rRTN, rRTN, 1
146         blr
147 L(equal):
148         li      rRTN, 0
149         blr
151 L(different):
152         ld      rWORD1, -8(rSTR1)
153         xor.    rBITDIF, rWORD1, rWORD2
154         sub     rRTN, rWORD1, rWORD2
155         blt-    L(highbit)
156         sradi   rRTN, rRTN, 63
157         ori     rRTN, rRTN, 1
158         blr
159 L(highbit):
160         sradi   rRTN, rWORD2, 63
161         ori     rRTN, rRTN, 1
162         blr
163 #endif
165 /* Oh well.  In this case, we just do a byte-by-byte comparison.  */
166         .align 4
167 L(tail):
168         and.    rTMP, rTMP, rNEG
169         cmpd    cr1, rWORD1, rWORD2
170         bne-    L(endstring)
171         addi    rSTR1, rSTR1, 8
172         bne-    cr1, L(different)
173         addi    rSTR2, rSTR2, 8
174         cmpldi  cr1, rN, 0
175 L(unaligned):
176         mtctr   rN      /* Power4 wants mtctr 1st in dispatch group */
177         ble     cr1, L(ux)
178 L(uz):
179         lbz     rWORD1, 0(rSTR1)
180         lbz     rWORD2, 0(rSTR2)
181         .align 4
182 L(u1):
183         cmpdi   cr1, rWORD1, 0
184         bdz     L(u4)
185         cmpd    rWORD1, rWORD2
186         beq-    cr1, L(u4)
187         bne-    L(u4)
188         lbzu    rWORD3, 1(rSTR1)
189         lbzu    rWORD4, 1(rSTR2)
190         cmpdi   cr1, rWORD3, 0
191         bdz     L(u3)
192         cmpd    rWORD3, rWORD4
193         beq-    cr1, L(u3)
194         bne-    L(u3)
195         lbzu    rWORD1, 1(rSTR1)
196         lbzu    rWORD2, 1(rSTR2)
197         cmpdi   cr1, rWORD1, 0
198         bdz     L(u4)
199         cmpd    rWORD1, rWORD2
200         beq-    cr1, L(u4)
201         bne-    L(u4)
202         lbzu    rWORD3, 1(rSTR1)
203         lbzu    rWORD4, 1(rSTR2)
204         cmpdi   cr1, rWORD3, 0
205         bdz     L(u3)
206         cmpd    rWORD3, rWORD4
207         beq-    cr1, L(u3)
208         bne-    L(u3)
209         lbzu    rWORD1, 1(rSTR1)
210         lbzu    rWORD2, 1(rSTR2)
211         b       L(u1)
213 L(u3):  sub     rRTN, rWORD3, rWORD4
214         blr
215 L(u4):  sub     rRTN, rWORD1, rWORD2
216         blr
217 L(ux):
218         li      rRTN, 0
219         blr
220 END (strncmp)
221 libc_hidden_builtin_def (strncmp)