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