xref: /linux/arch/microblaze/lib/memset.c (revision 4f2c0a4acffbec01079c28f839422e64ddeff004)
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