libxr  1.0
Want to be the best embedded framework
Loading...
Searching...
No Matches
libxr_mem.cpp
1#include "libxr_mem.hpp"
2
3#include "libxr_def.hpp"
4
5void LibXR::Memory::FastCopy(void* dst, const void* src, size_t size)
6{
7 uint8_t* d = static_cast<uint8_t*>(dst);
8 const uint8_t* s = static_cast<const uint8_t*>(src);
9
10 uintptr_t d_offset = reinterpret_cast<uintptr_t>(d) & (LibXR::ALIGN_SIZE - 1);
11 uintptr_t s_offset = reinterpret_cast<uintptr_t>(s) & (LibXR::ALIGN_SIZE - 1);
12
17 if (d_offset == s_offset)
18 {
20 if (d_offset)
21 {
22 size_t head = LibXR::ALIGN_SIZE - d_offset;
23 if (head > size)
24 {
25 head = size;
26 }
27 while (head--)
28 {
29 *d++ = *s++;
30 --size;
31 }
32 }
33
34 if constexpr (LibXR::ALIGN_SIZE == 8)
35 {
37 auto* dw = reinterpret_cast<uint64_t*>(d);
38 auto* sw = reinterpret_cast<const uint64_t*>(s);
39
40 while (size >= 64)
41 {
42 dw[0] = sw[0];
43 dw[1] = sw[1];
44 dw[2] = sw[2];
45 dw[3] = sw[3];
46 dw[4] = sw[4];
47 dw[5] = sw[5];
48 dw[6] = sw[6];
49 dw[7] = sw[7];
50 dw += 8;
51 sw += 8;
52 size -= 64;
53 }
54 while (size >= 8)
55 {
56 *dw++ = *sw++;
57 size -= 8;
58 }
59
60 d = reinterpret_cast<uint8_t*>(dw);
61 s = reinterpret_cast<const uint8_t*>(sw);
62 }
63 else
64 {
66 auto* dw = reinterpret_cast<uint32_t*>(d);
67 auto* sw = reinterpret_cast<const uint32_t*>(s);
68
69 while (size >= 32)
70 {
71 dw[0] = sw[0];
72 dw[1] = sw[1];
73 dw[2] = sw[2];
74 dw[3] = sw[3];
75 dw[4] = sw[4];
76 dw[5] = sw[5];
77 dw[6] = sw[6];
78 dw[7] = sw[7];
79 dw += 8;
80 sw += 8;
81 size -= 32;
82 }
83 while (size >= 4)
84 {
85 *dw++ = *sw++;
86 size -= 4;
87 }
88
89 d = reinterpret_cast<uint8_t*>(dw);
90 s = reinterpret_cast<const uint8_t*>(sw);
91 }
92 }
97 else
98 {
99 uintptr_t addr_diff = reinterpret_cast<uintptr_t>(s) - reinterpret_cast<uintptr_t>(d);
100
101 if constexpr (LibXR::ALIGN_SIZE == 8)
102 {
104 if ((addr_diff & 3) == 0 && size > 0)
105 {
106 while ((reinterpret_cast<uintptr_t>(d) & 3) && size)
107 {
108 *d++ = *s++;
109 --size;
110 }
111 auto* d32 = reinterpret_cast<uint32_t*>(d);
112 auto* s32 = reinterpret_cast<const uint32_t*>(s);
113
114 while (size >= 32)
115 {
116 d32[0] = s32[0];
117 d32[1] = s32[1];
118 d32[2] = s32[2];
119 d32[3] = s32[3];
120 d32[4] = s32[4];
121 d32[5] = s32[5];
122 d32[6] = s32[6];
123 d32[7] = s32[7];
124 d32 += 8;
125 s32 += 8;
126 size -= 32;
127 }
128 while (size >= 4)
129 {
130 *d32++ = *s32++;
131 size -= 4;
132 }
133
134 d = reinterpret_cast<uint8_t*>(d32);
135 s = reinterpret_cast<const uint8_t*>(s32);
136 }
138 else if ((addr_diff & 1) == 0 && size > 0)
139 {
140 if (reinterpret_cast<uintptr_t>(d) & 1)
141 {
142 *d++ = *s++;
143 --size;
144 }
145 auto* d16 = reinterpret_cast<uint16_t*>(d);
146 auto* s16 = reinterpret_cast<const uint16_t*>(s);
147
148 while (size >= 16)
149 {
150 d16[0] = s16[0];
151 d16[1] = s16[1];
152 d16[2] = s16[2];
153 d16[3] = s16[3];
154 d16[4] = s16[4];
155 d16[5] = s16[5];
156 d16[6] = s16[6];
157 d16[7] = s16[7];
158 d16 += 8;
159 s16 += 8;
160 size -= 16;
161 }
162 while (size >= 2)
163 {
164 *d16++ = *s16++;
165 size -= 2;
166 }
167
168 d = reinterpret_cast<uint8_t*>(d16);
169 s = reinterpret_cast<const uint8_t*>(s16);
170 }
171 }
172 else if ((addr_diff & 1) == 0 && size > 0)
173 {
174 if (reinterpret_cast<uintptr_t>(d) & 1)
175 {
176 *d++ = *s++;
177 --size;
178 }
179 auto* d16 = reinterpret_cast<uint16_t*>(d);
180 auto* s16 = reinterpret_cast<const uint16_t*>(s);
181
182 while (size >= 16)
183 {
184 d16[0] = s16[0];
185 d16[1] = s16[1];
186 d16[2] = s16[2];
187 d16[3] = s16[3];
188 d16[4] = s16[4];
189 d16[5] = s16[5];
190 d16[6] = s16[6];
191 d16[7] = s16[7];
192 d16 += 8;
193 s16 += 8;
194 size -= 16;
195 }
196 while (size >= 2)
197 {
198 *d16++ = *s16++;
199 size -= 2;
200 }
201
202 d = reinterpret_cast<uint8_t*>(d16);
203 s = reinterpret_cast<const uint8_t*>(s16);
204 }
205 // Otherwise, fallback to byte-wise copying below.
206 }
207
209 while (size--)
210 {
211 *d++ = *s++;
212 }
213}
214
215void LibXR::Memory::FastSet(void* dst, uint8_t value, size_t size)
216{
217 if (size == 0)
218 {
219 return;
220 }
221
222 uint8_t* d = static_cast<uint8_t*>(dst);
223
224 uintptr_t d_offset = reinterpret_cast<uintptr_t>(d) & (LibXR::ALIGN_SIZE - 1);
225
226 // 先处理头部到对齐
227 if (d_offset)
228 {
229 size_t head = LibXR::ALIGN_SIZE - d_offset;
230 if (head > size)
231 {
232 head = size;
233 }
234 while (head--)
235 {
236 *d++ = value;
237 --size;
238 }
239 }
240
241 if constexpr (LibXR::ALIGN_SIZE == 8)
242 {
243 // 8-byte pattern
244 uint64_t pat = value;
245 pat |= pat << 8;
246 pat |= pat << 16;
247 pat |= pat << 32;
248
249 auto* dw = reinterpret_cast<uint64_t*>(d);
250
251 while (size >= 64)
252 {
253 dw[0] = pat;
254 dw[1] = pat;
255 dw[2] = pat;
256 dw[3] = pat;
257 dw[4] = pat;
258 dw[5] = pat;
259 dw[6] = pat;
260 dw[7] = pat;
261 dw += 8;
262 size -= 64;
263 }
264 while (size >= 8)
265 {
266 *dw++ = pat;
267 size -= 8;
268 }
269
270 d = reinterpret_cast<uint8_t*>(dw);
271 }
272 else
273 {
274 // 4-byte pattern
275 uint32_t pat = value;
276 pat |= pat << 8;
277 pat |= pat << 16;
278
279 auto* dw = reinterpret_cast<uint32_t*>(d);
280
281 while (size >= 32)
282 {
283 dw[0] = pat;
284 dw[1] = pat;
285 dw[2] = pat;
286 dw[3] = pat;
287 dw[4] = pat;
288 dw[5] = pat;
289 dw[6] = pat;
290 dw[7] = pat;
291 dw += 8;
292 size -= 32;
293 }
294 while (size >= 4)
295 {
296 *dw++ = pat;
297 size -= 4;
298 }
299
300 d = reinterpret_cast<uint8_t*>(dw);
301 }
302
303 // 尾巴
304 while (size--)
305 {
306 *d++ = value;
307 }
308}
309
310int LibXR::Memory::FastCmp(const void* a, const void* b, size_t size)
311{
312 const uint8_t* p = static_cast<const uint8_t*>(a);
313 const uint8_t* q = static_cast<const uint8_t*>(b);
314 const uint8_t* mismatch_p = nullptr;
315 const uint8_t* mismatch_q = nullptr;
316 size_t mismatch_size = 0;
317
318 if ((size == 0) || (p == q))
319 {
320 return 0;
321 }
322
323 uintptr_t p_off = reinterpret_cast<uintptr_t>(p) & (LibXR::ALIGN_SIZE - 1);
324 uintptr_t q_off = reinterpret_cast<uintptr_t>(q) & (LibXR::ALIGN_SIZE - 1);
325
326 // 若同相位:先补齐到 LibXR::ALIGN_SIZE 对齐再做宽比较
327 if ((p_off == q_off) && (p_off != 0))
328 {
329 size_t head = LibXR::ALIGN_SIZE - p_off;
330 if (head > size)
331 {
332 head = size;
333 }
334
335 while (head--)
336 {
337 int diff = static_cast<int>(*p++) - static_cast<int>(*q++);
338 if (diff != 0)
339 {
340 return diff;
341 }
342 --size;
343 }
344 }
345
346 if constexpr (LibXR::ALIGN_SIZE == 8)
347 {
348 // 8-byte compare(仅在两者均 8 对齐时才安全/快)
349 if ((((reinterpret_cast<uintptr_t>(p) | reinterpret_cast<uintptr_t>(q)) & 7u) == 0u))
350 {
351 auto* pw = reinterpret_cast<const uint64_t*>(p);
352 auto* qw = reinterpret_cast<const uint64_t*>(q);
353
354 while (size >= 64)
355 {
356 if (pw[0] != qw[0])
357 {
358 mismatch_p = reinterpret_cast<const uint8_t*>(pw + 0);
359 mismatch_q = reinterpret_cast<const uint8_t*>(qw + 0);
360 mismatch_size = 8;
361 goto compare_fixed_bytes;
362 }
363 if (pw[1] != qw[1])
364 {
365 mismatch_p = reinterpret_cast<const uint8_t*>(pw + 1);
366 mismatch_q = reinterpret_cast<const uint8_t*>(qw + 1);
367 mismatch_size = 8;
368 goto compare_fixed_bytes;
369 }
370 if (pw[2] != qw[2])
371 {
372 mismatch_p = reinterpret_cast<const uint8_t*>(pw + 2);
373 mismatch_q = reinterpret_cast<const uint8_t*>(qw + 2);
374 mismatch_size = 8;
375 goto compare_fixed_bytes;
376 }
377 if (pw[3] != qw[3])
378 {
379 mismatch_p = reinterpret_cast<const uint8_t*>(pw + 3);
380 mismatch_q = reinterpret_cast<const uint8_t*>(qw + 3);
381 mismatch_size = 8;
382 goto compare_fixed_bytes;
383 }
384 if (pw[4] != qw[4])
385 {
386 mismatch_p = reinterpret_cast<const uint8_t*>(pw + 4);
387 mismatch_q = reinterpret_cast<const uint8_t*>(qw + 4);
388 mismatch_size = 8;
389 goto compare_fixed_bytes;
390 }
391 if (pw[5] != qw[5])
392 {
393 mismatch_p = reinterpret_cast<const uint8_t*>(pw + 5);
394 mismatch_q = reinterpret_cast<const uint8_t*>(qw + 5);
395 mismatch_size = 8;
396 goto compare_fixed_bytes;
397 }
398 if (pw[6] != qw[6])
399 {
400 mismatch_p = reinterpret_cast<const uint8_t*>(pw + 6);
401 mismatch_q = reinterpret_cast<const uint8_t*>(qw + 6);
402 mismatch_size = 8;
403 goto compare_fixed_bytes;
404 }
405 if (pw[7] != qw[7])
406 {
407 mismatch_p = reinterpret_cast<const uint8_t*>(pw + 7);
408 mismatch_q = reinterpret_cast<const uint8_t*>(qw + 7);
409 mismatch_size = 8;
410 goto compare_fixed_bytes;
411 }
412
413 pw += 8;
414 qw += 8;
415 size -= 64;
416 }
417
418 while (size >= 8)
419 {
420 if (*pw != *qw)
421 {
422 mismatch_p = reinterpret_cast<const uint8_t*>(pw);
423 mismatch_q = reinterpret_cast<const uint8_t*>(qw);
424 mismatch_size = 8;
425 goto compare_fixed_bytes;
426 }
427 ++pw;
428 ++qw;
429 size -= 8;
430 }
431
432 p = reinterpret_cast<const uint8_t*>(pw);
433 q = reinterpret_cast<const uint8_t*>(qw);
434 }
435 }
436 else
437 {
438 // 4-byte compare(两者均 4 对齐)
439 if ((((reinterpret_cast<uintptr_t>(p) | reinterpret_cast<uintptr_t>(q)) & 3u) == 0u))
440 {
441 auto* pw = reinterpret_cast<const uint32_t*>(p);
442 auto* qw = reinterpret_cast<const uint32_t*>(q);
443
444 while (size >= 32)
445 {
446 if (pw[0] != qw[0])
447 {
448 mismatch_p = reinterpret_cast<const uint8_t*>(pw + 0);
449 mismatch_q = reinterpret_cast<const uint8_t*>(qw + 0);
450 mismatch_size = 4;
451 goto compare_fixed_bytes;
452 }
453 if (pw[1] != qw[1])
454 {
455 mismatch_p = reinterpret_cast<const uint8_t*>(pw + 1);
456 mismatch_q = reinterpret_cast<const uint8_t*>(qw + 1);
457 mismatch_size = 4;
458 goto compare_fixed_bytes;
459 }
460 if (pw[2] != qw[2])
461 {
462 mismatch_p = reinterpret_cast<const uint8_t*>(pw + 2);
463 mismatch_q = reinterpret_cast<const uint8_t*>(qw + 2);
464 mismatch_size = 4;
465 goto compare_fixed_bytes;
466 }
467 if (pw[3] != qw[3])
468 {
469 mismatch_p = reinterpret_cast<const uint8_t*>(pw + 3);
470 mismatch_q = reinterpret_cast<const uint8_t*>(qw + 3);
471 mismatch_size = 4;
472 goto compare_fixed_bytes;
473 }
474 if (pw[4] != qw[4])
475 {
476 mismatch_p = reinterpret_cast<const uint8_t*>(pw + 4);
477 mismatch_q = reinterpret_cast<const uint8_t*>(qw + 4);
478 mismatch_size = 4;
479 goto compare_fixed_bytes;
480 }
481 if (pw[5] != qw[5])
482 {
483 mismatch_p = reinterpret_cast<const uint8_t*>(pw + 5);
484 mismatch_q = reinterpret_cast<const uint8_t*>(qw + 5);
485 mismatch_size = 4;
486 goto compare_fixed_bytes;
487 }
488 if (pw[6] != qw[6])
489 {
490 mismatch_p = reinterpret_cast<const uint8_t*>(pw + 6);
491 mismatch_q = reinterpret_cast<const uint8_t*>(qw + 6);
492 mismatch_size = 4;
493 goto compare_fixed_bytes;
494 }
495 if (pw[7] != qw[7])
496 {
497 mismatch_p = reinterpret_cast<const uint8_t*>(pw + 7);
498 mismatch_q = reinterpret_cast<const uint8_t*>(qw + 7);
499 mismatch_size = 4;
500 goto compare_fixed_bytes;
501 }
502
503 pw += 8;
504 qw += 8;
505 size -= 32;
506 }
507
508 while (size >= 4)
509 {
510 if (*pw != *qw)
511 {
512 mismatch_p = reinterpret_cast<const uint8_t*>(pw);
513 mismatch_q = reinterpret_cast<const uint8_t*>(qw);
514 mismatch_size = 4;
515 goto compare_fixed_bytes;
516 }
517 ++pw;
518 ++qw;
519 size -= 4;
520 }
521
522 p = reinterpret_cast<const uint8_t*>(pw);
523 q = reinterpret_cast<const uint8_t*>(qw);
524 }
525 }
526
527compare_fixed_bytes:
528 if (mismatch_size == 8)
529 {
530 int diff = static_cast<int>(mismatch_p[0]) - static_cast<int>(mismatch_q[0]);
531 if (diff != 0)
532 {
533 return diff;
534 }
535 diff = static_cast<int>(mismatch_p[1]) - static_cast<int>(mismatch_q[1]);
536 if (diff != 0)
537 {
538 return diff;
539 }
540 diff = static_cast<int>(mismatch_p[2]) - static_cast<int>(mismatch_q[2]);
541 if (diff != 0)
542 {
543 return diff;
544 }
545 diff = static_cast<int>(mismatch_p[3]) - static_cast<int>(mismatch_q[3]);
546 if (diff != 0)
547 {
548 return diff;
549 }
550 diff = static_cast<int>(mismatch_p[4]) - static_cast<int>(mismatch_q[4]);
551 if (diff != 0)
552 {
553 return diff;
554 }
555 diff = static_cast<int>(mismatch_p[5]) - static_cast<int>(mismatch_q[5]);
556 if (diff != 0)
557 {
558 return diff;
559 }
560 diff = static_cast<int>(mismatch_p[6]) - static_cast<int>(mismatch_q[6]);
561 if (diff != 0)
562 {
563 return diff;
564 }
565 return static_cast<int>(mismatch_p[7]) - static_cast<int>(mismatch_q[7]);
566 }
567
568 if (mismatch_size == 4)
569 {
570 int diff = static_cast<int>(mismatch_p[0]) - static_cast<int>(mismatch_q[0]);
571 if (diff != 0)
572 {
573 return diff;
574 }
575 diff = static_cast<int>(mismatch_p[1]) - static_cast<int>(mismatch_q[1]);
576 if (diff != 0)
577 {
578 return diff;
579 }
580 diff = static_cast<int>(mismatch_p[2]) - static_cast<int>(mismatch_q[2]);
581 if (diff != 0)
582 {
583 return diff;
584 }
585 return static_cast<int>(mismatch_p[3]) - static_cast<int>(mismatch_q[3]);
586 }
587
588 // tail byte compare(包括:未满足宽比较对齐条件的情况)
589 while (size--)
590 {
591 int diff = static_cast<int>(*p++) - static_cast<int>(*q++);
592 if (diff != 0)
593 {
594 return diff;
595 }
596 }
597
598 return 0;
599}
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:5
constexpr size_t ALIGN_SIZE
平台自然对齐大小 / Native platform alignment size
Definition libxr_def.hpp:35