1 /*
2 * Copyright (c) 2021-2021 Huawei Device Co., Ltd. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without modification,
5 * are permitted provided that the following conditions are met:
6 *
7 * 1. Redistributions of source code must retain the above copyright notice, this list of
8 * conditions and the following disclaimer.
9 *
10 * 2. Redistributions in binary form must reproduce the above copyright notice, this list
11 * of conditions and the following disclaimer in the documentation and/or other materials
12 * provided with the distribution.
13 *
14 * 3. Neither the name of the copyright holder nor the names of its contributors may be used
15 * to endorse or promote products derived from this software without specific prior written
16 * permission.
17 *
18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
20 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
21 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
22 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
23 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
24 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
25 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
26 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
27 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
28 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 */
30
31 #include <stdio.h>
32 #include <string.h>
33 #include <stdlib.h>
34 #include <stdint.h>
35
memset(void * dest,int c,size_t n)36 void *memset(void *dest, int c, size_t n)
37 {
38 char *pos = dest;
39 uint32_t c32 = 0;
40 uint64_t c64 = 0;
41
42 if (n == 0) return dest;
43
44 c = c & 0xFF;
45 if (c) {
46 c32 = c;
47 c32 |= c32 << 8;
48 c32 |= c32 << 16;
49 c64 = c32;
50 c64 |= c64 << 32;
51 }
52
53 if (((uintptr_t)(pos) & 7) != 0) {
54 int unalignedCnt = 8 - ((uintptr_t)(pos) & 7);
55 if (n >= unalignedCnt) {
56 n = n - unalignedCnt;
57 } else {
58 unalignedCnt = n;
59 n = 0;
60 }
61 for (int loop = 1; loop <= unalignedCnt; ++loop) {
62 *pos = (char)c;
63 pos++;
64 }
65 }
66
67 /* L32_byte_aligned */
68 while (n >= 32) {
69 *(uint64_t *)(pos) = c64;
70 *(uint64_t *)(pos + 8) = c64;
71 *(uint64_t *)(pos + 16) = c64;
72 *(uint64_t *)(pos + 24) = c64;
73 n -= 32;
74 pos += 32;
75 }
76 if (n == 0) return dest;
77
78 /* L16_byte_aligned */
79 if (n >= 16) {
80 *(uint64_t *)(pos) = c64;
81 *(uint64_t *)(pos + 8) = c64;
82 n -= 16;
83 pos += 16;
84 if (n == 0) return dest;
85 }
86
87 /* L8_byte_aligned */
88 if (n >= 8) {
89 *(uint64_t *)(pos) = c64;
90 n -= 8;
91 pos += 8;
92 if (n == 0) return dest;
93 }
94
95 /* L4_byte_aligned */
96 if (n >= 4) {
97 *(uint32_t *)(pos) = c32;
98 n -= 4;
99 pos += 4;
100 if (n == 0) return dest;
101 }
102 while (n--) {
103 *pos++ = c;
104 }
105
106 return dest;
107 }