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 CONFIG_OPT_LIB_FUNCTION 34 void *memset(void *v_src, int c, __kernel_size_t n) 35 { 36 char *src = v_src; 37 uint32_t *i_src; 38 uint32_t w32 = 0; 39 40 /* Truncate c to 8 bits */ 41 c = (c & 0xFF); 42 43 if (unlikely(c)) { 44 /* Make a repeating word out of it */ 45 w32 = c; 46 w32 |= w32 << 8; 47 w32 |= w32 << 16; 48 } 49 50 if (likely(n >= 4)) { 51 /* Align the destination to a word boundary */ 52 /* This is done in an endian independent manner */ 53 switch ((unsigned) src & 3) { 54 case 1: 55 *src++ = c; 56 --n; 57 fallthrough; 58 case 2: 59 *src++ = c; 60 --n; 61 fallthrough; 62 case 3: 63 *src++ = c; 64 --n; 65 } 66 67 i_src = (void *)src; 68 69 /* Do as many full-word copies as we can */ 70 for (; n >= 4; n -= 4) 71 *i_src++ = w32; 72 73 src = (void *)i_src; 74 } 75 76 /* Simple, byte oriented memset or the rest of count. */ 77 switch (n) { 78 case 3: 79 *src++ = c; 80 fallthrough; 81 case 2: 82 *src++ = c; 83 fallthrough; 84 case 1: 85 *src++ = c; 86 break; 87 default: 88 break; 89 } 90 91 return v_src; 92 } 93 EXPORT_SYMBOL(memset); 94 #endif /* CONFIG_OPT_LIB_FUNCTION */ 95