1322ae8ebSMichal Simek /*
2322ae8ebSMichal Simek * Copyright (C) 2008-2009 Michal Simek <monstr@monstr.eu>
3322ae8ebSMichal Simek * Copyright (C) 2008-2009 PetaLogix
4322ae8ebSMichal Simek * Copyright (C) 2007 John Williams
5322ae8ebSMichal Simek *
6322ae8ebSMichal Simek * Reasonably optimised generic C-code for memset on Microblaze
7322ae8ebSMichal Simek * This is generic C code to do efficient, alignment-aware memcpy.
8322ae8ebSMichal Simek *
9322ae8ebSMichal Simek * It is based on demo code originally Copyright 2001 by Intel Corp, taken from
10322ae8ebSMichal Simek * http://www.embedded.com/showArticle.jhtml?articleID=19205567
11322ae8ebSMichal Simek *
12af901ca1SAndré Goddard Rosa * Attempts were made, unsuccessfully, to contact the original
13322ae8ebSMichal Simek * author of this code (Michael Morrow, Intel). Below is the original
14322ae8ebSMichal Simek * copyright notice.
15322ae8ebSMichal Simek *
16322ae8ebSMichal Simek * This software has been developed by Intel Corporation.
17322ae8ebSMichal Simek * Intel specifically disclaims all warranties, express or
18322ae8ebSMichal Simek * implied, and all liability, including consequential and
19322ae8ebSMichal Simek * other indirect damages, for the use of this program, including
20322ae8ebSMichal Simek * liability for infringement of any proprietary rights,
21322ae8ebSMichal Simek * and including the warranties of merchantability and fitness
22322ae8ebSMichal Simek * for a particular purpose. Intel does not assume any
23322ae8ebSMichal Simek * responsibility for and errors which may appear in this program
24322ae8ebSMichal Simek * not any responsibility to update it.
25322ae8ebSMichal Simek */
26322ae8ebSMichal Simek
27d64af918SMichal Simek #include <linux/export.h>
28322ae8ebSMichal Simek #include <linux/types.h>
29322ae8ebSMichal Simek #include <linux/stddef.h>
30322ae8ebSMichal Simek #include <linux/compiler.h>
31322ae8ebSMichal Simek #include <linux/string.h>
32322ae8ebSMichal Simek
338f0f265eSMichal Simek #ifdef CONFIG_OPT_LIB_FUNCTION
memset(void * v_src,int c,__kernel_size_t n)3493e2e851SMichal Simek void *memset(void *v_src, int c, __kernel_size_t n)
3593e2e851SMichal Simek {
3693e2e851SMichal Simek char *src = v_src;
3793e2e851SMichal Simek uint32_t *i_src;
3893e2e851SMichal Simek uint32_t w32 = 0;
3993e2e851SMichal Simek
4093e2e851SMichal Simek /* Truncate c to 8 bits */
4193e2e851SMichal Simek c = (c & 0xFF);
4293e2e851SMichal Simek
4378ebfa88SMichal Simek if (unlikely(c)) {
44322ae8ebSMichal Simek /* Make a repeating word out of it */
45322ae8ebSMichal Simek w32 = c;
46322ae8ebSMichal Simek w32 |= w32 << 8;
47322ae8ebSMichal Simek w32 |= w32 << 16;
4878ebfa88SMichal Simek }
49322ae8ebSMichal Simek
5078ebfa88SMichal Simek if (likely(n >= 4)) {
51322ae8ebSMichal Simek /* Align the destination to a word boundary */
5225985edcSLucas De Marchi /* This is done in an endian independent manner */
53322ae8ebSMichal Simek switch ((unsigned) src & 3) {
54322ae8ebSMichal Simek case 1:
55322ae8ebSMichal Simek *src++ = c;
56322ae8ebSMichal Simek --n;
5747de4477SRandy Dunlap fallthrough;
58322ae8ebSMichal Simek case 2:
59322ae8ebSMichal Simek *src++ = c;
60322ae8ebSMichal Simek --n;
6147de4477SRandy Dunlap fallthrough;
62322ae8ebSMichal Simek case 3:
63322ae8ebSMichal Simek *src++ = c;
64322ae8ebSMichal Simek --n;
65322ae8ebSMichal Simek }
66322ae8ebSMichal Simek
67322ae8ebSMichal Simek i_src = (void *)src;
68322ae8ebSMichal Simek
69322ae8ebSMichal Simek /* Do as many full-word copies as we can */
70322ae8ebSMichal Simek for (; n >= 4; n -= 4)
71322ae8ebSMichal Simek *i_src++ = w32;
72322ae8ebSMichal Simek
73322ae8ebSMichal Simek src = (void *)i_src;
74322ae8ebSMichal Simek }
7593e2e851SMichal Simek
76322ae8ebSMichal Simek /* Simple, byte oriented memset or the rest of count. */
77*95fee37bSMichal Simek switch (n) {
78*95fee37bSMichal Simek case 3:
79322ae8ebSMichal Simek *src++ = c;
80*95fee37bSMichal Simek fallthrough;
81*95fee37bSMichal Simek case 2:
82*95fee37bSMichal Simek *src++ = c;
83*95fee37bSMichal Simek fallthrough;
84*95fee37bSMichal Simek case 1:
85*95fee37bSMichal Simek *src++ = c;
86*95fee37bSMichal Simek break;
87*95fee37bSMichal Simek default:
88*95fee37bSMichal Simek break;
89*95fee37bSMichal Simek }
90322ae8ebSMichal Simek
91322ae8ebSMichal Simek return v_src;
92322ae8ebSMichal Simek }
93322ae8ebSMichal Simek EXPORT_SYMBOL(memset);
948f0f265eSMichal Simek #endif /* CONFIG_OPT_LIB_FUNCTION */
95