OSDN Git Service

2013.10.24
[uclinux-h8/uClinux-dist.git] / uClibc / libpthread / nptl / sysdeps / unix / sysv / linux / i386 / i486 / sem_wait.S
1 /* Copyright (C) 2002, 2003, 2005, 2007 Free Software Foundation, Inc.
2    This file is part of the GNU C Library.
3    Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
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 <pthread-errnos.h>
22 #include <structsem.h>
23 #include <lowlevellock.h>
24
25
26 #if VALUE != 0
27 # error "code needs to be rewritten for VALUE != 0"
28 #endif
29
30         .text
31
32         .globl  __new_sem_wait
33         .type   __new_sem_wait,@function
34         .align  16
35 __new_sem_wait:
36 .LSTARTCODE:
37         pushl   %ebx
38 .Lpush_ebx:
39         pushl   %esi
40 .Lpush_esi:
41         subl    $4, %esp
42 .Lsub_esp:
43
44         movl    16(%esp), %ebx
45
46         movl    (%ebx), %eax
47 2:      testl   %eax, %eax
48         je      1f
49
50         leal    -1(%eax), %edx
51         LOCK
52         cmpxchgl %edx, (%ebx)
53         jne     2b
54 7:      xorl    %eax, %eax
55
56 9:      movl    4(%esp), %esi
57         movl    8(%esp), %ebx
58         addl    $12, %esp
59 .Ladd_esp:
60         ret
61
62 .Lafter_ret:
63 1:      LOCK
64         incl    NWAITERS(%ebx)
65
66 .LcleanupSTART:
67 6:      call    __pthread_enable_asynccancel
68         movl    %eax, (%esp)
69
70 #if FUTEX_WAIT == 0
71         movl    PRIVATE(%ebx), %ecx
72 #else
73         movl    $FUTEX_WAIT, %ecx
74         orl     PRIVATE(%ebx), %ecx
75 #endif
76         xorl    %esi, %esi
77         xorl    %edx, %edx
78         movl    $SYS_futex, %eax
79         ENTER_KERNEL
80         movl    %eax, %esi
81
82         movl    (%esp), %eax
83         call    __pthread_disable_asynccancel
84 .LcleanupEND:
85
86         testl   %esi, %esi
87         je      3f
88         cmpl    $-EWOULDBLOCK, %esi
89         jne     4f
90
91 3:
92         movl    (%ebx), %eax
93 5:      testl   %eax, %eax
94         je      6b
95
96         leal    -1(%eax), %edx
97         LOCK
98         cmpxchgl %edx, (%ebx)
99         jne     5b
100
101         LOCK
102         decl    NWAITERS(%ebx)
103         jmp     7b
104
105 4:      LOCK
106         decl    NWAITERS(%ebx)
107
108         negl    %esi
109 #ifdef __PIC__
110         call    __x86.get_pc_thunk.bx
111 #else
112         movl    $8f, %ebx
113 8:
114 #endif
115         addl    $_GLOBAL_OFFSET_TABLE_, %ebx
116 #if USE___THREAD
117 # ifdef NO_TLS_DIRECT_SEG_REFS
118         movl    errno@gotntpoff(%ebx), %edx
119         addl    %gs:0, %edx
120         movl    %esi, (%edx)
121 # else
122         movl    errno@gotntpoff(%ebx), %edx
123         movl    %esi, %gs:(%edx)
124 # endif
125 #else
126         call    __errno_location@plt
127         movl    %esi, (%eax)
128 #endif
129         orl     $-1, %eax
130
131         jmp     9b
132         .size   __new_sem_wait,.-__new_sem_wait
133 weak_alias(__new_sem_wait, sem_wait)
134
135
136         .type   sem_wait_cleanup,@function
137 sem_wait_cleanup:
138         LOCK
139         decl    NWAITERS(%ebx)
140         movl    %eax, (%esp)
141 .LcallUR:
142         call    _Unwind_Resume@PLT
143         hlt
144 .LENDCODE:
145         .size   sem_wait_cleanup,.-sem_wait_cleanup
146
147
148         .section .gcc_except_table,"a",@progbits
149 .LexceptSTART:
150         .byte   0xff                            # @LPStart format (omit)
151         .byte   0xff                            # @TType format (omit)
152         .byte   0x01                            # call-site format
153                                                 # DW_EH_PE_uleb128
154         .uleb128 .Lcstend-.Lcstbegin
155 .Lcstbegin:
156         .uleb128 .LcleanupSTART-.LSTARTCODE
157         .uleb128 .LcleanupEND-.LcleanupSTART
158         .uleb128 sem_wait_cleanup-.LSTARTCODE
159         .uleb128  0
160         .uleb128 .LcallUR-.LSTARTCODE
161         .uleb128 .LENDCODE-.LcallUR
162         .uleb128 0
163         .uleb128  0
164 .Lcstend:
165
166
167         .section .eh_frame,"a",@progbits
168 .LSTARTFRAME:
169         .long   .LENDCIE-.LSTARTCIE             # Length of the CIE.
170 .LSTARTCIE:
171         .long   0                               # CIE ID.
172         .byte   1                               # Version number.
173 #ifdef SHARED
174         .string "zPLR"                          # NUL-terminated augmentation
175                                                 # string.
176 #else
177         .string "zPL"                           # NUL-terminated augmentation
178                                                 # string.
179 #endif
180         .uleb128 1                              # Code alignment factor.
181         .sleb128 -4                             # Data alignment factor.
182         .byte   8                               # Return address register
183                                                 # column.
184 #ifdef SHARED
185         .uleb128 7                              # Augmentation value length.
186         .byte   0x9b                            # Personality: DW_EH_PE_pcrel
187                                                 # + DW_EH_PE_sdata4
188                                                 # + DW_EH_PE_indirect
189         .long   DW.ref.__gcc_personality_v0-.
190         .byte   0x1b                            # LSDA Encoding: DW_EH_PE_pcrel
191                                                 # + DW_EH_PE_sdata4.
192         .byte   0x1b                            # FDE Encoding: DW_EH_PE_pcrel
193                                                 # + DW_EH_PE_sdata4.
194 #else
195         .uleb128 6                              # Augmentation value length.
196         .byte   0x0                             # Personality: absolute
197         .long   __gcc_personality_v0
198         .byte   0x0                             # LSDA Encoding: absolute
199 #endif
200         .byte 0x0c                              # DW_CFA_def_cfa
201         .uleb128 4
202         .uleb128 4
203         .byte   0x88                            # DW_CFA_offset, column 0x10
204         .uleb128 1
205         .align 4
206 .LENDCIE:
207
208         .long   .LENDFDE-.LSTARTFDE             # Length of the FDE.
209 .LSTARTFDE:
210         .long   .LSTARTFDE-.LSTARTFRAME         # CIE pointer.
211 #ifdef SHARED
212         .long   .LSTARTCODE-.                   # PC-relative start address
213                                                 # of the code.
214 #else
215         .long   .LSTARTCODE                     # Start address of the code.
216 #endif
217         .long   .LENDCODE-.LSTARTCODE           # Length of the code.
218         .uleb128 4                              # Augmentation size
219 #ifdef SHARED
220         .long   .LexceptSTART-.
221 #else
222         .long   .LexceptSTART
223 #endif
224
225         .byte   4                               # DW_CFA_advance_loc4
226         .long   .Lpush_ebx-.LSTARTCODE
227         .byte   14                              # DW_CFA_def_cfa_offset
228         .uleb128 8
229         .byte   0x83                            # DW_CFA_offset %ebx
230         .uleb128 2
231         .byte   4                               # DW_CFA_advance_loc4
232         .long   .Lpush_esi-.Lpush_ebx
233         .byte   14                              # DW_CFA_def_cfa_offset
234         .uleb128 12
235         .byte   0x86                            # DW_CFA_offset %esi
236         .uleb128 3
237         .byte   4                               # DW_CFA_advance_loc4
238         .long   .Lsub_esp-.Lpush_esi
239         .byte   14                              # DW_CFA_def_cfa_offset
240         .uleb128 16
241         .byte   4                               # DW_CFA_advance_loc4
242         .long   .Ladd_esp-.Lsub_esp
243         .byte   14                              # DW_CFA_def_cfa_offset
244         .uleb128 4
245         .byte   0xc3                            # DW_CFA_restore %ebx
246         .byte   0xc6                            # DW_CFA_restore %esi
247         .byte   4                               # DW_CFA_advance_loc4
248         .long   .Lafter_ret-.Ladd_esp
249         .byte   14                              # DW_CFA_def_cfa_offset
250         .uleb128 16
251         .byte   0x83                            # DW_CFA_offset %ebx
252         .uleb128 2
253         .byte   0x86                            # DW_CFA_offset %esi
254         .uleb128 3
255         .align  4
256 .LENDFDE:
257
258
259 #ifdef SHARED
260         .hidden DW.ref.__gcc_personality_v0
261         .weak   DW.ref.__gcc_personality_v0
262         .section .gnu.linkonce.d.DW.ref.__gcc_personality_v0,"aw",@progbits
263         .align  4
264         .type   DW.ref.__gcc_personality_v0, @object
265         .size   DW.ref.__gcc_personality_v0, 4
266 DW.ref.__gcc_personality_v0:
267         .long   __gcc_personality_v0
268 #endif
269