2.9
[glibc/nacl-glibc.git] / nptl / sysdeps / unix / sysv / linux / x86_64 / sem_wait.S
blob5320a91e19a4238cbf6c209a2c74695db573a7b0
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.
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 <lowlevellock.h>
22 #include <shlib-compat.h>
23 #include <pthread-errnos.h>
24 #include <structsem.h>
27         .text
29         .globl  sem_wait
30         .type   sem_wait,@function
31         .align  16
32 sem_wait:
33 .LSTARTCODE:
34         pushq   %r12
35 .Lpush_r12:
36         pushq   %r13
37 .Lpush_r13:
38         movq    %rdi, %r13
40 #if VALUE == 0
41         movl    (%r13), %eax
42 #else
43         movl    VALUE(%r13), %eax
44 #endif
45 2:      testl   %eax, %eax
46         je      1f
48         leal    -1(%rax), %edx
49         LOCK
50 #if VALUE == 0
51         cmpxchgl %edx, (%r13)
52 #else
53         cmpxchgl %edx, VALUE(%r13)
54 #endif
55         jne     2b
57 7:      xorl    %eax, %eax
59 9:      popq    %r13
60 .Lpop_r13:
61         popq    %r12
62 .Lpop_r12:
64         retq
66 .Lafter_retq:
67 1:      LOCK
68         addq    $1, NWAITERS(%r13)
70 .LcleanupSTART:
71 6:      call    __pthread_enable_asynccancel
72         movl    %eax, %r8d
74         xorq    %r10, %r10
75         movl    $SYS_futex, %eax
76         movq    %r13, %rdi
77 #if FUTEX_WAIT == 0
78         movl    PRIVATE(%rdi), %esi
79 #else
80         movl    $FUTEX_WAIT, %esi
81         orl     PRIVATE(%rdi), %esi
82 #endif
83         xorl    %edx, %edx
84         syscall
85         movq    %rax, %r12
87         movl    %r8d, %edi
88         call    __pthread_disable_asynccancel
89 .LcleanupEND:
91         testq   %r12, %r12
92         je      3f
93         cmpq    $-EWOULDBLOCK, %r12
94         jne     4f
97 #if VALUE == 0
98         movl    (%r13), %eax
99 #else
100         movl    VALUE(%r13), %eax
101 #endif
102 5:      testl   %eax, %eax
103         je      6b
105         leal    -1(%rax), %edx
106         LOCK
107 #if VALUE == 0
108         cmpxchgl %edx, (%r13)
109 #else
110         cmpxchgl %edx, VALUE(%r13)
111 #endif
112         jne     5b
114         LOCK
115         subq    $1, NWAITERS(%r13)
116         jmp     7b
118 4:      negq    %r12
119 #if USE___THREAD
120         movq    errno@gottpoff(%rip), %rdx
121         movl    %r12d, %fs:(%rdx)
122 #else
123         callq   __errno_location@plt
124         movl    %r12d, (%rax)
125 #endif
126         orl     $-1, %eax
128         LOCK
129         subq    $1, NWAITERS(%r13)
131         jmp 9b
132         .size   sem_wait,.-sem_wait
135         .type   sem_wait_cleanup,@function
136 sem_wait_cleanup:
137         LOCK
138         subq    $1, NWAITERS(%r13)
139         movq    %rax, %rdi
140 .LcallUR:
141         call    _Unwind_Resume@PLT
142         hlt
143 .LENDCODE:
144         .size   sem_wait_cleanup,.-sem_wait_cleanup
147         .section .gcc_except_table,"a",@progbits
148 .LexceptSTART:
149         .byte   0xff                            # @LPStart format (omit)
150         .byte   0xff                            # @TType format (omit)
151         .byte   0x01                            # call-site format
152                                                 # DW_EH_PE_uleb128
153         .uleb128 .Lcstend-.Lcstbegin
154 .Lcstbegin:
155         .uleb128 .LcleanupSTART-.LSTARTCODE
156         .uleb128 .LcleanupEND-.LcleanupSTART
157         .uleb128 sem_wait_cleanup-.LSTARTCODE
158         .uleb128  0
159         .uleb128 .LcallUR-.LSTARTCODE
160         .uleb128 .LENDCODE-.LcallUR
161         .uleb128 0
162         .uleb128  0
163 .Lcstend:
166         .section .eh_frame,"a",@progbits
167 .LSTARTFRAME:
168         .long   .LENDCIE-.LSTARTCIE             # Length of the CIE.
169 .LSTARTCIE:
170         .long   0                               # CIE ID.
171         .byte   1                               # Version number.
172 #ifdef SHARED
173         .string "zPLR"                          # NUL-terminated augmentation
174                                                 # string.
175 #else
176         .string "zPL"                           # NUL-terminated augmentation
177                                                 # string.
178 #endif
179         .uleb128 1                              # Code alignment factor.
180         .sleb128 -8                             # Data alignment factor.
181         .byte   16                              # Return address register
182                                                 # column.
183 #ifdef SHARED
184         .uleb128 7                              # Augmentation value length.
185         .byte   0x9b                            # Personality: DW_EH_PE_pcrel
186                                                 # + DW_EH_PE_sdata4
187                                                 # + DW_EH_PE_indirect
188         .long   DW.ref.__gcc_personality_v0-.
189         .byte   0x1b                            # LSDA Encoding: DW_EH_PE_pcrel
190                                                 # + DW_EH_PE_sdata4.
191         .byte   0x1b                            # FDE Encoding: DW_EH_PE_pcrel
192                                                 # + DW_EH_PE_sdata4.
193 #else
194         .uleb128 10                             # Augmentation value length.
195         .byte   0x0                             # Personality: absolute
196         .quad   __gcc_personality_v0
197         .byte   0x0                             # LSDA Encoding: absolute
198 #endif
199         .byte 0x0c                              # DW_CFA_def_cfa
200         .uleb128 7
201         .uleb128 8
202         .byte   0x90                            # DW_CFA_offset, column 0x10
203         .uleb128 1
204         .align 8
205 .LENDCIE:
207         .long   .LENDFDE-.LSTARTFDE             # Length of the FDE.
208 .LSTARTFDE:
209         .long   .LSTARTFDE-.LSTARTFRAME         # CIE pointer.
210 #ifdef SHARED
211         .long   .LSTARTCODE-.                   # PC-relative start address
212                                                 # of the code.
213         .long   .LENDCODE-.LSTARTCODE           # Length of the code.
214         .uleb128 4                              # Augmentation size
215         .long   .LexceptSTART-.
216 #else
217         .quad   .LSTARTCODE                     # Start address of the code.
218         .quad   .LENDCODE-.LSTARTCODE           # Length of the code.
219         .uleb128 8                              # Augmentation size
220         .quad   .LexceptSTART
221 #endif
223         .byte   4                               # DW_CFA_advance_loc4
224         .long   .Lpush_r12-.LSTARTCODE
225         .byte   14                              # DW_CFA_def_cfa_offset
226         .uleb128 16
227         .byte   0x8c                            # DW_CFA_offset %r12
228         .uleb128 2
229         .byte   4                               # DW_CFA_advance_loc4
230         .long   .Lpush_r13-.Lpush_r12
231         .byte   14                              # DW_CFA_def_cfa_offset
232         .uleb128 24
233         .byte   0x8d                            # DW_CFA_offset %r13
234         .uleb128 3
235         .byte   4                               # DW_CFA_advance_loc4
236         .long   .Lpop_r13-.Lpush_r13
237         .byte   14                              # DW_CFA_def_cfa_offset
238         .uleb128 16
239         .byte   0xcd                            # DW_CFA_restore %r13
240         .byte   4                               # DW_CFA_advance_loc4
241         .long   .Lpop_r12-.Lpop_r13
242         .byte   14                              # DW_CFA_def_cfa_offset
243         .uleb128 8
244         .byte   0xcc                            # DW_CFA_restore %r12
245         .byte   4                               # DW_CFA_advance_loc4
246         .long   .Lafter_retq-.Lpop_r12
247         .byte   14                              # DW_CFA_def_cfa_offset
248         .uleb128 24
249         .byte   0x8c                            # DW_CFA_offset %r12
250         .uleb128 2
251         .byte   0x8d                            # DW_CFA_offset %r13
252         .uleb128 3
253         .align  8
254 .LENDFDE:
257 #ifdef SHARED
258         .hidden DW.ref.__gcc_personality_v0
259         .weak   DW.ref.__gcc_personality_v0
260         .section .gnu.linkonce.d.DW.ref.__gcc_personality_v0,"aw",@progbits
261         .align  8
262         .type   DW.ref.__gcc_personality_v0, @object
263         .size   DW.ref.__gcc_personality_v0, 8
264 DW.ref.__gcc_personality_v0:
265         .quad   __gcc_personality_v0
266 #endif