* sysdeps/i386/add_n.S: Add call frame information.
[glibc.git] / sysdeps / i386 / i686 / memcmp.S
blob4f1c7413fc997f2a0fc2f38ef939f02a3f50a4d0
1 /* Compare two memory blocks for differences in the first COUNT bytes.
2    Copyright (C) 2004, 2005 Free Software Foundation, Inc.
3    This file is part of the GNU C Library.
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.
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.
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.  */
20 #include <sysdep.h>
21 #include "asm-syntax.h"
22 #include "bp-sym.h"
23 #include "bp-asm.h"
25 #define PARMS           LINKAGE+4       /* Preserve EBX.  */
26 #define BLK1            PARMS
27 #define BLK2            BLK1+PTR_SIZE
28 #define LEN             BLK2+PTR_SIZE
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); \
32                         cfi_restore (ebx); LEAVE; ret
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.  */
37 #define LOAD_JUMP_TABLE_ENTRY(TABLE, INDEX) \
38   /* We first load PC into EBX.  */                                           \
39   call  __i686.get_pc_thunk.bx;                                               \
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.  */                                                    \
44   addl  (%ebx,INDEX,4), %ebx
46 #ifdef HAVE_HIDDEN
47         .section        .gnu.linkonce.t.__i686.get_pc_thunk.bx,"ax",@progbits
48         .globl  __i686.get_pc_thunk.bx
49         .hidden __i686.get_pc_thunk.bx
50 #else
51         .text
52 #endif
53         ALIGN (4)
54         .type   __i686.get_pc_thunk.bx,@function
55 __i686.get_pc_thunk.bx:
56         movl    (%esp), %ebx
57         ret
59         .text
60         ALIGN (4)
61 ENTRY (BP_SYM (memcmp))
62         ENTRANCE
64         movl    BLK1(%esp), %eax
65         movl    BLK2(%esp), %edx
66         movl    LEN(%esp), %ecx
68         cmpl    $1, %ecx
69         jne     L(not_1)
70         movzbl  (%eax), %ecx            /* LEN == 1  */
71         cmpb    (%edx), %cl
72         jne     L(neq)
73 L(bye):
74         xorl    %eax, %eax
75         RETURN
77 L(neq):
78         sbbl    %eax, %eax
79         sbbl    $-1, %eax
80         RETURN
82 L(not_1):
83         jl      L(bye)                  /* LEN == 0  */
85         pushl   %esi
86         cfi_adjust_cfa_offset (4)
87         movl    %eax, %esi
88         cfi_rel_offset (esi, 0)
89         cmpl    $32, %ecx;
90         jge     L(32bytesormore)        /* LEN => 32  */
92         LOAD_JUMP_TABLE_ENTRY (L(table_32bytes), %ecx)
93         addl    %ecx, %edx
94         addl    %ecx, %esi
95         jmp     *%ebx
97         ALIGN (4)
98 L(28bytes):
99         movl    -28(%esi), %eax
100         movl    -28(%edx), %ecx
101         cmpl    %ecx, %eax
102         jne     L(find_diff)
103 L(24bytes):
104         movl    -24(%esi), %eax
105         movl    -24(%edx), %ecx
106         cmpl    %ecx, %eax
107         jne     L(find_diff)
108 L(20bytes):
109         movl    -20(%esi), %eax
110         movl    -20(%edx), %ecx
111         cmpl    %ecx, %eax
112         jne     L(find_diff)
113 L(16bytes):
114         movl    -16(%esi), %eax
115         movl    -16(%edx), %ecx
116         cmpl    %ecx, %eax
117         jne     L(find_diff)
118 L(12bytes):
119         movl    -12(%esi), %eax
120         movl    -12(%edx), %ecx
121         cmpl    %ecx, %eax
122         jne     L(find_diff)
123 L(8bytes):
124         movl    -8(%esi), %eax
125         movl    -8(%edx), %ecx
126         cmpl    %ecx, %eax
127         jne     L(find_diff)
128 L(4bytes):
129         movl    -4(%esi), %eax
130         movl    -4(%edx), %ecx
131         cmpl    %ecx, %eax
132         jne     L(find_diff)
133 L(0bytes):
134         popl    %esi
135         cfi_adjust_cfa_offset (-4)
136         cfi_restore (esi)
137         xorl    %eax, %eax
138         RETURN
140         cfi_adjust_cfa_offset (4)
141         cfi_rel_offset (esi, 0)
142 L(29bytes):
143         movl    -29(%esi), %eax
144         movl    -29(%edx), %ecx
145         cmpl    %ecx, %eax
146         jne     L(find_diff)
147 L(25bytes):
148         movl    -25(%esi), %eax
149         movl    -25(%edx), %ecx
150         cmpl    %ecx, %eax
151         jne     L(find_diff)
152 L(21bytes):
153         movl    -21(%esi), %eax
154         movl    -21(%edx), %ecx
155         cmpl    %ecx, %eax
156         jne     L(find_diff)
157 L(17bytes):
158         movl    -17(%esi), %eax
159         movl    -17(%edx), %ecx
160         cmpl    %ecx, %eax
161         jne     L(find_diff)
162 L(13bytes):
163         movl    -13(%esi), %eax
164         movl    -13(%edx), %ecx
165         cmpl    %ecx, %eax
166         jne     L(find_diff)
167 L(9bytes):
168         movl    -9(%esi), %eax
169         movl    -9(%edx), %ecx
170         cmpl    %ecx, %eax
171         jne     L(find_diff)
172 L(5bytes):
173         movl    -5(%esi), %eax
174         movl    -5(%edx), %ecx
175         cmpl    %ecx, %eax
176         jne     L(find_diff)
177 L(1bytes):
178         movzbl  -1(%esi), %eax
179         cmpb    -1(%edx), %al
180         jne     L(set)
181         popl    %esi
182         cfi_adjust_cfa_offset (-4)
183         cfi_restore (esi)
184         xorl    %eax, %eax
185         RETURN
187         cfi_adjust_cfa_offset (4)
188         cfi_rel_offset (esi, 0)
189 L(30bytes):
190         movl    -30(%esi), %eax
191         movl    -30(%edx), %ecx
192         cmpl    %ecx, %eax
193         jne     L(find_diff)
194 L(26bytes):
195         movl    -26(%esi), %eax
196         movl    -26(%edx), %ecx
197         cmpl    %ecx, %eax
198         jne     L(find_diff)
199 L(22bytes):
200         movl    -22(%esi), %eax
201         movl    -22(%edx), %ecx
202         cmpl    %ecx, %eax
203         jne     L(find_diff)
204 L(18bytes):
205         movl    -18(%esi), %eax
206         movl    -18(%edx), %ecx
207         cmpl    %ecx, %eax
208         jne     L(find_diff)
209 L(14bytes):
210         movl    -14(%esi), %eax
211         movl    -14(%edx), %ecx
212         cmpl    %ecx, %eax
213         jne     L(find_diff)
214 L(10bytes):
215         movl    -10(%esi), %eax
216         movl    -10(%edx), %ecx
217         cmpl    %ecx, %eax
218         jne     L(find_diff)
219 L(6bytes):
220         movl    -6(%esi), %eax
221         movl    -6(%edx), %ecx
222         cmpl    %ecx, %eax
223         jne     L(find_diff)
224 L(2bytes):
225         movzwl  -2(%esi), %eax
226         movzwl  -2(%edx), %ecx
227         cmpb    %cl, %al
228         jne     L(set)
229         cmpl    %ecx, %eax
230         jne     L(set)
231         popl    %esi
232         cfi_adjust_cfa_offset (-4)
233         cfi_restore (esi)
234         xorl    %eax, %eax
235         RETURN
237         cfi_adjust_cfa_offset (4)
238         cfi_rel_offset (esi, 0)
239 L(31bytes):
240         movl    -31(%esi), %eax
241         movl    -31(%edx), %ecx
242         cmpl    %ecx, %eax
243         jne     L(find_diff)
244 L(27bytes):
245         movl    -27(%esi), %eax
246         movl    -27(%edx), %ecx
247         cmpl    %ecx, %eax
248         jne     L(find_diff)
249 L(23bytes):
250         movl    -23(%esi), %eax
251         movl    -23(%edx), %ecx
252         cmpl    %ecx, %eax
253         jne     L(find_diff)
254 L(19bytes):
255         movl    -19(%esi), %eax
256         movl    -19(%edx), %ecx
257         cmpl    %ecx, %eax
258         jne     L(find_diff)
259 L(15bytes):
260         movl    -15(%esi), %eax
261         movl    -15(%edx), %ecx
262         cmpl    %ecx, %eax
263         jne     L(find_diff)
264 L(11bytes):
265         movl    -11(%esi), %eax
266         movl    -11(%edx), %ecx
267         cmpl    %ecx, %eax
268         jne     L(find_diff)
269 L(7bytes):
270         movl    -7(%esi), %eax
271         movl    -7(%edx), %ecx
272         cmpl    %ecx, %eax
273         jne     L(find_diff)
274 L(3bytes):
275         movzwl  -3(%esi), %eax
276         movzwl  -3(%edx), %ecx
277         cmpb    %cl, %al
278         jne     L(set)
279         cmpl    %ecx, %eax
280         jne     L(set)
281         movzbl  -1(%esi), %eax
282         cmpb    -1(%edx), %al
283         jne     L(set)
284         popl    %esi
285         cfi_adjust_cfa_offset (-4)
286         cfi_restore (esi)
287         xorl    %eax, %eax
288         RETURN
290         cfi_adjust_cfa_offset (4)
291         cfi_rel_offset (esi, 0)
292         ALIGN (4)
293 /* ECX >= 32.  */
294 L(32bytesormore):
295         subl    $32, %ecx
297         movl    (%esi), %eax
298         cmpl    (%edx), %eax
299         jne     L(load_ecx)
301         movl    4(%esi), %eax
302         cmpl    4(%edx), %eax
303         jne     L(load_ecx_4)
305         movl    8(%esi), %eax
306         cmpl    8(%edx), %eax
307         jne     L(load_ecx_8)
309         movl    12(%esi), %eax
310         cmpl    12(%edx), %eax
311         jne     L(load_ecx_12)
313         movl    16(%esi), %eax
314         cmpl    16(%edx), %eax
315         jne     L(load_ecx_16)
317         movl    20(%esi), %eax
318         cmpl    20(%edx), %eax
319         jne     L(load_ecx_20)
321         movl    24(%esi), %eax
322         cmpl    24(%edx), %eax
323         jne     L(load_ecx_24)
325         movl    28(%esi), %eax
326         cmpl    28(%edx), %eax
327         jne     L(load_ecx_28)
329         addl    $32, %esi
330         addl    $32, %edx
331         cmpl    $32, %ecx
332         jge     L(32bytesormore)
334         LOAD_JUMP_TABLE_ENTRY (L(table_32bytes), %ecx)
335         addl    %ecx, %edx
336         addl    %ecx, %esi
337         jmp     *%ebx
339 L(load_ecx_28):
340         addl    $0x4, %edx
341 L(load_ecx_24):
342         addl    $0x4, %edx
343 L(load_ecx_20):
344         addl    $0x4, %edx
345 L(load_ecx_16):
346         addl    $0x4, %edx
347 L(load_ecx_12):
348         addl    $0x4, %edx
349 L(load_ecx_8):
350         addl    $0x4, %edx
351 L(load_ecx_4):
352         addl    $0x4, %edx
353 L(load_ecx):
354         movl    (%edx), %ecx
356 L(find_diff):
357         cmpb    %cl, %al
358         jne     L(set)
359         cmpb    %ch, %ah
360         jne     L(set)
361         shrl    $16,%eax
362         shrl    $16,%ecx
363         cmpb    %cl, %al
364         jne     L(set)
365         /* We get there only if we already know there is a
366            difference.  */
367         cmpl    %ecx, %eax
368 L(set):
369         sbbl    %eax, %eax
370         sbbl    $-1, %eax
371         popl    %esi
372         cfi_adjust_cfa_offset (-4)
373         cfi_restore (esi)
374         RETURN
375 END (BP_SYM (memcmp))
377         .section        .rodata
378         ALIGN (2)
379 L(table_32bytes) :
380         .long   L(0bytes) - . + 0x0
381         .long   L(1bytes) - . + 0x4
382         .long   L(2bytes) - . + 0x8
383         .long   L(3bytes) - . + 0xc
384         .long   L(4bytes) - . + 0x10
385         .long   L(5bytes) - . + 0x14
386         .long   L(6bytes) - . + 0x18
387         .long   L(7bytes) - . + 0x1c
388         .long   L(8bytes) - . + 0x20
389         .long   L(9bytes) - . + 0x24
390         .long   L(10bytes) - . + 0x28
391         .long   L(11bytes) - . + 0x2c
392         .long   L(12bytes) - . + 0x30
393         .long   L(13bytes) - . + 0x34
394         .long   L(14bytes) - . + 0x38
395         .long   L(15bytes) - . + 0x3c
396         .long   L(16bytes) - . + 0x40
397         .long   L(17bytes) - . + 0x44
398         .long   L(18bytes) - . + 0x48
399         .long   L(19bytes) - . + 0x4c
400         .long   L(20bytes) - . + 0x50
401         .long   L(21bytes) - . + 0x54
402         .long   L(22bytes) - . + 0x58
403         .long   L(23bytes) - . + 0x5c
404         .long   L(24bytes) - . + 0x60
405         .long   L(25bytes) - . + 0x64
406         .long   L(26bytes) - . + 0x68
407         .long   L(27bytes) - . + 0x6c
408         .long   L(28bytes) - . + 0x70
409         .long   L(29bytes) - . + 0x74
410         .long   L(30bytes) - . + 0x78
411         .long   L(31bytes) - . + 0x7c
414 #undef bcmp
415 weak_alias (BP_SYM (memcmp), BP_SYM (bcmp))
416 libc_hidden_builtin_def (BP_SYM (memcmp))