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