xref: /netbsd-src/sys/lib/libkern/arch/powerpc/memset.S (revision b1c86f5f087524e68db12794ee9c3e3da1ab17a0)
1/*	$NetBSD: memset.S,v 1.6 2007/03/04 06:03:12 christos Exp $ */
2
3/*-
4 * Copyright (C) 2003	Matt Thomas <matt@3am-software.com>
5 * Copyright (C) 2001	Martin J. Laubach <mjl@NetBSD.org>
6 * All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 * 1. Redistributions of source code must retain the above copyright
12 *    notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 *    notice, this list of conditions and the following disclaimer in the
15 *    documentation and/or other materials provided with the distribution.
16 * 3. The name of the author may not be used to endorse or promote products
17 *    derived from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
20 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
21 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
22 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
23 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
24 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 */
30/*----------------------------------------------------------------------*/
31
32#define _NOREGNAMES
33#include <machine/asm.h>
34
35/*----------------------------------------------------------------------*/
36/*
37     void bzero(void *b r3, size_t len r4);
38     void *memset(void *b r3, int c r4, size_t len r5);
39*/
40/*----------------------------------------------------------------------*/
41
42#define r_dst	%r4
43#define r_len	%r5
44#define r_tmp	%r6
45#define r_val	%r0
46
47ENTRY(bzero)
48		li	r_val, 0		/* Value to fill with */
49		mr	r_len, %r4
50		b	cb_memset
51
52ENTRY(memset)
53		mr	r_val, %r4		/* Value to fill with */
54
55cb_memset:
56		cmplwi	r_len, 0		/* is the length 0? */
57		beqlr-				/*    nothing to do */
58		mr	r_dst, %r3
59		/*
60		 * r3=start, r4=dstptr, r5=length, r0=fill-val
61		 */
62		cmplwi	r_len, 6		/* more than 6 bytes? */
63		bgt	complex_fill		/*    do it the complex way */
64		subi	r_dst, r_dst, 1		/* presubtract for stbu */
65simple_fill:	mtctr	r_len			/* set CTR */
661:		stbu	r_val, 1(r_dst)		/* update memory */
67		bdnz+	1b			/*    until CTR is 0 */
68		blr				/* return */
69
70complex_fill:
71		rlwimi	r_val, r_val, 8, 16, 23	/* word extend fill value */
72		rlwimi	r_val, r_val, 16, 0, 15
73		andi.	r_tmp, r_dst, 0x03
74		beq+	word_fill		/* already aligned to word? */
75		andi.	r_tmp, r_dst, 0x01
76		beq	half_fill		/* aligned to halfword? */
77		stb	r_val, 0(r_dst)
78		addi	r_dst, r_dst, 1
79		subi	r_len, r_len, 1		/* subtract byte */
80		andi.	r_tmp, r_dst, 0x02
81		beq	word_fill		/* aligned to word? */
82half_fill:
83		sth	r_val, 0(r_dst)
84		addi	r_dst, r_dst, 2
85		subi	r_len, r_len, 2		/* subtract halfword */
86
87word_fill:
88		cmplwi	r_len, 4		/* we have more than 4 bytes? */
89		blt-	trailing_bytes		/* no?  finish writing */
90		srwi	r_tmp, r_len, 2		/* get word count */
91		mtctr	r_tmp
92		subi	r_dst, r_dst, 4
931:		stwu	r_val, 4(r_dst)
94		bdnz+	1b
95
96trailing_bytes:
97		andi.	r_len, r_len, 0x03	/* how much left? */
98		beqlr+				/* nothing? return */
99		addi	r_dst, r_dst, 3
100		b	simple_fill
101