1 /* Copyright (C) 2014-2018 Free Software Foundation, Inc.
2 This file is part of the GNU C Library.
4 The GNU C Library is free software; you can redistribute it and/or
5 modify it under the terms of the GNU Lesser General Public
6 License as published by the Free Software Foundation; either
7 version 2.1 of the License, or (at your option) any later version.
9 The GNU C Library is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 Lesser General Public License for more details.
14 You should have received a copy of the GNU Lesser General Public
15 License along with the GNU C Library. If not, see
16 <http://www.gnu.org/licenses/>. */
18 #ifdef ANDROID_CHANGES
19 # include "machine/asm.h"
20 # include "machine/regdef.h"
25 #elif defined _COMPILING_NEWLIB
26 # include "machine/asm.h"
27 # include "machine/regdef.h"
33 /* Technically strcmp should not read past the end of the strings being
34 compared. We will read a full word that may contain excess bits beyond
35 the NULL string terminator but unless ENABLE_READAHEAD is set, we will not
36 read the next word after the end of string. Setting ENABLE_READAHEAD will
37 improve performance but is technically illegal based on the definition of
39 #ifdef ENABLE_READAHEAD
42 # define DELAY_READ nop
45 /* Testing on a little endian machine showed using CLZ was a
46 performance loss, so we are not turning it on by default. */
47 #if defined(ENABLE_CLZ) && (__mips_isa_rev > 1)
51 /* Some asm.h files do not have the L macro definition. */
53 # if _MIPS_SIM == _ABIO32
54 # define L(label) $L ## label
56 # define L(label) .L ## label
60 /* Some asm.h files do not have the PTR_ADDIU macro definition. */
63 # define PTR_ADDIU daddiu
65 # define PTR_ADDIU addiu
69 /* Allow the routine to be named something else if desired. */
71 # define STRCMP_NAME strcmp
74 #ifdef ANDROID_CHANGES
84 bne t0, zero, L(byteloop)
86 /* Both strings are 4 byte aligned at this point. */
93 #define STRCMP32(OFFSET) \
97 bne v0, v1, L(worddiff); \
100 bne t0, zero, L(returnzero)
133 # if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
139 # if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
150 # if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
152 beq t0, zero, L(wexit01)
154 bne t0, t1, L(wexit01)
159 beq t8, zero, L(wexit89)
161 bne t8, t9, L(wexit89)
166 beq t0, zero, L(wexit01)
168 bne t0, t1, L(wexit01)
172 # else /* __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ */
174 beq t0, zero, L(wexit01)
176 bne t0, t1, L(wexit01)
181 beq t8, zero, L(wexit89)
183 bne t8, t9, L(wexit89)
188 beq t0, zero, L(wexit01)
190 bne t0, t1, L(wexit01)
194 # endif /* __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ */
204 /* It might seem better to do the 'beq' instruction between the two 'lbu'
205 instructions so that the nop is not needed but testing showed that this
206 code is actually faster (based on glibc strcmp test). */
207 #define BYTECMP01(OFFSET) \
208 lbu v0, OFFSET(a0); \
209 lbu v1, OFFSET(a1); \
210 beq v0, zero, L(bexit01); \
212 bne v0, v1, L(bexit01)
214 #define BYTECMP89(OFFSET) \
215 lbu t8, OFFSET(a0); \
216 lbu t9, OFFSET(a1); \
217 beq t8, zero, L(bexit89); \
219 bne t8, t9, L(bexit89)
245 #ifndef ANDROID_CHANGES
247 libc_hidden_builtin_def (STRCMP_NAME)