summaryrefslogtreecommitdiff
path: root/sys/lib/libkern/arch/amd64/strcmp.S
diff options
context:
space:
mode:
Diffstat (limited to 'sys/lib/libkern/arch/amd64/strcmp.S')
-rw-r--r--sys/lib/libkern/arch/amd64/strcmp.S88
1 files changed, 88 insertions, 0 deletions
diff --git a/sys/lib/libkern/arch/amd64/strcmp.S b/sys/lib/libkern/arch/amd64/strcmp.S
new file mode 100644
index 00000000000..559563666d4
--- /dev/null
+++ b/sys/lib/libkern/arch/amd64/strcmp.S
@@ -0,0 +1,88 @@
+/*
+ * Written by J.T. Conklin <jtc@netbsd.org>.
+ * Public domain.
+ * Adapted for NetBSD/x86_64 by Frank van der Linden <fvdl@wasabisystems.com>
+ */
+
+#include <machine/asm.h>
+
+#if defined(LIBC_SCCS)
+ RCSID("$NetBSD: strcmp.S,v 1.1 2001/06/19 00:22:47 fvdl Exp $")
+#endif
+
+/*
+ * NOTE: I've unrolled the loop eight times: large enough to make a
+ * significant difference, and small enough not to totally trash the
+ * cache.
+ */
+
+ENTRY(strcmp)
+ jmp L2 /* Jump into the loop. */
+
+L1: incq %rdi
+ incq %rsi
+L2: movb (%rdi),%cl
+ testb %cl,%cl /* null terminator */
+ jz L3
+ cmpb %cl,(%rsi) /* chars match */
+ jne L3
+
+ incq %rdi
+ incq %rsi
+ movb (%rdi),%cl
+ testb %cl,%cl
+ jz L3
+ cmpb %cl,(%rsi)
+ jne L3
+
+ incq %rdi
+ incq %rsi
+ movb (%rdi),%cl
+ testb %cl,%cl
+ jz L3
+ cmpb %cl,(%rsi)
+ jne L3
+
+ incq %rdi
+ incq %rsi
+ movb (%rdi),%cl
+ testb %cl,%cl
+ jz L3
+ cmpb %cl,(%rsi)
+ jne L3
+
+ incq %rdi
+ incq %rsi
+ movb (%rdi),%cl
+ testb %cl,%cl
+ jz L3
+ cmpb %cl,(%rsi)
+ jne L3
+
+ incq %rdi
+ incq %rsi
+ movb (%rdi),%cl
+ testb %cl,%cl
+ jz L3
+ cmpb %cl,(%rsi)
+ jne L3
+
+ incq %rdi
+ incq %rsi
+ movb (%rdi),%cl
+ testb %cl,%cl
+ jz L3
+ cmpb %cl,(%rsi)
+ jne L3
+
+ incq %rdi
+ incq %rsi
+ movb (%rdi),%cl
+ testb %cl,%cl
+ jz L3
+ cmpb %cl,(%rsi)
+ je L1
+L3: movzbl (%rdi),%eax /* unsigned comparison */
+ movzbl (%rsi),%edx
+ subl %edx,%eax
+ ret