atomic64_cx8_32.S 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185
  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. .macro read64 reg
  14. movl %ebx, %eax
  15. movl %ecx, %edx
  16. /* we need LOCK_PREFIX since otherwise cmpxchg8b always does the write */
  17. LOCK_PREFIX
  18. cmpxchg8b (\reg)
  19. .endm
  20. ENTRY(atomic64_read_cx8)
  21. read64 %ecx
  22. ret
  23. ENDPROC(atomic64_read_cx8)
  24. ENTRY(atomic64_set_cx8)
  25. 1:
  26. /* we don't need LOCK_PREFIX since aligned 64-bit writes
  27. * are atomic on 586 and newer */
  28. cmpxchg8b (%esi)
  29. jne 1b
  30. ret
  31. ENDPROC(atomic64_set_cx8)
  32. ENTRY(atomic64_xchg_cx8)
  33. 1:
  34. LOCK_PREFIX
  35. cmpxchg8b (%esi)
  36. jne 1b
  37. ret
  38. ENDPROC(atomic64_xchg_cx8)
  39. .macro addsub_return func ins insc
  40. ENTRY(atomic64_\func\()_return_cx8)
  41. pushl %ebp
  42. pushl %ebx
  43. pushl %esi
  44. pushl %edi
  45. movl %eax, %esi
  46. movl %edx, %edi
  47. movl %ecx, %ebp
  48. read64 %ecx
  49. 1:
  50. movl %eax, %ebx
  51. movl %edx, %ecx
  52. \ins\()l %esi, %ebx
  53. \insc\()l %edi, %ecx
  54. LOCK_PREFIX
  55. cmpxchg8b (%ebp)
  56. jne 1b
  57. 10:
  58. movl %ebx, %eax
  59. movl %ecx, %edx
  60. popl %edi
  61. popl %esi
  62. popl %ebx
  63. popl %ebp
  64. ret
  65. ENDPROC(atomic64_\func\()_return_cx8)
  66. .endm
  67. addsub_return add add adc
  68. addsub_return sub sub sbb
  69. .macro incdec_return func ins insc
  70. ENTRY(atomic64_\func\()_return_cx8)
  71. pushl %ebx
  72. read64 %esi
  73. 1:
  74. movl %eax, %ebx
  75. movl %edx, %ecx
  76. \ins\()l $1, %ebx
  77. \insc\()l $0, %ecx
  78. LOCK_PREFIX
  79. cmpxchg8b (%esi)
  80. jne 1b
  81. 10:
  82. movl %ebx, %eax
  83. movl %ecx, %edx
  84. popl %ebx
  85. ret
  86. ENDPROC(atomic64_\func\()_return_cx8)
  87. .endm
  88. incdec_return inc add adc
  89. incdec_return dec sub sbb
  90. ENTRY(atomic64_dec_if_positive_cx8)
  91. pushl %ebx
  92. read64 %esi
  93. 1:
  94. movl %eax, %ebx
  95. movl %edx, %ecx
  96. subl $1, %ebx
  97. sbb $0, %ecx
  98. js 2f
  99. LOCK_PREFIX
  100. cmpxchg8b (%esi)
  101. jne 1b
  102. 2:
  103. movl %ebx, %eax
  104. movl %ecx, %edx
  105. popl %ebx
  106. ret
  107. ENDPROC(atomic64_dec_if_positive_cx8)
  108. ENTRY(atomic64_add_unless_cx8)
  109. pushl %ebp
  110. pushl %ebx
  111. /* these just push these two parameters on the stack */
  112. pushl %edi
  113. pushl %ecx
  114. movl %eax, %ebp
  115. movl %edx, %edi
  116. read64 %esi
  117. 1:
  118. cmpl %eax, 0(%esp)
  119. je 4f
  120. 2:
  121. movl %eax, %ebx
  122. movl %edx, %ecx
  123. addl %ebp, %ebx
  124. adcl %edi, %ecx
  125. LOCK_PREFIX
  126. cmpxchg8b (%esi)
  127. jne 1b
  128. movl $1, %eax
  129. 3:
  130. addl $8, %esp
  131. popl %ebx
  132. popl %ebp
  133. ret
  134. 4:
  135. cmpl %edx, 4(%esp)
  136. jne 2b
  137. xorl %eax, %eax
  138. jmp 3b
  139. ENDPROC(atomic64_add_unless_cx8)
  140. ENTRY(atomic64_inc_not_zero_cx8)
  141. pushl %ebx
  142. read64 %esi
  143. 1:
  144. movl %eax, %ecx
  145. orl %edx, %ecx
  146. jz 3f
  147. movl %eax, %ebx
  148. xorl %ecx, %ecx
  149. addl $1, %ebx
  150. adcl %edx, %ecx
  151. LOCK_PREFIX
  152. cmpxchg8b (%esi)
  153. jne 1b
  154. movl $1, %eax
  155. 3:
  156. popl %ebx
  157. ret
  158. ENDPROC(atomic64_inc_not_zero_cx8)