OSDN Git Service

build: Get rids of PIC macro using compiler flag __PIC__ instead
[uclinux-h8/uClibc.git] / libpthread / nptl / sysdeps / unix / sysv / linux / sh / pthread_cond_wait.S
1 /* Copyright (C) 2003, 2004 Free Software Foundation, Inc.
2    This file is part of the GNU C Library.
3
4    The GNU C Library is free software; you can redistribute it and/or
5    modify it under the terms of the GNU Lesser General Public
6    License as published by the Free Software Foundation; either
7    version 2.1 of the License, or (at your option) any later version.
8
9    The GNU C Library is distributed in the hope that it will be useful,
10    but WITHOUT ANY WARRANTY; without even the implied warranty of
11    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12    Lesser General Public License for more details.
13
14    You should have received a copy of the GNU Lesser General Public
15    License along with the GNU C Library; if not, write to the Free
16    Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
17    02111-1307 USA.  */
18
19 #include <sysdep.h>
20 #include <lowlevelcond.h>
21 #include "lowlevel-atomic.h"
22
23 #define FUTEX_WAIT              0
24 #define FUTEX_WAKE              1
25
26
27         .text
28
29 /* int pthread_cond_wait (pthread_cond_t *cond, pthread_mutex_t *mutex)  */
30         .globl  __pthread_cond_wait
31         .type   __pthread_cond_wait, @function
32         .align  5
33 __pthread_cond_wait:
34 .LSTARTCODE:
35         mov.l   r8, @-r15
36 .Lpush_r8:
37         mov.l   r9, @-r15
38 .Lpush_r9:
39         mov.l   r10, @-r15
40 .Lpush_r10:
41         mov.l   r11, @-r15
42 .Lpush_r11:
43         mov.l   r12, @-r15
44 .Lpush_r12:
45         sts.l   pr, @-r15
46 .Lpush_pr:
47         add     #-48, r15
48 .Lalloc:
49         mov     r4, r8
50         mov     r5, r9
51 #ifdef __PIC__
52         mova    .Lgot0, r0
53         mov.l   .Lgot0, r12
54         add     r0, r12
55 #endif
56
57         /* Get internal lock.  */
58         mov     #0, r3
59         mov     #1, r4
60 #if cond_lock != 0
61         CMPXCHG (r3, @(cond_lock,r8), r4, r2)
62 #else
63         CMPXCHG (r3, @r8, r4, r2)
64 #endif
65         bt      2f
66         bra     1f
67          nop
68 #ifdef __PIC__
69         .align  2
70 .Lgot0:
71         .long   _GLOBAL_OFFSET_TABLE_
72 #endif
73
74 2:
75         /* Store the reference to the mutex.  If there is already a
76            different value in there this is a bad user bug.  */
77         mov.l   @(dep_mutex,r8),r0
78         cmp/eq  #-1, r0
79         bt      15f
80         mov.l   r9, @(dep_mutex,r8)
81
82 15:
83         /* Unlock the mutex.  */
84         mov.l   .Lmunlock0, r1
85         mov     #0, r5
86         bsrf    r1
87          mov    r9, r4
88 .Lmunlock0b:
89
90         tst     r0, r0
91         bt      0f
92         bra     12f
93          nop
94 0:
95         mov     #1, r2
96         mov     #0, r3
97
98         clrt
99         mov.l   @(total_seq,r8),r0
100         mov.l   @(total_seq+4,r8),r1
101         addc    r2, r0
102         addc    r3, r1
103         mov.l   r0,@(total_seq,r8)
104         mov.l   r1,@(total_seq+4,r8)
105         mov.l   @(cond_futex,r8),r0
106         add     r2, r0
107         mov.l   r0,@(cond_futex,r8)
108         mov     #(1 << clock_bits), r2
109         mov.l   @(cond_nwaiters,r8), r0
110         add     r2, r0
111         mov.l   r0, @(cond_nwaiters,r8)
112
113         /* Get and store current wakeup_seq value.  */
114         mov.l   @(wakeup_seq,r8), r10
115         mov.l   @(wakeup_seq+4,r8), r11
116         mov.l   @(broadcast_seq,r8), r0
117         mov.l   r0, @(4,r15)
118
119 8:
120         mov.l   @(cond_futex,r8),r0
121         mov.l   r0, @(8,r15)
122
123         /* Unlock.  */
124 #if cond_lock != 0
125         DEC (@(cond_lock,r8), r2)
126 #else
127         DEC (@r8, r2)
128 #endif
129         tst     r2, r2
130         bf      3f
131 4:
132 .LcleanupSTART:
133         mov.l   .Lenable0, r1
134         bsrf    r1
135          nop
136 .Lenable0b:
137         mov.l   r0, @r15
138
139         mov     #0, r7
140         mov     #FUTEX_WAIT, r5
141         mov.l   @(8,r15), r6
142         mov     r8, r4
143         add     #cond_futex, r4
144         mov     #SYS_futex, r3
145         extu.b  r3, r3
146         trapa   #0x14
147         SYSCALL_INST_PAD
148
149         mov.l   .Ldisable0, r1
150         bsrf    r1
151          mov.l  @r15, r4
152 .Ldisable0b:
153 .LcleanupEND:
154
155         /* Lock.  */
156         mov     #0, r3
157         mov     #1, r4
158 #if cond_lock != 0
159         CMPXCHG (r3, @(cond_lock,r8), r4, r2)
160 #else
161         CMPXCHG (r3, @r8, r4, r2)
162 #endif
163         bf      5f
164 6:
165         mov.l   @(broadcast_seq,r8), r0
166         mov.l   @(4,r15), r1
167         cmp/eq  r0, r1
168         bf      16f
169
170         mov.l   @(woken_seq,r8), r0
171         mov.l   @(woken_seq+4,r8), r1
172
173         mov.l   @(wakeup_seq,r8), r2
174         mov.l   @(wakeup_seq+4,r8), r3
175
176         cmp/eq  r3, r11
177         bf      7f
178         cmp/eq  r2, r10
179         bt      8b
180 7:
181         cmp/eq  r1, r3
182         bf      9f
183         cmp/eq  r0, r2
184         bt      8b
185 9:
186         mov     #1, r2
187         mov     #0, r3
188
189         clrt
190         mov.l   @(woken_seq,r8),r0
191         mov.l   @(woken_seq+4,r8),r1
192         addc    r2, r0
193         addc    r3, r1
194         mov.l   r0,@(woken_seq,r8)
195         mov.l   r1,@(woken_seq+4,r8)
196
197 16:
198         mov     #(1 << clock_bits), r2
199         mov.l   @(cond_nwaiters,r8),r0
200         sub     r2, r0
201         mov.l   r0,@(cond_nwaiters,r8)
202
203         /* Wake up a thread which wants to destroy the condvar object.  */
204         mov.l   @(total_seq,r8),r0
205         mov.l   @(total_seq+4,r8),r1
206         and     r1, r0
207         not     r0, r0
208         cmp/eq  #0, r0
209         bf/s    17f
210          mov    #((1 << clock_bits) - 1), r1
211         not     r1, r1
212         mov.l   @(cond_nwaiters,r8),r0
213         tst     r1, r0
214         bf      17f
215
216         mov     r8, r4
217         add     #cond_nwaiters, r4
218         mov     #FUTEX_WAKE, r5
219         mov     #1, r6
220         mov     #0, r7
221         mov     #SYS_futex, r3
222         extu.b  r3, r3
223         trapa   #0x14
224         SYSCALL_INST_PAD
225
226 17:
227 #if cond_lock != 0
228         DEC (@(cond_lock,r8), r2)
229 #else
230         DEC (@r8, r2)
231 #endif
232         tst     r2, r2
233         bf      10f
234
235 11:
236         mov.l   .Lmlocki0, r1
237         bsrf    r1
238          mov    r9, r4
239 .Lmlocki0b:
240         /* We return the result of the mutex_lock operation.  */
241
242 14:
243         add     #48, r15
244         lds.l   @r15+, pr
245         mov.l   @r15+, r12
246         mov.l   @r15+, r11
247         mov.l   @r15+, r10
248         mov.l   @r15+, r9
249         rts
250          mov.l  @r15+, r8
251
252         .align  2
253 .Lmunlock0:
254         .long   __pthread_mutex_unlock_usercnt-.Lmunlock0b
255 .Lenable0:
256         .long   __pthread_enable_asynccancel-.Lenable0b
257 .Ldisable0:
258         .long   __pthread_disable_asynccancel-.Ldisable0b
259 .Lmlocki0:
260         .long   __pthread_mutex_cond_lock-.Lmlocki0b
261
262 1:
263         /* Initial locking failed.  */
264         mov     r8, r5
265 #if cond_lock != 0
266         add     #cond_lock, r5
267 #endif
268         mov.l   .Lmwait0, r1
269         bsrf    r1
270          mov    r2, r4
271 .Lmwait0b:
272         bra     2b
273          nop
274 3:
275         /* Unlock in loop requires waekup.  */
276         mov     r8, r4
277 #if cond_lock != 0
278         add     #cond_lock, r4
279 #endif
280         mov.l   .Lmwake0, r1
281         bsrf    r1
282          nop
283 .Lmwake0b:
284         bra     4b
285          nop
286
287 5:
288         /* Locking in loop failed.  */
289         mov     r8, r5
290 #if cond_lock != 0
291         add     #cond_lock, r5
292 #endif
293         mov.l   .Lmwait1, r1
294         bsrf    r1
295          mov    r2, r4
296 .Lmwait1b:
297         bra     6b
298          nop
299
300 10:
301         /* Unlock after loop requires wakeup.  */
302         mov     r8, r4
303 #if cond_lock != 0
304         add     #cond_lock, r4
305 #endif
306         mov.l   .Lmwake1, r1
307         bsrf    r1
308          nop
309 .Lmwake1b:
310         bra     11b
311          nop
312
313 12:
314         /* The initial unlocking of the mutex failed.  */
315         mov.l   r0, @(12,r15)
316 #if cond_lock != 0
317         DEC (@(cond_lock,r8), r2)
318 #else
319         DEC (@r8, r2)
320 #endif
321         tst     r2, r2
322         bf      13f
323
324         mov     r8, r4
325 #if cond_lock != 0
326         add     #cond_lock, r4
327 #endif
328         mov.l   .Lmwake2, r1
329         bsrf    r1
330          nop
331 .Lmwake2b:
332
333 13:
334         bra     14b
335          mov.l  @(12,r15), r0
336
337         .align  2
338 .Lmwait0:
339         .long   __lll_mutex_lock_wait-.Lmwait0b
340 .Lmwake0:
341         .long   __lll_mutex_unlock_wake-.Lmwake0b
342 .Lmwait1:
343         .long   __lll_mutex_lock_wait-.Lmwait1b
344 .Lmwake1:
345         .long   __lll_mutex_unlock_wake-.Lmwake1b
346 .Lmwake2:
347         .long   __lll_mutex_unlock_wake-.Lmwake2b
348         .size   __pthread_cond_wait, .-__pthread_cond_wait
349 weak_alias (__pthread_cond_wait, pthread_cond_wait)
350
351
352         .type   __condvar_w_cleanup, @function
353 __condvar_w_cleanup:
354         mov     r4, r11
355
356         /* Get internal lock.  */
357         mov     #0, r3
358         mov     #1, r4
359 #if cond_lock != 0
360         CMPXCHG (r3, @(cond_lock,r8), r4, r2)
361 #else
362         CMPXCHG (r3, @r8, r4, r2)
363 #endif
364         bt      1f
365          nop
366
367         mov     r8, r5
368 #if cond_lock != 0
369         add     #cond_lock, r5
370 #endif
371         mov.l   .Lmwait3, r1
372         bsrf    r1
373          mov    r2, r4
374 .Lmwait3b:
375
376 1:
377         mov.l   @(broadcast_seq,r8), r0
378         mov.l   @(4,r15), r1
379         cmp/eq  r0, r1
380         bf      3f
381
382         mov     #1, r2
383         mov     #0, r3
384
385         clrt
386         mov.l   @(wakeup_seq,r8),r0
387         mov.l   @(wakeup_seq+4,r8),r1
388         addc    r2, r0
389         addc    r3, r1
390         mov.l   r0,@(wakeup_seq,r8)
391         mov.l   r1,@(wakeup_seq+4,r8)
392         mov.l   @(cond_futex,r8),r0
393         add     r2, r0
394         mov.l   r0,@(cond_futex,r8)
395
396         clrt
397         mov.l   @(woken_seq,r8),r0
398         mov.l   @(woken_seq+4,r8),r1
399         addc    r2, r0
400         addc    r3, r1
401         mov.l   r0,@(woken_seq,r8)
402         mov.l   r1,@(woken_seq+4,r8)
403
404 3:
405         mov     #(1 << clock_bits), r2
406         mov.l   @(cond_nwaiters,r8),r0
407         sub     r2, r0
408         mov.l   r0,@(cond_nwaiters,r8)
409
410         /* Wake up a thread which wants to destroy the condvar object.  */
411         mov     #0, r10
412         mov.l   @(total_seq,r8),r0
413         mov.l   @(total_seq+4,r8),r1
414         and     r1, r0
415         not     r0, r0
416         cmp/eq  #0, r0
417         bf/s    4f
418          mov    #((1 << clock_bits) - 1), r1
419         not     r1, r1
420         mov.l   @(cond_nwaiters,r8),r0
421         tst     r1, r0
422         bf      4f
423
424         mov     r8, r4
425         add     #cond_nwaiters, r4
426         mov     #FUTEX_WAKE, r5
427         mov     #1, r6
428         mov     #0, r7
429         mov     #SYS_futex, r3
430         extu.b  r3, r3
431         trapa   #0x14
432         SYSCALL_INST_PAD
433         mov     #1, r10
434
435 4:
436 #if cond_lock != 0
437         DEC (@(cond_lock,r8), r2)
438 #else
439         DEC (@r8, r2)
440 #endif
441         tst     r2, r2
442         bt      2f
443
444         mov     r8, r4
445 #if cond_lock != 0
446         add     #cond_lock, r4
447 #endif
448         mov.l   .Lmwake3, r1
449         bsrf    r1
450          nop
451 .Lmwake3b:
452
453 2:
454         /* Wake up all waiters to make sure no signal gets lost.  */
455         tst     r10, r10
456         bf/s    5f
457          mov    r8, r4
458         add     #cond_futex, r4
459         mov     #FUTEX_WAKE, r5
460         mov     #-1, r6
461         shlr    r6              /* r6 = 0x7fffffff */
462         mov     #0, r7
463         mov     #SYS_futex, r3
464         extu.b  r3, r3
465         trapa   #0x14
466         SYSCALL_INST_PAD
467
468 5:
469         mov.l   .Lmlocki3, r1
470         bsrf    r1
471          mov     r9, r4
472 .Lmlocki3b:
473
474 .LcallUR:
475         mov.l   .Lresume, r1
476 #ifdef __PIC__
477         add     r12, r1
478 #endif
479         jsr     @r1
480          mov    r11, r4
481         sleep
482
483         .align  2
484 .Lmwait3:
485         .long   __lll_mutex_lock_wait-.Lmwait3b
486 .Lmwake3:
487         .long   __lll_mutex_unlock_wake-.Lmwake3b
488 .Lmlocki3:
489         .long   __pthread_mutex_cond_lock-.Lmlocki3b
490 .Lresume:
491 #ifdef __PIC__
492         .long   _Unwind_Resume@GOTOFF
493 #else
494         .long   _Unwind_Resume
495 #endif
496 .LENDCODE:
497         .size   __condvar_w_cleanup, .-__condvar_w_cleanup
498
499
500         .section .gcc_except_table,"a",@progbits
501 .LexceptSTART:
502         .byte   0xff                            ! @LPStart format (omit)
503         .byte   0xff                            ! @TType format (omit)
504         .byte   0x0b                            ! call-site format
505                                                 ! DW_EH_PE_sdata4
506         .uleb128 .Lcstend-.Lcstbegin
507 .Lcstbegin:
508         .ualong .LcleanupSTART-.LSTARTCODE
509         .ualong .LcleanupEND-.LcleanupSTART
510         .ualong __condvar_w_cleanup-.LSTARTCODE
511         .uleb128  0
512         .ualong .LcallUR-.LSTARTCODE
513         .ualong .LENDCODE-.LcallUR
514         .ualong 0
515         .uleb128  0
516 .Lcstend:
517
518         .section .eh_frame,"a",@progbits
519 .LSTARTFRAME:
520         .ualong .LENDCIE-.LSTARTCIE             ! Length of the CIE.
521 .LSTARTCIE:
522         .ualong 0                               ! CIE ID.
523         .byte   1                               ! Version number.
524 #ifdef SHARED
525         .string "zPLR"                          ! NUL-terminated augmentation
526                                                 ! string.
527 #else
528         .string "zPL"                           ! NUL-terminated augmentation
529                                                 ! string.
530 #endif
531         .uleb128 1                              ! Code alignment factor.
532         .sleb128 -4                             ! Data alignment factor.
533         .byte   0x11                            ! Return address register
534                                                 ! column.
535 #ifdef SHARED
536         .uleb128 7                              ! Augmentation value length.
537         .byte   0x9b                            ! Personality: DW_EH_PE_pcrel
538                                                 ! + DW_EH_PE_sdata4
539                                                 ! + DW_EH_PE_indirect
540         .ualong DW.ref.__gcc_personality_v0-.
541         .byte   0x1b                            ! LSDA Encoding: DW_EH_PE_pcrel
542                                                 ! + DW_EH_PE_sdata4.
543         .byte   0x1b                            ! FDE Encoding: DW_EH_PE_pcrel
544                                                 ! + DW_EH_PE_sdata4.
545 #else
546         .uleb128 6                              ! Augmentation value length.
547         .byte   0x0                             ! Personality: absolute
548         .ualong __gcc_personality_v0
549         .byte   0x0                             ! LSDA Encoding: absolute
550 #endif
551         .byte 0x0c                              ! DW_CFA_def_cfa
552         .uleb128 0xf
553         .uleb128 0
554         .align 2
555 .LENDCIE:
556
557         .ualong .LENDFDE-.LSTARTFDE             ! Length of the FDE.
558 .LSTARTFDE:
559         .ualong .LSTARTFDE-.LSTARTFRAME         ! CIE pointer.
560 #ifdef SHARED
561         .ualong .LSTARTCODE-.                   ! PC-relative start address
562                                                 ! of the code.
563 #else
564         .ualong .LSTARTCODE                     ! Start address of the code.
565 #endif
566         .ualong .LENDCODE-.LSTARTCODE           ! Length of the code.
567         .uleb128 4                              ! Augmentation size
568 #ifdef SHARED
569         .ualong .LexceptSTART-.
570 #else
571         .ualong .LexceptSTART
572 #endif
573         .byte   0x4
574         .ualong .Lpush_r8-.LSTARTCODE
575         .byte   0xe
576         .uleb128 4
577         .byte   0x88
578         .uleb128 1
579         .byte   0x4
580         .ualong .Lpush_r9-.Lpush_r8
581         .byte   0xe
582         .uleb128 8
583         .byte   0x89
584         .uleb128 2
585         .byte   0x4
586         .ualong .Lpush_r10-.Lpush_r9
587         .byte   0xe
588         .uleb128 12
589         .byte   0x8a
590         .uleb128 3
591         .byte   0x4
592         .ualong .Lpush_r11-.Lpush_r10
593         .byte   0xe
594         .uleb128 16
595         .byte   0x8b
596         .uleb128 4
597         .byte   0x4
598         .ualong .Lpush_r12-.Lpush_r11
599         .byte   0xe
600         .uleb128 20
601         .byte   0x8c
602         .uleb128 5
603         .byte   0x4
604         .ualong .Lpush_pr-.Lpush_r12
605         .byte   0xe
606         .uleb128 24
607         .byte   0x91
608         .uleb128 6
609         .byte   0x4
610         .ualong .Lalloc-.Lpush_pr
611         .byte   0xe
612         .uleb128 72
613         .align  2
614 .LENDFDE:
615
616 #ifdef SHARED
617         .hidden DW.ref.__gcc_personality_v0
618         .weak   DW.ref.__gcc_personality_v0
619         .section .gnu.linkonce.d.DW.ref.__gcc_personality_v0,"aw",@progbits
620         .align 4
621         .type   DW.ref.__gcc_personality_v0, @object
622         .size   DW.ref.__gcc_personality_v0, 4
623 DW.ref.__gcc_personality_v0:
624         .long   __gcc_personality_v0
625 #endif