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 // To avoid warning about deprecated instructions, add an explicit 35 // arch. The code generated is exactly the same. 36 .arch armv7-a 37 38#ifdef __ARMEB__ 39#define SHFT2LSB lsl 40#define SHFT2LSBEQ lsleq 41#define SHFT2MSB lsr 42#define SHFT2MSBEQ lsreq 43#define MSB 0x000000ff 44#define LSB 0xff000000 45#else 46#define SHFT2LSB lsr 47#define SHFT2LSBEQ lsreq 48#define SHFT2MSB lsl 49#define SHFT2MSBEQ lsleq 50#define MSB 0xff000000 51#define LSB 0x000000ff 52#endif 53 54#define magic1(REG) REG 55#define magic2(REG) REG, lsl #7 56 57ENTRY(strcmp_generic) 58 pld [r0, #0] 59 pld [r1, #0] 60 eor r2, r0, r1 61 tst r2, #3 62 63 /* Strings not at same byte offset from a word boundary. */ 64 bne .Lstrcmp_unaligned 65 ands r2, r0, #3 66 bic r0, r0, #3 67 bic r1, r1, #3 68 ldr ip, [r0], #4 69 it eq 70 ldreq r3, [r1], #4 71 beq 1f 72 73 /* Although s1 and s2 have identical initial alignment, they are 74 * not currently word aligned. Rather than comparing bytes, 75 * make sure that any bytes fetched from before the addressed 76 * bytes are forced to 0xff. Then they will always compare 77 * equal. 78 */ 79 eor r2, r2, #3 80 lsl r2, r2, #3 81 mvn r3, #MSB 82 SHFT2LSB r2, r3, r2 83 ldr r3, [r1], #4 84 orr ip, ip, r2 85 orr r3, r3, r2 861: 87 /* Load the 'magic' constant 0x01010101. */ 88 str r4, [sp, #-4]! 89 mov r4, #1 90 orr r4, r4, r4, lsl #8 91 orr r4, r4, r4, lsl #16 92 .p2align 2 934: 94 pld [r0, #8] 95 pld [r1, #8] 96 sub r2, ip, magic1(r4) 97 cmp ip, r3 98 itttt eq 99 100 /* check for any zero bytes in first word */ 101 biceq r2, r2, ip 102 tsteq r2, magic2(r4) 103 ldreq ip, [r0], #4 104 ldreq r3, [r1], #4 105 beq 4b 1062: 107 /* There's a zero or a different byte in the word */ 108 SHFT2MSB r0, ip, #24 109 SHFT2LSB ip, ip, #8 110 cmp r0, #1 111 it cs 112 cmpcs r0, r3, SHFT2MSB #24 113 it eq 114 SHFT2LSBEQ r3, r3, #8 115 beq 2b 116 /* On a big-endian machine, r0 contains the desired byte in bits 117 * 0-7; on a little-endian machine they are in bits 24-31. In 118 * both cases the other bits in r0 are all zero. For r3 the 119 * interesting byte is at the other end of the word, but the 120 * other bits are not necessarily zero. We need a signed result 121 * representing the differnece in the unsigned bytes, so for the 122 * little-endian case we can't just shift the interesting bits up. 123 */ 124#ifdef __ARMEB__ 125 sub r0, r0, r3, lsr #24 126#else 127 and r3, r3, #255 128 /* No RSB instruction in Thumb2 */ 129#ifdef __thumb2__ 130 lsr r0, r0, #24 131 sub r0, r0, r3 132#else 133 rsb r0, r3, r0, lsr #24 134#endif 135#endif 136 ldr r4, [sp], #4 137 bx lr 138 139.Lstrcmp_unaligned: 140 wp1 .req r0 141 wp2 .req r1 142 b1 .req r2 143 w1 .req r4 144 w2 .req r5 145 t1 .req ip 146 @ r3 is scratch 147 148 /* First of all, compare bytes until wp1(sp1) is word-aligned. */ 1491: 150 tst wp1, #3 151 beq 2f 152 ldrb r2, [wp1], #1 153 ldrb r3, [wp2], #1 154 cmp r2, #1 155 it cs 156 cmpcs r2, r3 157 beq 1b 158 sub r0, r2, r3 159 bx lr 160 1612: 162 str r5, [sp, #-4]! 163 str r4, [sp, #-4]! 164 mov b1, #1 165 orr b1, b1, b1, lsl #8 166 orr b1, b1, b1, lsl #16 167 168 and t1, wp2, #3 169 bic wp2, wp2, #3 170 ldr w1, [wp1], #4 171 ldr w2, [wp2], #4 172 cmp t1, #2 173 beq 2f 174 bhi 3f 175 176 /* Critical inner Loop: Block with 3 bytes initial overlap */ 177 .p2align 2 1781: 179 bic t1, w1, #MSB 180 cmp t1, w2, SHFT2LSB #8 181 sub r3, w1, b1 182 bic r3, r3, w1 183 bne 4f 184 ands r3, r3, b1, lsl #7 185 it eq 186 ldreq w2, [wp2], #4 187 bne 5f 188 eor t1, t1, w1 189 cmp t1, w2, SHFT2MSB #24 190 bne 6f 191 ldr w1, [wp1], #4 192 b 1b 1934: 194 SHFT2LSB w2, w2, #8 195 b 8f 196 1975: 198#ifdef __ARMEB__ 199 /* The syndrome value may contain false ones if the string ends 200 * with the bytes 0x01 0x00 201 */ 202 tst w1, #0xff000000 203 itt ne 204 tstne w1, #0x00ff0000 205 tstne w1, #0x0000ff00 206 beq 7f 207#else 208 bics r3, r3, #0xff000000 209 bne 7f 210#endif 211 ldrb w2, [wp2] 212 SHFT2LSB t1, w1, #24 213#ifdef __ARMEB__ 214 lsl w2, w2, #24 215#endif 216 b 8f 217 2186: 219 SHFT2LSB t1, w1, #24 220 and w2, w2, #LSB 221 b 8f 222 223 /* Critical inner Loop: Block with 2 bytes initial overlap */ 224 .p2align 2 2252: 226 SHFT2MSB t1, w1, #16 227 sub r3, w1, b1 228 SHFT2LSB t1, t1, #16 229 bic r3, r3, w1 230 cmp t1, w2, SHFT2LSB #16 231 bne 4f 232 ands r3, r3, b1, lsl #7 233 it eq 234 ldreq w2, [wp2], #4 235 bne 5f 236 eor t1, t1, w1 237 cmp t1, w2, SHFT2MSB #16 238 bne 6f 239 ldr w1, [wp1], #4 240 b 2b 241 2425: 243#ifdef __ARMEB__ 244 /* The syndrome value may contain false ones if the string ends 245 * with the bytes 0x01 0x00 246 */ 247 tst w1, #0xff000000 248 it ne 249 tstne w1, #0x00ff0000 250 beq 7f 251#else 252 lsls r3, r3, #16 253 bne 7f 254#endif 255 ldrh w2, [wp2] 256 SHFT2LSB t1, w1, #16 257#ifdef __ARMEB__ 258 lsl w2, w2, #16 259#endif 260 b 8f 261 2626: 263 SHFT2MSB w2, w2, #16 264 SHFT2LSB t1, w1, #16 2654: 266 SHFT2LSB w2, w2, #16 267 b 8f 268 269 /* Critical inner Loop: Block with 1 byte initial overlap */ 270 .p2align 2 2713: 272 and t1, w1, #LSB 273 cmp t1, w2, SHFT2LSB #24 274 sub r3, w1, b1 275 bic r3, r3, w1 276 bne 4f 277 ands r3, r3, b1, lsl #7 278 it eq 279 ldreq w2, [wp2], #4 280 bne 5f 281 eor t1, t1, w1 282 cmp t1, w2, SHFT2MSB #8 283 bne 6f 284 ldr w1, [wp1], #4 285 b 3b 2864: 287 SHFT2LSB w2, w2, #24 288 b 8f 2895: 290 /* The syndrome value may contain false ones if the string ends 291 * with the bytes 0x01 0x00 292 */ 293 tst w1, #LSB 294 beq 7f 295 ldr w2, [wp2], #4 2966: 297 SHFT2LSB t1, w1, #8 298 bic w2, w2, #MSB 299 b 8f 3007: 301 mov r0, #0 302 ldr r4, [sp], #4 303 ldr r5, [sp], #4 304 bx lr 305 3068: 307 and r2, t1, #LSB 308 and r0, w2, #LSB 309 cmp r0, #1 310 it cs 311 cmpcs r0, r2 312 itt eq 313 SHFT2LSBEQ t1, t1, #8 314 SHFT2LSBEQ w2, w2, #8 315 beq 8b 316 sub r0, r2, r0 317 ldr r4, [sp], #4 318 ldr r5, [sp], #4 319 bx lr 320END(strcmp_generic) 321