1/* 2 * Copyright 2008 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#ifdef USE_AS_STRNCMP 100 test %r14, %r14 101 jz LABEL(exitafter) 102#endif 103 104 .p2align 4 105 106LABEL(alignafter): 107 108 mov %r15, -32 (%rsp) 109 mov %rbp, -24 (%rsp) 110 mov %rbx, -16 (%rsp) 111 112LABEL(pagealigntry): /* page align by "destination" */ 113 lea (%rdi, %rcx), %ebp 114 mov $AMD64PAGESIZE, %r15d 115 and $AMD64PAGEMASK, %ebp 116 sub %r15d, %ebp 117 /* 118 * When we go to 64gobble, %ebp was adjusted at the top of 64loop. 119 * When we go to 64nibble(crossing page boundary), we'll compare 120 * 128 byte since we'll fall through to 64gobble. Therefore, %ebp 121 * needs to be re-adjusted(add 64) when we fall into 64nibble. 122 * It can be done by adjusting %r15 since %r15 is only used to 123 * rewind %ebp when crossing page boundary. 124 */ 125 sub $64, %r15d 126 127LABEL(64): /* 64-byte */ 128 mov $0xfefefefefefefeff, %rbx /* magic number */ 129 130 .p2align 4 131 132LABEL(64loop): 133 add $64, %ebp /* check if "destination" crosses a page unevenly */ 134 jle LABEL(64gobble) 135 136 sub %r15d, %ebp 137 lea 64 (%rcx), %r8 138 139 .p2align 4 140 141LABEL(64nibble): 142 mov (%rsi, %rcx), %al 143 mov (%rdi, %rcx), %dl 144 145#ifdef USE_AS_STRNCMP 146 dec %r14 147 jle LABEL(exit) 148#endif 149 150 cmp %dl, %al /* check if same character */ 151 jne LABEL(exit) 152 test %al, %al /* check if character a NUL */ 153 jz LABEL(exit) 154 155 inc %ecx 156 157 cmp %ecx, %r8d 158 ja LABEL(64nibble) 159 160 .p2align 4 161 162LABEL(64gobble): 163 mov (%rsi, %rcx), %rax 164 mov (%rdi, %rcx), %rdx 165 166#ifdef USE_AS_STRNCMP 167 sub $8, %r14 168 jle LABEL(tail) 169#endif 170 171 mov %rbx, %r8 172 add %rax, %r8 173 sbb %r10, %r10 174 175 mov %rbx, %r9 176 add %rdx, %r9 177 sbb %r11, %r11 178 179 xor %rax, %r8 180 or %rbx, %r8 181 sub %r10, %r8 182 jnz LABEL(tail) 183 184 xor %rdx, %r9 185 or %rbx, %r9 186 sub %r11, %r9 187 jnz LABEL(tail) 188 189 cmp %rdx, %rax 190 jne LABEL(tail) 191 192 mov 8 (%rsi, %rcx), %rax 193 mov 8 (%rdi, %rcx), %rdx 194 add $8, %ecx 195 196#ifdef USE_AS_STRNCMP 197 sub $8, %r14 198 jle LABEL(tail) 199#endif 200 201 mov %rbx, %r8 202 add %rax, %r8 203 sbb %r10, %r10 204 205 mov %rbx, %r9 206 add %rdx, %r9 207 sbb %r11, %r11 208 209 xor %rax, %r8 210 or %rbx, %r8 211 sub %r10, %r8 212 jnz LABEL(tail) 213 214 xor %rdx, %r9 215 or %rbx, %r9 216 sub %r11, %r9 217 jnz LABEL(tail) 218 219 cmp %rdx, %rax 220 jne LABEL(tail) 221 222 mov 8 (%rsi, %rcx), %rax 223 mov 8 (%rdi, %rcx), %rdx 224 add $8, %ecx 225 226#ifdef USE_AS_STRNCMP 227 sub $8, %r14 228 jle LABEL(tail) 229#endif 230 231 mov %rbx, %r8 232 add %rax, %r8 233 sbb %r10, %r10 234 235 mov %rbx, %r9 236 add %rdx, %r9 237 sbb %r11, %r11 238 239 xor %rax, %r8 240 or %rbx, %r8 241 sub %r10, %r8 242 jnz LABEL(tail) 243 244 xor %rdx, %r9 245 or %rbx, %r9 246 sub %r11, %r9 247 jnz LABEL(tail) 248 249 cmp %rdx, %rax 250 jne LABEL(tail) 251 252 mov 8 (%rsi, %rcx), %rax 253 mov 8 (%rdi, %rcx), %rdx 254 add $8, %ecx 255 256#ifdef USE_AS_STRNCMP 257 sub $8, %r14 258 jle LABEL(tail) 259#endif 260 261 mov %rbx, %r8 262 add %rax, %r8 263 sbb %r10, %r10 264 265 mov %rbx, %r9 266 add %rdx, %r9 267 sbb %r11, %r11 268 269 xor %rax, %r8 270 or %rbx, %r8 271 sub %r10, %r8 272 jnz LABEL(tail) 273 274 xor %rdx, %r9 275 or %rbx, %r9 276 sub %r11, %r9 277 jnz LABEL(tail) 278 279 cmp %rdx, %rax 280 jne LABEL(tail) 281 282 mov 8 (%rsi, %rcx), %rax 283 mov 8 (%rdi, %rcx), %rdx 284 add $8, %ecx 285 286#ifdef USE_AS_STRNCMP 287 sub $8, %r14 288 jle LABEL(tail) 289#endif 290 291 mov %rbx, %r8 292 add %rax, %r8 293 sbb %r10, %r10 294 295 mov %rbx, %r9 296 add %rdx, %r9 297 sbb %r11, %r11 298 299 xor %rax, %r8 300 or %rbx, %r8 301 sub %r10, %r8 302 jnz LABEL(tail) 303 304 xor %rdx, %r9 305 or %rbx, %r9 306 sub %r11, %r9 307 jnz LABEL(tail) 308 309 cmp %rdx, %rax 310 jne LABEL(tail) 311 312 mov 8 (%rsi, %rcx), %rax 313 mov 8 (%rdi, %rcx), %rdx 314 add $8, %ecx 315 316#ifdef USE_AS_STRNCMP 317 sub $8, %r14 318 jle LABEL(tail) 319#endif 320 321 mov %rbx, %r8 322 add %rax, %r8 323 sbb %r10, %r10 324 325 mov %rbx, %r9 326 add %rdx, %r9 327 sbb %r11, %r11 328 329 xor %rax, %r8 330 or %rbx, %r8 331 sub %r10, %r8 332 jnz LABEL(tail) 333 334 xor %rdx, %r9 335 or %rbx, %r9 336 sub %r11, %r9 337 jnz LABEL(tail) 338 339 cmp %rdx, %rax 340 jne LABEL(tail) 341 342 mov 8 (%rsi, %rcx), %rax 343 mov 8 (%rdi, %rcx), %rdx 344 add $8, %ecx 345 346#ifdef USE_AS_STRNCMP 347 sub $8, %r14 348 jle LABEL(tail) 349#endif 350 351 mov %rbx, %r8 352 add %rax, %r8 353 sbb %r10, %r10 354 355 mov %rbx, %r9 356 add %rdx, %r9 357 sbb %r11, %r11 358 359 xor %rax, %r8 360 or %rbx, %r8 361 sub %r10, %r8 362 jnz LABEL(tail) 363 364 xor %rdx, %r9 365 or %rbx, %r9 366 sub %r11, %r9 367 jnz LABEL(tail) 368 369 cmp %rdx, %rax 370 jne LABEL(tail) 371 372 mov 8 (%rsi, %rcx), %rax 373 mov 8 (%rdi, %rcx), %rdx 374 add $8, %ecx 375 376#ifdef USE_AS_STRNCMP 377 sub $8, %r14 378 jle LABEL(tail) 379#endif 380 381 mov %rbx, %r8 382 add %rax, %r8 383 sbb %r10, %r10 384 385 mov %rbx, %r9 386 add %rdx, %r9 387 sbb %r11, %r11 388 389 xor %rax, %r8 390 or %rbx, %r8 391 sub %r10, %r8 392 jnz LABEL(tail) 393 394 xor %rdx, %r9 395 or %rbx, %r9 396 sub %r11, %r9 397 jnz LABEL(tail) 398 399 cmp %rdx, %rax 400 jne LABEL(tail) 401 402 add $8, %ecx 403 404 jmp LABEL(64loop) 405 406LABEL(64after): 407 408LABEL(tailtry): 409 410LABEL(tail): /* byte tail */ 411#ifdef USE_AS_STRNCMP 412 add $7, %r14 413#endif 414 415 cmp %dl, %al /* check if same character */ 416 jne LABEL(exit) 417 test %al, %al /* check if character a NUL */ 418 jz LABEL(exit) 419 420 shr $8, %rax 421 shr $8, %rdx 422 423#ifdef USE_AS_STRNCMP 424 dec %r14 425 jl LABEL(exit) 426#endif 427 428 cmp %dl, %al 429 jne LABEL(exit) 430 test %al, %al 431 jz LABEL(exit) 432 433 shr $8, %rax 434 shr $8, %rdx 435 436#ifdef USE_AS_STRNCMP 437 dec %r14 438 jl LABEL(exit) 439#endif 440 441 cmp %dl, %al 442 jne LABEL(exit) 443 test %al, %al 444 jz LABEL(exit) 445 446 shr $8, %rax 447 shr $8, %rdx 448 449#ifdef USE_AS_STRNCMP 450 dec %r14 451 jl LABEL(exit) 452#endif 453 454 cmp %dl, %al 455 jne LABEL(exit) 456 test %al, %al 457 jz LABEL(exit) 458 459 shr $8, %rax 460 shr $8, %rdx 461 462#ifdef USE_AS_STRNCMP 463 dec %r14 464 jl LABEL(exit) 465#endif 466 467 cmp %dl, %al 468 jne LABEL(exit) 469 test %al, %al 470 jz LABEL(exit) 471 472 shr $8, %eax 473 shr $8, %edx 474 475#ifdef USE_AS_STRNCMP 476 dec %r14 477 jl LABEL(exit) 478#endif 479 480 cmp %dl, %al 481 jne LABEL(exit) 482 test %al, %al 483 jz LABEL(exit) 484 485 shr $8, %eax 486 shr $8, %edx 487 488#ifdef USE_AS_STRNCMP 489 dec %r14 490 jl LABEL(exit) 491#endif 492 493 cmp %dl, %al 494 jne LABEL(exit) 495 test %al, %al 496 jz LABEL(exit) 497 498 shr $8, %eax 499 shr $8, %edx 500 501#ifdef USE_AS_STRNCMP 502 dec %r14 503 jl LABEL(exit) 504#endif 505 506 cmp %dl, %al 507 jne LABEL(exit) 508 509 .p2align 4,, 15 510 511LABEL(tailafter): 512 513LABEL(exit): 514 mov -32 (%rsp), %r15 515 mov -24 (%rsp), %rbp 516 mov -16 (%rsp), %rbx 517 518 .p2align 4,, 3 519 520LABEL(exitafter): 521#ifdef USE_AS_STRNCMP 522 test %r14, %r14 523 cmovl %edx, %eax 524#endif 525 526 movzx %al, %eax 527 movzx %dl, %edx 528 sub %eax, %edx 529 xchg %edx, %eax 530 531#ifdef USE_AS_STRNCMP 532LABEL(exitz): 533 mov -8 (%rsp), %r14 534#endif 535 ret 536 537#ifdef USE_AS_STRNCMP 538 SET_SIZE(strncmp) 539#else 540 SET_SIZE(strcmp) /* (const char *, const char *) */ 541#endif 542