atomic-ops.S 7.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265
  1. /* atomic-ops.S: kernel atomic operations
  2. *
  3. * For an explanation of how atomic ops work in this arch, see:
  4. * Documentation/fujitsu/frv/atomic-ops.txt
  5. *
  6. * Copyright (C) 2004 Red Hat, Inc. All Rights Reserved.
  7. * Written by David Howells (dhowells@redhat.com)
  8. *
  9. * This program is free software; you can redistribute it and/or
  10. * modify it under the terms of the GNU General Public License
  11. * as published by the Free Software Foundation; either version
  12. * 2 of the License, or (at your option) any later version.
  13. */
  14. #include <asm/spr-regs.h>
  15. .text
  16. .balign 4
  17. ###############################################################################
  18. #
  19. # unsigned long atomic_test_and_ANDNOT_mask(unsigned long mask, volatile unsigned long *v);
  20. #
  21. ###############################################################################
  22. .globl atomic_test_and_ANDNOT_mask
  23. .type atomic_test_and_ANDNOT_mask,@function
  24. atomic_test_and_ANDNOT_mask:
  25. not.p gr8,gr10
  26. 0:
  27. orcc gr0,gr0,gr0,icc3 /* set ICC3.Z */
  28. ckeq icc3,cc7
  29. ld.p @(gr9,gr0),gr8 /* LD.P/ORCR must be atomic */
  30. orcr cc7,cc7,cc3 /* set CC3 to true */
  31. and gr8,gr10,gr11
  32. cst.p gr11,@(gr9,gr0) ,cc3,#1
  33. corcc gr29,gr29,gr0 ,cc3,#1 /* clear ICC3.Z if store happens */
  34. beq icc3,#0,0b
  35. bralr
  36. .size atomic_test_and_ANDNOT_mask, .-atomic_test_and_ANDNOT_mask
  37. ###############################################################################
  38. #
  39. # unsigned long atomic_test_and_OR_mask(unsigned long mask, volatile unsigned long *v);
  40. #
  41. ###############################################################################
  42. .globl atomic_test_and_OR_mask
  43. .type atomic_test_and_OR_mask,@function
  44. atomic_test_and_OR_mask:
  45. or.p gr8,gr8,gr10
  46. 0:
  47. orcc gr0,gr0,gr0,icc3 /* set ICC3.Z */
  48. ckeq icc3,cc7
  49. ld.p @(gr9,gr0),gr8 /* LD.P/ORCR must be atomic */
  50. orcr cc7,cc7,cc3 /* set CC3 to true */
  51. or gr8,gr10,gr11
  52. cst.p gr11,@(gr9,gr0) ,cc3,#1
  53. corcc gr29,gr29,gr0 ,cc3,#1 /* clear ICC3.Z if store happens */
  54. beq icc3,#0,0b
  55. bralr
  56. .size atomic_test_and_OR_mask, .-atomic_test_and_OR_mask
  57. ###############################################################################
  58. #
  59. # unsigned long atomic_test_and_XOR_mask(unsigned long mask, volatile unsigned long *v);
  60. #
  61. ###############################################################################
  62. .globl atomic_test_and_XOR_mask
  63. .type atomic_test_and_XOR_mask,@function
  64. atomic_test_and_XOR_mask:
  65. or.p gr8,gr8,gr10
  66. 0:
  67. orcc gr0,gr0,gr0,icc3 /* set ICC3.Z */
  68. ckeq icc3,cc7
  69. ld.p @(gr9,gr0),gr8 /* LD.P/ORCR must be atomic */
  70. orcr cc7,cc7,cc3 /* set CC3 to true */
  71. xor gr8,gr10,gr11
  72. cst.p gr11,@(gr9,gr0) ,cc3,#1
  73. corcc gr29,gr29,gr0 ,cc3,#1 /* clear ICC3.Z if store happens */
  74. beq icc3,#0,0b
  75. bralr
  76. .size atomic_test_and_XOR_mask, .-atomic_test_and_XOR_mask
  77. ###############################################################################
  78. #
  79. # int atomic_add_return(int i, atomic_t *v)
  80. #
  81. ###############################################################################
  82. .globl atomic_add_return
  83. .type atomic_add_return,@function
  84. atomic_add_return:
  85. or.p gr8,gr8,gr10
  86. 0:
  87. orcc gr0,gr0,gr0,icc3 /* set ICC3.Z */
  88. ckeq icc3,cc7
  89. ld.p @(gr9,gr0),gr8 /* LD.P/ORCR must be atomic */
  90. orcr cc7,cc7,cc3 /* set CC3 to true */
  91. add gr8,gr10,gr8
  92. cst.p gr8,@(gr9,gr0) ,cc3,#1
  93. corcc gr29,gr29,gr0 ,cc3,#1 /* clear ICC3.Z if store happens */
  94. beq icc3,#0,0b
  95. bralr
  96. .size atomic_add_return, .-atomic_add_return
  97. ###############################################################################
  98. #
  99. # int atomic_sub_return(int i, atomic_t *v)
  100. #
  101. ###############################################################################
  102. .globl atomic_sub_return
  103. .type atomic_sub_return,@function
  104. atomic_sub_return:
  105. or.p gr8,gr8,gr10
  106. 0:
  107. orcc gr0,gr0,gr0,icc3 /* set ICC3.Z */
  108. ckeq icc3,cc7
  109. ld.p @(gr9,gr0),gr8 /* LD.P/ORCR must be atomic */
  110. orcr cc7,cc7,cc3 /* set CC3 to true */
  111. sub gr8,gr10,gr8
  112. cst.p gr8,@(gr9,gr0) ,cc3,#1
  113. corcc gr29,gr29,gr0 ,cc3,#1 /* clear ICC3.Z if store happens */
  114. beq icc3,#0,0b
  115. bralr
  116. .size atomic_sub_return, .-atomic_sub_return
  117. ###############################################################################
  118. #
  119. # uint8_t __xchg_8(uint8_t i, uint8_t *v)
  120. #
  121. ###############################################################################
  122. .globl __xchg_8
  123. .type __xchg_8,@function
  124. __xchg_8:
  125. or.p gr8,gr8,gr10
  126. 0:
  127. orcc gr0,gr0,gr0,icc3 /* set ICC3.Z */
  128. ckeq icc3,cc7
  129. ldub.p @(gr9,gr0),gr8 /* LD.P/ORCR must be atomic */
  130. orcr cc7,cc7,cc3 /* set CC3 to true */
  131. cstb.p gr10,@(gr9,gr0) ,cc3,#1
  132. corcc gr29,gr29,gr0 ,cc3,#1 /* clear ICC3.Z if store happens */
  133. beq icc3,#0,0b
  134. bralr
  135. .size __xchg_8, .-__xchg_8
  136. ###############################################################################
  137. #
  138. # uint16_t __xchg_16(uint16_t i, uint16_t *v)
  139. #
  140. ###############################################################################
  141. .globl __xchg_16
  142. .type __xchg_16,@function
  143. __xchg_16:
  144. or.p gr8,gr8,gr10
  145. 0:
  146. orcc gr0,gr0,gr0,icc3 /* set ICC3.Z */
  147. ckeq icc3,cc7
  148. lduh.p @(gr9,gr0),gr8 /* LD.P/ORCR must be atomic */
  149. orcr cc7,cc7,cc3 /* set CC3 to true */
  150. csth.p gr10,@(gr9,gr0) ,cc3,#1
  151. corcc gr29,gr29,gr0 ,cc3,#1 /* clear ICC3.Z if store happens */
  152. beq icc3,#0,0b
  153. bralr
  154. .size __xchg_16, .-__xchg_16
  155. ###############################################################################
  156. #
  157. # uint32_t __xchg_32(uint32_t i, uint32_t *v)
  158. #
  159. ###############################################################################
  160. .globl __xchg_32
  161. .type __xchg_32,@function
  162. __xchg_32:
  163. or.p gr8,gr8,gr10
  164. 0:
  165. orcc gr0,gr0,gr0,icc3 /* set ICC3.Z */
  166. ckeq icc3,cc7
  167. ld.p @(gr9,gr0),gr8 /* LD.P/ORCR must be atomic */
  168. orcr cc7,cc7,cc3 /* set CC3 to true */
  169. cst.p gr10,@(gr9,gr0) ,cc3,#1
  170. corcc gr29,gr29,gr0 ,cc3,#1 /* clear ICC3.Z if store happens */
  171. beq icc3,#0,0b
  172. bralr
  173. .size __xchg_32, .-__xchg_32
  174. ###############################################################################
  175. #
  176. # uint8_t __cmpxchg_8(uint8_t *v, uint8_t test, uint8_t new)
  177. #
  178. ###############################################################################
  179. .globl __cmpxchg_8
  180. .type __cmpxchg_8,@function
  181. __cmpxchg_8:
  182. or.p gr8,gr8,gr11
  183. 0:
  184. orcc gr0,gr0,gr0,icc3
  185. ckeq icc3,cc7
  186. ldub.p @(gr11,gr0),gr8
  187. orcr cc7,cc7,cc3
  188. sub gr8,gr9,gr7
  189. sllicc gr7,#24,gr0,icc0
  190. bne icc0,#0,1f
  191. cstb.p gr10,@(gr11,gr0) ,cc3,#1
  192. corcc gr29,gr29,gr0 ,cc3,#1
  193. beq icc3,#0,0b
  194. 1:
  195. bralr
  196. .size __cmpxchg_8, .-__cmpxchg_8
  197. ###############################################################################
  198. #
  199. # uint16_t __cmpxchg_16(uint16_t *v, uint16_t test, uint16_t new)
  200. #
  201. ###############################################################################
  202. .globl __cmpxchg_16
  203. .type __cmpxchg_16,@function
  204. __cmpxchg_16:
  205. or.p gr8,gr8,gr11
  206. 0:
  207. orcc gr0,gr0,gr0,icc3
  208. ckeq icc3,cc7
  209. lduh.p @(gr11,gr0),gr8
  210. orcr cc7,cc7,cc3
  211. sub gr8,gr9,gr7
  212. sllicc gr7,#16,gr0,icc0
  213. bne icc0,#0,1f
  214. csth.p gr10,@(gr11,gr0) ,cc3,#1
  215. corcc gr29,gr29,gr0 ,cc3,#1
  216. beq icc3,#0,0b
  217. 1:
  218. bralr
  219. .size __cmpxchg_16, .-__cmpxchg_16
  220. ###############################################################################
  221. #
  222. # uint32_t __cmpxchg_32(uint32_t *v, uint32_t test, uint32_t new)
  223. #
  224. ###############################################################################
  225. .globl __cmpxchg_32
  226. .type __cmpxchg_32,@function
  227. __cmpxchg_32:
  228. or.p gr8,gr8,gr11
  229. 0:
  230. orcc gr0,gr0,gr0,icc3
  231. ckeq icc3,cc7
  232. ld.p @(gr11,gr0),gr8
  233. orcr cc7,cc7,cc3
  234. subcc gr8,gr9,gr7,icc0
  235. bne icc0,#0,1f
  236. cst.p gr10,@(gr11,gr0) ,cc3,#1
  237. corcc gr29,gr29,gr0 ,cc3,#1
  238. beq icc3,#0,0b
  239. 1:
  240. bralr
  241. .size __cmpxchg_32, .-__cmpxchg_32