diff options
Diffstat (limited to 'sysdeps/unix/sysv/linux/sh/sem_wait.S')
-rw-r--r-- | sysdeps/unix/sysv/linux/sh/sem_wait.S | 229 |
1 files changed, 229 insertions, 0 deletions
diff --git a/sysdeps/unix/sysv/linux/sh/sem_wait.S b/sysdeps/unix/sysv/linux/sh/sem_wait.S new file mode 100644 index 0000000000..04a6a405d4 --- /dev/null +++ b/sysdeps/unix/sysv/linux/sh/sem_wait.S @@ -0,0 +1,229 @@ +/* Copyright (C) 2003-2014 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ + +#include <sysdep.h> +#include <shlib-compat.h> +#include <pthread-errnos.h> +#include <tcb-offsets.h> +#include <structsem.h> +#include <lowlevellock.h> +#include "lowlevel-atomic.h" + + +#if VALUE != 0 +# error "code needs to be rewritten for VALUE != 0" +#endif + + .text + + .globl __new_sem_wait + .type __new_sem_wait,@function + .align 5 + cfi_startproc +__new_sem_wait: +.LSTARTCODE: +#ifdef SHARED + cfi_personality(DW_EH_PE_pcrel | DW_EH_PE_sdata4 | DW_EH_PE_indirect, + DW.ref.__gcc_personality_v0) + cfi_lsda(DW_EH_PE_pcrel | DW_EH_PE_sdata4, .LexceptSTART) +#else + cfi_personality(DW_EH_PE_absptr, __gcc_personality_v0) + cfi_lsda(DW_EH_PE_absptr, .LexceptSTART) +#endif + mov.l r8, @-r15 + cfi_adjust_cfa_offset (4) + cfi_rel_offset (r8, 0) + mov.l r10, @-r15 + cfi_adjust_cfa_offset (4) + cfi_rel_offset (r10, 0) + mov.l r12, @-r15 + cfi_adjust_cfa_offset (4) + cfi_rel_offset (r12, 0) + sts.l pr, @-r15 + cfi_adjust_cfa_offset (4) + cfi_rel_offset (pr, 0) + + mov r4, r8 + mov.l @r8, r0 +2: + tst r0, r0 + bt 1f + mov r0, r3 + mov r0, r4 + add #-1, r3 + CMPXCHG (r4, @r8, r3, r2) + bf/s 2b + mov r2, r0 +7: + mov #0, r0 +9: + cfi_remember_state + lds.l @r15+, pr + cfi_adjust_cfa_offset (-4) + cfi_restore (pr) + mov.l @r15+, r12 + cfi_adjust_cfa_offset (-4) + cfi_restore (r12) + mov.l @r15+, r10 + cfi_adjust_cfa_offset (-4) + cfi_restore (r10) + rts + mov.l @r15+, r8 + /* Omit CFI for restore in delay slot. */ + cfi_restore_state + +.Lafter_ret: +1: + INC (@(NWAITERS,r8),r2) + +.LcleanupSTART: +6: + mov.l .Lenable0, r1 + bsrf r1 + nop +.Lenable0b: + mov r0, r10 + + mov r8, r4 +#if FUTEX_WAIT == 0 + mov.l @(PRIVATE,r8), r5 +#else + mov.l @(PRIVATE,r8), r5 + mov #FUTEX_WAIT, r0 + or r0, r5 +#endif + mov #0, r6 + mov #0, r7 + mov #SYS_futex, r3 + extu.b r3, r3 + trapa #0x14 + SYSCALL_INST_PAD + + mov.l .Ldisable0, r1 + mov r10, r4 + bsrf r1 + mov r0, r10 +.Ldisable0b: + mov r10, r0 +.LcleanupEND: + + tst r0, r0 + bt 3f + cmp/eq #-EWOULDBLOCK, r0 + bf 4f + +3: + mov.l @r8, r0 +5: + tst r0, r0 + bt 6b + + mov r0, r3 + mov r0, r4 + add #-1, r3 + CMPXCHG (r4, @r8, r3, r2) + bf/s 5b + mov r2, r0 + + DEC (@(NWAITERS,r8), r2) + bra 7b + nop + +4: + neg r0, r0 + mov r0, r4 + DEC (@(NWAITERS,r8), r2) + mov r4, r8 + mova .Lgot0, r0 + mov.l .Lgot0, r12 + add r0, r12 + + mov.l .Lerrno0, r0 + stc gbr, r1 + mov.l @(r0, r12), r0 + bra .Lexit + add r1, r0 + .align 2 +.Lerrno0: + .long errno@GOTTPOFF +.Lexit: + mov.l r8, @r0 + bra 9b + mov #-1, r0 + + .align 2 +.Lgot0: + .long _GLOBAL_OFFSET_TABLE_ +.Lenable0: + .long __pthread_enable_asynccancel-.Lenable0b +.Ldisable0: + .long __pthread_disable_asynccancel-.Ldisable0b + .size __new_sem_wait,.-__new_sem_wait + versioned_symbol(libpthread, __new_sem_wait, sem_wait, GLIBC_2_1) + + + .type sem_wait_cleanup,@function +sem_wait_cleanup: + DEC (@(NWAITERS,r8), r2) +.LcallUR: + mov.l .Lresume, r1 +#ifdef PIC + add r12, r1 +#endif + jsr @r1 + nop + sleep + + .align 2 +.Lresume: +#ifdef PIC + .long _Unwind_Resume@GOTOFF +#else + .long _Unwind_Resume +#endif +.LENDCODE: + cfi_endproc + .size sem_wait_cleanup,.-sem_wait_cleanup + + + .section .gcc_except_table,"a",@progbits +.LexceptSTART: + .byte DW_EH_PE_omit ! @LPStart format (omit) + .byte DW_EH_PE_omit ! @TType format (omit) + .byte DW_EH_PE_uleb128 ! call-site format + .uleb128 .Lcstend-.Lcstbegin +.Lcstbegin: + .uleb128 .LcleanupSTART-.LSTARTCODE + .uleb128 .LcleanupEND-.LcleanupSTART + .uleb128 sem_wait_cleanup-.LSTARTCODE + .uleb128 0 + .uleb128 .LcallUR-.LSTARTCODE + .uleb128 .LENDCODE-.LcallUR + .uleb128 0 + .uleb128 0 +.Lcstend: + +#ifdef SHARED + .hidden DW.ref.__gcc_personality_v0 + .weak DW.ref.__gcc_personality_v0 + .section .gnu.linkonce.d.DW.ref.__gcc_personality_v0,"aw",@progbits + .align 4 + .type DW.ref.__gcc_personality_v0, @object + .size DW.ref.__gcc_personality_v0, 4 +DW.ref.__gcc_personality_v0: + .long __gcc_personality_v0 +#endif |