sem_timedwait.S 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357
  1. /* Copyright (C) 2003, 2004, 2007 Free Software Foundation, Inc.
  2. This file is part of the GNU C Library.
  3. The GNU C Library is free software; you can redistribute it and/or
  4. modify it under the terms of the GNU Lesser General Public
  5. License as published by the Free Software Foundation; either
  6. version 2.1 of the License, or (at your option) any later version.
  7. The GNU C Library is distributed in the hope that it will be useful,
  8. but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  10. Lesser General Public License for more details.
  11. You should have received a copy of the GNU Lesser General Public
  12. License along with the GNU C Library; if not, see
  13. <http://www.gnu.org/licenses/>. */
  14. #include <sysdep.h>
  15. #include <pthread-errnos.h>
  16. #include <tcb-offsets.h>
  17. #include <structsem.h>
  18. #include <lowlevellock.h>
  19. #include "lowlevel-atomic.h"
  20. #if VALUE != 0
  21. # error "code needs to be rewritten for VALUE != 0"
  22. #endif
  23. .text
  24. .globl sem_timedwait
  25. .type sem_timedwait,@function
  26. .align 5
  27. sem_timedwait:
  28. .LSTARTCODE:
  29. mov.l @r4, r0
  30. 2:
  31. tst r0, r0
  32. bt 1f
  33. mov r0, r3
  34. mov r0, r6
  35. add #-1, r3
  36. CMPXCHG (r6, @r4, r3, r2)
  37. bf/s 2b
  38. mov r2, r0
  39. rts
  40. mov #0, r0
  41. 1:
  42. /* Check whether the timeout value is valid. */
  43. mov.l r8, @-r15
  44. .Lpush_r8:
  45. mov.l r9, @-r15
  46. .Lpush_r9:
  47. mov.l r10, @-r15
  48. .Lpush_r10:
  49. mov.l r12, @-r15
  50. .Lpush_r12:
  51. sts.l pr, @-r15
  52. .Lpush_pr:
  53. add #-8, r15
  54. .Lalloc:
  55. mov r4, r8
  56. mov r5, r9
  57. /* Check for invalid nanosecond field. */
  58. mov.l @(4,r9), r0
  59. mov.l .L1g, r1
  60. cmp/hs r1, r0
  61. bt/s 6f
  62. mov #EINVAL, r0
  63. INC (@(NWAITERS,r8),r2)
  64. 7:
  65. /* Compute relative timeout. */
  66. mov r15, r4
  67. mov #0, r5
  68. mov #__NR_gettimeofday, r3
  69. trapa #0x12
  70. SYSCALL_INST_PAD
  71. mov.l @(4,r15), r0
  72. mov.w .L1k, r1
  73. dmulu.l r0, r1 /* Milli seconds to nano seconds. */
  74. mov.l @r9, r2
  75. mov.l @(4,r9), r3
  76. mov.l @r15, r0
  77. sts macl, r1
  78. sub r0, r2
  79. clrt
  80. subc r1, r3
  81. bf 5f
  82. mov.l .L1g, r1
  83. add r1, r3
  84. add #-1, r2
  85. 5:
  86. cmp/pz r2
  87. bf/s 6f /* Time is already up. */
  88. mov #ETIMEDOUT, r0
  89. /* Store relative timeout. */
  90. mov.l r2, @r15
  91. mov.l r3, @(4,r15)
  92. .LcleanupSTART:
  93. mov.l .Lenable0, r1
  94. bsrf r1
  95. nop
  96. .Lenable0b:
  97. mov r0, r10
  98. mov r8, r4
  99. #if FUTEX_WAIT == 0
  100. mov.l @(PRIVATE,r8), r5
  101. #else
  102. mov.l @(PRIVATE,r8), r5
  103. mov #FUTEX_WAIT, r0
  104. or r0, r5
  105. #endif
  106. mov #0, r6
  107. mov r15, r7
  108. mov #SYS_futex, r3
  109. extu.b r3, r3
  110. trapa #0x14
  111. SYSCALL_INST_PAD
  112. mov.l .Ldisable0, r1
  113. mov r10, r4
  114. bsrf r1
  115. mov r0, r10
  116. .Ldisable0b:
  117. mov r10, r0
  118. .LcleanupEND:
  119. tst r0, r0
  120. bt 9f
  121. cmp/eq #-EWOULDBLOCK, r0
  122. bf 3f
  123. 9:
  124. mov.l @r8, r0
  125. 8:
  126. tst r0, r0
  127. bt 7b
  128. mov r0, r3
  129. mov r0, r4
  130. add #-1, r3
  131. CMPXCHG (r4, @r8, r3, r2)
  132. bf/s 8b
  133. mov r2, r0
  134. DEC (@(NWAITERS,r8), r2)
  135. mov #0, r0
  136. 10:
  137. add #8, r15
  138. lds.l @r15+, pr
  139. mov.l @r15+, r12
  140. mov.l @r15+, r10
  141. mov.l @r15+, r9
  142. mov.l @r15+, r8
  143. rts
  144. nop
  145. 3:
  146. neg r0, r0
  147. 6:
  148. mov r0, r10
  149. mova .Lgot2, r0
  150. mov.l .Lgot2, r12
  151. add r0, r12
  152. #if USE___THREAD
  153. mov.l .Lerrno2, r0
  154. stc gbr, r1
  155. mov.l @(r0, r12), r0
  156. bra .Lexit
  157. add r1, r0
  158. .align 2
  159. .Lerrno2:
  160. .long errno@GOTTPOFF
  161. .Lexit:
  162. #else
  163. mov.l .Lerrloc2, r1
  164. bsrf r1
  165. nop
  166. .Lerrloc2b:
  167. #endif
  168. mov.l r10, @r0
  169. DEC (@(NWAITERS,r8), r2)
  170. bra 10b
  171. mov #-1, r0
  172. .L1k:
  173. .word 1000
  174. .align 2
  175. .L1g:
  176. .long 1000000000
  177. .Lgot2:
  178. .long _GLOBAL_OFFSET_TABLE_
  179. #if !USE___THREAD
  180. .Lerrloc2:
  181. .long __errno_location@PLT-(.Lerrloc2b-.)
  182. #endif
  183. .Lenable0:
  184. .long __pthread_enable_asynccancel-.Lenable0b
  185. .Ldisable0:
  186. .long __pthread_disable_asynccancel-.Ldisable0b
  187. .size sem_timedwait,.-sem_timedwait
  188. .type sem_wait_cleanup,@function
  189. sem_wait_cleanup:
  190. DEC (@(NWAITERS,r8), r2)
  191. .LcallUR:
  192. mov.l .Lresume, r1
  193. #ifdef __PIC__
  194. add r12, r1
  195. #endif
  196. jsr @r1
  197. nop
  198. sleep
  199. .align 2
  200. .Lresume:
  201. #ifdef __PIC__
  202. .long _Unwind_Resume@GOTOFF
  203. #else
  204. .long _Unwind_Resume
  205. #endif
  206. .LENDCODE:
  207. .size sem_wait_cleanup,.-sem_wait_cleanup
  208. .section .gcc_except_table,"a",@progbits
  209. .LexceptSTART:
  210. .byte 0xff ! @LPStart format (omit)
  211. .byte 0xff ! @TType format (omit)
  212. .byte 0x01 ! call-site format
  213. ! DW_EH_PE_uleb128
  214. .uleb128 .Lcstend-.Lcstbegin
  215. .Lcstbegin:
  216. .uleb128 .LcleanupSTART-.LSTARTCODE
  217. .uleb128 .LcleanupEND-.LcleanupSTART
  218. .uleb128 sem_wait_cleanup-.LSTARTCODE
  219. .uleb128 0
  220. .uleb128 .LcallUR-.LSTARTCODE
  221. .uleb128 .LENDCODE-.LcallUR
  222. .uleb128 0
  223. .uleb128 0
  224. .Lcstend:
  225. .section .eh_frame,"a",@progbits
  226. .LSTARTFRAME:
  227. .ualong .LENDCIE-.LSTARTCIE ! Length of the CIE.
  228. .LSTARTCIE:
  229. .ualong 0 ! CIE ID.
  230. .byte 1 ! Version number.
  231. #ifdef SHARED
  232. .string "zPLR" ! NUL-terminated augmentation
  233. ! string.
  234. #else
  235. .string "zPL" ! NUL-terminated augmentation
  236. ! string.
  237. #endif
  238. .uleb128 1 ! Code alignment factor.
  239. .sleb128 -4 ! Data alignment factor.
  240. .byte 0x11 ! Return address register
  241. ! column.
  242. #ifdef SHARED
  243. .uleb128 7 ! Augmentation value length.
  244. .byte 0x9b ! Personality: DW_EH_PE_pcrel
  245. ! + DW_EH_PE_sdata4
  246. ! + DW_EH_PE_indirect
  247. .ualong DW.ref.__gcc_personality_v0-.
  248. .byte 0x1b ! LSDA Encoding: DW_EH_PE_pcrel
  249. ! + DW_EH_PE_sdata4.
  250. .byte 0x1b ! FDE Encoding: DW_EH_PE_pcrel
  251. ! + DW_EH_PE_sdata4.
  252. #else
  253. .uleb128 6 ! Augmentation value length.
  254. .byte 0x0 ! Personality: absolute
  255. .ualong __gcc_personality_v0
  256. .byte 0x0 ! LSDA Encoding: absolute
  257. #endif
  258. .byte 0x0c ! DW_CFA_def_cfa
  259. .uleb128 0xf
  260. .uleb128 0
  261. .align 4
  262. .LENDCIE:
  263. .ualong .LENDFDE-.LSTARTFDE ! Length of the FDE.
  264. .LSTARTFDE:
  265. .ualong .LSTARTFDE-.LSTARTFRAME ! CIE pointer.
  266. #ifdef SHARED
  267. .ualong .LSTARTCODE-. ! PC-relative start address
  268. ! of the code.
  269. #else
  270. .ualong .LSTARTCODE ! Start address of the code.
  271. #endif
  272. .ualong .LENDCODE-.LSTARTCODE ! Length of the code.
  273. .uleb128 4 ! Augmentation size
  274. #ifdef SHARED
  275. .ualong .LexceptSTART-.
  276. #else
  277. .ualong .LexceptSTART
  278. #endif
  279. .byte 4 ! DW_CFA_advance_loc4
  280. .ualong .Lpush_r8-.LSTARTCODE
  281. .byte 14 ! DW_CFA_def_cfa_offset
  282. .uleb128 4
  283. .byte 0x88 ! DW_CFA_offset r8
  284. .uleb128 1
  285. .byte 4 ! DW_CFA_advance_loc4
  286. .ualong .Lpush_r9-.Lpush_r8
  287. .byte 14 ! DW_CFA_def_cfa_offset
  288. .uleb128 8
  289. .byte 0x89 ! DW_CFA_offset r9
  290. .uleb128 2
  291. .byte 4 ! DW_CFA_advance_loc4
  292. .ualong .Lpush_r10-.Lpush_r9
  293. .byte 14 ! DW_CFA_def_cfa_offset
  294. .uleb128 12
  295. .byte 0x8a ! DW_CFA_offset r10
  296. .uleb128 3
  297. .byte 4 ! DW_CFA_advance_loc4
  298. .ualong .Lpush_r12-.Lpush_r10
  299. .byte 14 ! DW_CFA_def_cfa_offset
  300. .uleb128 16
  301. .byte 0x8c ! DW_CFA_offset r12
  302. .uleb128 4
  303. .byte 4 ! DW_CFA_advance_loc4
  304. .ualong .Lpush_pr-.Lpush_r12
  305. .byte 14 ! DW_CFA_def_cfa_offset
  306. .uleb128 20
  307. .byte 0x91 ! DW_CFA_offset pr
  308. .uleb128 5
  309. .byte 4 ! DW_CFA_advance_loc4
  310. .ualong .Lalloc-.Lpush_pr
  311. .byte 14 ! DW_CFA_def_cfa_offset
  312. .uleb128 28
  313. .align 4
  314. .LENDFDE:
  315. #ifdef SHARED
  316. .hidden DW.ref.__gcc_personality_v0
  317. .weak DW.ref.__gcc_personality_v0
  318. .section .gnu.linkonce.d.DW.ref.__gcc_personality_v0,"aw",@progbits
  319. .align 4
  320. .type DW.ref.__gcc_personality_v0, @object
  321. .size DW.ref.__gcc_personality_v0, 4
  322. DW.ref.__gcc_personality_v0:
  323. .long __gcc_personality_v0
  324. #endif