10Sstevel@tonic-gate/* 20Sstevel@tonic-gate * CDDL HEADER START 30Sstevel@tonic-gate * 40Sstevel@tonic-gate * The contents of this file are subject to the terms of the 56515Sraf * Common Development and Distribution License (the "License"). 66515Sraf * You may not use this file except in compliance with the License. 70Sstevel@tonic-gate * 80Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 90Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 100Sstevel@tonic-gate * See the License for the specific language governing permissions 110Sstevel@tonic-gate * and limitations under the License. 120Sstevel@tonic-gate * 130Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 140Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 150Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 160Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 170Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 180Sstevel@tonic-gate * 190Sstevel@tonic-gate * CDDL HEADER END 200Sstevel@tonic-gate */ 216515Sraf 220Sstevel@tonic-gate/* 236515Sraf * Copyright 2008 Sun Microsystems, Inc. All rights reserved. 240Sstevel@tonic-gate * Use is subject to license terms. 250Sstevel@tonic-gate */ 260Sstevel@tonic-gate 27*7298SMark.J.Nelson@Sun.COM .file "memset.s" 280Sstevel@tonic-gate 290Sstevel@tonic-gate/* 300Sstevel@tonic-gate * memset(sp, c, n) 310Sstevel@tonic-gate * 320Sstevel@tonic-gate * Set an array of n chars starting at sp to the character c. 330Sstevel@tonic-gate * Return sp. 340Sstevel@tonic-gate * 350Sstevel@tonic-gate * Fast assembler language version of the following C-program for memset 360Sstevel@tonic-gate * which represents the `standard' for the C-library. 370Sstevel@tonic-gate * 380Sstevel@tonic-gate * void * 390Sstevel@tonic-gate * memset(void *sp1, int c, size_t n) 400Sstevel@tonic-gate * { 410Sstevel@tonic-gate * if (n != 0) { 420Sstevel@tonic-gate * char *sp = sp1; 430Sstevel@tonic-gate * do { 440Sstevel@tonic-gate * *sp++ = (char)c; 450Sstevel@tonic-gate * } while (--n != 0); 460Sstevel@tonic-gate * } 470Sstevel@tonic-gate * return (sp1); 480Sstevel@tonic-gate * } 490Sstevel@tonic-gate * 500Sstevel@tonic-gate * 510Sstevel@tonic-gate * 520Sstevel@tonic-gate * Algorithm used: 530Sstevel@tonic-gate * For small stores (6 or fewer bytes), bytes will be stored one at a time. 540Sstevel@tonic-gate * 550Sstevel@tonic-gate * When setting 15 or more bytes, there will be at least 8 bytes aligned 560Sstevel@tonic-gate * on an 8-byte boundary. So, leading bytes will be set, then as many 570Sstevel@tonic-gate * 8-byte aligned chunks as possible will be set, followed by any trailing 580Sstevel@tonic-gate * bytes. 590Sstevel@tonic-gate * 600Sstevel@tonic-gate * For between 8 and 14 bytes (inclusive), leading odd bytes will be 610Sstevel@tonic-gate * set, followed by 4-byte chunks, followed by trailing bytes. 620Sstevel@tonic-gate * 630Sstevel@tonic-gate * Inputs: 640Sstevel@tonic-gate * o0: pointer to start of area to be set to a given value 650Sstevel@tonic-gate * o1: character used to set memory at location in i0 660Sstevel@tonic-gate * o2: number of bytes to be set 670Sstevel@tonic-gate * 680Sstevel@tonic-gate * Outputs: 690Sstevel@tonic-gate * o0: pointer to start of area set (same as input value in o0) 700Sstevel@tonic-gate * 710Sstevel@tonic-gate */ 720Sstevel@tonic-gate 730Sstevel@tonic-gate#include <sys/asm_linkage.h> 740Sstevel@tonic-gate 750Sstevel@tonic-gate ANSI_PRAGMA_WEAK(memset,function) 760Sstevel@tonic-gate 770Sstevel@tonic-gate ENTRY(memset) 780Sstevel@tonic-gate mov %o0, %o5 ! need to return this value 790Sstevel@tonic-gate cmp %o2, 7 800Sstevel@tonic-gate blu,pn %xcc, .wrchar ! small count: just set bytes 810Sstevel@tonic-gate and %o1, 0xff, %o1 820Sstevel@tonic-gate 830Sstevel@tonic-gate sll %o1, 8, %o4 ! generate 4 bytes filled with char 840Sstevel@tonic-gate or %o1, %o4, %o1 850Sstevel@tonic-gate sll %o1, 16, %o4 860Sstevel@tonic-gate cmp %o2, 15 870Sstevel@tonic-gate blu,pn %xcc, .walign ! not enough to guarantee 8-byte align 880Sstevel@tonic-gate or %o1, %o4, %o1 890Sstevel@tonic-gate 900Sstevel@tonic-gate sllx %o1, 32, %o4 ! now fill the other 4 bytes with char 910Sstevel@tonic-gate or %o1, %o4, %o1 920Sstevel@tonic-gate 930Sstevel@tonic-gate.dalign: ! Set bytes until 8-byte aligned 940Sstevel@tonic-gate btst 7, %o5 ! 8-byte aligned? 950Sstevel@tonic-gate bz,a,pn %icc, .wrdbl 960Sstevel@tonic-gate andn %o2, 7, %o3 ! o3 has 8-byte multiple 970Sstevel@tonic-gate 980Sstevel@tonic-gate dec %o2 990Sstevel@tonic-gate stb %o1, [%o5] ! clear a byte 1000Sstevel@tonic-gate b .dalign ! go see if aligned yet 1010Sstevel@tonic-gate inc %o5 1020Sstevel@tonic-gate 1030Sstevel@tonic-gate .align 32 1040Sstevel@tonic-gate.wrdbl: 1050Sstevel@tonic-gate stx %o1, [%o5] ! write aligned 8 bytes 1060Sstevel@tonic-gate subcc %o3, 8, %o3 1070Sstevel@tonic-gate bnz,pt %xcc, .wrdbl 1080Sstevel@tonic-gate inc 8, %o5 1090Sstevel@tonic-gate 1100Sstevel@tonic-gate b .wrchar ! write the remaining bytes 1110Sstevel@tonic-gate and %o2, 7, %o2 ! leftover count, if any 1120Sstevel@tonic-gate 1130Sstevel@tonic-gate.walign: ! Set bytes until 4-byte aligned 1140Sstevel@tonic-gate btst 3, %o5 ! if bigger, align to 4 bytes 1150Sstevel@tonic-gate bz,pn %icc, .wrword 1160Sstevel@tonic-gate andn %o2, 3, %o3 ! create word sized count in %o3 1170Sstevel@tonic-gate 1180Sstevel@tonic-gate dec %o2 ! decrement count 1190Sstevel@tonic-gate stb %o1, [%o5] ! clear a byte 1200Sstevel@tonic-gate b .walign 1210Sstevel@tonic-gate inc %o5 ! next byte 1220Sstevel@tonic-gate 1230Sstevel@tonic-gate.wrword: 1240Sstevel@tonic-gate st %o1, [%o5] ! 4-byte writing loop 1250Sstevel@tonic-gate subcc %o3, 4, %o3 1260Sstevel@tonic-gate bnz,pn %xcc, .wrword 1270Sstevel@tonic-gate inc 4, %o5 1280Sstevel@tonic-gate 1290Sstevel@tonic-gate and %o2, 3, %o2 ! leftover count, if any 1300Sstevel@tonic-gate 1310Sstevel@tonic-gate.wrchar: 1320Sstevel@tonic-gate deccc %o2 ! byte clearing loop 1330Sstevel@tonic-gate inc %o5 1340Sstevel@tonic-gate bgeu,a,pt %xcc, .wrchar 1350Sstevel@tonic-gate stb %o1, [%o5 + -1] ! we've already incremented the address 1360Sstevel@tonic-gate 1370Sstevel@tonic-gate retl 1380Sstevel@tonic-gate sub %o0, %g0, %o0 1390Sstevel@tonic-gate 1400Sstevel@tonic-gate SET_SIZE(memset) 141