atomic64_cx8_32.S 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205
  1. /*
  2. * atomic64_t for 586+
  3. *
  4. * Copyright © 2010 Luca Barbieri
  5. *
  6. * This program is free software; you can redistribute it and/or modify
  7. * it under the terms of the GNU General Public License as published by
  8. * the Free Software Foundation; either version 2 of the License, or
  9. * (at your option) any later version.
  10. */
  11. #include <linux/linkage.h>
  12. #include <asm/alternative-asm.h>
  13. #include <asm/dwarf2.h>
  14. .macro read64 reg
  15. movl %ebx, %eax
  16. movl %ecx, %edx
  17. /* we need LOCK_PREFIX since otherwise cmpxchg8b always does the write */
  18. LOCK_PREFIX
  19. cmpxchg8b (\reg)
  20. .endm
  21. ENTRY(atomic64_read_cx8)
  22. CFI_STARTPROC
  23. read64 %ecx
  24. ret
  25. CFI_ENDPROC
  26. ENDPROC(atomic64_read_cx8)
  27. ENTRY(atomic64_set_cx8)
  28. CFI_STARTPROC
  29. 1:
  30. /* we don't need LOCK_PREFIX since aligned 64-bit writes
  31. * are atomic on 586 and newer */
  32. cmpxchg8b (%esi)
  33. jne 1b
  34. ret
  35. CFI_ENDPROC
  36. ENDPROC(atomic64_set_cx8)
  37. ENTRY(atomic64_xchg_cx8)
  38. CFI_STARTPROC
  39. 1:
  40. LOCK_PREFIX
  41. cmpxchg8b (%esi)
  42. jne 1b
  43. ret
  44. CFI_ENDPROC
  45. ENDPROC(atomic64_xchg_cx8)
  46. .macro addsub_return func ins insc
  47. ENTRY(atomic64_\func\()_return_cx8)
  48. CFI_STARTPROC
  49. pushl_cfi_reg ebp
  50. pushl_cfi_reg ebx
  51. pushl_cfi_reg esi
  52. pushl_cfi_reg edi
  53. movl %eax, %esi
  54. movl %edx, %edi
  55. movl %ecx, %ebp
  56. read64 %ecx
  57. 1:
  58. movl %eax, %ebx
  59. movl %edx, %ecx
  60. \ins\()l %esi, %ebx
  61. \insc\()l %edi, %ecx
  62. LOCK_PREFIX
  63. cmpxchg8b (%ebp)
  64. jne 1b
  65. 10:
  66. movl %ebx, %eax
  67. movl %ecx, %edx
  68. popl_cfi_reg edi
  69. popl_cfi_reg esi
  70. popl_cfi_reg ebx
  71. popl_cfi_reg ebp
  72. ret
  73. CFI_ENDPROC
  74. ENDPROC(atomic64_\func\()_return_cx8)
  75. .endm
  76. addsub_return add add adc
  77. addsub_return sub sub sbb
  78. .macro incdec_return func ins insc
  79. ENTRY(atomic64_\func\()_return_cx8)
  80. CFI_STARTPROC
  81. pushl_cfi_reg ebx
  82. read64 %esi
  83. 1:
  84. movl %eax, %ebx
  85. movl %edx, %ecx
  86. \ins\()l $1, %ebx
  87. \insc\()l $0, %ecx
  88. LOCK_PREFIX
  89. cmpxchg8b (%esi)
  90. jne 1b
  91. 10:
  92. movl %ebx, %eax
  93. movl %ecx, %edx
  94. popl_cfi_reg ebx
  95. ret
  96. CFI_ENDPROC
  97. ENDPROC(atomic64_\func\()_return_cx8)
  98. .endm
  99. incdec_return inc add adc
  100. incdec_return dec sub sbb
  101. ENTRY(atomic64_dec_if_positive_cx8)
  102. CFI_STARTPROC
  103. pushl_cfi_reg ebx
  104. read64 %esi
  105. 1:
  106. movl %eax, %ebx
  107. movl %edx, %ecx
  108. subl $1, %ebx
  109. sbb $0, %ecx
  110. js 2f
  111. LOCK_PREFIX
  112. cmpxchg8b (%esi)
  113. jne 1b
  114. 2:
  115. movl %ebx, %eax
  116. movl %ecx, %edx
  117. popl_cfi_reg ebx
  118. ret
  119. CFI_ENDPROC
  120. ENDPROC(atomic64_dec_if_positive_cx8)
  121. ENTRY(atomic64_add_unless_cx8)
  122. CFI_STARTPROC
  123. pushl_cfi_reg ebp
  124. pushl_cfi_reg ebx
  125. /* these just push these two parameters on the stack */
  126. pushl_cfi_reg edi
  127. pushl_cfi_reg ecx
  128. movl %eax, %ebp
  129. movl %edx, %edi
  130. read64 %esi
  131. 1:
  132. cmpl %eax, 0(%esp)
  133. je 4f
  134. 2:
  135. movl %eax, %ebx
  136. movl %edx, %ecx
  137. addl %ebp, %ebx
  138. adcl %edi, %ecx
  139. LOCK_PREFIX
  140. cmpxchg8b (%esi)
  141. jne 1b
  142. movl $1, %eax
  143. 3:
  144. addl $8, %esp
  145. CFI_ADJUST_CFA_OFFSET -8
  146. popl_cfi_reg ebx
  147. popl_cfi_reg ebp
  148. ret
  149. 4:
  150. cmpl %edx, 4(%esp)
  151. jne 2b
  152. xorl %eax, %eax
  153. jmp 3b
  154. CFI_ENDPROC
  155. ENDPROC(atomic64_add_unless_cx8)
  156. ENTRY(atomic64_inc_not_zero_cx8)
  157. CFI_STARTPROC
  158. pushl_cfi_reg ebx
  159. read64 %esi
  160. 1:
  161. movl %eax, %ecx
  162. orl %edx, %ecx
  163. jz 3f
  164. movl %eax, %ebx
  165. xorl %ecx, %ecx
  166. addl $1, %ebx
  167. adcl %edx, %ecx
  168. LOCK_PREFIX
  169. cmpxchg8b (%esi)
  170. jne 1b
  171. movl $1, %eax
  172. 3:
  173. popl_cfi_reg ebx
  174. ret
  175. CFI_ENDPROC
  176. ENDPROC(atomic64_inc_not_zero_cx8)