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 <machine/cpu-features.h> 31 32 .text 33 34 .global strcmp 35 .type strcmp, %function 36 .align 4 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 57strcmp: 58 .fnstart 59 PLD(r0, #0) 60 PLD(r1, #0) 61 eor r2, r0, r1 62 tst r2, #3 63 64 /* Strings not at same byte offset from a word boundary. */ 65 bne .Lstrcmp_unaligned 66 ands r2, r0, #3 67 bic r0, r0, #3 68 bic r1, r1, #3 69 ldr ip, [r0], #4 70 it eq 71 ldreq r3, [r1], #4 72 beq 1f 73 74 /* Although s1 and s2 have identical initial alignment, they are 75 * not currently word aligned. Rather than comparing bytes, 76 * make sure that any bytes fetched from before the addressed 77 * bytes are forced to 0xff. Then they will always compare 78 * equal. 79 */ 80 eor r2, r2, #3 81 lsl r2, r2, #3 82 mvn r3, #MSB 83 SHFT2LSB r2, r3, r2 84 ldr r3, [r1], #4 85 orr ip, ip, r2 86 orr r3, r3, r2 871: 88 /* Load the 'magic' constant 0x01010101. */ 89 str r4, [sp, #-4]! 90 mov r4, #1 91 orr r4, r4, r4, lsl #8 92 orr r4, r4, r4, lsl #16 93 .p2align 2 944: 95 PLD(r0, #8) 96 PLD(r1, #8) 97 sub r2, ip, magic1(r4) 98 cmp ip, r3 99 itttt eq 100 101 /* check for any zero bytes in first word */ 102 biceq r2, r2, ip 103 tsteq r2, magic2(r4) 104 ldreq ip, [r0], #4 105 ldreq r3, [r1], #4 106 beq 4b 1072: 108 /* There's a zero or a different byte in the word */ 109 SHFT2MSB r0, ip, #24 110 SHFT2LSB ip, ip, #8 111 cmp r0, #1 112 it cs 113 cmpcs r0, r3, SHFT2MSB #24 114 it eq 115 SHFT2LSBEQ r3, r3, #8 116 beq 2b 117 /* On a big-endian machine, r0 contains the desired byte in bits 118 * 0-7; on a little-endian machine they are in bits 24-31. In 119 * both cases the other bits in r0 are all zero. For r3 the 120 * interesting byte is at the other end of the word, but the 121 * other bits are not necessarily zero. We need a signed result 122 * representing the differnece in the unsigned bytes, so for the 123 * little-endian case we can't just shift the interesting bits up. 124 */ 125#ifdef __ARMEB__ 126 sub r0, r0, r3, lsr #24 127#else 128 and r3, r3, #255 129 /* No RSB instruction in Thumb2 */ 130#ifdef __thumb2__ 131 lsr r0, r0, #24 132 sub r0, r0, r3 133#else 134 rsb r0, r3, r0, lsr #24 135#endif 136#endif 137 ldr r4, [sp], #4 138 bx lr 139 .fnend 140 141.Lstrcmp_unaligned: 142 wp1 .req r0 143 wp2 .req r1 144 b1 .req r2 145 w1 .req r4 146 w2 .req r5 147 t1 .req ip 148 @ r3 is scratch 149 150 /* First of all, compare bytes until wp1(sp1) is word-aligned. */ 1511: 152 tst wp1, #3 153 beq 2f 154 ldrb r2, [wp1], #1 155 ldrb r3, [wp2], #1 156 cmp r2, #1 157 it cs 158 cmpcs r2, r3 159 beq 1b 160 sub r0, r2, r3 161 bx lr 162 1632: 164 str r5, [sp, #-4]! 165 str r4, [sp, #-4]! 166 mov b1, #1 167 orr b1, b1, b1, lsl #8 168 orr b1, b1, b1, lsl #16 169 170 and t1, wp2, #3 171 bic wp2, wp2, #3 172 ldr w1, [wp1], #4 173 ldr w2, [wp2], #4 174 cmp t1, #2 175 beq 2f 176 bhi 3f 177 178 /* Critical inner Loop: Block with 3 bytes initial overlap */ 179 .p2align 2 1801: 181 bic t1, w1, #MSB 182 cmp t1, w2, SHFT2LSB #8 183 sub r3, w1, b1 184 bic r3, r3, w1 185 bne 4f 186 ands r3, r3, b1, lsl #7 187 it eq 188 ldreq w2, [wp2], #4 189 bne 5f 190 eor t1, t1, w1 191 cmp t1, w2, SHFT2MSB #24 192 bne 6f 193 ldr w1, [wp1], #4 194 b 1b 1954: 196 SHFT2LSB w2, w2, #8 197 b 8f 198 1995: 200#ifdef __ARMEB__ 201 /* The syndrome value may contain false ones if the string ends 202 * with the bytes 0x01 0x00 203 */ 204 tst w1, #0xff000000 205 itt ne 206 tstne w1, #0x00ff0000 207 tstne w1, #0x0000ff00 208 beq 7f 209#else 210 bics r3, r3, #0xff000000 211 bne 7f 212#endif 213 ldrb w2, [wp2] 214 SHFT2LSB t1, w1, #24 215#ifdef __ARMEB__ 216 lsl w2, w2, #24 217#endif 218 b 8f 219 2206: 221 SHFT2LSB t1, w1, #24 222 and w2, w2, #LSB 223 b 8f 224 225 /* Critical inner Loop: Block with 2 bytes initial overlap */ 226 .p2align 2 2272: 228 SHFT2MSB t1, w1, #16 229 sub r3, w1, b1 230 SHFT2LSB t1, t1, #16 231 bic r3, r3, w1 232 cmp t1, w2, SHFT2LSB #16 233 bne 4f 234 ands r3, r3, b1, lsl #7 235 it eq 236 ldreq w2, [wp2], #4 237 bne 5f 238 eor t1, t1, w1 239 cmp t1, w2, SHFT2MSB #16 240 bne 6f 241 ldr w1, [wp1], #4 242 b 2b 243 2445: 245#ifdef __ARMEB__ 246 /* The syndrome value may contain false ones if the string ends 247 * with the bytes 0x01 0x00 248 */ 249 tst w1, #0xff000000 250 it ne 251 tstne w1, #0x00ff0000 252 beq 7f 253#else 254 lsls r3, r3, #16 255 bne 7f 256#endif 257 ldrh w2, [wp2] 258 SHFT2LSB t1, w1, #16 259#ifdef __ARMEB__ 260 lsl w2, w2, #16 261#endif 262 b 8f 263 2646: 265 SHFT2MSB w2, w2, #16 266 SHFT2LSB t1, w1, #16 2674: 268 SHFT2LSB w2, w2, #16 269 b 8f 270 271 /* Critical inner Loop: Block with 1 byte initial overlap */ 272 .p2align 2 2733: 274 and t1, w1, #LSB 275 cmp t1, w2, SHFT2LSB #24 276 sub r3, w1, b1 277 bic r3, r3, w1 278 bne 4f 279 ands r3, r3, b1, lsl #7 280 it eq 281 ldreq w2, [wp2], #4 282 bne 5f 283 eor t1, t1, w1 284 cmp t1, w2, SHFT2MSB #8 285 bne 6f 286 ldr w1, [wp1], #4 287 b 3b 2884: 289 SHFT2LSB w2, w2, #24 290 b 8f 2915: 292 /* The syndrome value may contain false ones if the string ends 293 * with the bytes 0x01 0x00 294 */ 295 tst w1, #LSB 296 beq 7f 297 ldr w2, [wp2], #4 2986: 299 SHFT2LSB t1, w1, #8 300 bic w2, w2, #MSB 301 b 8f 3027: 303 mov r0, #0 304 ldr r4, [sp], #4 305 ldr r5, [sp], #4 306 bx lr 307 3088: 309 and r2, t1, #LSB 310 and r0, w2, #LSB 311 cmp r0, #1 312 it cs 313 cmpcs r0, r2 314 itt eq 315 SHFT2LSBEQ t1, t1, #8 316 SHFT2LSBEQ w2, w2, #8 317 beq 8b 318 sub r0, r2, r0 319 ldr r4, [sp], #4 320 ldr r5, [sp], #4 321 bx lr 322