Use libc_hidden_* for fputs (bug 15105).
[glibc.git] / sysdeps / powerpc / powerpc64 / strcmp.S
blob1862a2e5cef878984cabfe79cee52b8ea7f581cc
1 /* Optimized strcmp implementation for PowerPC64.
2    Copyright (C) 1997-2018 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 #ifndef STRCMP
26 # define STRCMP strcmp
27 #endif
29 ENTRY_TOCLESS (STRCMP, 4)
30         CALL_MCOUNT 2
32 #define rTMP2   r0
33 #define rRTN    r3
34 #define rSTR1   r3      /* first string arg */
35 #define rSTR2   r4      /* second string arg */
36 #define rWORD1  r5      /* current word in s1 */
37 #define rWORD2  r6      /* current word in s2 */
38 #define rFEFE   r7      /* constant 0xfefefefefefefeff (-0x0101010101010101) */
39 #define r7F7F   r8      /* constant 0x7f7f7f7f7f7f7f7f */
40 #define rNEG    r9      /* ~(word in s1 | 0x7f7f7f7f7f7f7f7f) */
41 #define rBITDIF r10     /* bits that differ in s1 & s2 words */
42 #define rTMP    r11
44         dcbt    0,rSTR1
45         or      rTMP, rSTR2, rSTR1
46         dcbt    0,rSTR2
47         clrldi. rTMP, rTMP, 61
48         lis     rFEFE, -0x101
49         bne     L(unaligned)
51         ld      rWORD1, 0(rSTR1)
52         ld      rWORD2, 0(rSTR2)
53         lis     r7F7F, 0x7f7f
54         addi    rFEFE, rFEFE, -0x101
55         addi    r7F7F, r7F7F, 0x7f7f
56         sldi    rTMP, rFEFE, 32
57         insrdi  r7F7F, r7F7F, 32, 0
58         add     rFEFE, rFEFE, rTMP
59         b       L(g1)
61 L(g0):  ldu     rWORD1, 8(rSTR1)
62         bne     cr1, L(different)
63         ldu     rWORD2, 8(rSTR2)
64 L(g1):  add     rTMP, rFEFE, rWORD1
65         nor     rNEG, r7F7F, rWORD1
66         and.    rTMP, rTMP, rNEG
67         cmpd    cr1, rWORD1, rWORD2
68         beq+    L(g0)
70 /* OK. We've hit the end of the string. We need to be careful that
71    we don't compare two strings as different because of gunk beyond
72    the end of the strings...  */
73 #ifdef __LITTLE_ENDIAN__
74 L(endstring):
75         addi    rTMP2, rTMP, -1
76         beq     cr1, L(equal)
77         andc    rTMP2, rTMP2, rTMP
78         rldimi  rTMP2, rTMP2, 1, 0
79         and     rWORD2, rWORD2, rTMP2   /* Mask off gunk.  */
80         and     rWORD1, rWORD1, rTMP2
81         cmpd    cr1, rWORD1, rWORD2
82         beq     cr1, L(equal)
83         xor     rBITDIF, rWORD1, rWORD2 /* rBITDIF has bits that differ.  */
84         neg     rNEG, rBITDIF
85         and     rNEG, rNEG, rBITDIF     /* rNEG has LS bit that differs.  */
86         cntlzd  rNEG, rNEG              /* bitcount of the bit.  */
87         andi.   rNEG, rNEG, 56          /* bitcount to LS byte that differs. */
88         sld     rWORD1, rWORD1, rNEG    /* shift left to clear MS bytes.  */
89         sld     rWORD2, rWORD2, rNEG
90         xor.    rBITDIF, rWORD1, rWORD2
91         sub     rRTN, rWORD1, rWORD2
92         blt-    L(highbit)
93         sradi   rRTN, rRTN, 63          /* must return an int.  */
94         ori     rRTN, rRTN, 1
95         blr
96 L(equal):
97         li      rRTN, 0
98         blr
100 L(different):
101         ld      rWORD1, -8(rSTR1)
102         xor     rBITDIF, rWORD1, rWORD2 /* rBITDIF has bits that differ.  */
103         neg     rNEG, rBITDIF
104         and     rNEG, rNEG, rBITDIF     /* rNEG has LS bit that differs.  */
105         cntlzd  rNEG, rNEG              /* bitcount of the bit.  */
106         andi.   rNEG, rNEG, 56          /* bitcount to LS byte that differs. */
107         sld     rWORD1, rWORD1, rNEG    /* shift left to clear MS bytes.  */
108         sld     rWORD2, rWORD2, rNEG
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         sradi   rRTN, rWORD2, 63
117         ori     rRTN, rRTN, 1
118         blr
120 #else
121 L(endstring):
122         and     rTMP, r7F7F, rWORD1
123         beq     cr1, L(equal)
124         add     rTMP, rTMP, r7F7F
125         xor.    rBITDIF, rWORD1, rWORD2
126         andc    rNEG, rNEG, rTMP
127         blt-    L(highbit)
128         cntlzd  rBITDIF, rBITDIF
129         cntlzd  rNEG, rNEG
130         addi    rNEG, rNEG, 7
131         cmpd    cr1, rNEG, rBITDIF
132         sub     rRTN, rWORD1, rWORD2
133         blt-    cr1, L(equal)
134         sradi   rRTN, rRTN, 63          /* must return an int.  */
135         ori     rRTN, rRTN, 1
136         blr
137 L(equal):
138         li      rRTN, 0
139         blr
141 L(different):
142         ld      rWORD1, -8(rSTR1)
143         xor.    rBITDIF, rWORD1, rWORD2
144         sub     rRTN, rWORD1, rWORD2
145         blt-    L(highbit)
146         sradi   rRTN, rRTN, 63
147         ori     rRTN, rRTN, 1
148         blr
149 L(highbit):
150         sradi   rRTN, rWORD2, 63
151         ori     rRTN, rRTN, 1
152         blr
153 #endif
155 /* Oh well.  In this case, we just do a byte-by-byte comparison.  */
156         .align 4
157 L(unaligned):
158         lbz     rWORD1, 0(rSTR1)
159         lbz     rWORD2, 0(rSTR2)
160         b       L(u1)
162 L(u0):  lbzu    rWORD1, 1(rSTR1)
163         bne-    L(u4)
164         lbzu    rWORD2, 1(rSTR2)
165 L(u1):  cmpwi   cr1, rWORD1, 0
166         beq-    cr1, L(u3)
167         cmpd    rWORD1, rWORD2
168         bne-    L(u3)
169         lbzu    rWORD1, 1(rSTR1)
170         lbzu    rWORD2, 1(rSTR2)
171         cmpdi   cr1, rWORD1, 0
172         cmpd    rWORD1, rWORD2
173         bne+    cr1, L(u0)
174 L(u3):  sub     rRTN, rWORD1, rWORD2
175         blr
176 L(u4):  lbz     rWORD1, -1(rSTR1)
177         sub     rRTN, rWORD1, rWORD2
178         blr
179 END (STRCMP)
180 libc_hidden_builtin_def (strcmp)