libxr  1.0
Want to be the best embedded framework
Loading...
Searching...
No Matches
libxr_mem_cmp.cpp
1#include "libxr_def.hpp"
2#include "libxr_mem.hpp"
3
4int LibXR::Memory::FastCmp(const void* a, const void* b, size_t size)
5{
6 const uint8_t* p = static_cast<const uint8_t*>(a);
7 const uint8_t* q = static_cast<const uint8_t*>(b);
8 const uint8_t* mismatch_p = nullptr;
9 const uint8_t* mismatch_q = nullptr;
10 size_t mismatch_size = 0;
11
12 if ((size == 0) || (p == q))
13 {
14 return 0;
15 }
16
17 uintptr_t p_off = reinterpret_cast<uintptr_t>(p) & (LibXR::ALIGN_SIZE - 1);
18 uintptr_t q_off = reinterpret_cast<uintptr_t>(q) & (LibXR::ALIGN_SIZE - 1);
19
20 // 若同相位:先补齐到 LibXR::ALIGN_SIZE 对齐再做宽比较
21 if ((p_off == q_off) && (p_off != 0))
22 {
23 size_t head = LibXR::ALIGN_SIZE - p_off;
24 if (head > size)
25 {
26 head = size;
27 }
28
29 while (head--)
30 {
31 int diff = static_cast<int>(*p++) - static_cast<int>(*q++);
32 if (diff != 0)
33 {
34 return diff;
35 }
36 --size;
37 }
38 }
39
40 if constexpr (LibXR::ALIGN_SIZE == 8)
41 {
42 // 8-byte compare(仅在两者均 8 对齐时才安全/快)
43 if ((((reinterpret_cast<uintptr_t>(p) | reinterpret_cast<uintptr_t>(q)) & 7u) == 0u))
44 {
45 auto* pw = reinterpret_cast<const uint64_t*>(p);
46 auto* qw = reinterpret_cast<const uint64_t*>(q);
47
48 while (size >= 64)
49 {
50 if (pw[0] != qw[0])
51 {
52 mismatch_p = reinterpret_cast<const uint8_t*>(pw + 0);
53 mismatch_q = reinterpret_cast<const uint8_t*>(qw + 0);
54 mismatch_size = 8;
55 goto compare_fixed_bytes;
56 }
57 if (pw[1] != qw[1])
58 {
59 mismatch_p = reinterpret_cast<const uint8_t*>(pw + 1);
60 mismatch_q = reinterpret_cast<const uint8_t*>(qw + 1);
61 mismatch_size = 8;
62 goto compare_fixed_bytes;
63 }
64 if (pw[2] != qw[2])
65 {
66 mismatch_p = reinterpret_cast<const uint8_t*>(pw + 2);
67 mismatch_q = reinterpret_cast<const uint8_t*>(qw + 2);
68 mismatch_size = 8;
69 goto compare_fixed_bytes;
70 }
71 if (pw[3] != qw[3])
72 {
73 mismatch_p = reinterpret_cast<const uint8_t*>(pw + 3);
74 mismatch_q = reinterpret_cast<const uint8_t*>(qw + 3);
75 mismatch_size = 8;
76 goto compare_fixed_bytes;
77 }
78 if (pw[4] != qw[4])
79 {
80 mismatch_p = reinterpret_cast<const uint8_t*>(pw + 4);
81 mismatch_q = reinterpret_cast<const uint8_t*>(qw + 4);
82 mismatch_size = 8;
83 goto compare_fixed_bytes;
84 }
85 if (pw[5] != qw[5])
86 {
87 mismatch_p = reinterpret_cast<const uint8_t*>(pw + 5);
88 mismatch_q = reinterpret_cast<const uint8_t*>(qw + 5);
89 mismatch_size = 8;
90 goto compare_fixed_bytes;
91 }
92 if (pw[6] != qw[6])
93 {
94 mismatch_p = reinterpret_cast<const uint8_t*>(pw + 6);
95 mismatch_q = reinterpret_cast<const uint8_t*>(qw + 6);
96 mismatch_size = 8;
97 goto compare_fixed_bytes;
98 }
99 if (pw[7] != qw[7])
100 {
101 mismatch_p = reinterpret_cast<const uint8_t*>(pw + 7);
102 mismatch_q = reinterpret_cast<const uint8_t*>(qw + 7);
103 mismatch_size = 8;
104 goto compare_fixed_bytes;
105 }
106
107 pw += 8;
108 qw += 8;
109 size -= 64;
110 }
111
112 while (size >= 8)
113 {
114 if (*pw != *qw)
115 {
116 mismatch_p = reinterpret_cast<const uint8_t*>(pw);
117 mismatch_q = reinterpret_cast<const uint8_t*>(qw);
118 mismatch_size = 8;
119 goto compare_fixed_bytes;
120 }
121 ++pw;
122 ++qw;
123 size -= 8;
124 }
125
126 p = reinterpret_cast<const uint8_t*>(pw);
127 q = reinterpret_cast<const uint8_t*>(qw);
128 }
129 }
130 else
131 {
132 // 4-byte compare(两者均 4 对齐)
133 if ((((reinterpret_cast<uintptr_t>(p) | reinterpret_cast<uintptr_t>(q)) & 3u) == 0u))
134 {
135 auto* pw = reinterpret_cast<const uint32_t*>(p);
136 auto* qw = reinterpret_cast<const uint32_t*>(q);
137
138 while (size >= 32)
139 {
140 if (pw[0] != qw[0])
141 {
142 mismatch_p = reinterpret_cast<const uint8_t*>(pw + 0);
143 mismatch_q = reinterpret_cast<const uint8_t*>(qw + 0);
144 mismatch_size = 4;
145 goto compare_fixed_bytes;
146 }
147 if (pw[1] != qw[1])
148 {
149 mismatch_p = reinterpret_cast<const uint8_t*>(pw + 1);
150 mismatch_q = reinterpret_cast<const uint8_t*>(qw + 1);
151 mismatch_size = 4;
152 goto compare_fixed_bytes;
153 }
154 if (pw[2] != qw[2])
155 {
156 mismatch_p = reinterpret_cast<const uint8_t*>(pw + 2);
157 mismatch_q = reinterpret_cast<const uint8_t*>(qw + 2);
158 mismatch_size = 4;
159 goto compare_fixed_bytes;
160 }
161 if (pw[3] != qw[3])
162 {
163 mismatch_p = reinterpret_cast<const uint8_t*>(pw + 3);
164 mismatch_q = reinterpret_cast<const uint8_t*>(qw + 3);
165 mismatch_size = 4;
166 goto compare_fixed_bytes;
167 }
168 if (pw[4] != qw[4])
169 {
170 mismatch_p = reinterpret_cast<const uint8_t*>(pw + 4);
171 mismatch_q = reinterpret_cast<const uint8_t*>(qw + 4);
172 mismatch_size = 4;
173 goto compare_fixed_bytes;
174 }
175 if (pw[5] != qw[5])
176 {
177 mismatch_p = reinterpret_cast<const uint8_t*>(pw + 5);
178 mismatch_q = reinterpret_cast<const uint8_t*>(qw + 5);
179 mismatch_size = 4;
180 goto compare_fixed_bytes;
181 }
182 if (pw[6] != qw[6])
183 {
184 mismatch_p = reinterpret_cast<const uint8_t*>(pw + 6);
185 mismatch_q = reinterpret_cast<const uint8_t*>(qw + 6);
186 mismatch_size = 4;
187 goto compare_fixed_bytes;
188 }
189 if (pw[7] != qw[7])
190 {
191 mismatch_p = reinterpret_cast<const uint8_t*>(pw + 7);
192 mismatch_q = reinterpret_cast<const uint8_t*>(qw + 7);
193 mismatch_size = 4;
194 goto compare_fixed_bytes;
195 }
196
197 pw += 8;
198 qw += 8;
199 size -= 32;
200 }
201
202 while (size >= 4)
203 {
204 if (*pw != *qw)
205 {
206 mismatch_p = reinterpret_cast<const uint8_t*>(pw);
207 mismatch_q = reinterpret_cast<const uint8_t*>(qw);
208 mismatch_size = 4;
209 goto compare_fixed_bytes;
210 }
211 ++pw;
212 ++qw;
213 size -= 4;
214 }
215
216 p = reinterpret_cast<const uint8_t*>(pw);
217 q = reinterpret_cast<const uint8_t*>(qw);
218 }
219 }
220
221compare_fixed_bytes:
222 if (mismatch_size == 8)
223 {
224 int diff = static_cast<int>(mismatch_p[0]) - static_cast<int>(mismatch_q[0]);
225 if (diff != 0)
226 {
227 return diff;
228 }
229 diff = static_cast<int>(mismatch_p[1]) - static_cast<int>(mismatch_q[1]);
230 if (diff != 0)
231 {
232 return diff;
233 }
234 diff = static_cast<int>(mismatch_p[2]) - static_cast<int>(mismatch_q[2]);
235 if (diff != 0)
236 {
237 return diff;
238 }
239 diff = static_cast<int>(mismatch_p[3]) - static_cast<int>(mismatch_q[3]);
240 if (diff != 0)
241 {
242 return diff;
243 }
244 diff = static_cast<int>(mismatch_p[4]) - static_cast<int>(mismatch_q[4]);
245 if (diff != 0)
246 {
247 return diff;
248 }
249 diff = static_cast<int>(mismatch_p[5]) - static_cast<int>(mismatch_q[5]);
250 if (diff != 0)
251 {
252 return diff;
253 }
254 diff = static_cast<int>(mismatch_p[6]) - static_cast<int>(mismatch_q[6]);
255 if (diff != 0)
256 {
257 return diff;
258 }
259 return static_cast<int>(mismatch_p[7]) - static_cast<int>(mismatch_q[7]);
260 }
261
262 if (mismatch_size == 4)
263 {
264 int diff = static_cast<int>(mismatch_p[0]) - static_cast<int>(mismatch_q[0]);
265 if (diff != 0)
266 {
267 return diff;
268 }
269 diff = static_cast<int>(mismatch_p[1]) - static_cast<int>(mismatch_q[1]);
270 if (diff != 0)
271 {
272 return diff;
273 }
274 diff = static_cast<int>(mismatch_p[2]) - static_cast<int>(mismatch_q[2]);
275 if (diff != 0)
276 {
277 return diff;
278 }
279 return static_cast<int>(mismatch_p[3]) - static_cast<int>(mismatch_q[3]);
280 }
281
282 // tail byte compare(包括:未满足宽比较对齐条件的情况)
283 while (size--)
284 {
285 int diff = static_cast<int>(*p++) - static_cast<int>(*q++);
286 if (diff != 0)
287 {
288 return diff;
289 }
290 }
291
292 return 0;
293}
static int FastCmp(const void *a, const void *b, size_t size)
快速内存比较 / Fast memory comparison
constexpr size_t ALIGN_SIZE
平台自然对齐大小 / Native platform alignment size
Definition libxr_def.hpp:67