1/* SPDX-License-Identifier: GPL-2.0-or-later */
2#include <linux/types.h>
3#include <asm/string.h>
4
5#define OPSIZ (BITS_PER_LONG/8)
6typedef unsigned long op_t;
7
8void *
9memset (void *dstpp, int sc, size_t len)
10{
11 unsigned int c = sc;
12 long int dstp = (long int) dstpp;
13
14 if (len >= 8)
15 {
16 size_t xlen;
17 op_t cccc;
18
19 cccc = (unsigned char) c;
20 cccc |= cccc << 8;
21 cccc |= cccc << 16;
22 if (OPSIZ > 4)
23 /* Do the shift in two steps to avoid warning if long has 32 bits. */
24 cccc |= (cccc << 16) << 16;
25
26 /* There are at least some bytes to set.
27 No need to test for LEN == 0 in this alignment loop. */
28 while (dstp % OPSIZ != 0)
29 {
30 ((unsigned char *) dstp)[0] = c;
31 dstp += 1;
32 len -= 1;
33 }
34
35 /* Write 8 `op_t' per iteration until less than 8 `op_t' remain. */
36 xlen = len / (OPSIZ * 8);
37 while (xlen > 0)
38 {
39 ((op_t *) dstp)[0] = cccc;
40 ((op_t *) dstp)[1] = cccc;
41 ((op_t *) dstp)[2] = cccc;
42 ((op_t *) dstp)[3] = cccc;
43 ((op_t *) dstp)[4] = cccc;
44 ((op_t *) dstp)[5] = cccc;
45 ((op_t *) dstp)[6] = cccc;
46 ((op_t *) dstp)[7] = cccc;
47 dstp += 8 * OPSIZ;
48 xlen -= 1;
49 }
50 len %= OPSIZ * 8;
51
52 /* Write 1 `op_t' per iteration until less than OPSIZ bytes remain. */
53 xlen = len / OPSIZ;
54 while (xlen > 0)
55 {
56 ((op_t *) dstp)[0] = cccc;
57 dstp += OPSIZ;
58 xlen -= 1;
59 }
60 len %= OPSIZ;
61 }
62
63 /* Write the last few bytes. */
64 while (len > 0)
65 {
66 ((unsigned char *) dstp)[0] = c;
67 dstp += 1;
68 len -= 1;
69 }
70
71 return dstpp;
72}
73

source code of linux/arch/parisc/lib/memset.c