summaryrefslogtreecommitdiffstats
path: root/lib/libc/amd64/string/strcmp.S
diff options
context:
space:
mode:
Diffstat (limited to 'lib/libc/amd64/string/strcmp.S')
-rw-r--r--lib/libc/amd64/string/strcmp.S73
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
OpenPOWER on IntegriCloud