powerpc: POWER7 optimizations
[glibc.git] / sysdeps / powerpc / powerpc32 / power7 / strncmp.S
blobba72d0a029e89a925967bd1c20951c2d6cb5ba9d
1 /* Optimized strcmp implementation for POWER7/PowerPC32.
2    Copyright (C) 2010 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., 51 Franklin Street, Fifth Floor, Boston MA
18    02110-1301 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],
27                      const char *s2 [r4],
28                      size_t size [r5])  */
30 EALIGN (BP_SYM(strncmp),4,0)
32 #define rTMP    r0
33 #define rRTN    r3
34 #define rSTR1   r3      /* first string arg */
35 #define rSTR2   r4      /* second string arg */
36 #define rN      r5      /* max string length */
37 /* Note:  The Bounded pointer support in this code is broken.  This code
38    was inherited from PPC32 and and that support was never completed.
39    Current PPC gcc does not support -fbounds-check or -fbounded-pointers.  */
40 #define rWORD1  r6      /* current word in s1 */
41 #define rWORD2  r7      /* current word in s2 */
42 #define rWORD3  r10
43 #define rWORD4  r11
44 #define rFEFE   r8      /* constant 0xfefefeff (-0x01010101) */
45 #define r7F7F   r9      /* constant 0x7f7f7f7f */
46 #define rNEG    r10     /* ~(word in s1 | 0x7f7f7f7f) */
47 #define rBITDIF r11     /* bits that differ in s1 & s2 words */
49         dcbt    0,rSTR1
50         or      rTMP,rSTR2,rSTR1
51         lis     r7F7F,0x7f7f
52         dcbt    0,rSTR2
53         clrlwi. rTMP,rTMP,30
54         cmplwi  cr1,rN,0
55         lis     rFEFE,-0x101
56         bne     L(unaligned)
57 /* We are word alligned so set up for two loops.  first a word
58    loop, then fall into the byte loop if any residual.  */
59         srwi.   rTMP,rN,2
60         clrlwi  rN,rN,30
61         addi    rFEFE,rFEFE,-0x101
62         addi    r7F7F,r7F7F,0x7f7f
63         cmplwi  cr1,rN,0
64         beq     L(unaligned)
66         mtctr   rTMP
67         lwz     rWORD1,0(rSTR1)
68         lwz     rWORD2,0(rSTR2)
69         b       L(g1)
71 L(g0):
72         lwzu    rWORD1,4(rSTR1)
73         bne     cr1,L(different)
74         lwzu    rWORD2,4(rSTR2)
75 L(g1):  add     rTMP,rFEFE,rWORD1
76         nor     rNEG,r7F7F,rWORD1
77         bdz     L(tail)
78         and.    rTMP,rTMP,rNEG
79         cmpw    cr1,rWORD1,rWORD2
80         beq     L(g0)
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...  */
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         cntlzw  rBITDIF,rBITDIF
95         cntlzw  rNEG,rNEG
96         addi    rNEG,rNEG,7
97         cmpw    cr1,rNEG,rBITDIF
98         sub     rRTN,rWORD1,rWORD2
99         blt     cr1,L(equal)
100         srawi   rRTN,rRTN,31
101         ori     rRTN,rRTN,1
102         blr
103 L(equal):
104         li      rRTN,0
105         blr
107 L(different):
108         lwzu    rWORD1,-4(rSTR1)
109         xor.    rBITDIF,rWORD1,rWORD2
110         sub     rRTN,rWORD1,rWORD2
111         blt     L(highbit)
112         srawi   rRTN,rRTN,31
113         ori     rRTN,rRTN,1
114         blr
115 L(highbit):
116         srwi    rWORD2,rWORD2,24
117         srwi    rWORD1,rWORD1,24
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         cmpw    cr1,rWORD1,rWORD2
127         bne     L(endstring)
128         addi    rSTR1,rSTR1,4
129         bne     cr1,L(different)
130         addi    rSTR2,rSTR2,4
131         cmplwi  cr1,rN,0
132 L(unaligned):
133         mtctr   rN
134         ble     cr1,L(ux)
135 L(uz):
136         lbz     rWORD1,0(rSTR1)
137         lbz     rWORD2,0(rSTR2)
138         .align  4
139 L(u1):
140         cmpwi   cr1,rWORD1,0
141         bdz     L(u4)
142         cmpw    rWORD1,rWORD2
143         beq     cr1,L(u4)
144         lbzu    rWORD3,1(rSTR1)
145         lbzu    rWORD4,1(rSTR2)
146         bne     L(u4)
147         cmpwi   cr1,rWORD3,0
148         bdz     L(u3)
149         cmpw    rWORD3,rWORD4
150         beq     cr1,L(u3)
151         lbzu    rWORD1,1(rSTR1)
152         lbzu    rWORD2,1(rSTR2)
153         bne     L(u3)
154         cmpwi   cr1,rWORD1,0
155         bdz     L(u4)
156         cmpw    rWORD1,rWORD2
157         beq     cr1,L(u4)
158         lbzu    rWORD3,1(rSTR1)
159         lbzu    rWORD4,1(rSTR2)
160         bne     L(u4)
161         cmpwi   cr1,rWORD3,0
162         bdz     L(u3)
163         cmpw    rWORD3,rWORD4
164         beq     cr1,L(u3)
165         lbzu    rWORD1,1(rSTR1)
166         lbzu    rWORD2,1(rSTR2)
167         beq     L(u1)
169 L(u3):  sub     rRTN,rWORD3,rWORD4
170         blr
171 L(u4):  sub     rRTN,rWORD1,rWORD2
172         blr
173 L(ux):
174         li      rRTN,0
175         blr
176 END (BP_SYM (strncmp))
177 libc_hidden_builtin_def (strncmp)