16059Samurai/*
26059Samurai * Written by J.T. Conklin <jtc@acorntoolworks.com>
36059Samurai * Public domain.
46059Samurai */
56059Samurai
66059Samurai#include <machine/asm.h>
76059Samurai
86059Samurai#if defined(LIBC_SCCS)
96059Samurai	RCSID("$NetBSD: strcpy.S,v 1.11 2005/03/15 15:16:59 christos Exp $")
106059Samurai#endif
116059Samurai
126059Samurai/*
136059Samurai * This strcpy implementation copies a byte at a time until the
146059Samurai * source pointer is aligned to a word boundary, it then copies by
156059Samurai * words until it finds a word containing a zero byte, and finally
166059Samurai * copies by bytes until the end of the string is reached.
176059Samurai *
186059Samurai * While this may result in unaligned stores if the source and
198857Srgrimes * destination pointers are unaligned with respect to each other,
2011336Samurai * it is still faster than either byte copies or the overhead of
218857Srgrimes * an implementation suitable for machines with strict alignment
226059Samurai * requirements.
236059Samurai */
246735Samurai
256059SamuraiENTRY(strcpy)
266059Samurai	pushl	%ebx
276059Samurai	movl	8(%esp),%ecx
286059Samurai	movl	12(%esp),%eax
296059Samurai
306059Samurai	/*
316059Samurai	 * Align source to a word boundary.
326059Samurai	 * Consider unrolling loop?
336735Samurai	 */
346059Samurai	_ALIGN_TEXT
356059Samurai.Lalign:
366059Samurai	testl	$3,%eax
376059Samurai	je	.Lword_aligned
386059Samurai	movb	(%eax),%bl
3910528Samurai	incl	%eax
406059Samurai	movb	%bl,(%ecx)
416059Samurai	incl	%ecx
426059Samurai	testb	%bl,%bl
436059Samurai	jne	.Lalign
446059Samurai	jmp	.Ldone
456735Samurai
466059Samurai	_ALIGN_TEXT
476059Samurai.Lloop:
486059Samurai	movl	%ebx,(%ecx)
496059Samurai	addl	$4,%ecx
5010528Samurai.Lword_aligned:
516735Samurai	movl	(%eax),%ebx
526059Samurai	addl	$4,%eax
536059Samurai	leal	-0x01010101(%ebx),%edx
546059Samurai	testl	$0x80808080,%edx
556059Samurai	je	.Lloop
566059Samurai
576059Samurai	/*
5810528Samurai	 * In rare cases, the above loop may exit prematurely. We must
596059Samurai	 * return to the loop if none of the bytes in the word equal 0.
606059Samurai	 */
616059Samurai
626059Samurai	movb	%bl,(%ecx)
636059Samurai	incl	%ecx
646059Samurai	testb	%bl,%bl
656059Samurai	je	.Ldone
666059Samurai
676059Samurai	movb	%bh,(%ecx)
686059Samurai	incl	%ecx
696059Samurai	testb	%bh,%bh
706059Samurai	je	.Ldone
716059Samurai
726059Samurai	shrl	$16,%ebx
736764Samurai	movb	%bl,(%ecx)
746059Samurai	incl	%ecx
756059Samurai	testb	%bl,%bl
766059Samurai	je	.Ldone
776059Samurai
786059Samurai	movb	%bh,(%ecx)
796059Samurai	incl	%ecx
806059Samurai	testb	%bh,%bh
816059Samurai	jne	.Lword_aligned
826764Samurai
836764Samurai.Ldone:
846059Samurai	movl	8(%esp),%eax
856059Samurai	popl	%ebx
866059Samurai	ret
876059Samurai