OSDN Git Service

Revert "libc x86: Remove strcat.S"
authorElliott Hughes <enh@google.com>
Sat, 8 Jun 2013 00:42:35 +0000 (00:42 +0000)
committerElliott Hughes <enh@google.com>
Sat, 8 Jun 2013 00:42:35 +0000 (00:42 +0000)
This reverts commit 4fe461b3a67148a2f557605e10a34deff9c8773a

Change-Id: Ibeb76e24f054abd7c96ad6899366c2f9bfc2a5ad

libc/arch-x86/string/strcat.S [new file with mode: 0644]

diff --git a/libc/arch-x86/string/strcat.S b/libc/arch-x86/string/strcat.S
new file mode 100644 (file)
index 0000000..c75f38a
--- /dev/null
@@ -0,0 +1,74 @@
+/*     $OpenBSD: strcat.S,v 1.8 2005/08/07 11:30:38 espie Exp $ */
+/*
+ * Written by J.T. Conklin <jtc@netbsd.org>.
+ * Public domain.
+ */
+
+#include <machine/asm.h>
+
+#if defined(APIWARN)
+#APP
+       .section .gnu.warning.strcat
+       .ascii "warning: strcat() is almost always misused, please use strlcat()"
+#NO_APP
+#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(strcat)
+       pushl   %edi                    /* save edi */
+       movl    8(%esp),%edi            /* dst address */
+       movl    12(%esp),%edx           /* src address */
+       pushl   %edi                    /* push destination address */
+
+       cld                             /* set search forward */
+       xorl    %eax,%eax               /* set search for null terminator */
+       movl    $-1,%ecx                /* set search for lots of characters */
+       repne                           /* search! */
+       scasb
+
+       leal    -1(%edi),%ecx           /* correct dst address */
+
+       .align 2,0x90
+L1:    movb    (%edx),%al              /* unroll loop, but not too much */
+       movb    %al,(%ecx)
+       testb   %al,%al
+       jz      L2
+       movb    1(%edx),%al
+       movb    %al,1(%ecx)
+       testb   %al,%al
+       jz      L2
+       movb    2(%edx),%al
+       movb    %al,2(%ecx)
+       testb   %al,%al
+       jz      L2
+       movb    3(%edx),%al
+       movb    %al,3(%ecx)
+       testb   %al,%al
+       jz      L2
+       movb    4(%edx),%al
+       movb    %al,4(%ecx)
+       testb   %al,%al
+       jz      L2
+       movb    5(%edx),%al
+       movb    %al,5(%ecx)
+       testb   %al,%al
+       jz      L2
+       movb    6(%edx),%al
+       movb    %al,6(%ecx)
+       testb   %al,%al
+       jz      L2
+       movb    7(%edx),%al
+       movb    %al,7(%ecx)
+       addl    $8,%edx
+       addl    $8,%ecx
+       testb   %al,%al
+       jnz     L1
+L2:    popl    %eax                    /* pop destination address */
+       popl    %edi                    /* restore edi */
+       ret
+END(strcat)