.
[glibc/history.git] / sysdeps / powerpc / powerpc64 / strncmp.S
blob34479e2e91168f55b5e0a15e0eefd9b002641b85
1 /* Optimized strcmp implementation for PowerPC64.
2    Copyright (C) 2003 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, write to the Free
17    Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
18    02111-1307 USA.  */
20 #include <sysdep.h>
21 #include <bp-sym.h>
22 #include <bp-asm.h>
24 /* See strlen.s for comments on how the end-of-string testing works.  */
26 /* int [r3] strncmp (const char *s1 [r3], const char *s2 [r4], size_t size [r5])  */
28 EALIGN (BP_SYM(strncmp), 4, 0)
29         CALL_MCOUNT 3
31 #define rTMP    r0
32 #define rRTN    r3
33 #define rSTR1   r3      /* first string arg */
34 #define rSTR2   r4      /* second string arg */
35 #define rN      r5      /* max string length */
36 /* Note:  The Bounded pointer support in this code is broken.  This code
37    was inherited from PPC32 and and that support was never completed.  
38    Current PPC gcc does not support -fbounds-check or -fbounded-pointers.  */
39 #define rWORD1  r6      /* current word in s1 */
40 #define rWORD2  r7      /* current word in s2 */
41 #define rFEFE   r8      /* constant 0xfefefefefefefeff (-0x0101010101010101) */
42 #define r7F7F   r9      /* constant 0x7f7f7f7f7f7f7f7f */
43 #define rNEG    r10     /* ~(word in s1 | 0x7f7f7f7f7f7f7f7f) */
44 #define rBITDIF r11     /* bits that differ in s1 & s2 words */
46         dcbt    0,rSTR1
47         or      rTMP, rSTR2, rSTR1
48         lis     r7F7F, 0x7f7f
49         dcbt    0,rSTR2
50         clrldi. rTMP, rTMP, 61
51         cmpldi  cr1, rN, 0
52         lis     rFEFE, -0x101
53         bne     L(unaligned)
54 /* We are doubleword alligned so set up for two loops.  first a double word
55    loop, then fall into the byte loop if any residual.  */
56         srdi.   rTMP, rN, 3
57         clrldi  rN, rN, 61
58         addi    rFEFE, rFEFE, -0x101
59         addi    r7F7F, r7F7F, 0x7f7f
60         cmpldi  cr1, rN, 0      
61         beq     L(unaligned)
63         mtctr   rTMP    /* Power4 wants mtctr 1st in dispatch group.  */
64         ld      rWORD1, 0(rSTR1)
65         ld      rWORD2, 0(rSTR2)
66         sldi    rTMP, rFEFE, 32
67         insrdi  r7F7F, r7F7F, 32, 0
68         add     rFEFE, rFEFE, rTMP
69         b       L(g1)
71 L(g0):  
72         ldu     rWORD1, 8(rSTR1)
73         bne-    cr1, L(different)
74         ldu     rWORD2, 8(rSTR2)
75 L(g1):  add     rTMP, rFEFE, rWORD1
76         nor     rNEG, r7F7F, rWORD1
77         bdz     L(tail)
78         and.    rTMP, rTMP, rNEG
79         cmpd    cr1, rWORD1, rWORD2
80         beq+    L(g0)
81         
82 /* OK. We've hit the end of the string. We need to be careful that
83    we don't compare two strings as different because of gunk beyond
84    the end of the strings...  */
85         
86 L(endstring):
87         and     rTMP, r7F7F, rWORD1
88         beq     cr1, L(equal)
89         add     rTMP, rTMP, r7F7F
90         xor.    rBITDIF, rWORD1, rWORD2
92         andc    rNEG, rNEG, rTMP
93         blt-    L(highbit)
94         cntlzd  rBITDIF, rBITDIF
95         cntlzd  rNEG, rNEG
96         addi    rNEG, rNEG, 7
97         cmpd    cr1, rNEG, rBITDIF
98         sub     rRTN, rWORD1, rWORD2
99         blt-    cr1, L(equal)
100         sradi   rRTN, rRTN, 63
101         ori     rRTN, rRTN, 1
102         blr
103 L(equal):
104         li      rRTN, 0
105         blr
107 L(different):
108         ldu     rWORD1, -8(rSTR1)
109         xor.    rBITDIF, rWORD1, rWORD2
110         sub     rRTN, rWORD1, rWORD2
111         blt-    L(highbit)
112         sradi   rRTN, rRTN, 63
113         ori     rRTN, rRTN, 1
114         blr
115 L(highbit):
116         srdi    rWORD2, rWORD2, 56
117         srdi    rWORD1, rWORD1, 56
118         sub     rRTN, rWORD1, rWORD2
119         blr
122 /* Oh well.  In this case, we just do a byte-by-byte comparison.  */
123         .align 4
124 L(tail):
125         and.    rTMP, rTMP, rNEG
126         cmpd    cr1, rWORD1, rWORD2
127         bne-    L(endstring)
128         addi    rSTR1, rSTR1, 8
129         bne-    cr1, L(different)
130         addi    rSTR2, rSTR2, 8
131         cmpldi  cr1, rN, 0
132 L(unaligned):
133         mtctr   rN      /* Power4 wants mtctr 1st in dispatch group */
134         bgt     cr1, L(uz)
135 L(ux):
136         li      rRTN, 0
137         blr
138         .align 4
139 L(uz):
140         lbz     rWORD1, 0(rSTR1)
141         lbz     rWORD2, 0(rSTR2)
142         nop
143         b       L(u1)
144 L(u0):
145         lbzu    rWORD2, 1(rSTR2)
146 L(u1):
147         bdz     L(u3)
148         cmpdi   cr1, rWORD1, 0
149         cmpd    rWORD1, rWORD2
150         beq-    cr1, L(u3)
151         lbzu    rWORD1, 1(rSTR1)
152         bne-    L(u2)
153         lbzu    rWORD2, 1(rSTR2)
154         bdz     L(u3)
155         cmpdi   cr1, rWORD1, 0
156         cmpd    rWORD1, rWORD2
157         bne-    L(u3)
158         lbzu    rWORD1, 1(rSTR1)
159         bne+    cr1, L(u0)
161 L(u2):  lbzu    rWORD1, -1(rSTR1)       
162 L(u3):  sub     rRTN, rWORD1, rWORD2
163         blr
164 END (BP_SYM (strncmp))
165 libc_hidden_builtin_def (strncmp)