]> git.ipfire.org Git - thirdparty/glibc.git/blob - nptl/sysdeps/unix/sysv/linux/i386/i486/sem_wait.S
3d9ee743f3b4666a735f2cce23119c576b6bd809
[thirdparty/glibc.git] / nptl / sysdeps / unix / sysv / linux / i386 / i486 / sem_wait.S
1 /* Copyright (C) 2002-2003, 2005, 2007, 2011-2012 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 <shlib-compat.h>
22 #include <pthread-errnos.h>
23 #include <structsem.h>
24 #include <lowlevellock.h>
25
26
27 #if VALUE != 0
28 # error "code needs to be rewritten for VALUE != 0"
29 #endif
30
31 .text
32
33 .globl __new_sem_wait
34 .type __new_sem_wait,@function
35 .align 16
36 __new_sem_wait:
37 .LSTARTCODE:
38 pushl %ebx
39 .Lpush_ebx:
40 pushl %esi
41 .Lpush_esi:
42 subl $4, %esp
43 .Lsub_esp:
44
45 movl 16(%esp), %ebx
46
47 movl (%ebx), %eax
48 2: testl %eax, %eax
49 je 1f
50
51 leal -1(%eax), %edx
52 LOCK
53 cmpxchgl %edx, (%ebx)
54 jne 2b
55 7: xorl %eax, %eax
56
57 9: movl 4(%esp), %esi
58 movl 8(%esp), %ebx
59 addl $12, %esp
60 .Ladd_esp:
61 ret
62
63 .Lafter_ret:
64 1: LOCK
65 incl NWAITERS(%ebx)
66
67 .LcleanupSTART:
68 6: call __pthread_enable_asynccancel
69 movl %eax, (%esp)
70
71 #if FUTEX_WAIT == 0
72 movl PRIVATE(%ebx), %ecx
73 #else
74 movl $FUTEX_WAIT, %ecx
75 orl PRIVATE(%ebx), %ecx
76 #endif
77 xorl %esi, %esi
78 xorl %edx, %edx
79 movl $SYS_futex, %eax
80 ENTER_KERNEL
81 movl %eax, %esi
82
83 movl (%esp), %eax
84 call __pthread_disable_asynccancel
85 .LcleanupEND:
86
87 testl %esi, %esi
88 je 3f
89 cmpl $-EWOULDBLOCK, %esi
90 jne 4f
91
92 3:
93 movl (%ebx), %eax
94 5: testl %eax, %eax
95 je 6b
96
97 leal -1(%eax), %edx
98 LOCK
99 cmpxchgl %edx, (%ebx)
100 jne 5b
101
102 LOCK
103 decl NWAITERS(%ebx)
104 jmp 7b
105
106 4: LOCK
107 decl NWAITERS(%ebx)
108
109 negl %esi
110 #ifdef PIC
111 SETUP_PIC_REG(bx)
112 #else
113 movl $8f, %ebx
114 8:
115 #endif
116 addl $_GLOBAL_OFFSET_TABLE_, %ebx
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 orl $-1, %eax
126
127 jmp 9b
128 .size __new_sem_wait,.-__new_sem_wait
129 versioned_symbol(libpthread, __new_sem_wait, sem_wait, GLIBC_2_1)
130
131
132 .type sem_wait_cleanup,@function
133 sem_wait_cleanup:
134 LOCK
135 decl NWAITERS(%ebx)
136 movl %eax, (%esp)
137 .LcallUR:
138 call _Unwind_Resume@PLT
139 hlt
140 .LENDCODE:
141 .size sem_wait_cleanup,.-sem_wait_cleanup
142
143
144 .section .gcc_except_table,"a",@progbits
145 .LexceptSTART:
146 .byte 0xff # @LPStart format (omit)
147 .byte 0xff # @TType format (omit)
148 .byte 0x01 # call-site format
149 # DW_EH_PE_uleb128
150 .uleb128 .Lcstend-.Lcstbegin
151 .Lcstbegin:
152 .uleb128 .LcleanupSTART-.LSTARTCODE
153 .uleb128 .LcleanupEND-.LcleanupSTART
154 .uleb128 sem_wait_cleanup-.LSTARTCODE
155 .uleb128 0
156 .uleb128 .LcallUR-.LSTARTCODE
157 .uleb128 .LENDCODE-.LcallUR
158 .uleb128 0
159 .uleb128 0
160 .Lcstend:
161
162
163 .section .eh_frame,"a",@progbits
164 .LSTARTFRAME:
165 .long .LENDCIE-.LSTARTCIE # Length of the CIE.
166 .LSTARTCIE:
167 .long 0 # CIE ID.
168 .byte 1 # Version number.
169 #ifdef SHARED
170 .string "zPLR" # NUL-terminated augmentation
171 # string.
172 #else
173 .string "zPL" # NUL-terminated augmentation
174 # string.
175 #endif
176 .uleb128 1 # Code alignment factor.
177 .sleb128 -4 # Data alignment factor.
178 .byte 8 # Return address register
179 # column.
180 #ifdef SHARED
181 .uleb128 7 # Augmentation value length.
182 .byte 0x9b # Personality: DW_EH_PE_pcrel
183 # + DW_EH_PE_sdata4
184 # + DW_EH_PE_indirect
185 .long DW.ref.__gcc_personality_v0-.
186 .byte 0x1b # LSDA Encoding: DW_EH_PE_pcrel
187 # + DW_EH_PE_sdata4.
188 .byte 0x1b # FDE Encoding: DW_EH_PE_pcrel
189 # + DW_EH_PE_sdata4.
190 #else
191 .uleb128 6 # Augmentation value length.
192 .byte 0x0 # Personality: absolute
193 .long __gcc_personality_v0
194 .byte 0x0 # LSDA Encoding: absolute
195 #endif
196 .byte 0x0c # DW_CFA_def_cfa
197 .uleb128 4
198 .uleb128 4
199 .byte 0x88 # DW_CFA_offset, column 0x10
200 .uleb128 1
201 .align 4
202 .LENDCIE:
203
204 .long .LENDFDE-.LSTARTFDE # Length of the FDE.
205 .LSTARTFDE:
206 .long .LSTARTFDE-.LSTARTFRAME # CIE pointer.
207 #ifdef SHARED
208 .long .LSTARTCODE-. # PC-relative start address
209 # of the code.
210 #else
211 .long .LSTARTCODE # Start address of the code.
212 #endif
213 .long .LENDCODE-.LSTARTCODE # Length of the code.
214 .uleb128 4 # Augmentation size
215 #ifdef SHARED
216 .long .LexceptSTART-.
217 #else
218 .long .LexceptSTART
219 #endif
220
221 .byte 4 # DW_CFA_advance_loc4
222 .long .Lpush_ebx-.LSTARTCODE
223 .byte 14 # DW_CFA_def_cfa_offset
224 .uleb128 8
225 .byte 0x83 # DW_CFA_offset %ebx
226 .uleb128 2
227 .byte 4 # DW_CFA_advance_loc4
228 .long .Lpush_esi-.Lpush_ebx
229 .byte 14 # DW_CFA_def_cfa_offset
230 .uleb128 12
231 .byte 0x86 # DW_CFA_offset %esi
232 .uleb128 3
233 .byte 4 # DW_CFA_advance_loc4
234 .long .Lsub_esp-.Lpush_esi
235 .byte 14 # DW_CFA_def_cfa_offset
236 .uleb128 16
237 .byte 4 # DW_CFA_advance_loc4
238 .long .Ladd_esp-.Lsub_esp
239 .byte 14 # DW_CFA_def_cfa_offset
240 .uleb128 4
241 .byte 0xc3 # DW_CFA_restore %ebx
242 .byte 0xc6 # DW_CFA_restore %esi
243 .byte 4 # DW_CFA_advance_loc4
244 .long .Lafter_ret-.Ladd_esp
245 .byte 14 # DW_CFA_def_cfa_offset
246 .uleb128 16
247 .byte 0x83 # DW_CFA_offset %ebx
248 .uleb128 2
249 .byte 0x86 # DW_CFA_offset %esi
250 .uleb128 3
251 .align 4
252 .LENDFDE:
253
254
255 #ifdef SHARED
256 .hidden DW.ref.__gcc_personality_v0
257 .weak DW.ref.__gcc_personality_v0
258 .section .gnu.linkonce.d.DW.ref.__gcc_personality_v0,"aw",@progbits
259 .align 4
260 .type DW.ref.__gcc_personality_v0, @object
261 .size DW.ref.__gcc_personality_v0, 4
262 DW.ref.__gcc_personality_v0:
263 .long __gcc_personality_v0
264 #endif
265
266
267 #if SHLIB_COMPAT(libpthread, GLIBC_2_0, GLIBC_2_1)
268 .section ".text.compat", "ax"
269 .global __old_sem_wait
270 .type __old_sem_wait,@function
271 .align 16
272 cfi_startproc
273 __old_sem_wait:
274 pushl %ebx
275 cfi_adjust_cfa_offset(4)
276 pushl %esi
277 cfi_adjust_cfa_offset(4)
278 subl $4, %esp
279 cfi_adjust_cfa_offset(4)
280
281 movl 16(%esp), %ebx
282 cfi_offset(ebx, -8)
283
284 cfi_offset(esi, -12)
285 3: movl (%ebx), %eax
286 2: testl %eax, %eax
287 je 1f
288
289 leal -1(%eax), %edx
290 LOCK
291 cmpxchgl %edx, (%ebx)
292 jne 2b
293 xorl %eax, %eax
294
295 5: movl 4(%esp), %esi
296 movl 8(%esp), %ebx
297 addl $12, %esp
298 cfi_restore(ebx)
299 cfi_restore(esi)
300 cfi_adjust_cfa_offset(-12)
301 ret
302
303 cfi_adjust_cfa_offset(12)
304 cfi_offset(ebx, -8)
305 cfi_offset(esi, -12)
306 1: call __pthread_enable_asynccancel
307 movl %eax, (%esp)
308
309 xorl %esi, %esi
310 movl $SYS_futex, %eax
311 movl %esi, %ecx
312 movl %esi, %edx
313 ENTER_KERNEL
314 movl %eax, %esi
315
316 movl (%esp), %eax
317 call __pthread_disable_asynccancel
318
319 testl %esi, %esi
320 je 3b
321 cmpl $-EWOULDBLOCK, %esi
322 je 3b
323 negl %esi
324 #ifdef PIC
325 SETUP_PIC_REG(bx)
326 #else
327 movl $4f, %ebx
328 4:
329 #endif
330 addl $_GLOBAL_OFFSET_TABLE_, %ebx
331 #ifdef NO_TLS_DIRECT_SEG_REFS
332 movl errno@gotntpoff(%ebx), %edx
333 addl %gs:0, %edx
334 movl %esi, (%edx)
335 #else
336 movl errno@gotntpoff(%ebx), %edx
337 movl %esi, %gs:(%edx)
338 #endif
339 orl $-1, %eax
340 jmp 5b
341 cfi_endproc
342 .size __old_sem_wait,.-__old_sem_wait
343 compat_symbol(libpthread, __old_sem_wait, sem_wait, GLIBC_2_0)
344 #endif