1*dbaef6efSGabe Black /* 2*dbaef6efSGabe Black * Copyright (C) 1991,1992,1993,1997,1998,2003, 2005 Free Software Foundation, Inc. 3*dbaef6efSGabe Black * This file is part of the GNU C Library. 4*dbaef6efSGabe Black * Copyright (c) 2011 The Chromium OS Authors. 5*dbaef6efSGabe Black * 6*dbaef6efSGabe Black * See file CREDITS for list of people who contributed to this 7*dbaef6efSGabe Black * project. 8*dbaef6efSGabe Black * 9*dbaef6efSGabe Black * This program is free software; you can redistribute it and/or 10*dbaef6efSGabe Black * modify it under the terms of the GNU General Public License as 11*dbaef6efSGabe Black * published by the Free Software Foundation; either version 2 of 12*dbaef6efSGabe Black * the License, or (at your option) any later version. 13*dbaef6efSGabe Black * 14*dbaef6efSGabe Black * This program is distributed in the hope that it will be useful, 15*dbaef6efSGabe Black * but WITHOUT ANY WARRANTY; without even the implied warranty of 16*dbaef6efSGabe Black * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17*dbaef6efSGabe Black * GNU General Public License for more details. 18*dbaef6efSGabe Black * 19*dbaef6efSGabe Black * You should have received a copy of the GNU General Public License 20*dbaef6efSGabe Black * along with this program; if not, write to the Free Software 21*dbaef6efSGabe Black * Foundation, Inc., 59 Temple Place, Suite 330, Boston, 22*dbaef6efSGabe Black * MA 02111-1307 USA 23*dbaef6efSGabe Black */ 24*dbaef6efSGabe Black 25*dbaef6efSGabe Black /* From glibc-2.14, sysdeps/i386/memset.c */ 26*dbaef6efSGabe Black 27*dbaef6efSGabe Black #include <compiler.h> 28*dbaef6efSGabe Black #include <asm/string.h> 29*dbaef6efSGabe Black #include <linux/types.h> 30*dbaef6efSGabe Black 31*dbaef6efSGabe Black typedef uint32_t op_t; 32*dbaef6efSGabe Black 33*dbaef6efSGabe Black void *memset(void *dstpp, int c, size_t len) 34*dbaef6efSGabe Black { 35*dbaef6efSGabe Black int d0; 36*dbaef6efSGabe Black unsigned long int dstp = (unsigned long int) dstpp; 37*dbaef6efSGabe Black 38*dbaef6efSGabe Black /* This explicit register allocation improves code very much indeed. */ 39*dbaef6efSGabe Black register op_t x asm("ax"); 40*dbaef6efSGabe Black 41*dbaef6efSGabe Black x = (unsigned char) c; 42*dbaef6efSGabe Black 43*dbaef6efSGabe Black /* Clear the direction flag, so filling will move forward. */ 44*dbaef6efSGabe Black asm volatile("cld"); 45*dbaef6efSGabe Black 46*dbaef6efSGabe Black /* This threshold value is optimal. */ 47*dbaef6efSGabe Black if (len >= 12) { 48*dbaef6efSGabe Black /* Fill X with four copies of the char we want to fill with. */ 49*dbaef6efSGabe Black x |= (x << 8); 50*dbaef6efSGabe Black x |= (x << 16); 51*dbaef6efSGabe Black 52*dbaef6efSGabe Black /* Adjust LEN for the bytes handled in the first loop. */ 53*dbaef6efSGabe Black len -= (-dstp) % sizeof(op_t); 54*dbaef6efSGabe Black 55*dbaef6efSGabe Black /* 56*dbaef6efSGabe Black * There are at least some bytes to set. No need to test for 57*dbaef6efSGabe Black * LEN == 0 in this alignment loop. 58*dbaef6efSGabe Black */ 59*dbaef6efSGabe Black 60*dbaef6efSGabe Black /* Fill bytes until DSTP is aligned on a longword boundary. */ 61*dbaef6efSGabe Black asm volatile( 62*dbaef6efSGabe Black "rep\n" 63*dbaef6efSGabe Black "stosb" /* %0, %2, %3 */ : 64*dbaef6efSGabe Black "=D" (dstp), "=c" (d0) : 65*dbaef6efSGabe Black "0" (dstp), "1" ((-dstp) % sizeof(op_t)), "a" (x) : 66*dbaef6efSGabe Black "memory"); 67*dbaef6efSGabe Black 68*dbaef6efSGabe Black /* Fill longwords. */ 69*dbaef6efSGabe Black asm volatile( 70*dbaef6efSGabe Black "rep\n" 71*dbaef6efSGabe Black "stosl" /* %0, %2, %3 */ : 72*dbaef6efSGabe Black "=D" (dstp), "=c" (d0) : 73*dbaef6efSGabe Black "0" (dstp), "1" (len / sizeof(op_t)), "a" (x) : 74*dbaef6efSGabe Black "memory"); 75*dbaef6efSGabe Black len %= sizeof(op_t); 76*dbaef6efSGabe Black } 77*dbaef6efSGabe Black 78*dbaef6efSGabe Black /* Write the last few bytes. */ 79*dbaef6efSGabe Black asm volatile( 80*dbaef6efSGabe Black "rep\n" 81*dbaef6efSGabe Black "stosb" /* %0, %2, %3 */ : 82*dbaef6efSGabe Black "=D" (dstp), "=c" (d0) : 83*dbaef6efSGabe Black "0" (dstp), "1" (len), "a" (x) : 84*dbaef6efSGabe Black "memory"); 85*dbaef6efSGabe Black 86*dbaef6efSGabe Black return dstpp; 87*dbaef6efSGabe Black } 88