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