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