xref: /openbsd-src/sys/lib/libkern/arch/i386/memset.S (revision 737e061132473fb2b37fc15648b2a2378e910cae)
1*737e0611Stedu/*	$OpenBSD: memset.S,v 1.4 2014/11/29 18:51:23 tedu Exp $	*/
2fd2290ccSmickey
37fde9e0dSmickey/*
47fde9e0dSmickey * Written by J.T. Conklin <jtc@netbsd.org>.
57fde9e0dSmickey * Public domain.
67fde9e0dSmickey */
77fde9e0dSmickey
87fde9e0dSmickey#include <machine/asm.h>
97fde9e0dSmickey
107fde9e0dSmickeyENTRY(memset)
117fde9e0dSmickey	pushl	%edi
127fde9e0dSmickey	pushl	%ebx
137fde9e0dSmickey	movl	12(%esp),%edi
147fde9e0dSmickey	movzbl	16(%esp),%eax		/* unsigned char, zero extend */
157fde9e0dSmickey	movl	20(%esp),%ecx
167fde9e0dSmickey	pushl	%edi			/* push address of buffer */
177fde9e0dSmickey
187fde9e0dSmickey	/*
197fde9e0dSmickey	 * if the string is too short, it's really not worth the overhead
20f70d55c3Skrw	 * of aligning to word boundaries, etc.  So we jump to a plain
217fde9e0dSmickey	 * unaligned set.
227fde9e0dSmickey	 */
237fde9e0dSmickey	cmpl	$0x0f,%ecx
247fde9e0dSmickey	jle	L1
257fde9e0dSmickey
267fde9e0dSmickey	movb	%al,%ah			/* copy char to all bytes in word */
277fde9e0dSmickey	movl	%eax,%edx
287fde9e0dSmickey	sall	$16,%eax
297fde9e0dSmickey	orl	%edx,%eax
307fde9e0dSmickey
317fde9e0dSmickey	movl	%edi,%edx		/* compute misalignment */
327fde9e0dSmickey	negl	%edx
337fde9e0dSmickey	andl	$3,%edx
347fde9e0dSmickey	movl	%ecx,%ebx
357fde9e0dSmickey	subl	%edx,%ebx
367fde9e0dSmickey
377fde9e0dSmickey	movl	%edx,%ecx		/* set until word aligned */
387fde9e0dSmickey	rep
397fde9e0dSmickey	stosb
407fde9e0dSmickey
417fde9e0dSmickey	movl	%ebx,%ecx
427fde9e0dSmickey	shrl	$2,%ecx			/* set by words */
437fde9e0dSmickey	rep
447fde9e0dSmickey	stosl
457fde9e0dSmickey
467fde9e0dSmickey	movl	%ebx,%ecx		/* set remainder by bytes */
477fde9e0dSmickey	andl	$3,%ecx
487fde9e0dSmickeyL1:	rep
497fde9e0dSmickey	stosb
507fde9e0dSmickey
517fde9e0dSmickey	popl	%eax			/* pop address of buffer */
527fde9e0dSmickey	popl	%ebx
537fde9e0dSmickey	popl	%edi
547fde9e0dSmickey	ret
55