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