sem_timedwait.S 7.0 KB

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