xref: /netbsd-src/common/lib/libc/arch/i386/string/memcpy.S (revision 2c56941e163201dcb781df7fdeec6bd093647c91)
1*2c56941eSjakllsch/*	$NetBSD: memcpy.S,v 1.4 2014/03/22 19:38:46 jakllsch Exp $	*/
237c9f0a6Schristos
337c9f0a6Schristos/*-
437c9f0a6Schristos * Copyright (c) 1990 The Regents of the University of California.
537c9f0a6Schristos * All rights reserved.
637c9f0a6Schristos *
737c9f0a6Schristos * This code is derived from locore.s.
837c9f0a6Schristos * Optimised by David Laight 2003
937c9f0a6Schristos *
1037c9f0a6Schristos * Redistribution and use in source and binary forms, with or without
1137c9f0a6Schristos * modification, are permitted provided that the following conditions
1237c9f0a6Schristos * are met:
1337c9f0a6Schristos * 1. Redistributions of source code must retain the above copyright
1437c9f0a6Schristos *    notice, this list of conditions and the following disclaimer.
1537c9f0a6Schristos * 2. Redistributions in binary form must reproduce the above copyright
1637c9f0a6Schristos *    notice, this list of conditions and the following disclaimer in the
1737c9f0a6Schristos *    documentation and/or other materials provided with the distribution.
1837c9f0a6Schristos * 3. Neither the name of the University nor the names of its contributors
1937c9f0a6Schristos *    may be used to endorse or promote products derived from this software
2037c9f0a6Schristos *    without specific prior written permission.
2137c9f0a6Schristos *
2237c9f0a6Schristos * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
2337c9f0a6Schristos * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
2437c9f0a6Schristos * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
2537c9f0a6Schristos * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
2637c9f0a6Schristos * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
2737c9f0a6Schristos * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
2837c9f0a6Schristos * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
2937c9f0a6Schristos * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
3037c9f0a6Schristos * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
3137c9f0a6Schristos * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
3237c9f0a6Schristos * SUCH DAMAGE.
3337c9f0a6Schristos */
3437c9f0a6Schristos
3537c9f0a6Schristos#include <machine/asm.h>
3637c9f0a6Schristos
3737c9f0a6Schristos#if defined(LIBC_SCCS)
38*2c56941eSjakllsch	RCSID("$NetBSD: memcpy.S,v 1.4 2014/03/22 19:38:46 jakllsch Exp $")
3937c9f0a6Schristos#endif
4037c9f0a6Schristos
4137c9f0a6Schristos	/*
4237c9f0a6Schristos	 * (ov)bcopy (src,dst,cnt)
4337c9f0a6Schristos	 *  ws@tools.de     (Wolfgang Solfrank, TooLs GmbH) +49-228-985800
4437c9f0a6Schristos	 */
4537c9f0a6Schristos
4637c9f0a6Schristos#ifdef BCOPY
4737c9f0a6SchristosENTRY(bcopy)
4837c9f0a6Schristos#else
4937c9f0a6Schristos#ifdef MEMMOVE
5037c9f0a6SchristosENTRY(memmove)
5137c9f0a6Schristos#else
5237c9f0a6Schristos#define MEMCPY
5337c9f0a6Schristos#define NO_OVERLAP
5437c9f0a6SchristosENTRY(memcpy)
5537c9f0a6Schristos#endif
5637c9f0a6Schristos#endif
5737c9f0a6Schristos	push	%esi
5837c9f0a6Schristos	mov	%edi,%edx
5937c9f0a6Schristos#if defined(MEMCPY) || defined(MEMMOVE)
6037c9f0a6Schristos	movl	8(%esp),%edi
6137c9f0a6Schristos	movl	12(%esp),%esi
6237c9f0a6Schristos#else
6337c9f0a6Schristos	movl	8(%esp),%esi
6437c9f0a6Schristos	movl	12(%esp),%edi
6537c9f0a6Schristos#endif
6637c9f0a6Schristos	movl	16(%esp),%ecx
6737c9f0a6Schristos#if defined(NO_OVERLAP)
6837c9f0a6Schristos	movl	%ecx,%eax
6937c9f0a6Schristos#else
7037c9f0a6Schristos	movl	%edi,%eax
7137c9f0a6Schristos	subl	%esi,%eax
7237c9f0a6Schristos	cmpl	%ecx,%eax	/* overlapping? */
7337c9f0a6Schristos	movl	%ecx,%eax
7488cde7b8Syamt	jb	.Lbackwards
7537c9f0a6Schristos#endif
7651a21598Sad	/* nope, copy forwards. */
7737c9f0a6Schristos	shrl	$2,%ecx		/* copy by words */
7837c9f0a6Schristos	rep
7937c9f0a6Schristos	movsl
8037c9f0a6Schristos	and	$3,%eax		/* any bytes left? */
8188cde7b8Syamt	jnz	.Ltrailing
8288cde7b8Syamt.Ldone:
8337c9f0a6Schristos#if defined(MEMCPY) || defined(MEMMOVE)
8437c9f0a6Schristos	movl	8(%esp),%eax
8537c9f0a6Schristos#endif
8637c9f0a6Schristos	mov	%edx,%edi
8737c9f0a6Schristos	pop	%esi
8837c9f0a6Schristos	ret
8937c9f0a6Schristos
9088cde7b8Syamt.Ltrailing:
9137c9f0a6Schristos	cmp	$2,%eax
9237c9f0a6Schristos	jb	1f
9337c9f0a6Schristos	movw	(%esi),%ax
9437c9f0a6Schristos	movw	%ax,(%edi)
9588cde7b8Syamt	je	.Ldone
9637c9f0a6Schristos	movb	2(%esi),%al
9737c9f0a6Schristos	movb	%al,2(%edi)
9888cde7b8Syamt	jmp	.Ldone
9937c9f0a6Schristos1:	movb	(%esi),%al
10037c9f0a6Schristos	movb	%al,(%edi)
10188cde7b8Syamt	jmp	.Ldone
10237c9f0a6Schristos
10337c9f0a6Schristos#if !defined(NO_OVERLAP)
10488cde7b8Syamt.Lbackwards:
10537c9f0a6Schristos	addl	%ecx,%edi	/* copy backwards. */
10637c9f0a6Schristos	addl	%ecx,%esi
10737c9f0a6Schristos	and	$3,%eax		/* any fractional bytes? */
10888cde7b8Syamt	jnz	.Lback_align
10988cde7b8Syamt.Lback_aligned:
11037c9f0a6Schristos	shrl	$2,%ecx
11137c9f0a6Schristos	subl	$4,%esi
11237c9f0a6Schristos	subl	$4,%edi
11337c9f0a6Schristos	std
11437c9f0a6Schristos	rep
11537c9f0a6Schristos	movsl
11637c9f0a6Schristos	cld
11788cde7b8Syamt	jmp	.Ldone
11837c9f0a6Schristos
11988cde7b8Syamt.Lback_align:
12037c9f0a6Schristos	sub	%eax,%esi
12137c9f0a6Schristos	sub	%eax,%edi
12237c9f0a6Schristos	cmp	$2,%eax
12337c9f0a6Schristos	jb	1f
12437c9f0a6Schristos	je	2f
12537c9f0a6Schristos	movb	2(%esi),%al
12637c9f0a6Schristos	movb	%al,2(%edi)
12737c9f0a6Schristos2:	movw	(%esi),%ax
12837c9f0a6Schristos	movw	%ax,(%edi)
12988cde7b8Syamt	jmp	.Lback_aligned
13037c9f0a6Schristos1:	movb	(%esi),%al
13137c9f0a6Schristos	movb	%al,(%edi)
13288cde7b8Syamt	jmp	.Lback_aligned
13337c9f0a6Schristos#endif
134*2c56941eSjakllsch
135*2c56941eSjakllsch#ifdef BCOPY
136*2c56941eSjakllschEND(bcopy)
137*2c56941eSjakllsch#else
138*2c56941eSjakllsch#ifdef MEMMOVE
139*2c56941eSjakllschEND(memmove)
140*2c56941eSjakllsch#else
141*2c56941eSjakllschEND(memcpy)
142*2c56941eSjakllsch#endif
143*2c56941eSjakllsch#endif
144