1 /* 2 * Copyright (C) 2008-2009 Michal Simek <monstr@monstr.eu> 3 * Copyright (C) 2008-2009 PetaLogix 4 * Copyright (C) 2007 John Williams 5 * 6 * Reasonably optimised generic C-code for memset on Microblaze 7 * This is generic C code to do efficient, alignment-aware memcpy. 8 * 9 * It is based on demo code originally Copyright 2001 by Intel Corp, taken from 10 * http://www.embedded.com/showArticle.jhtml?articleID=19205567 11 * 12 * Attempts were made, unsuccessfully, to contact the original 13 * author of this code (Michael Morrow, Intel). Below is the original 14 * copyright notice. 15 * 16 * This software has been developed by Intel Corporation. 17 * Intel specifically disclaims all warranties, express or 18 * implied, and all liability, including consequential and 19 * other indirect damages, for the use of this program, including 20 * liability for infringement of any proprietary rights, 21 * and including the warranties of merchantability and fitness 22 * for a particular purpose. Intel does not assume any 23 * responsibility for and errors which may appear in this program 24 * not any responsibility to update it. 25 */ 26 27 #include <linux/export.h> 28 #include <linux/types.h> 29 #include <linux/stddef.h> 30 #include <linux/compiler.h> 31 #include <linux/string.h> 32 33 #ifdef __HAVE_ARCH_MEMSET 34 #ifndef CONFIG_OPT_LIB_FUNCTION 35 void *memset(void *v_src, int c, __kernel_size_t n) 36 { 37 char *src = v_src; 38 39 /* Truncate c to 8 bits */ 40 c = (c & 0xFF); 41 42 /* Simple, byte oriented memset or the rest of count. */ 43 while (n--) 44 *src++ = c; 45 46 return v_src; 47 } 48 #else /* CONFIG_OPT_LIB_FUNCTION */ 49 void *memset(void *v_src, int c, __kernel_size_t n) 50 { 51 char *src = v_src; 52 uint32_t *i_src; 53 uint32_t w32 = 0; 54 55 /* Truncate c to 8 bits */ 56 c = (c & 0xFF); 57 58 if (unlikely(c)) { 59 /* Make a repeating word out of it */ 60 w32 = c; 61 w32 |= w32 << 8; 62 w32 |= w32 << 16; 63 } 64 65 if (likely(n >= 4)) { 66 /* Align the destination to a word boundary */ 67 /* This is done in an endian independent manner */ 68 switch ((unsigned) src & 3) { 69 case 1: 70 *src++ = c; 71 --n; 72 fallthrough; 73 case 2: 74 *src++ = c; 75 --n; 76 fallthrough; 77 case 3: 78 *src++ = c; 79 --n; 80 } 81 82 i_src = (void *)src; 83 84 /* Do as many full-word copies as we can */ 85 for (; n >= 4; n -= 4) 86 *i_src++ = w32; 87 88 src = (void *)i_src; 89 } 90 91 /* Simple, byte oriented memset or the rest of count. */ 92 while (n--) 93 *src++ = c; 94 95 return v_src; 96 } 97 #endif /* CONFIG_OPT_LIB_FUNCTION */ 98 EXPORT_SYMBOL(memset); 99 #endif /* __HAVE_ARCH_MEMSET */ 100