]> git.proxmox.com Git - ceph.git/blob - ceph/src/pmdk/src/libpmem2/x86_64/memset/memset_t_avx.c
import ceph 16.2.7
[ceph.git] / ceph / src / pmdk / src / libpmem2 / x86_64 / memset / memset_t_avx.c
1 // SPDX-License-Identifier: BSD-3-Clause
2 /* Copyright 2017-2020, Intel Corporation */
3
4 #include <immintrin.h>
5 #include <stddef.h>
6 #include <stdint.h>
7
8 #include "pmem2_arch.h"
9 #include "avx.h"
10 #include "flush.h"
11 #include "memcpy_memset.h"
12 #include "memset_avx.h"
13
14 static force_inline void
15 mm256_store_si256(char *dest, unsigned idx, __m256i src)
16 {
17 _mm256_store_si256((__m256i *)dest + idx, src);
18 }
19
20 static force_inline void
21 memset_mov8x64b(char *dest, __m256i ymm, flush64b_fn flush64b)
22 {
23 mm256_store_si256(dest, 0, ymm);
24 mm256_store_si256(dest, 1, ymm);
25 mm256_store_si256(dest, 2, ymm);
26 mm256_store_si256(dest, 3, ymm);
27 mm256_store_si256(dest, 4, ymm);
28 mm256_store_si256(dest, 5, ymm);
29 mm256_store_si256(dest, 6, ymm);
30 mm256_store_si256(dest, 7, ymm);
31 mm256_store_si256(dest, 8, ymm);
32 mm256_store_si256(dest, 9, ymm);
33 mm256_store_si256(dest, 10, ymm);
34 mm256_store_si256(dest, 11, ymm);
35 mm256_store_si256(dest, 12, ymm);
36 mm256_store_si256(dest, 13, ymm);
37 mm256_store_si256(dest, 14, ymm);
38 mm256_store_si256(dest, 15, ymm);
39
40 flush64b(dest + 0 * 64);
41 flush64b(dest + 1 * 64);
42 flush64b(dest + 2 * 64);
43 flush64b(dest + 3 * 64);
44 flush64b(dest + 4 * 64);
45 flush64b(dest + 5 * 64);
46 flush64b(dest + 6 * 64);
47 flush64b(dest + 7 * 64);
48 }
49
50 static force_inline void
51 memset_mov4x64b(char *dest, __m256i ymm, flush64b_fn flush64b)
52 {
53 mm256_store_si256(dest, 0, ymm);
54 mm256_store_si256(dest, 1, ymm);
55 mm256_store_si256(dest, 2, ymm);
56 mm256_store_si256(dest, 3, ymm);
57 mm256_store_si256(dest, 4, ymm);
58 mm256_store_si256(dest, 5, ymm);
59 mm256_store_si256(dest, 6, ymm);
60 mm256_store_si256(dest, 7, ymm);
61
62 flush64b(dest + 0 * 64);
63 flush64b(dest + 1 * 64);
64 flush64b(dest + 2 * 64);
65 flush64b(dest + 3 * 64);
66 }
67
68 static force_inline void
69 memset_mov2x64b(char *dest, __m256i ymm, flush64b_fn flush64b)
70 {
71 mm256_store_si256(dest, 0, ymm);
72 mm256_store_si256(dest, 1, ymm);
73 mm256_store_si256(dest, 2, ymm);
74 mm256_store_si256(dest, 3, ymm);
75
76 flush64b(dest + 0 * 64);
77 flush64b(dest + 1 * 64);
78 }
79
80 static force_inline void
81 memset_mov1x64b(char *dest, __m256i ymm, flush64b_fn flush64b)
82 {
83 mm256_store_si256(dest, 0, ymm);
84 mm256_store_si256(dest, 1, ymm);
85
86 flush64b(dest + 0 * 64);
87 }
88
89 static force_inline void
90 memset_mov_avx(char *dest, int c, size_t len,
91 flush_fn flush, flush64b_fn flush64b)
92 {
93 __m256i ymm = _mm256_set1_epi8((char)c);
94
95 size_t cnt = (uint64_t)dest & 63;
96 if (cnt > 0) {
97 cnt = 64 - cnt;
98
99 if (cnt > len)
100 cnt = len;
101
102 memset_small_avx(dest, ymm, cnt, flush);
103
104 dest += cnt;
105 len -= cnt;
106 }
107
108 while (len >= 8 * 64) {
109 memset_mov8x64b(dest, ymm, flush64b);
110 dest += 8 * 64;
111 len -= 8 * 64;
112 }
113
114 if (len >= 4 * 64) {
115 memset_mov4x64b(dest, ymm, flush64b);
116 dest += 4 * 64;
117 len -= 4 * 64;
118 }
119
120 if (len >= 2 * 64) {
121 memset_mov2x64b(dest, ymm, flush64b);
122 dest += 2 * 64;
123 len -= 2 * 64;
124 }
125
126 if (len >= 1 * 64) {
127 memset_mov1x64b(dest, ymm, flush64b);
128
129 dest += 1 * 64;
130 len -= 1 * 64;
131 }
132
133 if (len)
134 memset_small_avx(dest, ymm, len, flush);
135
136 avx_zeroupper();
137 }
138
139 void
140 memset_mov_avx_noflush(char *dest, int c, size_t len)
141 {
142 LOG(15, "dest %p c %d len %zu", dest, c, len);
143
144 memset_mov_avx(dest, c, len, noflush, noflush64b);
145 }
146
147 void
148 memset_mov_avx_empty(char *dest, int c, size_t len)
149 {
150 LOG(15, "dest %p c %d len %zu", dest, c, len);
151
152 memset_mov_avx(dest, c, len, flush_empty_nolog, flush64b_empty);
153 }
154
155 void
156 memset_mov_avx_clflush(char *dest, int c, size_t len)
157 {
158 LOG(15, "dest %p c %d len %zu", dest, c, len);
159
160 memset_mov_avx(dest, c, len, flush_clflush_nolog, pmem_clflush);
161 }
162
163 void
164 memset_mov_avx_clflushopt(char *dest, int c, size_t len)
165 {
166 LOG(15, "dest %p c %d len %zu", dest, c, len);
167
168 memset_mov_avx(dest, c, len, flush_clflushopt_nolog,
169 pmem_clflushopt);
170 }
171
172 void
173 memset_mov_avx_clwb(char *dest, int c, size_t len)
174 {
175 LOG(15, "dest %p c %d len %zu", dest, c, len);
176
177 memset_mov_avx(dest, c, len, flush_clwb_nolog, pmem_clwb);
178 }