xref: /openbmc/linux/arch/nios2/lib/memset.c (revision 0da85d1e)
1 /*
2  * Copyright (C) 2011 Tobias Klauser <tklauser@distanz.ch>
3  * Copyright (C) 2004 Microtronix Datacom Ltd
4  *
5  * This file is subject to the terms and conditions of the GNU General Public
6  * License.  See the file "COPYING" in the main directory of this archive
7  * for more details.
8  */
9 
10 #include <linux/types.h>
11 #include <linux/string.h>
12 
13 #ifdef __HAVE_ARCH_MEMSET
14 void *memset(void *s, int c, size_t count)
15 {
16 	int destptr, charcnt, dwordcnt, fill8reg, wrkrega;
17 
18 	if (!count)
19 		return s;
20 
21 	c &= 0xFF;
22 
23 	if (count <= 8) {
24 		char *xs = (char *) s;
25 
26 		while (count--)
27 			*xs++ = c;
28 		return s;
29 	}
30 
31 	__asm__ __volatile__ (
32 		/* fill8 %3, %5 (c & 0xff) */
33 		"	slli	%4, %5, 8\n"
34 		"	or	%4, %4, %5\n"
35 		"	slli    %3, %4, 16\n"
36 		"	or	%3, %3, %4\n"
37 		/* Word-align %0 (s) if necessary */
38 		"	andi	%4, %0, 0x01\n"
39 		"	beq	%4, zero, 1f\n"
40 		"	addi	%1, %1, -1\n"
41 		"	stb	%3, 0(%0)\n"
42 		"	addi	%0, %0, 1\n"
43 		"1:	mov	%2, %1\n"
44 		/* Dword-align %0 (s) if necessary */
45 		"	andi	%4, %0, 0x02\n"
46 		"	beq	%4, zero, 2f\n"
47 		"	addi	%1, %1, -2\n"
48 		"	sth	%3, 0(%0)\n"
49 		"	addi	%0, %0, 2\n"
50 		"	mov	%2, %1\n"
51 		/* %1 and %2 are how many more bytes to set */
52 		"2:	srli	%2, %2, 2\n"
53 		/* %2 is how many dwords to set */
54 		"3:	stw	%3, 0(%0)\n"
55 		"	addi	%0, %0, 4\n"
56 		"	addi    %2, %2, -1\n"
57 		"	bne	%2, zero, 3b\n"
58 		/* store residual word and/or byte if necessary */
59 		"	andi	%4, %1, 0x02\n"
60 		"	beq	%4, zero, 4f\n"
61 		"	sth	%3, 0(%0)\n"
62 		"	addi	%0, %0, 2\n"
63 		/* store residual byte if necessary */
64 		"4:	andi	%4, %1, 0x01\n"
65 		"	beq	%4, zero, 5f\n"
66 		"	stb	%3, 0(%0)\n"
67 		"5:\n"
68 		: "=r" (destptr),	/* %0  Output */
69 		  "=r" (charcnt),	/* %1  Output */
70 		  "=r" (dwordcnt),	/* %2  Output */
71 		  "=r" (fill8reg),	/* %3  Output */
72 		  "=r" (wrkrega)	/* %4  Output */
73 		: "r" (c),		/* %5  Input */
74 		  "0" (s),		/* %0  Input/Output */
75 		  "1" (count)		/* %1  Input/Output */
76 		: "memory"		/* clobbered */
77 	);
78 
79 	return s;
80 }
81 #endif /* __HAVE_ARCH_MEMSET */
82