1/* 2 * Copyright 2004 Sun Microsystems, Inc. All rights reserved. 3 * Use is subject to license terms. 4 */ 5 6/* 7 * Copyright (c) 2002 Advanced Micro Devices, Inc. 8 * 9 * All rights reserved. 10 * 11 * Redistribution and use in source and binary forms, with or 12 * without modification, are permitted provided that the 13 * following conditions are met: 14 * 15 * + Redistributions of source code must retain the above 16 * copyright notice, this list of conditions and the 17 * following disclaimer. 18 * 19 * + Redistributions in binary form must reproduce the above 20 * copyright notice, this list of conditions and the 21 * following disclaimer in the documentation and/or other 22 * materials provided with the distribution. 23 * 24 * + Neither the name of Advanced Micro Devices, Inc. nor the 25 * names of its contributors may be used to endorse or 26 * promote products derived from this software without 27 * specific prior written permission. 28 * 29 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND 30 * CONTRIBUTORS AS IS AND ANY EXPRESS OR IMPLIED WARRANTIES, 31 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 32 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 33 * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, 34 * INC. OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 35 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 36 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE 37 * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 38 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 39 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 40 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT 41 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 42 * POSSIBILITY OF SUCH DAMAGE. 43 * 44 * It is licensee's responsibility to comply with any export 45 * regulations applicable in licensee's jurisdiction. 46 */ 47 48 .file "strcmp.s" 49 50#include "SYS.h" 51#include "cache.h" 52 53#define LABEL(s) .strcmp/**/s 54 55#ifdef USE_AS_STRNCMP 56 ENTRY(strncmp) 57#else 58 ENTRY(strcmp) /* (const char *, const char *) */ 59#endif 60 xor %ecx, %ecx 61 62#ifdef USE_AS_STRNCMP 63 test %rdx, %rdx /* (const char *, const char *, size_t) */ 64 mov %r14, -8 (%rsp) 65 mov %rdx, %r14 66 mov %edx, %eax 67 jz LABEL(exitz) /* early exit */ 68#endif 69 70LABEL(aligntry): 71 mov %rsi, %r8 /* align by "source" */ 72 and $8 - 1, %r8 /* between 0 and 8 characters compared */ 73 jz LABEL(alignafter) 74 75LABEL(align): 76 sub $8, %r8 77 78 .p2align 4 79 80LABEL(alignloop): 81 mov (%rsi, %rcx), %al 82 mov (%rdi, %rcx), %dl 83 84#ifdef USE_AS_STRNCMP 85 dec %r14 86 jl LABEL(exitafter) 87#endif 88 89 cmp %dl, %al /* check if same character */ 90 jne LABEL(exitafter) 91 test %al, %al /* check if character a NUL */ 92 jz LABEL(exitafter) 93 94 inc %ecx 95 96 inc %r8 97 jnz LABEL(alignloop) 98 99 .p2align 4 100 101LABEL(alignafter): 102 103 mov %r15, -32 (%rsp) 104 mov %rbp, -24 (%rsp) 105 mov %rbx, -16 (%rsp) 106 107LABEL(pagealigntry): /* page align by "destination" */ 108 lea (%rdi, %rcx), %ebp 109 mov $AMD64PAGESIZE, %r15d 110 and $AMD64PAGEMASK, %ebp 111 sub %r15d, %ebp 112 113LABEL(64): /* 64-byte */ 114 mov $0xfefefefefefefeff, %rbx /* magic number */ 115 116 .p2align 4 117 118LABEL(64loop): 119 add $64, %ebp /* check if "destination" crosses a page unevenly */ 120 jle LABEL(64gobble) 121 122 sub %r15d, %ebp 123 lea 64 (%rcx), %r8 124 125 .p2align 4 126 127LABEL(64nibble): 128 mov (%rsi, %rcx), %al 129 mov (%rdi, %rcx), %dl 130 131#ifdef USE_AS_STRNCMP 132 dec %r14 133 jl LABEL(exit) 134#endif 135 136 cmp %dl, %al /* check if same character */ 137 jne LABEL(exit) 138 test %al, %al /* check if character a NUL */ 139 jz LABEL(exit) 140 141 inc %ecx 142 143 cmp %ecx, %r8d 144 ja LABEL(64nibble) 145 146 .p2align 4 147 148LABEL(64gobble): 149 mov (%rsi, %rcx), %rax 150 mov (%rdi, %rcx), %rdx 151 152#ifdef USE_AS_STRNCMP 153 sub $8, %r14 154 jl LABEL(tail) 155#endif 156 157 mov %rbx, %r8 158 add %rax, %r8 159 sbb %r10, %r10 160 161 mov %rbx, %r9 162 add %rdx, %r9 163 sbb %r11, %r11 164 165 xor %rax, %r8 166 or %rbx, %r8 167 sub %r10, %r8 168 jnz LABEL(tail) 169 170 xor %rdx, %r9 171 or %rbx, %r9 172 sub %r11, %r9 173 jnz LABEL(tail) 174 175 cmp %rdx, %rax 176 jne LABEL(tail) 177 178 mov 8 (%rsi, %rcx), %rax 179 mov 8 (%rdi, %rcx), %rdx 180 add $8, %ecx 181 182#ifdef USE_AS_STRNCMP 183 sub $8, %r14 184 jl LABEL(tail) 185#endif 186 187 mov %rbx, %r8 188 add %rax, %r8 189 sbb %r10, %r10 190 191 mov %rbx, %r9 192 add %rdx, %r9 193 sbb %r11, %r11 194 195 xor %rax, %r8 196 or %rbx, %r8 197 sub %r10, %r8 198 jnz LABEL(tail) 199 200 xor %rdx, %r9 201 or %rbx, %r9 202 sub %r11, %r9 203 jnz LABEL(tail) 204 205 cmp %rdx, %rax 206 jne LABEL(tail) 207 208 mov 8 (%rsi, %rcx), %rax 209 mov 8 (%rdi, %rcx), %rdx 210 add $8, %ecx 211 212#ifdef USE_AS_STRNCMP 213 sub $8, %r14 214 jl LABEL(tail) 215#endif 216 217 mov %rbx, %r8 218 add %rax, %r8 219 sbb %r10, %r10 220 221 mov %rbx, %r9 222 add %rdx, %r9 223 sbb %r11, %r11 224 225 xor %rax, %r8 226 or %rbx, %r8 227 sub %r10, %r8 228 jnz LABEL(tail) 229 230 xor %rdx, %r9 231 or %rbx, %r9 232 sub %r11, %r9 233 jnz LABEL(tail) 234 235 cmp %rdx, %rax 236 jne LABEL(tail) 237 238 mov 8 (%rsi, %rcx), %rax 239 mov 8 (%rdi, %rcx), %rdx 240 add $8, %ecx 241 242#ifdef USE_AS_STRNCMP 243 sub $8, %r14 244 jl LABEL(tail) 245#endif 246 247 mov %rbx, %r8 248 add %rax, %r8 249 sbb %r10, %r10 250 251 mov %rbx, %r9 252 add %rdx, %r9 253 sbb %r11, %r11 254 255 xor %rax, %r8 256 or %rbx, %r8 257 sub %r10, %r8 258 jnz LABEL(tail) 259 260 xor %rdx, %r9 261 or %rbx, %r9 262 sub %r11, %r9 263 jnz LABEL(tail) 264 265 cmp %rdx, %rax 266 jne LABEL(tail) 267 268 mov 8 (%rsi, %rcx), %rax 269 mov 8 (%rdi, %rcx), %rdx 270 add $8, %ecx 271 272#ifdef USE_AS_STRNCMP 273 sub $8, %r14 274 jl LABEL(tail) 275#endif 276 277 mov %rbx, %r8 278 add %rax, %r8 279 sbb %r10, %r10 280 281 mov %rbx, %r9 282 add %rdx, %r9 283 sbb %r11, %r11 284 285 xor %rax, %r8 286 or %rbx, %r8 287 sub %r10, %r8 288 jnz LABEL(tail) 289 290 xor %rdx, %r9 291 or %rbx, %r9 292 sub %r11, %r9 293 jnz LABEL(tail) 294 295 cmp %rdx, %rax 296 jne LABEL(tail) 297 298 mov 8 (%rsi, %rcx), %rax 299 mov 8 (%rdi, %rcx), %rdx 300 add $8, %ecx 301 302#ifdef USE_AS_STRNCMP 303 sub $8, %r14 304 jl LABEL(tail) 305#endif 306 307 mov %rbx, %r8 308 add %rax, %r8 309 sbb %r10, %r10 310 311 mov %rbx, %r9 312 add %rdx, %r9 313 sbb %r11, %r11 314 315 xor %rax, %r8 316 or %rbx, %r8 317 sub %r10, %r8 318 jnz LABEL(tail) 319 320 xor %rdx, %r9 321 or %rbx, %r9 322 sub %r11, %r9 323 jnz LABEL(tail) 324 325 cmp %rdx, %rax 326 jne LABEL(tail) 327 328 mov 8 (%rsi, %rcx), %rax 329 mov 8 (%rdi, %rcx), %rdx 330 add $8, %ecx 331 332#ifdef USE_AS_STRNCMP 333 sub $8, %r14 334 jl LABEL(tail) 335#endif 336 337 mov %rbx, %r8 338 add %rax, %r8 339 sbb %r10, %r10 340 341 mov %rbx, %r9 342 add %rdx, %r9 343 sbb %r11, %r11 344 345 xor %rax, %r8 346 or %rbx, %r8 347 sub %r10, %r8 348 jnz LABEL(tail) 349 350 xor %rdx, %r9 351 or %rbx, %r9 352 sub %r11, %r9 353 jnz LABEL(tail) 354 355 cmp %rdx, %rax 356 jne LABEL(tail) 357 358 mov 8 (%rsi, %rcx), %rax 359 mov 8 (%rdi, %rcx), %rdx 360 add $8, %ecx 361 362#ifdef USE_AS_STRNCMP 363 sub $8, %r14 364 jl LABEL(tail) 365#endif 366 367 mov %rbx, %r8 368 add %rax, %r8 369 sbb %r10, %r10 370 371 mov %rbx, %r9 372 add %rdx, %r9 373 sbb %r11, %r11 374 375 xor %rax, %r8 376 or %rbx, %r8 377 sub %r10, %r8 378 jnz LABEL(tail) 379 380 xor %rdx, %r9 381 or %rbx, %r9 382 sub %r11, %r9 383 jnz LABEL(tail) 384 385 cmp %rdx, %rax 386 jne LABEL(tail) 387 388 add $8, %ecx 389 390 jmp LABEL(64loop) 391 392LABEL(64after): 393 394LABEL(tailtry): 395 396LABEL(tail): /* byte tail */ 397#ifdef USE_AS_STRNCMP 398 add $7, %r14 399#endif 400 401 cmp %dl, %al /* check if same character */ 402 jne LABEL(exit) 403 test %al, %al /* check if character a NUL */ 404 jz LABEL(exit) 405 406 shr $8, %rax 407 shr $8, %rdx 408 409#ifdef USE_AS_STRNCMP 410 dec %r14 411 jl LABEL(exit) 412#endif 413 414 cmp %dl, %al 415 jne LABEL(exit) 416 test %al, %al 417 jz LABEL(exit) 418 419 shr $8, %rax 420 shr $8, %rdx 421 422#ifdef USE_AS_STRNCMP 423 dec %r14 424 jl LABEL(exit) 425#endif 426 427 cmp %dl, %al 428 jne LABEL(exit) 429 test %al, %al 430 jz LABEL(exit) 431 432 shr $8, %rax 433 shr $8, %rdx 434 435#ifdef USE_AS_STRNCMP 436 dec %r14 437 jl LABEL(exit) 438#endif 439 440 cmp %dl, %al 441 jne LABEL(exit) 442 test %al, %al 443 jz LABEL(exit) 444 445 shr $8, %rax 446 shr $8, %rdx 447 448#ifdef USE_AS_STRNCMP 449 dec %r14 450 jl LABEL(exit) 451#endif 452 453 cmp %dl, %al 454 jne LABEL(exit) 455 test %al, %al 456 jz LABEL(exit) 457 458 shr $8, %eax 459 shr $8, %edx 460 461#ifdef USE_AS_STRNCMP 462 dec %r14 463 jl LABEL(exit) 464#endif 465 466 cmp %dl, %al 467 jne LABEL(exit) 468 test %al, %al 469 jz LABEL(exit) 470 471 shr $8, %eax 472 shr $8, %edx 473 474#ifdef USE_AS_STRNCMP 475 dec %r14 476 jl LABEL(exit) 477#endif 478 479 cmp %dl, %al 480 jne LABEL(exit) 481 test %al, %al 482 jz LABEL(exit) 483 484 shr $8, %eax 485 shr $8, %edx 486 487#ifdef USE_AS_STRNCMP 488 dec %r14 489 jl LABEL(exit) 490#endif 491 492 cmp %dl, %al 493 jne LABEL(exit) 494 495 .p2align 4,, 15 496 497LABEL(tailafter): 498 499LABEL(exit): 500 mov -32 (%rsp), %r15 501 mov -24 (%rsp), %rbp 502 mov -16 (%rsp), %rbx 503 504 .p2align 4,, 3 505 506LABEL(exitafter): 507#ifdef USE_AS_STRNCMP 508 test %r14, %r14 509 cmovl %edx, %eax 510#endif 511 512 movzx %al, %eax 513 movzx %dl, %edx 514 sub %eax, %edx 515 xchg %edx, %eax 516 517#ifdef USE_AS_STRNCMP 518LABEL(exitz): 519 mov -8 (%rsp), %r14 520#endif 521 ret 522 523#ifdef USE_AS_STRNCMP 524 SET_SIZE(strncmp) 525#else 526 SET_SIZE(strcmp) /* (const char *, const char *) */ 527#endif 528