rwsem.S 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165
  1. /* rwsem.S: RW semaphore assembler.
  2. *
  3. * Written by David S. Miller (davem@redhat.com), 2001.
  4. * Derived from asm-i386/rwsem.h
  5. */
  6. #include <asm/rwsem-const.h>
  7. .section .sched.text
  8. .globl __down_read
  9. __down_read:
  10. 1: lduw [%o0], %g1
  11. add %g1, 1, %g7
  12. cas [%o0], %g1, %g7
  13. cmp %g1, %g7
  14. bne,pn %icc, 1b
  15. add %g7, 1, %g7
  16. cmp %g7, 0
  17. bl,pn %icc, 3f
  18. membar #StoreLoad | #StoreStore
  19. 2:
  20. retl
  21. nop
  22. 3:
  23. save %sp, -192, %sp
  24. call rwsem_down_read_failed
  25. mov %i0, %o0
  26. ret
  27. restore
  28. .size __down_read, .-__down_read
  29. .globl __down_read_trylock
  30. __down_read_trylock:
  31. 1: lduw [%o0], %g1
  32. add %g1, 1, %g7
  33. cmp %g7, 0
  34. bl,pn %icc, 2f
  35. mov 0, %o1
  36. cas [%o0], %g1, %g7
  37. cmp %g1, %g7
  38. bne,pn %icc, 1b
  39. mov 1, %o1
  40. membar #StoreLoad | #StoreStore
  41. 2: retl
  42. mov %o1, %o0
  43. .size __down_read_trylock, .-__down_read_trylock
  44. .globl __down_write
  45. __down_write:
  46. sethi %hi(RWSEM_ACTIVE_WRITE_BIAS), %g1
  47. or %g1, %lo(RWSEM_ACTIVE_WRITE_BIAS), %g1
  48. 1:
  49. lduw [%o0], %g3
  50. add %g3, %g1, %g7
  51. cas [%o0], %g3, %g7
  52. cmp %g3, %g7
  53. bne,pn %icc, 1b
  54. cmp %g7, 0
  55. bne,pn %icc, 3f
  56. membar #StoreLoad | #StoreStore
  57. 2: retl
  58. nop
  59. 3:
  60. save %sp, -192, %sp
  61. call rwsem_down_write_failed
  62. mov %i0, %o0
  63. ret
  64. restore
  65. .size __down_write, .-__down_write
  66. .globl __down_write_trylock
  67. __down_write_trylock:
  68. sethi %hi(RWSEM_ACTIVE_WRITE_BIAS), %g1
  69. or %g1, %lo(RWSEM_ACTIVE_WRITE_BIAS), %g1
  70. 1:
  71. lduw [%o0], %g3
  72. cmp %g3, 0
  73. bne,pn %icc, 2f
  74. mov 0, %o1
  75. add %g3, %g1, %g7
  76. cas [%o0], %g3, %g7
  77. cmp %g3, %g7
  78. bne,pn %icc, 1b
  79. mov 1, %o1
  80. membar #StoreLoad | #StoreStore
  81. 2: retl
  82. mov %o1, %o0
  83. .size __down_write_trylock, .-__down_write_trylock
  84. .globl __up_read
  85. __up_read:
  86. 1:
  87. lduw [%o0], %g1
  88. sub %g1, 1, %g7
  89. cas [%o0], %g1, %g7
  90. cmp %g1, %g7
  91. bne,pn %icc, 1b
  92. cmp %g7, 0
  93. bl,pn %icc, 3f
  94. membar #StoreLoad | #StoreStore
  95. 2: retl
  96. nop
  97. 3: sethi %hi(RWSEM_ACTIVE_MASK), %g1
  98. sub %g7, 1, %g7
  99. or %g1, %lo(RWSEM_ACTIVE_MASK), %g1
  100. andcc %g7, %g1, %g0
  101. bne,pn %icc, 2b
  102. nop
  103. save %sp, -192, %sp
  104. call rwsem_wake
  105. mov %i0, %o0
  106. ret
  107. restore
  108. .size __up_read, .-__up_read
  109. .globl __up_write
  110. __up_write:
  111. sethi %hi(RWSEM_ACTIVE_WRITE_BIAS), %g1
  112. or %g1, %lo(RWSEM_ACTIVE_WRITE_BIAS), %g1
  113. 1:
  114. lduw [%o0], %g3
  115. sub %g3, %g1, %g7
  116. cas [%o0], %g3, %g7
  117. cmp %g3, %g7
  118. bne,pn %icc, 1b
  119. sub %g7, %g1, %g7
  120. cmp %g7, 0
  121. bl,pn %icc, 3f
  122. membar #StoreLoad | #StoreStore
  123. 2:
  124. retl
  125. nop
  126. 3:
  127. save %sp, -192, %sp
  128. call rwsem_wake
  129. mov %i0, %o0
  130. ret
  131. restore
  132. .size __up_write, .-__up_write
  133. .globl __downgrade_write
  134. __downgrade_write:
  135. sethi %hi(RWSEM_WAITING_BIAS), %g1
  136. or %g1, %lo(RWSEM_WAITING_BIAS), %g1
  137. 1:
  138. lduw [%o0], %g3
  139. sub %g3, %g1, %g7
  140. cas [%o0], %g3, %g7
  141. cmp %g3, %g7
  142. bne,pn %icc, 1b
  143. sub %g7, %g1, %g7
  144. cmp %g7, 0
  145. bl,pn %icc, 3f
  146. membar #StoreLoad | #StoreStore
  147. 2:
  148. retl
  149. nop
  150. 3:
  151. save %sp, -192, %sp
  152. call rwsem_downgrade_wake
  153. mov %i0, %o0
  154. ret
  155. restore
  156. .size __downgrade_write, .-__downgrade_write