These changes are the raw update to linux-4.4.6-rt14. Kernel sources
[kvmfornfv.git] / kernel / arch / nios2 / lib / memset.c
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 void *memset(void *s, int c, size_t count)
14 {
15         int destptr, charcnt, dwordcnt, fill8reg, wrkrega;
16
17         if (!count)
18                 return s;
19
20         c &= 0xFF;
21
22         if (count <= 8) {
23                 char *xs = (char *) s;
24
25                 while (count--)
26                         *xs++ = c;
27                 return s;
28         }
29
30         __asm__ __volatile__ (
31                 /* fill8 %3, %5 (c & 0xff) */
32                 "       slli    %4, %5, 8\n"
33                 "       or      %4, %4, %5\n"
34                 "       slli    %3, %4, 16\n"
35                 "       or      %3, %3, %4\n"
36                 /* Word-align %0 (s) if necessary */
37                 "       andi    %4, %0, 0x01\n"
38                 "       beq     %4, zero, 1f\n"
39                 "       addi    %1, %1, -1\n"
40                 "       stb     %3, 0(%0)\n"
41                 "       addi    %0, %0, 1\n"
42                 "1:     mov     %2, %1\n"
43                 /* Dword-align %0 (s) if necessary */
44                 "       andi    %4, %0, 0x02\n"
45                 "       beq     %4, zero, 2f\n"
46                 "       addi    %1, %1, -2\n"
47                 "       sth     %3, 0(%0)\n"
48                 "       addi    %0, %0, 2\n"
49                 "       mov     %2, %1\n"
50                 /* %1 and %2 are how many more bytes to set */
51                 "2:     srli    %2, %2, 2\n"
52                 /* %2 is how many dwords to set */
53                 "3:     stw     %3, 0(%0)\n"
54                 "       addi    %0, %0, 4\n"
55                 "       addi    %2, %2, -1\n"
56                 "       bne     %2, zero, 3b\n"
57                 /* store residual word and/or byte if necessary */
58                 "       andi    %4, %1, 0x02\n"
59                 "       beq     %4, zero, 4f\n"
60                 "       sth     %3, 0(%0)\n"
61                 "       addi    %0, %0, 2\n"
62                 /* store residual byte if necessary */
63                 "4:     andi    %4, %1, 0x01\n"
64                 "       beq     %4, zero, 5f\n"
65                 "       stb     %3, 0(%0)\n"
66                 "5:\n"
67                 : "=r" (destptr),       /* %0  Output */
68                   "=r" (charcnt),       /* %1  Output */
69                   "=r" (dwordcnt),      /* %2  Output */
70                   "=r" (fill8reg),      /* %3  Output */
71                   "=r" (wrkrega)        /* %4  Output */
72                 : "r" (c),              /* %5  Input */
73                   "0" (s),              /* %0  Input/Output */
74                   "1" (count)           /* %1  Input/Output */
75                 : "memory"              /* clobbered */
76         );
77
78         return s;
79 }