libxr  1.0
Want to be the best embedded framework
Loading...
Searching...
No Matches
libxr_mem.cpp
1#include "libxr_def.hpp"
2
3void LibXR::Memory::FastCopy(void* dst, const void* src, size_t size)
4{
5 uint8_t* d = static_cast<uint8_t*>(dst);
6 const uint8_t* s = static_cast<const uint8_t*>(src);
7
8 uintptr_t d_offset = reinterpret_cast<uintptr_t>(d) & (LIBXR_ALIGN_SIZE - 1);
9 uintptr_t s_offset = reinterpret_cast<uintptr_t>(s) & (LIBXR_ALIGN_SIZE - 1);
10
15 if (d_offset == s_offset)
16 {
18 if (d_offset)
19 {
20 size_t head = LIBXR_ALIGN_SIZE - d_offset;
21 if (head > size)
22 {
23 head = size;
24 }
25 while (head--)
26 {
27 *d++ = *s++;
28 --size;
29 }
30 }
31
32#if LIBXR_ALIGN_SIZE == 8
34 auto* dw = reinterpret_cast<uint64_t*>(d);
35 auto* sw = reinterpret_cast<const uint64_t*>(s);
36
37 while (size >= 64)
38 {
39 dw[0] = sw[0];
40 dw[1] = sw[1];
41 dw[2] = sw[2];
42 dw[3] = sw[3];
43 dw[4] = sw[4];
44 dw[5] = sw[5];
45 dw[6] = sw[6];
46 dw[7] = sw[7];
47 dw += 8;
48 sw += 8;
49 size -= 64;
50 }
51 while (size >= 8)
52 {
53 *dw++ = *sw++;
54 size -= 8;
55 }
56
57 d = reinterpret_cast<uint8_t*>(dw);
58 s = reinterpret_cast<const uint8_t*>(sw);
59#else
61 auto* dw = reinterpret_cast<uint32_t*>(d);
62 auto* sw = reinterpret_cast<const uint32_t*>(s);
63
64 while (size >= 32)
65 {
66 dw[0] = sw[0];
67 dw[1] = sw[1];
68 dw[2] = sw[2];
69 dw[3] = sw[3];
70 dw[4] = sw[4];
71 dw[5] = sw[5];
72 dw[6] = sw[6];
73 dw[7] = sw[7];
74 dw += 8;
75 sw += 8;
76 size -= 32;
77 }
78 while (size >= 4)
79 {
80 *dw++ = *sw++;
81 size -= 4;
82 }
83
84 d = reinterpret_cast<uint8_t*>(dw);
85 s = reinterpret_cast<const uint8_t*>(sw);
86#endif
87 }
92 else
93 {
94 uintptr_t addr_diff = reinterpret_cast<uintptr_t>(s) - reinterpret_cast<uintptr_t>(d);
95
96#if LIBXR_ALIGN_SIZE == 8
98 if ((addr_diff & 3) == 0 && size > 0)
99 {
100 while ((reinterpret_cast<uintptr_t>(d) & 3) && size)
101 {
102 *d++ = *s++;
103 --size;
104 }
105 auto* d32 = reinterpret_cast<uint32_t*>(d);
106 auto* s32 = reinterpret_cast<const uint32_t*>(s);
107
108 while (size >= 32)
109 {
110 d32[0] = s32[0];
111 d32[1] = s32[1];
112 d32[2] = s32[2];
113 d32[3] = s32[3];
114 d32[4] = s32[4];
115 d32[5] = s32[5];
116 d32[6] = s32[6];
117 d32[7] = s32[7];
118 d32 += 8;
119 s32 += 8;
120 size -= 32;
121 }
122 while (size >= 4)
123 {
124 *d32++ = *s32++;
125 size -= 4;
126 }
127
128 d = reinterpret_cast<uint8_t*>(d32);
129 s = reinterpret_cast<const uint8_t*>(s32);
130 }
132 else
133#endif
134 if ((addr_diff & 1) == 0 && size > 0)
135 {
136 if (reinterpret_cast<uintptr_t>(d) & 1)
137 {
138 *d++ = *s++;
139 --size;
140 }
141 auto* d16 = reinterpret_cast<uint16_t*>(d);
142 auto* s16 = reinterpret_cast<const uint16_t*>(s);
143
144 while (size >= 16)
145 {
146 d16[0] = s16[0];
147 d16[1] = s16[1];
148 d16[2] = s16[2];
149 d16[3] = s16[3];
150 d16[4] = s16[4];
151 d16[5] = s16[5];
152 d16[6] = s16[6];
153 d16[7] = s16[7];
154 d16 += 8;
155 s16 += 8;
156 size -= 16;
157 }
158 while (size >= 2)
159 {
160 *d16++ = *s16++;
161 size -= 2;
162 }
163
164 d = reinterpret_cast<uint8_t*>(d16);
165 s = reinterpret_cast<const uint8_t*>(s16);
166 }
167 // Otherwise, fallback to byte-wise copying below.
168 }
169
171 while (size--)
172 {
173 *d++ = *s++;
174 }
175}
176
177void LibXR::Memory::FastSet(void* dst, uint8_t value, size_t size)
178{
179 if (size == 0)
180 {
181 return;
182 }
183
184 uint8_t* d = static_cast<uint8_t*>(dst);
185
186 uintptr_t d_offset = reinterpret_cast<uintptr_t>(d) & (LIBXR_ALIGN_SIZE - 1);
187
188 // 先处理头部到对齐
189 if (d_offset)
190 {
191 size_t head = LIBXR_ALIGN_SIZE - d_offset;
192 if (head > size)
193 {
194 head = size;
195 }
196 while (head--)
197 {
198 *d++ = value;
199 --size;
200 }
201 }
202
203#if LIBXR_ALIGN_SIZE == 8
204 // 8-byte pattern
205 uint64_t pat = value;
206 pat |= pat << 8;
207 pat |= pat << 16;
208 pat |= pat << 32;
209
210 auto* dw = reinterpret_cast<uint64_t*>(d);
211
212 while (size >= 64)
213 {
214 dw[0] = pat;
215 dw[1] = pat;
216 dw[2] = pat;
217 dw[3] = pat;
218 dw[4] = pat;
219 dw[5] = pat;
220 dw[6] = pat;
221 dw[7] = pat;
222 dw += 8;
223 size -= 64;
224 }
225 while (size >= 8)
226 {
227 *dw++ = pat;
228 size -= 8;
229 }
230
231 d = reinterpret_cast<uint8_t*>(dw);
232#else
233 // 4-byte pattern
234 uint32_t pat = value;
235 pat |= pat << 8;
236 pat |= pat << 16;
237
238 auto* dw = reinterpret_cast<uint32_t*>(d);
239
240 while (size >= 32)
241 {
242 dw[0] = pat;
243 dw[1] = pat;
244 dw[2] = pat;
245 dw[3] = pat;
246 dw[4] = pat;
247 dw[5] = pat;
248 dw[6] = pat;
249 dw[7] = pat;
250 dw += 8;
251 size -= 32;
252 }
253 while (size >= 4)
254 {
255 *dw++ = pat;
256 size -= 4;
257 }
258
259 d = reinterpret_cast<uint8_t*>(dw);
260#endif
261
262 // 尾巴
263 while (size--)
264 {
265 *d++ = value;
266 }
267}
268
269int LibXR::Memory::FastCmp(const void* a, const void* b, size_t size)
270{
271 const uint8_t* p = static_cast<const uint8_t*>(a);
272 const uint8_t* q = static_cast<const uint8_t*>(b);
273
274 if ((size == 0) || (p == q))
275 {
276 return 0;
277 }
278
279 auto byte_cmp = [](const uint8_t* x, const uint8_t* y, size_t n) -> int
280 {
281 for (size_t i = 0; i < n; ++i)
282 {
283 int diff = static_cast<int>(x[i]) - static_cast<int>(y[i]);
284 if (diff != 0)
285 {
286 return diff;
287 }
288 }
289 return 0;
290 };
291
292 uintptr_t p_off = reinterpret_cast<uintptr_t>(p) & (LIBXR_ALIGN_SIZE - 1);
293 uintptr_t q_off = reinterpret_cast<uintptr_t>(q) & (LIBXR_ALIGN_SIZE - 1);
294
295 // 若同相位:先补齐到 LIBXR_ALIGN_SIZE 对齐再做宽比较
296 if ((p_off == q_off) && (p_off != 0))
297 {
298 size_t head = LIBXR_ALIGN_SIZE - p_off;
299 if (head > size)
300 {
301 head = size;
302 }
303
304 while (head--)
305 {
306 int diff = static_cast<int>(*p++) - static_cast<int>(*q++);
307 if (diff != 0)
308 {
309 return diff;
310 }
311 --size;
312 }
313 }
314
315#if LIBXR_ALIGN_SIZE == 8
316 // 8-byte compare(仅在两者均 8 对齐时才安全/快)
317 if ((((reinterpret_cast<uintptr_t>(p) | reinterpret_cast<uintptr_t>(q)) & 7u) == 0u))
318 {
319 auto* pw = reinterpret_cast<const uint64_t*>(p);
320 auto* qw = reinterpret_cast<const uint64_t*>(q);
321
322 while (size >= 64)
323 {
324 if (pw[0] != qw[0])
325 {
326 return byte_cmp(reinterpret_cast<const uint8_t*>(pw + 0),
327 reinterpret_cast<const uint8_t*>(qw + 0), 8);
328 }
329 if (pw[1] != qw[1])
330 {
331 return byte_cmp(reinterpret_cast<const uint8_t*>(pw + 1),
332 reinterpret_cast<const uint8_t*>(qw + 1), 8);
333 }
334 if (pw[2] != qw[2])
335 {
336 return byte_cmp(reinterpret_cast<const uint8_t*>(pw + 2),
337 reinterpret_cast<const uint8_t*>(qw + 2), 8);
338 }
339 if (pw[3] != qw[3])
340 {
341 return byte_cmp(reinterpret_cast<const uint8_t*>(pw + 3),
342 reinterpret_cast<const uint8_t*>(qw + 3), 8);
343 }
344 if (pw[4] != qw[4])
345 {
346 return byte_cmp(reinterpret_cast<const uint8_t*>(pw + 4),
347 reinterpret_cast<const uint8_t*>(qw + 4), 8);
348 }
349 if (pw[5] != qw[5])
350 {
351 return byte_cmp(reinterpret_cast<const uint8_t*>(pw + 5),
352 reinterpret_cast<const uint8_t*>(qw + 5), 8);
353 }
354 if (pw[6] != qw[6])
355 {
356 return byte_cmp(reinterpret_cast<const uint8_t*>(pw + 6),
357 reinterpret_cast<const uint8_t*>(qw + 6), 8);
358 }
359 if (pw[7] != qw[7])
360 {
361 return byte_cmp(reinterpret_cast<const uint8_t*>(pw + 7),
362 reinterpret_cast<const uint8_t*>(qw + 7), 8);
363 }
364
365 pw += 8;
366 qw += 8;
367 size -= 64;
368 }
369
370 while (size >= 8)
371 {
372 if (*pw != *qw)
373 {
374 return byte_cmp(reinterpret_cast<const uint8_t*>(pw),
375 reinterpret_cast<const uint8_t*>(qw), 8);
376 }
377 ++pw;
378 ++qw;
379 size -= 8;
380 }
381
382 p = reinterpret_cast<const uint8_t*>(pw);
383 q = reinterpret_cast<const uint8_t*>(qw);
384 }
385#else
386 // 4-byte compare(两者均 4 对齐)
387 if ((((reinterpret_cast<uintptr_t>(p) | reinterpret_cast<uintptr_t>(q)) & 3u) == 0u))
388 {
389 auto* pw = reinterpret_cast<const uint32_t*>(p);
390 auto* qw = reinterpret_cast<const uint32_t*>(q);
391
392 while (size >= 32)
393 {
394 if (pw[0] != qw[0])
395 {
396 return byte_cmp(reinterpret_cast<const uint8_t*>(pw + 0),
397 reinterpret_cast<const uint8_t*>(qw + 0), 4);
398 }
399 if (pw[1] != qw[1])
400 {
401 return byte_cmp(reinterpret_cast<const uint8_t*>(pw + 1),
402 reinterpret_cast<const uint8_t*>(qw + 1), 4);
403 }
404 if (pw[2] != qw[2])
405 {
406 return byte_cmp(reinterpret_cast<const uint8_t*>(pw + 2),
407 reinterpret_cast<const uint8_t*>(qw + 2), 4);
408 }
409 if (pw[3] != qw[3])
410 {
411 return byte_cmp(reinterpret_cast<const uint8_t*>(pw + 3),
412 reinterpret_cast<const uint8_t*>(qw + 3), 4);
413 }
414 if (pw[4] != qw[4])
415 {
416 return byte_cmp(reinterpret_cast<const uint8_t*>(pw + 4),
417 reinterpret_cast<const uint8_t*>(qw + 4), 4);
418 }
419 if (pw[5] != qw[5])
420 {
421 return byte_cmp(reinterpret_cast<const uint8_t*>(pw + 5),
422 reinterpret_cast<const uint8_t*>(qw + 5), 4);
423 }
424 if (pw[6] != qw[6])
425 {
426 return byte_cmp(reinterpret_cast<const uint8_t*>(pw + 6),
427 reinterpret_cast<const uint8_t*>(qw + 6), 4);
428 }
429 if (pw[7] != qw[7])
430 {
431 return byte_cmp(reinterpret_cast<const uint8_t*>(pw + 7),
432 reinterpret_cast<const uint8_t*>(qw + 7), 4);
433 }
434
435 pw += 8;
436 qw += 8;
437 size -= 32;
438 }
439
440 while (size >= 4)
441 {
442 if (*pw != *qw)
443 {
444 return byte_cmp(reinterpret_cast<const uint8_t*>(pw),
445 reinterpret_cast<const uint8_t*>(qw), 4);
446 }
447 ++pw;
448 ++qw;
449 size -= 4;
450 }
451
452 p = reinterpret_cast<const uint8_t*>(pw);
453 q = reinterpret_cast<const uint8_t*>(qw);
454 }
455#endif
456
457 // tail byte compare(包括:未满足宽比较对齐条件的情况)
458 while (size--)
459 {
460 int diff = static_cast<int>(*p++) - static_cast<int>(*q++);
461 if (diff != 0)
462 {
463 return diff;
464 }
465 }
466
467 return 0;
468}
static void FastSet(void *dst, uint8_t value, size_t size)
快速内存填充 / Fast memory fill
static int FastCmp(const void *a, const void *b, size_t size)
快速内存比较 / Fast memory comparison
static void FastCopy(void *dst, const void *src, size_t size)
快速内存拷贝 / Fast memory copy
Definition libxr_mem.cpp:3