xref: /netbsd-src/common/lib/libc/arch/i386/string/memset.S (revision 19ef5b5b0bcb90f63509df6e78769de1b57c2758)
1*19ef5b5bSuebayasi/*	$NetBSD: memset.S,v 1.5 2014/05/23 03:17:31 uebayasi Exp $	*/
237c9f0a6Schristos
337c9f0a6Schristos/*-
437c9f0a6Schristos * Copyright (c) 2003 The NetBSD Foundation, Inc.
537c9f0a6Schristos * All rights reserved.
637c9f0a6Schristos *
737c9f0a6Schristos * This code is derived from software contributed to The NetBSD Foundation
837c9f0a6Schristos * by David Laight.
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 *
1937c9f0a6Schristos * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
2037c9f0a6Schristos * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
2137c9f0a6Schristos * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
2237c9f0a6Schristos * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
2337c9f0a6Schristos * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
2437c9f0a6Schristos * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
2537c9f0a6Schristos * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
2637c9f0a6Schristos * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
2737c9f0a6Schristos * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
2837c9f0a6Schristos * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
2937c9f0a6Schristos * POSSIBILITY OF SUCH DAMAGE.
3037c9f0a6Schristos */
3137c9f0a6Schristos
3237c9f0a6Schristos#include <machine/asm.h>
3337c9f0a6Schristos
3437c9f0a6Schristos#if defined(LIBC_SCCS)
35*19ef5b5bSuebayasi	RCSID("$NetBSD: memset.S,v 1.5 2014/05/23 03:17:31 uebayasi Exp $")
3637c9f0a6Schristos#endif
3737c9f0a6Schristos
3837c9f0a6Schristos#ifdef BZERO
3937c9f0a6SchristosENTRY(bzero)
4037c9f0a6Schristos#else
4137c9f0a6SchristosENTRY(memset)
4237c9f0a6Schristos#endif
4337c9f0a6Schristos#ifdef BZERO
4437c9f0a6Schristos	movl	8(%esp),%ecx
4537c9f0a6Schristos	xor	%eax,%eax
4637c9f0a6Schristos#else
4737c9f0a6Schristos	movl	12(%esp),%ecx
4837c9f0a6Schristos	movzbl	8(%esp),%eax		/* unsigned char, zero extend */
4937c9f0a6Schristos#endif
5037c9f0a6Schristos	cmpl	$0x0f,%ecx		/* avoid mispredicted branch... */
5137c9f0a6Schristos
5237c9f0a6Schristos	pushl	%edi
5337c9f0a6Schristos	movl	8(%esp),%edi
5437c9f0a6Schristos
5537c9f0a6Schristos	/*
5637c9f0a6Schristos	 * if the string is too short, it's really not worth the overhead
5737c9f0a6Schristos	 * of aligning to word boundries, etc.  So we jump to a plain
5837c9f0a6Schristos	 * unaligned set.
5937c9f0a6Schristos	 *
6037c9f0a6Schristos	 * NB aligning the transfer is actually pointless on my athlon 700,
6137c9f0a6Schristos	 * It does make a difference to a PII though.
6237c9f0a6Schristos	 *
6337c9f0a6Schristos	 * The PII, PIII and PIV all seem to have a massive performance
6437c9f0a6Schristos	 * drop when the initial target address is an odd multiple of 4.
6537c9f0a6Schristos	 */
6688cde7b8Syamt	jbe	.Lby_bytes
6737c9f0a6Schristos
6837c9f0a6Schristos#ifndef BZERO
6937c9f0a6Schristos	movb	%al,%ah			/* copy char to all bytes in word */
7037c9f0a6Schristos	movl	%eax,%edx
7137c9f0a6Schristos	sall	$16,%eax
7237c9f0a6Schristos	orl	%edx,%eax
7337c9f0a6Schristos#endif
7437c9f0a6Schristos
7537c9f0a6Schristos	movl	%edi,%edx		/* detect misalignment */
7637c9f0a6Schristos	neg	%edx
7737c9f0a6Schristos	andl	$7,%edx
7888cde7b8Syamt	jnz	.Lalign
7988cde7b8Syamt.Laligned:
8037c9f0a6Schristos	movl	%eax,-4(%edi,%ecx)	/* zap last 4 bytes */
8137c9f0a6Schristos	shrl	$2,%ecx			/* zero by words */
8237c9f0a6Schristos	rep
8337c9f0a6Schristos	stosl
8488cde7b8Syamt.Ldone:
8537c9f0a6Schristos#ifndef BZERO
8637c9f0a6Schristos	movl	8(%esp),%eax		/* return address of buffer */
8737c9f0a6Schristos#endif
8837c9f0a6Schristos	pop	%edi
8937c9f0a6Schristos	ret
9037c9f0a6Schristos
9188cde7b8Syamt.Lalign:
9237c9f0a6Schristos	movl	%eax,(%edi)		/* zap first 8 bytes */
9337c9f0a6Schristos	movl	%eax,4(%edi)
9437c9f0a6Schristos	subl	%edx,%ecx		/* remove from main count */
9537c9f0a6Schristos	add	%edx,%edi
9688cde7b8Syamt	jmp	.Laligned
9737c9f0a6Schristos
9888cde7b8Syamt.Lby_bytes:
9937c9f0a6Schristos	rep
10037c9f0a6Schristos	stosb
10137c9f0a6Schristos
10237c9f0a6Schristos#ifndef BZERO
10337c9f0a6Schristos	movl	8(%esp),%eax		/* return address of buffer */
10437c9f0a6Schristos#endif
10537c9f0a6Schristos	popl	%edi
10637c9f0a6Schristos	ret
107*19ef5b5bSuebayasi#ifdef BZERO
108*19ef5b5bSuebayasiEND(bzero)
109*19ef5b5bSuebayasi#else
110*19ef5b5bSuebayasiEND(memset)
111*19ef5b5bSuebayasi#endif
112