]>
Commit | Line | Data |
---|---|---|
221c6b37 | 1 | /* Compare two memory blocks for differences in the first COUNT bytes. |
9a1d9254 | 2 | Copyright (C) 2004, 2005, 2006, 2012 Free Software Foundation, Inc. |
221c6b37 UD |
3 | This file is part of the GNU C Library. |
4 | ||
5 | The GNU C Library is free software; you can redistribute it and/or | |
6 | modify it under the terms of the GNU Lesser General Public | |
7 | License as published by the Free Software Foundation; either | |
8 | version 2.1 of the License, or (at your option) any later version. | |
9 | ||
10 | The GNU C Library is distributed in the hope that it will be useful, | |
11 | but WITHOUT ANY WARRANTY; without even the implied warranty of | |
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
13 | Lesser General Public License for more details. | |
14 | ||
15 | You should have received a copy of the GNU Lesser General Public | |
16 | License along with the GNU C Library; if not, write to the Free | |
17 | Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA | |
18 | 02111-1307 USA. */ | |
19 | ||
20 | #include <sysdep.h> | |
21 | #include "asm-syntax.h" | |
22 | #include "bp-sym.h" | |
23 | #include "bp-asm.h" | |
24 | ||
25 | #define PARMS LINKAGE+4 /* Preserve EBX. */ | |
26 | #define BLK1 PARMS | |
27 | #define BLK2 BLK1+PTR_SIZE | |
28 | #define LEN BLK2+PTR_SIZE | |
1ad9da69 UD |
29 | #define ENTRANCE pushl %ebx; cfi_adjust_cfa_offset (4); \ |
30 | cfi_rel_offset (ebx, 0); ENTER | |
31 | #define RETURN popl %ebx; cfi_adjust_cfa_offset (-4); \ | |
b41f1d14 | 32 | cfi_restore (ebx); LEAVE; ret |
221c6b37 UD |
33 | |
34 | /* Load an entry in a jump table into EBX. TABLE is a jump table | |
35 | with relative offsets. INDEX is a register contains the index | |
36 | into the jump table. */ | |
f8fbb4c4 UD |
37 | #define LOAD_JUMP_TABLE_ENTRY(TABLE, INDEX) \ |
38 | /* We first load PC into EBX. */ \ | |
9a1d9254 | 39 | SETUP_PIC_REG(bx); \ |
f8fbb4c4 UD |
40 | /* Get the address of the jump table. */ \ |
41 | addl $(TABLE - .), %ebx; \ | |
42 | /* Get the entry and convert the relative offset to the \ | |
43 | absolute address. */ \ | |
221c6b37 UD |
44 | addl (%ebx,INDEX,4), %ebx |
45 | ||
221c6b37 UD |
46 | .text |
47 | ALIGN (4) | |
48 | ENTRY (BP_SYM (memcmp)) | |
49 | ENTRANCE | |
50 | ||
51 | movl BLK1(%esp), %eax | |
52 | movl BLK2(%esp), %edx | |
53 | movl LEN(%esp), %ecx | |
54 | ||
55 | cmpl $1, %ecx | |
56 | jne L(not_1) | |
57 | movzbl (%eax), %ecx /* LEN == 1 */ | |
58 | cmpb (%edx), %cl | |
59 | jne L(neq) | |
60 | L(bye): | |
61 | xorl %eax, %eax | |
62 | RETURN | |
63 | ||
b41f1d14 UD |
64 | cfi_adjust_cfa_offset (4) |
65 | cfi_rel_offset (ebx, 0) | |
221c6b37 UD |
66 | L(neq): |
67 | sbbl %eax, %eax | |
68 | sbbl $-1, %eax | |
69 | RETURN | |
70 | ||
fee732e5 UD |
71 | cfi_adjust_cfa_offset (4) |
72 | cfi_rel_offset (ebx, 0) | |
221c6b37 UD |
73 | L(not_1): |
74 | jl L(bye) /* LEN == 0 */ | |
75 | ||
76 | pushl %esi | |
1ad9da69 | 77 | cfi_adjust_cfa_offset (4) |
221c6b37 | 78 | movl %eax, %esi |
1ad9da69 | 79 | cfi_rel_offset (esi, 0) |
221c6b37 UD |
80 | cmpl $32, %ecx; |
81 | jge L(32bytesormore) /* LEN => 32 */ | |
82 | ||
83 | LOAD_JUMP_TABLE_ENTRY (L(table_32bytes), %ecx) | |
84 | addl %ecx, %edx | |
85 | addl %ecx, %esi | |
86 | jmp *%ebx | |
87 | ||
88 | ALIGN (4) | |
89 | L(28bytes): | |
90 | movl -28(%esi), %eax | |
91 | movl -28(%edx), %ecx | |
92 | cmpl %ecx, %eax | |
93 | jne L(find_diff) | |
94 | L(24bytes): | |
95 | movl -24(%esi), %eax | |
96 | movl -24(%edx), %ecx | |
97 | cmpl %ecx, %eax | |
98 | jne L(find_diff) | |
99 | L(20bytes): | |
100 | movl -20(%esi), %eax | |
101 | movl -20(%edx), %ecx | |
102 | cmpl %ecx, %eax | |
103 | jne L(find_diff) | |
104 | L(16bytes): | |
105 | movl -16(%esi), %eax | |
106 | movl -16(%edx), %ecx | |
107 | cmpl %ecx, %eax | |
108 | jne L(find_diff) | |
109 | L(12bytes): | |
110 | movl -12(%esi), %eax | |
111 | movl -12(%edx), %ecx | |
112 | cmpl %ecx, %eax | |
113 | jne L(find_diff) | |
114 | L(8bytes): | |
115 | movl -8(%esi), %eax | |
116 | movl -8(%edx), %ecx | |
117 | cmpl %ecx, %eax | |
118 | jne L(find_diff) | |
119 | L(4bytes): | |
120 | movl -4(%esi), %eax | |
121 | movl -4(%edx), %ecx | |
122 | cmpl %ecx, %eax | |
123 | jne L(find_diff) | |
124 | L(0bytes): | |
125 | popl %esi | |
1ad9da69 UD |
126 | cfi_adjust_cfa_offset (-4) |
127 | cfi_restore (esi) | |
221c6b37 UD |
128 | xorl %eax, %eax |
129 | RETURN | |
130 | ||
fee732e5 | 131 | cfi_adjust_cfa_offset (8) |
1ad9da69 | 132 | cfi_rel_offset (esi, 0) |
fee732e5 | 133 | cfi_rel_offset (ebx, 4) |
221c6b37 UD |
134 | L(29bytes): |
135 | movl -29(%esi), %eax | |
136 | movl -29(%edx), %ecx | |
137 | cmpl %ecx, %eax | |
138 | jne L(find_diff) | |
139 | L(25bytes): | |
140 | movl -25(%esi), %eax | |
141 | movl -25(%edx), %ecx | |
142 | cmpl %ecx, %eax | |
143 | jne L(find_diff) | |
144 | L(21bytes): | |
145 | movl -21(%esi), %eax | |
146 | movl -21(%edx), %ecx | |
147 | cmpl %ecx, %eax | |
148 | jne L(find_diff) | |
149 | L(17bytes): | |
150 | movl -17(%esi), %eax | |
151 | movl -17(%edx), %ecx | |
152 | cmpl %ecx, %eax | |
153 | jne L(find_diff) | |
154 | L(13bytes): | |
155 | movl -13(%esi), %eax | |
156 | movl -13(%edx), %ecx | |
157 | cmpl %ecx, %eax | |
158 | jne L(find_diff) | |
159 | L(9bytes): | |
160 | movl -9(%esi), %eax | |
161 | movl -9(%edx), %ecx | |
162 | cmpl %ecx, %eax | |
163 | jne L(find_diff) | |
164 | L(5bytes): | |
165 | movl -5(%esi), %eax | |
166 | movl -5(%edx), %ecx | |
167 | cmpl %ecx, %eax | |
168 | jne L(find_diff) | |
169 | L(1bytes): | |
170 | movzbl -1(%esi), %eax | |
171 | cmpb -1(%edx), %al | |
172 | jne L(set) | |
173 | popl %esi | |
1ad9da69 UD |
174 | cfi_adjust_cfa_offset (-4) |
175 | cfi_restore (esi) | |
221c6b37 UD |
176 | xorl %eax, %eax |
177 | RETURN | |
178 | ||
fee732e5 | 179 | cfi_adjust_cfa_offset (8) |
1ad9da69 | 180 | cfi_rel_offset (esi, 0) |
fee732e5 | 181 | cfi_rel_offset (ebx, 4) |
221c6b37 UD |
182 | L(30bytes): |
183 | movl -30(%esi), %eax | |
184 | movl -30(%edx), %ecx | |
185 | cmpl %ecx, %eax | |
186 | jne L(find_diff) | |
187 | L(26bytes): | |
188 | movl -26(%esi), %eax | |
189 | movl -26(%edx), %ecx | |
190 | cmpl %ecx, %eax | |
191 | jne L(find_diff) | |
192 | L(22bytes): | |
193 | movl -22(%esi), %eax | |
194 | movl -22(%edx), %ecx | |
195 | cmpl %ecx, %eax | |
196 | jne L(find_diff) | |
197 | L(18bytes): | |
198 | movl -18(%esi), %eax | |
199 | movl -18(%edx), %ecx | |
200 | cmpl %ecx, %eax | |
201 | jne L(find_diff) | |
202 | L(14bytes): | |
203 | movl -14(%esi), %eax | |
204 | movl -14(%edx), %ecx | |
205 | cmpl %ecx, %eax | |
206 | jne L(find_diff) | |
207 | L(10bytes): | |
208 | movl -10(%esi), %eax | |
209 | movl -10(%edx), %ecx | |
210 | cmpl %ecx, %eax | |
211 | jne L(find_diff) | |
212 | L(6bytes): | |
213 | movl -6(%esi), %eax | |
214 | movl -6(%edx), %ecx | |
215 | cmpl %ecx, %eax | |
216 | jne L(find_diff) | |
217 | L(2bytes): | |
218 | movzwl -2(%esi), %eax | |
219 | movzwl -2(%edx), %ecx | |
220 | cmpb %cl, %al | |
221 | jne L(set) | |
222 | cmpl %ecx, %eax | |
223 | jne L(set) | |
224 | popl %esi | |
1ad9da69 UD |
225 | cfi_adjust_cfa_offset (-4) |
226 | cfi_restore (esi) | |
221c6b37 UD |
227 | xorl %eax, %eax |
228 | RETURN | |
229 | ||
fee732e5 | 230 | cfi_adjust_cfa_offset (8) |
1ad9da69 | 231 | cfi_rel_offset (esi, 0) |
fee732e5 | 232 | cfi_rel_offset (ebx, 4) |
221c6b37 UD |
233 | L(31bytes): |
234 | movl -31(%esi), %eax | |
235 | movl -31(%edx), %ecx | |
236 | cmpl %ecx, %eax | |
237 | jne L(find_diff) | |
238 | L(27bytes): | |
239 | movl -27(%esi), %eax | |
240 | movl -27(%edx), %ecx | |
241 | cmpl %ecx, %eax | |
242 | jne L(find_diff) | |
243 | L(23bytes): | |
244 | movl -23(%esi), %eax | |
245 | movl -23(%edx), %ecx | |
246 | cmpl %ecx, %eax | |
247 | jne L(find_diff) | |
248 | L(19bytes): | |
249 | movl -19(%esi), %eax | |
250 | movl -19(%edx), %ecx | |
251 | cmpl %ecx, %eax | |
252 | jne L(find_diff) | |
253 | L(15bytes): | |
254 | movl -15(%esi), %eax | |
255 | movl -15(%edx), %ecx | |
256 | cmpl %ecx, %eax | |
257 | jne L(find_diff) | |
258 | L(11bytes): | |
259 | movl -11(%esi), %eax | |
260 | movl -11(%edx), %ecx | |
261 | cmpl %ecx, %eax | |
262 | jne L(find_diff) | |
263 | L(7bytes): | |
264 | movl -7(%esi), %eax | |
265 | movl -7(%edx), %ecx | |
266 | cmpl %ecx, %eax | |
267 | jne L(find_diff) | |
268 | L(3bytes): | |
269 | movzwl -3(%esi), %eax | |
270 | movzwl -3(%edx), %ecx | |
271 | cmpb %cl, %al | |
272 | jne L(set) | |
273 | cmpl %ecx, %eax | |
274 | jne L(set) | |
275 | movzbl -1(%esi), %eax | |
276 | cmpb -1(%edx), %al | |
277 | jne L(set) | |
278 | popl %esi | |
1ad9da69 UD |
279 | cfi_adjust_cfa_offset (-4) |
280 | cfi_restore (esi) | |
221c6b37 UD |
281 | xorl %eax, %eax |
282 | RETURN | |
283 | ||
fee732e5 | 284 | cfi_adjust_cfa_offset (8) |
1ad9da69 | 285 | cfi_rel_offset (esi, 0) |
fee732e5 | 286 | cfi_rel_offset (ebx, 4) |
221c6b37 UD |
287 | ALIGN (4) |
288 | /* ECX >= 32. */ | |
289 | L(32bytesormore): | |
290 | subl $32, %ecx | |
291 | ||
292 | movl (%esi), %eax | |
293 | cmpl (%edx), %eax | |
294 | jne L(load_ecx) | |
295 | ||
296 | movl 4(%esi), %eax | |
297 | cmpl 4(%edx), %eax | |
298 | jne L(load_ecx_4) | |
299 | ||
300 | movl 8(%esi), %eax | |
301 | cmpl 8(%edx), %eax | |
302 | jne L(load_ecx_8) | |
303 | ||
304 | movl 12(%esi), %eax | |
305 | cmpl 12(%edx), %eax | |
306 | jne L(load_ecx_12) | |
307 | ||
308 | movl 16(%esi), %eax | |
309 | cmpl 16(%edx), %eax | |
310 | jne L(load_ecx_16) | |
311 | ||
312 | movl 20(%esi), %eax | |
313 | cmpl 20(%edx), %eax | |
314 | jne L(load_ecx_20) | |
315 | ||
316 | movl 24(%esi), %eax | |
317 | cmpl 24(%edx), %eax | |
318 | jne L(load_ecx_24) | |
319 | ||
320 | movl 28(%esi), %eax | |
321 | cmpl 28(%edx), %eax | |
322 | jne L(load_ecx_28) | |
323 | ||
324 | addl $32, %esi | |
325 | addl $32, %edx | |
326 | cmpl $32, %ecx | |
327 | jge L(32bytesormore) | |
328 | ||
329 | LOAD_JUMP_TABLE_ENTRY (L(table_32bytes), %ecx) | |
330 | addl %ecx, %edx | |
331 | addl %ecx, %esi | |
332 | jmp *%ebx | |
333 | ||
334 | L(load_ecx_28): | |
335 | addl $0x4, %edx | |
336 | L(load_ecx_24): | |
337 | addl $0x4, %edx | |
338 | L(load_ecx_20): | |
339 | addl $0x4, %edx | |
340 | L(load_ecx_16): | |
341 | addl $0x4, %edx | |
342 | L(load_ecx_12): | |
343 | addl $0x4, %edx | |
344 | L(load_ecx_8): | |
345 | addl $0x4, %edx | |
346 | L(load_ecx_4): | |
347 | addl $0x4, %edx | |
348 | L(load_ecx): | |
349 | movl (%edx), %ecx | |
350 | ||
351 | L(find_diff): | |
352 | cmpb %cl, %al | |
353 | jne L(set) | |
354 | cmpb %ch, %ah | |
355 | jne L(set) | |
356 | shrl $16,%eax | |
357 | shrl $16,%ecx | |
358 | cmpb %cl, %al | |
359 | jne L(set) | |
360 | /* We get there only if we already know there is a | |
361 | difference. */ | |
362 | cmpl %ecx, %eax | |
363 | L(set): | |
364 | sbbl %eax, %eax | |
365 | sbbl $-1, %eax | |
366 | popl %esi | |
1ad9da69 UD |
367 | cfi_adjust_cfa_offset (-4) |
368 | cfi_restore (esi) | |
221c6b37 | 369 | RETURN |
8406a53a | 370 | END (BP_SYM (memcmp)) |
221c6b37 | 371 | |
f8fbb4c4 | 372 | .section .rodata |
221c6b37 UD |
373 | ALIGN (2) |
374 | L(table_32bytes) : | |
11bf311e UD |
375 | .long L(0bytes) - L(table_32bytes) |
376 | .long L(1bytes) - L(table_32bytes) | |
377 | .long L(2bytes) - L(table_32bytes) | |
378 | .long L(3bytes) - L(table_32bytes) | |
379 | .long L(4bytes) - L(table_32bytes) | |
380 | .long L(5bytes) - L(table_32bytes) | |
381 | .long L(6bytes) - L(table_32bytes) | |
382 | .long L(7bytes) - L(table_32bytes) | |
383 | .long L(8bytes) - L(table_32bytes) | |
384 | .long L(9bytes) - L(table_32bytes) | |
385 | .long L(10bytes) - L(table_32bytes) | |
386 | .long L(11bytes) - L(table_32bytes) | |
387 | .long L(12bytes) - L(table_32bytes) | |
388 | .long L(13bytes) - L(table_32bytes) | |
389 | .long L(14bytes) - L(table_32bytes) | |
390 | .long L(15bytes) - L(table_32bytes) | |
391 | .long L(16bytes) - L(table_32bytes) | |
392 | .long L(17bytes) - L(table_32bytes) | |
393 | .long L(18bytes) - L(table_32bytes) | |
394 | .long L(19bytes) - L(table_32bytes) | |
395 | .long L(20bytes) - L(table_32bytes) | |
396 | .long L(21bytes) - L(table_32bytes) | |
397 | .long L(22bytes) - L(table_32bytes) | |
398 | .long L(23bytes) - L(table_32bytes) | |
399 | .long L(24bytes) - L(table_32bytes) | |
400 | .long L(25bytes) - L(table_32bytes) | |
401 | .long L(26bytes) - L(table_32bytes) | |
402 | .long L(27bytes) - L(table_32bytes) | |
403 | .long L(28bytes) - L(table_32bytes) | |
404 | .long L(29bytes) - L(table_32bytes) | |
405 | .long L(30bytes) - L(table_32bytes) | |
406 | .long L(31bytes) - L(table_32bytes) | |
221c6b37 | 407 | |
221c6b37 UD |
408 | |
409 | #undef bcmp | |
410 | weak_alias (BP_SYM (memcmp), BP_SYM (bcmp)) | |
758b2153 | 411 | libc_hidden_builtin_def (BP_SYM (memcmp)) |