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