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 Dellermemset (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