2.9
[glibc/nacl-glibc.git] / nptl / sysdeps / unix / sysv / linux / i386 / i486 / pthread_cond_timedwait.S
blob83f8db25bb99d1197712d50bdd1d406393908c76
1 /* Copyright (C) 2002, 2003, 2004, 2006, 2007 Free Software Foundation, Inc.
2    This file is part of the GNU C Library.
3    Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
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 <shlib-compat.h>
22 #include <lowlevellock.h>
23 #include <lowlevelcond.h>
24 #include <pthread-errnos.h>
25 #include <kernel-features.h>
28         .text
30 /* int pthread_cond_timedwait (pthread_cond_t *cond, pthread_mutex_t *mutex,
31                                const struct timespec *abstime)  */
32         .globl  __pthread_cond_timedwait
33         .type   __pthread_cond_timedwait, @function
34         .align  16
35 __pthread_cond_timedwait:
36 .LSTARTCODE:
37         pushl   %ebp
38 .Lpush_ebp:
39         pushl   %edi
40 .Lpush_edi:
41         pushl   %esi
42 .Lpush_esi:
43         pushl   %ebx
44 .Lpush_ebx:
46         movl    20(%esp), %ebx
47         movl    28(%esp), %ebp
49         cmpl    $1000000000, 4(%ebp)
50         movl    $EINVAL, %eax
51         jae     18f
53         /* Get internal lock.  */
54         movl    $1, %edx
55         xorl    %eax, %eax
56         LOCK
57 #if cond_lock == 0
58         cmpxchgl %edx, (%ebx)
59 #else
60         cmpxchgl %edx, cond_lock(%ebx)
61 #endif
62         jnz     1f
64         /* Store the reference to the mutex.  If there is already a
65            different value in there this is a bad user bug.  */
66 2:      cmpl    $-1, dep_mutex(%ebx)
67         movl    24(%esp), %eax
68         je      17f
69         movl    %eax, dep_mutex(%ebx)
71         /* Unlock the mutex.  */
72 17:     xorl    %edx, %edx
73         call    __pthread_mutex_unlock_usercnt
75         testl   %eax, %eax
76         jne     16f
78         addl    $1, total_seq(%ebx)
79         adcl    $0, total_seq+4(%ebx)
80         addl    $1, cond_futex(%ebx)
81         addl    $(1 << nwaiters_shift), cond_nwaiters(%ebx)
83 #define FRAME_SIZE 24
84         subl    $FRAME_SIZE, %esp
85 .Lsubl:
87         /* Get and store current wakeup_seq value.  */
88         movl    wakeup_seq(%ebx), %edi
89         movl    wakeup_seq+4(%ebx), %edx
90         movl    broadcast_seq(%ebx), %eax
91         movl    %edi, 12(%esp)
92         movl    %edx, 16(%esp)
93         movl    %eax, 20(%esp)
95         /* Get the current time.  */
96 8:      movl    %ebx, %edx
97 #ifdef __NR_clock_gettime
98         /* Get the clock number.  */
99         movl    cond_nwaiters(%ebx), %ebx
100         andl    $((1 << nwaiters_shift) - 1), %ebx
101         /* Only clocks 0 and 1 are allowed so far.  Both are handled in the
102            kernel.  */
103         leal    4(%esp), %ecx
104         movl    $__NR_clock_gettime, %eax
105         ENTER_KERNEL
106 # ifndef __ASSUME_POSIX_TIMERS
107         cmpl    $-ENOSYS, %eax
108         je      19f
109 # endif
110         movl    %edx, %ebx
112         /* Compute relative timeout.  */
113         movl    (%ebp), %ecx
114         movl    4(%ebp), %edx
115         subl    4(%esp), %ecx
116         subl    8(%esp), %edx
117 #else
118         /* Get the current time.  */
119         leal    4(%esp), %ebx
120         xorl    %ecx, %ecx
121         movl    $__NR_gettimeofday, %eax
122         ENTER_KERNEL
123         movl    %edx, %ebx
125         /* Compute relative timeout.  */
126         movl    8(%esp), %eax
127         movl    $1000, %edx
128         mul     %edx            /* Milli seconds to nano seconds.  */
129         movl    (%ebp), %ecx
130         movl    4(%ebp), %edx
131         subl    4(%esp), %ecx
132         subl    %eax, %edx
133 #endif
134         jns     12f
135         addl    $1000000000, %edx
136         subl    $1, %ecx
137 12:     testl   %ecx, %ecx
138         movl    $-ETIMEDOUT, %esi
139         js      6f
141         /* Store relative timeout.  */
142 21:     movl    %ecx, 4(%esp)
143         movl    %edx, 8(%esp)
145         movl    cond_futex(%ebx), %edi
147         /* Unlock.  */
148         LOCK
149 #if cond_lock == 0
150         subl    $1, (%ebx)
151 #else
152         subl    $1, cond_lock(%ebx)
153 #endif
154         jne     3f
156 .LcleanupSTART:
157 4:      call    __pthread_enable_asynccancel
158         movl    %eax, (%esp)
160         leal    4(%esp), %esi
161 #if FUTEX_PRIVATE_FLAG > 255
162         xorl    %ecx, %ecx
163 #endif
164         cmpl    $-1, dep_mutex(%ebx)
165         sete    %cl
166         subl    $1, %ecx
167 #ifdef __ASSUME_PRIVATE_FUTEX
168         andl    $FUTEX_PRIVATE_FLAG, %ecx
169 #else
170         andl    %gs:PRIVATE_FUTEX, %ecx
171 #endif
172 #if FUTEX_WAIT != 0
173         addl    $FUTEX_WAIT, %ecx
174 #endif
175         movl    %edi, %edx
176         addl    $cond_futex, %ebx
177 .Ladd_cond_futex:
178         movl    $SYS_futex, %eax
179         ENTER_KERNEL
180         subl    $cond_futex, %ebx
181 .Lsub_cond_futex:
182         movl    %eax, %esi
184         movl    (%esp), %eax
185         call    __pthread_disable_asynccancel
186 .LcleanupEND:
188         /* Lock.  */
189         movl    $1, %edx
190         xorl    %eax, %eax
191         LOCK
192 #if cond_lock == 0
193         cmpxchgl %edx, (%ebx)
194 #else
195         cmpxchgl %edx, cond_lock(%ebx)
196 #endif
197         jnz     5f
199 6:      movl    broadcast_seq(%ebx), %eax
200         cmpl    20(%esp), %eax
201         jne     23f
203         movl    woken_seq(%ebx), %eax
204         movl    woken_seq+4(%ebx), %ecx
206         movl    wakeup_seq(%ebx), %edi
207         movl    wakeup_seq+4(%ebx), %edx
209         cmpl    16(%esp), %edx
210         jne     7f
211         cmpl    12(%esp), %edi
212         je      15f
214 7:      cmpl    %ecx, %edx
215         jne     9f
216         cmp     %eax, %edi
217         jne     9f
219 15:     cmpl    $-ETIMEDOUT, %esi
220         jne     8b
222         addl    $1, wakeup_seq(%ebx)
223         adcl    $0, wakeup_seq+4(%ebx)
224         addl    $1, cond_futex(%ebx)
225         movl    $ETIMEDOUT, %esi
226         jmp     14f
228 23:     xorl    %esi, %esi
229         jmp     24f
231 9:      xorl    %esi, %esi
232 14:     addl    $1, woken_seq(%ebx)
233         adcl    $0, woken_seq+4(%ebx)
235 24:     subl    $(1 << nwaiters_shift), cond_nwaiters(%ebx)
237         /* Wake up a thread which wants to destroy the condvar object.  */
238         movl    total_seq(%ebx), %eax
239         andl    total_seq+4(%ebx), %eax
240         cmpl    $0xffffffff, %eax
241         jne     25f
242         movl    cond_nwaiters(%ebx), %eax
243         andl    $~((1 << nwaiters_shift) - 1), %eax
244         jne     25f
246         addl    $cond_nwaiters, %ebx
247         movl    $SYS_futex, %eax
248 #if FUTEX_PRIVATE_FLAG > 255
249         xorl    %ecx, %ecx
250 #endif
251         cmpl    $-1, dep_mutex-cond_nwaiters(%ebx)
252         sete    %cl
253         subl    $1, %ecx
254 #ifdef __ASSUME_PRIVATE_FUTEX
255         andl    $FUTEX_PRIVATE_FLAG, %ecx
256 #else
257         andl    %gs:PRIVATE_FUTEX, %ecx
258 #endif
259         addl    $FUTEX_WAKE, %ecx
260         movl    $1, %edx
261         ENTER_KERNEL
262         subl    $cond_nwaiters, %ebx
264 25:     LOCK
265 #if cond_lock == 0
266         subl    $1, (%ebx)
267 #else
268         subl    $1, cond_lock(%ebx)
269 #endif
270         jne     10f
272         /* Remove cancellation handler.  */
273 11:     movl    24+FRAME_SIZE(%esp), %eax
274         call    __pthread_mutex_cond_lock
275         addl    $FRAME_SIZE, %esp
276 .Laddl:
278         /* We return the result of the mutex_lock operation if it failed.  */
279         testl   %eax, %eax
280 #ifdef HAVE_CMOV
281         cmovel  %esi, %eax
282 #else
283         jne     22f
284         movl    %esi, %eax
286 #endif
288 18:     popl    %ebx
289 .Lpop_ebx:
290         popl    %esi
291 .Lpop_esi:
292         popl    %edi
293 .Lpop_edi:
294         popl    %ebp
295 .Lpop_ebp:
297         ret
299         /* Initial locking failed.  */
301 .LSbl1:
302 #if cond_lock == 0
303         movl    %ebx, %edx
304 #else
305         leal    cond_lock(%ebx), %edx
306 #endif
307 #if (LLL_SHARED-LLL_PRIVATE) > 255
308         xorl    %ecx, %ecx
309 #endif
310         cmpl    $-1, dep_mutex(%ebx)
311         setne   %cl
312         subl    $1, %ecx
313         andl    $(LLL_SHARED-LLL_PRIVATE), %ecx
314 #if LLL_PRIVATE != 0
315         addl    $LLL_PRIVATE, %ecx
316 #endif
317         call    __lll_lock_wait
318         jmp     2b
320         /* Unlock in loop requires wakeup.  */
322 .LSbl2:
323 #if cond_lock == 0
324         movl    %ebx, %eax
325 #else
326         leal    cond_lock(%ebx), %eax
327 #endif
328 #if (LLL_SHARED-LLL_PRIVATE) > 255
329         xorl    %ecx, %ecx
330 #endif
331         cmpl    $-1, dep_mutex(%ebx)
332         setne   %cl
333         subl    $1, %ecx
334         andl    $(LLL_SHARED-LLL_PRIVATE), %ecx
335 #if LLL_PRIVATE != 0
336         addl    $LLL_PRIVATE, %ecx
337 #endif
338         call    __lll_unlock_wake
339         jmp     4b
341         /* Locking in loop failed.  */
343 #if cond_lock == 0
344         movl    %ebx, %edx
345 #else
346         leal    cond_lock(%ebx), %edx
347 #endif
348 #if (LLL_SHARED-LLL_PRIVATE) > 255
349         xorl    %ecx, %ecx
350 #endif
351         cmpl    $-1, dep_mutex(%ebx)
352         setne   %cl
353         subl    $1, %ecx
354         andl    $(LLL_SHARED-LLL_PRIVATE), %ecx
355 #if LLL_PRIVATE != 0
356         addl    $LLL_PRIVATE, %ecx
357 #endif
358         call    __lll_lock_wait
359         jmp     6b
361         /* Unlock after loop requires wakeup.  */
363 #if cond_lock == 0
364         movl    %ebx, %eax
365 #else
366         leal    cond_lock(%ebx), %eax
367 #endif
368 #if (LLL_SHARED-LLL_PRIVATE) > 255
369         xorl    %ecx, %ecx
370 #endif
371         cmpl    $-1, dep_mutex(%ebx)
372         setne   %cl
373         subl    $1, %ecx
374         andl    $(LLL_SHARED-LLL_PRIVATE), %ecx
375 #if LLL_PRIVATE != 0
376         addl    $LLL_PRIVATE, %ecx
377 #endif
378         call    __lll_unlock_wake
379         jmp     11b
381         /* The initial unlocking of the mutex failed.  */
383 .LSbl3:
384         LOCK
385 #if cond_lock == 0
386         subl    $1, (%ebx)
387 #else
388         subl    $1, cond_lock(%ebx)
389 #endif
390         jne     18b
392         movl    %eax, %esi
393 #if cond_lock == 0
394         movl    %ebx, %eax
395 #else
396         leal    cond_lock(%ebx), %eax
397 #endif
398 #if (LLL_SHARED-LLL_PRIVATE) > 255
399         xorl    %ecx, %ecx
400 #endif
401         cmpl    $-1, dep_mutex(%ebx)
402         setne   %cl
403         subl    $1, %ecx
404         andl    $(LLL_SHARED-LLL_PRIVATE), %ecx
405 #if LLL_PRIVATE != 0
406         addl    $LLL_PRIVATE, %ecx
407 #endif
408         call    __lll_unlock_wake
410         movl    %esi, %eax
411         jmp     18b
413 #if defined __NR_clock_gettime && !defined __ASSUME_POSIX_TIMERS
414         /* clock_gettime not available.  */
415 .LSbl4:
416 19:     leal    4(%esp), %ebx
417         xorl    %ecx, %ecx
418         movl    $__NR_gettimeofday, %eax
419         ENTER_KERNEL
420         movl    %edx, %ebx
422         /* Compute relative timeout.  */
423         movl    8(%esp), %eax
424         movl    $1000, %edx
425         mul     %edx            /* Milli seconds to nano seconds.  */
426         movl    (%ebp), %ecx
427         movl    4(%ebp), %edx
428         subl    4(%esp), %ecx
429         subl    %eax, %edx
430         jns     20f
431         addl    $1000000000, %edx
432         subl    $1, %ecx
433 20:     testl   %ecx, %ecx
434         movl    $-ETIMEDOUT, %esi
435         js      6b
436         jmp     21b
437 #endif
438         .size   __pthread_cond_timedwait, .-__pthread_cond_timedwait
439 versioned_symbol (libpthread, __pthread_cond_timedwait, pthread_cond_timedwait,
440                   GLIBC_2_3_2)
443         .type   __condvar_tw_cleanup2, @function
444 __condvar_tw_cleanup2:
445         subl    $cond_futex, %ebx
446 .LSbl5:
447         .size   __condvar_tw_cleanup2, .-__condvar_tw_cleanup2
448         .type   __condvar_tw_cleanup, @function
449 __condvar_tw_cleanup:
450         movl    %eax, %esi
452         /* Get internal lock.  */
453         movl    $1, %edx
454         xorl    %eax, %eax
455         LOCK
456 #if cond_lock == 0
457         cmpxchgl %edx, (%ebx)
458 #else
459         cmpxchgl %edx, cond_lock(%ebx)
460 #endif
461         jz      1f
463 #if cond_lock == 0
464         movl    %ebx, %edx
465 #else
466         leal    cond_lock(%ebx), %edx
467 #endif
468 #if (LLL_SHARED-LLL_PRIVATE) > 255
469         xorl    %ecx, %ecx
470 #endif
471         cmpl    $-1, dep_mutex(%ebx)
472         setne   %cl
473         subl    $1, %ecx
474         andl    $(LLL_SHARED-LLL_PRIVATE), %ecx
475 #if LLL_PRIVATE != 0
476         addl    $LLL_PRIVATE, %ecx
477 #endif
478         call    __lll_lock_wait
480 1:      movl    broadcast_seq(%ebx), %eax
481         cmpl    20(%esp), %eax
482         jne     3f
484         /* We increment the wakeup_seq counter only if it is lower than
485            total_seq.  If this is not the case the thread was woken and
486            then canceled.  In this case we ignore the signal.  */
487         movl    total_seq(%ebx), %eax
488         movl    total_seq+4(%ebx), %edi
489         cmpl    wakeup_seq+4(%ebx), %edi
490         jb      6f
491         ja      7f
492         cmpl    wakeup_seq(%ebx), %eax
493         jbe     7f
495 6:      addl    $1, wakeup_seq(%ebx)
496         adcl    $0, wakeup_seq+4(%ebx)
497         addl    $1, cond_futex(%ebx)
499 7:      addl    $1, woken_seq(%ebx)
500         adcl    $0, woken_seq+4(%ebx)
502 3:      subl    $(1 << nwaiters_shift), cond_nwaiters(%ebx)
504         /* Wake up a thread which wants to destroy the condvar object.  */
505         xorl    %edi, %edi
506         movl    total_seq(%ebx), %eax
507         andl    total_seq+4(%ebx), %eax
508         cmpl    $0xffffffff, %eax
509         jne     4f
510         movl    cond_nwaiters(%ebx), %eax
511         andl    $~((1 << nwaiters_shift) - 1), %eax
512         jne     4f
514         addl    $cond_nwaiters, %ebx
515         movl    $SYS_futex, %eax
516 #if FUTEX_PRIVATE_FLAG > 255
517         xorl    %ecx, %ecx
518 #endif
519         cmpl    $-1, dep_mutex-cond_nwaiters(%ebx)
520         sete    %cl
521         subl    $1, %ecx
522 #ifdef __ASSUME_PRIVATE_FUTEX
523         andl    $FUTEX_PRIVATE_FLAG, %ecx
524 #else
525         andl    %gs:PRIVATE_FUTEX, %ecx
526 #endif
527         addl    $FUTEX_WAKE, %ecx
528         movl    $1, %edx
529         ENTER_KERNEL
530         subl    $cond_nwaiters, %ebx
531         movl    $1, %edi
533 4:      LOCK
534 #if cond_lock == 0
535         subl    $1, (%ebx)
536 #else
537         subl    $1, cond_lock(%ebx)
538 #endif
539         je      2f
541 #if cond_lock == 0
542         movl    %ebx, %eax
543 #else
544         leal    cond_lock(%ebx), %eax
545 #endif
546 #if (LLL_SHARED-LLL_PRIVATE) > 255
547         xorl    %ecx, %ecx
548 #endif
549         cmpl    $-1, dep_mutex(%ebx)
550         setne   %cl
551         subl    $1, %ecx
552         andl    $(LLL_SHARED-LLL_PRIVATE), %ecx
553 #if LLL_PRIVATE != 0
554         addl    $LLL_PRIVATE, %ecx
555 #endif
556         call    __lll_unlock_wake
558         /* Wake up all waiters to make sure no signal gets lost.  */
559 2:      testl   %edi, %edi
560         jnz     5f
561         addl    $cond_futex, %ebx
562 #if FUTEX_PRIVATE_FLAG > 255
563         xorl    %ecx, %ecx
564 #endif
565         cmpl    $-1, dep_mutex-cond_futex(%ebx)
566         sete    %cl
567         subl    $1, %ecx
568 #ifdef __ASSUME_PRIVATE_FUTEX
569         andl    $FUTEX_PRIVATE_FLAG, %ecx
570 #else
571         andl    %gs:PRIVATE_FUTEX, %ecx
572 #endif
573         addl    $FUTEX_WAKE, %ecx
574         movl    $SYS_futex, %eax
575         movl    $0x7fffffff, %edx
576         ENTER_KERNEL
578 5:      movl    24+FRAME_SIZE(%esp), %eax
579         call    __pthread_mutex_cond_lock
581         movl    %esi, (%esp)
582 .LcallUR:
583         call    _Unwind_Resume
584         hlt
585 .LENDCODE:
586         .size   __condvar_tw_cleanup, .-__condvar_tw_cleanup
589         .section .gcc_except_table,"a",@progbits
590 .LexceptSTART:
591         .byte   0xff                            # @LPStart format (omit)
592         .byte   0xff                            # @TType format (omit)
593         .byte   0x0b                            # call-site format
594                                                 # DW_EH_PE_sdata4
595         .uleb128 .Lcstend-.Lcstbegin
596 .Lcstbegin:
597         .long   .LcleanupSTART-.LSTARTCODE
598         .long   .Ladd_cond_futex-.LcleanupSTART
599         .long   __condvar_tw_cleanup-.LSTARTCODE
600         .uleb128  0
601         .long   .Ladd_cond_futex-.LSTARTCODE
602         .long   .Lsub_cond_futex-.Ladd_cond_futex
603         .long   __condvar_tw_cleanup2-.LSTARTCODE
604         .uleb128  0
605         .long   .Lsub_cond_futex-.LSTARTCODE
606         .long   .LcleanupEND-.Lsub_cond_futex
607         .long   __condvar_tw_cleanup-.LSTARTCODE
608         .uleb128  0
609         .long   .LcallUR-.LSTARTCODE
610         .long   .LENDCODE-.LcallUR
611         .long   0
612         .uleb128  0
613 .Lcstend:
616         .section .eh_frame,"a",@progbits
617 .LSTARTFRAME:
618         .long   L(ENDCIE)-L(STARTCIE)           # Length of the CIE.
619 .LSTARTCIE:
620         .long   0                               # CIE ID.
621         .byte   1                               # Version number.
622 #ifdef SHARED
623         .string "zPLR"                          # NUL-terminated augmentation
624                                                 # string.
625 #else
626         .string "zPL"                           # NUL-terminated augmentation
627                                                 # string.
628 #endif
629         .uleb128 1                              # Code alignment factor.
630         .sleb128 -4                             # Data alignment factor.
631         .byte   8                               # Return address register
632                                                 # column.
633 #ifdef SHARED
634         .uleb128 7                              # Augmentation value length.
635         .byte   0x9b                            # Personality: DW_EH_PE_pcrel
636                                                 # + DW_EH_PE_sdata4
637                                                 # + DW_EH_PE_indirect
638         .long   DW.ref.__gcc_personality_v0-.
639         .byte   0x1b                            # LSDA Encoding: DW_EH_PE_pcrel
640                                                 # + DW_EH_PE_sdata4.
641         .byte   0x1b                            # FDE Encoding: DW_EH_PE_pcrel
642                                                 # + DW_EH_PE_sdata4.
643 #else
644         .uleb128 6                              # Augmentation value length.
645         .byte   0x0                             # Personality: absolute
646         .long   __gcc_personality_v0
647         .byte   0x0                             # LSDA Encoding: absolute
648 #endif
649         .byte 0x0c                              # DW_CFA_def_cfa
650         .uleb128 4
651         .uleb128 4
652         .byte   0x88                            # DW_CFA_offset, column 0x8
653         .uleb128 1
654         .align 4
655 .LENDCIE:
657         .long   .LENDFDE-.LSTARTFDE             # Length of the FDE.
658 .LSTARTFDE:
659         .long   .LSTARTFDE-.LSTARTFRAME         # CIE pointer.
660 #ifdef SHARED
661         .long   .LSTARTCODE-.                   # PC-relative start address
662                                                 # of the code
663 #else
664         .long   .LSTARTCODE                     # Start address of the code.
665 #endif
666         .long   .LENDCODE-.LSTARTCODE           # Length of the code.
667         .uleb128 4                              # Augmentation size
668 #ifdef SHARED
669         .long   .LexceptSTART-.
670 #else
671         .long   .LexceptSTART
672 #endif
673         .byte   0x40+.Lpush_ebp-.LSTARTCODE     # DW_CFA_advance_loc+N
674         .byte   14                              # DW_CFA_def_cfa_offset
675         .uleb128 8
676         .byte   0x85                            # DW_CFA_offset %ebp
677         .uleb128 2
678         .byte   0x40+ .Lpush_edi-.Lpush_ebp     # DW_CFA_advance_loc+N
679         .byte   14                              # DW_CFA_def_cfa_offset
680         .uleb128 12
681         .byte   0x87                            # DW_CFA_offset %edi
682         .uleb128 3
683         .byte   0x40+.Lpush_esi-.Lpush_edi      # DW_CFA_advance_loc+N
684         .byte   14                              # DW_CFA_def_cfa_offset
685         .uleb128 16
686         .byte   0x86                            # DW_CFA_offset %esi
687         .uleb128 4
688         .byte   0x40+.Lpush_ebx-.Lpush_esi      # DW_CFA_advance_loc+N
689         .byte   14                              # DW_CFA_def_cfa_offset
690         .uleb128 20
691         .byte   0x83                            # DW_CFA_offset %ebx
692         .uleb128 5
693         .byte   4                               # DW_CFA_advance_loc4
694         .4byte  .Lsubl-.Lpush_ebx
695         .byte   14                              # DW_CFA_def_cfa_offset
696         .uleb128 20+FRAME_SIZE
697         .byte   4                               # DW_CFA_advance_loc4
698         .4byte  .Laddl-.Lsubl
699         .byte   14                              # DW_CFA_def_cfa_offset
700         .uleb128 20
701         .byte   0x40+.Lpop_ebx-.Laddl           # DW_CFA_advance_loc+N
702         .byte   14                              # DW_CFA_def_cfa_offset
703         .uleb128 16
704         .byte   0xc3                            # DW_CFA_restore %ebx
705         .byte   0x40+.Lpop_esi-.Lpop_ebx        # DW_CFA_advance_loc+N
706         .byte   14                              # DW_CFA_def_cfa_offset
707         .uleb128 12
708         .byte   0xc6                            # DW_CFA_restore %esi
709         .byte   0x40+.Lpop_edi-.Lpop_esi        # DW_CFA_advance_loc+N
710         .byte   14                              # DW_CFA_def_cfa_offset
711         .uleb128 8
712         .byte   0xc7                            # DW_CFA_restore %edi
713         .byte   0x40+.Lpop_ebp-.Lpop_edi        # DW_CFA_advance_loc+N
714         .byte   14                              # DW_CFA_def_cfa_offset
715         .uleb128 4
716         .byte   0xc5                            # DW_CFA_restore %ebp
717         .byte   0x40+.LSbl1-.Lpop_edi           # DW_CFA_advance_loc+N
718         .byte   14                              # DW_CFA_def_cfa_offset
719         .uleb128 20
720         .byte   4                               # DW_CFA_advance_loc4
721         .4byte  .LSbl2-.LSbl1
722         .byte   14                              # DW_CFA_def_cfa_offset
723         .uleb128 20+FRAME_SIZE
724         .byte   0x85                            # DW_CFA_offset %ebp
725         .uleb128 2
726         .byte   0x87                            # DW_CFA_offset %edi
727         .uleb128 3
728         .byte   0x86                            # DW_CFA_offset %esi
729         .uleb128 4
730         .byte   0x83                            # DW_CFA_offset %ebx
731         .uleb128 5
732         .byte   4                               # DW_CFA_advance_loc4
733         .4byte  .LSbl3-.LSbl2
734         .byte   14                              # DW_CFA_def_cfa_offset
735         .uleb128 20
736         .byte   4                               # DW_CFA_advance_loc4
737 #if defined __NR_clock_gettime && !defined __ASSUME_POSIX_TIMERS
738         .4byte  .LSbl4-.LSbl3
739 #else
740         .4byte  .LSbl5-.LSbl3
741 #endif
742         .byte   14                              # DW_CFA_def_cfa_offset
743         .uleb128 20+FRAME_SIZE
744         .align  4
745 .LENDFDE:
747 #ifdef SHARED
748         .hidden DW.ref.__gcc_personality_v0
749         .weak   DW.ref.__gcc_personality_v0
750         .section .gnu.linkonce.d.DW.ref.__gcc_personality_v0,"aw",@progbits
751         .align 4
752         .type   DW.ref.__gcc_personality_v0, @object
753         .size   DW.ref.__gcc_personality_v0, 4
754 DW.ref.__gcc_personality_v0:
755         .long   __gcc_personality_v0
756 #endif