root/lib/libc/arch/i386/string/strcpy.S
/*      $OpenBSD: strcpy.S,v 1.10 2017/11/28 06:55:49 tb Exp $ */
/*
 * Written by J.T. Conklin <jtc@netbsd.org>.
 * Public domain.
 */

#include <machine/asm.h>

#if defined(APIWARN)
#APP
        .section .gnu.warning.strcpy
        .ascii "strcpy() is almost always misused, please use strlcpy()"
#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(strcpy)
        movl    4(%esp),%ecx            /* dst address */
        movl    8(%esp),%edx            /* src address */
        pushl   %ecx                    /* push 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 dst address */
        ret
END(strcpy)