Update copyright notices with scripts/update-copyrights
[glibc.git] / sysdeps / powerpc / powerpc32 / strcmp.S
blob09b5cea52f3e827926d609925e11c886766f12bb
1 /* Optimized strcmp implementation for PowerPC.
2    Copyright (C) 1997-2014 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] strcmp (const char *s1 [r3], const char *s2 [r4])  */
25 EALIGN (strcmp, 4, 0)
27 #define rTMP2   r0
28 #define rRTN    r3
29 #define rSTR1   r3      /* first string arg */
30 #define rSTR2   r4      /* second string arg */
31 #define rWORD1  r5      /* current word in s1 */
32 #define rWORD2  r6      /* current word in s2 */
33 #define rFEFE   r7      /* constant 0xfefefeff (-0x01010101) */
34 #define r7F7F   r8      /* constant 0x7f7f7f7f */
35 #define rNEG    r9      /* ~(word in s1 | 0x7f7f7f7f) */
36 #define rBITDIF r10     /* bits that differ in s1 & s2 words */
37 #define rTMP    r11
40         or      rTMP, rSTR2, rSTR1
41         clrlwi. rTMP, rTMP, 30
42         lis     rFEFE, -0x101
43         bne     L(unaligned)
45         lwz     rWORD1, 0(rSTR1)
46         lwz     rWORD2, 0(rSTR2)
47         lis     r7F7F, 0x7f7f
48         addi    rFEFE, rFEFE, -0x101
49         addi    r7F7F, r7F7F, 0x7f7f
50         b       L(g1)
52 L(g0):  lwzu    rWORD1, 4(rSTR1)
53         bne     cr1, L(different)
54         lwzu    rWORD2, 4(rSTR2)
55 L(g1):  add     rTMP, rFEFE, rWORD1
56         nor     rNEG, r7F7F, rWORD1
57         and.    rTMP, rTMP, rNEG
58         cmpw    cr1, rWORD1, rWORD2
59         beq+    L(g0)
61 /* OK. We've hit the end of the string. We need to be careful that
62    we don't compare two strings as different because of gunk beyond
63    the end of the strings...  */
64 #ifdef __LITTLE_ENDIAN__
65 L(endstring):
66         addi    rTMP2, rTMP, -1
67         andc    rTMP2, rTMP2, rTMP
68         rlwimi  rTMP2, rTMP2, 1, 0, 30
69         and     rWORD2, rWORD2, rTMP2           /* Mask off gunk.  */
70         and     rWORD1, rWORD1, rTMP2
71         rlwinm  rTMP2, rWORD2, 8, 0xffffffff    /* Byte reverse word.  */
72         rlwinm  rTMP, rWORD1, 8, 0xffffffff
73         rlwimi  rTMP2, rWORD2, 24, 0, 7
74         rlwimi  rTMP, rWORD1, 24, 0, 7
75         rlwimi  rTMP2, rWORD2, 24, 16, 23
76         rlwimi  rTMP, rWORD1, 24, 16, 23
77         xor.    rBITDIF, rTMP, rTMP2
78         sub     rRTN, rTMP, rTMP2
79         bgelr+
80         ori     rRTN, rTMP2, 1
81         blr
83 L(different):
84         lwz     rWORD1, -4(rSTR1)
85         rlwinm  rTMP2, rWORD2, 8, 0xffffffff    /* Byte reverse word.  */
86         rlwinm  rTMP, rWORD1, 8, 0xffffffff
87         rlwimi  rTMP2, rWORD2, 24, 0, 7
88         rlwimi  rTMP, rWORD1, 24, 0, 7
89         rlwimi  rTMP2, rWORD2, 24, 16, 23
90         rlwimi  rTMP, rWORD1, 24, 16, 23
91         xor.    rBITDIF, rTMP, rTMP2
92         sub     rRTN, rTMP, rTMP2
93         bgelr+
94         ori     rRTN, rTMP2, 1
95         blr
97 #else
98 L(endstring):
99         and     rTMP, r7F7F, rWORD1
100         beq     cr1, L(equal)
101         add     rTMP, rTMP, r7F7F
102         xor.    rBITDIF, rWORD1, rWORD2
103         andc    rNEG, rNEG, rTMP
104         blt-    L(highbit)
105         cntlzw  rBITDIF, rBITDIF
106         cntlzw  rNEG, rNEG
107         addi    rNEG, rNEG, 7
108         cmpw    cr1, rNEG, rBITDIF
109         sub     rRTN, rWORD1, rWORD2
110         bgelr+  cr1
111 L(equal):
112         li      rRTN, 0
113         blr
115 L(different):
116         lwz     rWORD1, -4(rSTR1)
117         xor.    rBITDIF, rWORD1, rWORD2
118         sub     rRTN, rWORD1, rWORD2
119         bgelr+
120 L(highbit):
121         ori     rRTN, rWORD2, 1
122         blr
123 #endif
125 /* Oh well.  In this case, we just do a byte-by-byte comparison.  */
126         .align 4
127 L(unaligned):
128         lbz     rWORD1, 0(rSTR1)
129         lbz     rWORD2, 0(rSTR2)
130         b       L(u1)
132 L(u0):  lbzu    rWORD1, 1(rSTR1)
133         bne-    L(u4)
134         lbzu    rWORD2, 1(rSTR2)
135 L(u1):  cmpwi   cr1, rWORD1, 0
136         beq-    cr1, L(u3)
137         cmpw    rWORD1, rWORD2
138         bne-    L(u3)
139         lbzu    rWORD1, 1(rSTR1)
140         lbzu    rWORD2, 1(rSTR2)
141         cmpwi   cr1, rWORD1, 0
142         cmpw    rWORD1, rWORD2
143         bne+    cr1, L(u0)
144 L(u3):  sub     rRTN, rWORD1, rWORD2
145         blr
146 L(u4):  lbz     rWORD1, -1(rSTR1)
147         sub     rRTN, rWORD1, rWORD2
148         blr
149 END (strcmp)
150 libc_hidden_builtin_def (strcmp)