Home | History | Annotate | Download | only in bionic
      1 /*
      2  * Copyright (c) 2011 The Android Open Source Project
      3  * Copyright (c) 2008 ARM Ltd
      4  * All rights reserved.
      5  *
      6  * Redistribution and use in source and binary forms, with or without
      7  * modification, are permitted provided that the following conditions
      8  * are met:
      9  * 1. Redistributions of source code must retain the above copyright
     10  *    notice, this list of conditions and the following disclaimer.
     11  * 2. Redistributions in binary form must reproduce the above copyright
     12  *    notice, this list of conditions and the following disclaimer in the
     13  *    documentation and/or other materials provided with the distribution.
     14  * 3. The name of the company may not be used to endorse or promote
     15  *    products derived from this software without specific prior written
     16  *    permission.
     17  *
     18  * THIS SOFTWARE IS PROVIDED BY ARM LTD ``AS IS'' AND ANY EXPRESS OR IMPLIED
     19  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
     20  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
     21  * IN NO EVENT SHALL ARM LTD BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
     22  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
     23  * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
     24  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
     25  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
     26  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
     27  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     28  */
     29 
     30 #include <private/bionic_asm.h>
     31 
     32 	.text
     33 
     34 #ifdef __ARMEB__
     35 #define SHFT2LSB lsl
     36 #define SHFT2LSBEQ lsleq
     37 #define SHFT2MSB lsr
     38 #define SHFT2MSBEQ lsreq
     39 #define MSB 0x000000ff
     40 #define LSB 0xff000000
     41 #else
     42 #define SHFT2LSB lsr
     43 #define SHFT2LSBEQ lsreq
     44 #define SHFT2MSB lsl
     45 #define SHFT2MSBEQ lsleq
     46 #define MSB 0xff000000
     47 #define LSB 0x000000ff
     48 #endif
     49 
     50 #define magic1(REG) REG
     51 #define magic2(REG) REG, lsl #7
     52 
     53 ENTRY(strcmp)
     54 	pld	[r0, #0]
     55 	pld	[r1, #0]
     56 	eor	r2, r0, r1
     57 	tst	r2, #3
     58 
     59 	/* Strings not at same byte offset from a word boundary.  */
     60 	bne	.Lstrcmp_unaligned
     61 	ands	r2, r0, #3
     62 	bic	r0, r0, #3
     63 	bic	r1, r1, #3
     64 	ldr	ip, [r0], #4
     65 	it	eq
     66 	ldreq	r3, [r1], #4
     67 	beq	1f
     68 
     69 	/* Although s1 and s2 have identical initial alignment, they are
     70 	 * not currently word aligned.  Rather than comparing bytes,
     71 	 * make sure that any bytes fetched from before the addressed
     72 	 * bytes are forced to 0xff.  Then they will always compare
     73 	 * equal.
     74 	 */
     75 	eor	r2, r2, #3
     76 	lsl	r2, r2, #3
     77 	mvn	r3, #MSB
     78 	SHFT2LSB	r2, r3, r2
     79 	ldr	r3, [r1], #4
     80 	orr	ip, ip, r2
     81 	orr	r3, r3, r2
     82 1:
     83 	/* Load the 'magic' constant 0x01010101. */
     84 	str	r4, [sp, #-4]!
     85 	mov	r4, #1
     86 	orr	r4, r4, r4, lsl #8
     87 	orr	r4, r4, r4, lsl #16
     88 	.p2align	2
     89 4:
     90 	pld	[r0, #8]
     91 	pld	[r1, #8]
     92 	sub	r2, ip, magic1(r4)
     93 	cmp	ip, r3
     94 	itttt	eq
     95 
     96 	/* check for any zero bytes in first word */
     97 	biceq	r2, r2, ip
     98 	tsteq	r2, magic2(r4)
     99 	ldreq	ip, [r0], #4
    100 	ldreq	r3, [r1], #4
    101 	beq	4b
    102 2:
    103 	/* There's a zero or a different byte in the word */
    104 	SHFT2MSB	r0, ip, #24
    105 	SHFT2LSB	ip, ip, #8
    106 	cmp	r0, #1
    107 	it	cs
    108 	cmpcs	r0, r3, SHFT2MSB #24
    109 	it	eq
    110 	SHFT2LSBEQ r3, r3, #8
    111 	beq	2b
    112 	/* On a big-endian machine, r0 contains the desired byte in bits
    113 	 * 0-7; on a little-endian machine they are in bits 24-31.  In
    114 	 * both cases the other bits in r0 are all zero.  For r3 the
    115 	 * interesting byte is at the other end of the word, but the
    116 	 * other bits are not necessarily zero.  We need a signed result
    117 	 * representing the differnece in the unsigned bytes, so for the
    118 	 * little-endian case we can't just shift the interesting bits up.
    119 	 */
    120 #ifdef __ARMEB__
    121 	sub	r0, r0, r3, lsr #24
    122 #else
    123 	and	r3, r3, #255
    124 	/* No RSB instruction in Thumb2 */
    125 #ifdef __thumb2__
    126 	lsr	r0, r0, #24
    127 	sub	r0, r0, r3
    128 #else
    129 	rsb	r0, r3, r0, lsr #24
    130 #endif
    131 #endif
    132 	ldr	r4, [sp], #4
    133 	bx	lr
    134 
    135 .Lstrcmp_unaligned:
    136 	wp1 .req r0
    137 	wp2 .req r1
    138 	b1  .req r2
    139 	w1  .req r4
    140 	w2  .req r5
    141 	t1  .req ip
    142 	@ r3 is scratch
    143 
    144 	/* First of all, compare bytes until wp1(sp1) is word-aligned. */
    145 1:
    146 	tst	wp1, #3
    147 	beq	2f
    148 	ldrb	r2, [wp1], #1
    149 	ldrb	r3, [wp2], #1
    150 	cmp	r2, #1
    151 	it	cs
    152 	cmpcs	r2, r3
    153 	beq	1b
    154 	sub	r0, r2, r3
    155 	bx	lr
    156 
    157 2:
    158 	str	r5, [sp, #-4]!
    159 	str	r4, [sp, #-4]!
    160 	mov	b1, #1
    161 	orr	b1, b1, b1, lsl #8
    162 	orr	b1, b1, b1, lsl #16
    163 
    164 	and	t1, wp2, #3
    165 	bic	wp2, wp2, #3
    166 	ldr	w1, [wp1], #4
    167 	ldr	w2, [wp2], #4
    168 	cmp	t1, #2
    169 	beq	2f
    170 	bhi	3f
    171 
    172 	/* Critical inner Loop: Block with 3 bytes initial overlap */
    173 	.p2align	2
    174 1:
    175 	bic	t1, w1, #MSB
    176 	cmp	t1, w2, SHFT2LSB #8
    177 	sub	r3, w1, b1
    178 	bic	r3, r3, w1
    179 	bne	4f
    180 	ands	r3, r3, b1, lsl #7
    181 	it	eq
    182 	ldreq	w2, [wp2], #4
    183 	bne	5f
    184 	eor	t1, t1, w1
    185 	cmp	t1, w2, SHFT2MSB #24
    186 	bne	6f
    187 	ldr	w1, [wp1], #4
    188 	b	1b
    189 4:
    190 	SHFT2LSB	w2, w2, #8
    191 	b	8f
    192 
    193 5:
    194 #ifdef __ARMEB__
    195 	/* The syndrome value may contain false ones if the string ends
    196 	 * with the bytes 0x01 0x00
    197 	 */
    198 	tst	w1, #0xff000000
    199 	itt	ne
    200 	tstne	w1, #0x00ff0000
    201 	tstne	w1, #0x0000ff00
    202 	beq	7f
    203 #else
    204 	bics	r3, r3, #0xff000000
    205 	bne	7f
    206 #endif
    207 	ldrb	w2, [wp2]
    208 	SHFT2LSB	t1, w1, #24
    209 #ifdef __ARMEB__
    210 	lsl	w2, w2, #24
    211 #endif
    212 	b	8f
    213 
    214 6:
    215 	SHFT2LSB	t1, w1, #24
    216 	and	w2, w2, #LSB
    217 	b	8f
    218 
    219 	/* Critical inner Loop: Block with 2 bytes initial overlap */
    220 	.p2align	2
    221 2:
    222 	SHFT2MSB	t1, w1, #16
    223 	sub	r3, w1, b1
    224 	SHFT2LSB	t1, t1, #16
    225 	bic	r3, r3, w1
    226 	cmp	t1, w2, SHFT2LSB #16
    227 	bne	4f
    228 	ands	r3, r3, b1, lsl #7
    229 	it	eq
    230 	ldreq	w2, [wp2], #4
    231 	bne	5f
    232 	eor	t1, t1, w1
    233 	cmp	t1, w2, SHFT2MSB #16
    234 	bne	6f
    235 	ldr	w1, [wp1], #4
    236 	b	2b
    237 
    238 5:
    239 #ifdef __ARMEB__
    240 	/* The syndrome value may contain false ones if the string ends
    241 	 * with the bytes 0x01 0x00
    242 	 */
    243 	tst	w1, #0xff000000
    244 	it	ne
    245 	tstne	w1, #0x00ff0000
    246 	beq	7f
    247 #else
    248 	lsls	r3, r3, #16
    249 	bne	7f
    250 #endif
    251 	ldrh	w2, [wp2]
    252 	SHFT2LSB	t1, w1, #16
    253 #ifdef __ARMEB__
    254 	lsl	w2, w2, #16
    255 #endif
    256 	b	8f
    257 
    258 6:
    259 	SHFT2MSB	w2, w2, #16
    260 	SHFT2LSB	t1, w1, #16
    261 4:
    262 	SHFT2LSB	w2, w2, #16
    263 	b	8f
    264 
    265 	/* Critical inner Loop: Block with 1 byte initial overlap */
    266 	.p2align	2
    267 3:
    268 	and	t1, w1, #LSB
    269 	cmp	t1, w2, SHFT2LSB #24
    270 	sub	r3, w1, b1
    271 	bic	r3, r3, w1
    272 	bne	4f
    273 	ands	r3, r3, b1, lsl #7
    274 	it	eq
    275 	ldreq	w2, [wp2], #4
    276 	bne	5f
    277 	eor	t1, t1, w1
    278 	cmp	t1, w2, SHFT2MSB #8
    279 	bne	6f
    280 	ldr	w1, [wp1], #4
    281 	b	3b
    282 4:
    283 	SHFT2LSB	w2, w2, #24
    284 	b	8f
    285 5:
    286 	/* The syndrome value may contain false ones if the string ends
    287 	 * with the bytes 0x01 0x00
    288 	 */
    289 	tst	w1, #LSB
    290 	beq	7f
    291 	ldr	w2, [wp2], #4
    292 6:
    293 	SHFT2LSB	t1, w1, #8
    294 	bic	w2, w2, #MSB
    295 	b	8f
    296 7:
    297 	mov	r0, #0
    298 	ldr	r4, [sp], #4
    299 	ldr	r5, [sp], #4
    300 	bx	lr
    301 
    302 8:
    303 	and	r2, t1, #LSB
    304 	and	r0, w2, #LSB
    305 	cmp	r0, #1
    306 	it	cs
    307 	cmpcs	r0, r2
    308 	itt	eq
    309 	SHFT2LSBEQ	t1, t1, #8
    310 	SHFT2LSBEQ	w2, w2, #8
    311 	beq	8b
    312 	sub	r0, r2, r0
    313 	ldr	r4, [sp], #4
    314 	ldr	r5, [sp], #4
    315 	bx	lr
    316 END(strcmp)
    317