diff options
Diffstat (limited to 'lib/libc/amd64/string/strcmp.S')
-rw-r--r-- | lib/libc/amd64/string/strcmp.S | 73 |
1 files changed, 73 insertions, 0 deletions
diff --git a/lib/libc/amd64/string/strcmp.S b/lib/libc/amd64/string/strcmp.S new file mode 100644 index 0000000..a7d2523 --- /dev/null +++ b/lib/libc/amd64/string/strcmp.S @@ -0,0 +1,73 @@ +/* + * Written by J.T. Conklin <jtc@acorntoolworks.com> + * Public domain. + */ + +#include <machine/asm.h> +__FBSDID("$FreeBSD$"); + +#if 0 + RCSID("$NetBSD: strcmp.S,v 1.3 2004/07/19 20:04:41 drochner Exp $") +#endif + +ENTRY(strcmp) + /* + * Align s1 to word boundary. + * Consider unrolling loop? + */ +.Ls1align: + testb $7,%dil + je .Ls1aligned + movb (%rdi),%al + incq %rdi + movb (%rsi),%dl + incq %rsi + testb %al,%al + je .Ldone + cmpb %al,%dl + je .Ls1align + jmp .Ldone + + /* + * Check whether s2 is aligned to a word boundry. If it is, we + * can compare by words. Otherwise we have to compare by bytes. + */ +.Ls1aligned: + testb $7,%sil + jne .Lbyte_loop + + movabsq $0x0101010101010101,%r8 + subq $8,%rdi + movabsq $0x8080808080808080,%r9 + subq $8,%rsi + + .align 4 +.Lword_loop: + movq 8(%rdi),%rax + addq $8,%rdi + movq 8(%rsi),%rdx + addq $8,%rsi + cmpq %rax,%rdx + jne .Lbyte_loop + subq %r8,%rdx + notq %rax + andq %rax,%rdx + testq %r9,%rdx + je .Lword_loop + + .align 4 +.Lbyte_loop: + movb (%rdi),%al + incq %rdi + movb (%rsi),%dl + incq %rsi + testb %al,%al + je .Ldone + cmpb %al,%dl + je .Lbyte_loop + +.Ldone: + movzbq %al,%rax + movzbq %dl,%rdx + subq %rdx,%rax + ret |