atomic64_386_32.S 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192
  1. /*
  2. * atomic64_t for 386/486
  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. /* if you want SMP support, implement these with real spinlocks */
  14. .macro LOCK reg
  15. pushfl
  16. cli
  17. .endm
  18. .macro UNLOCK reg
  19. popfl
  20. .endm
  21. #define BEGIN(op) \
  22. .macro endp; \
  23. ENDPROC(atomic64_##op##_386); \
  24. .purgem endp; \
  25. .endm; \
  26. ENTRY(atomic64_##op##_386); \
  27. LOCK v;
  28. #define ENDP endp
  29. #define RET \
  30. UNLOCK v; \
  31. ret
  32. #define RET_ENDP \
  33. RET; \
  34. ENDP
  35. #define v %ecx
  36. BEGIN(read)
  37. movl (v), %eax
  38. movl 4(v), %edx
  39. RET_ENDP
  40. #undef v
  41. #define v %esi
  42. BEGIN(set)
  43. movl %ebx, (v)
  44. movl %ecx, 4(v)
  45. RET_ENDP
  46. #undef v
  47. #define v %esi
  48. BEGIN(xchg)
  49. movl (v), %eax
  50. movl 4(v), %edx
  51. movl %ebx, (v)
  52. movl %ecx, 4(v)
  53. RET_ENDP
  54. #undef v
  55. #define v %ecx
  56. BEGIN(add)
  57. addl %eax, (v)
  58. adcl %edx, 4(v)
  59. RET_ENDP
  60. #undef v
  61. #define v %ecx
  62. BEGIN(add_return)
  63. addl (v), %eax
  64. adcl 4(v), %edx
  65. movl %eax, (v)
  66. movl %edx, 4(v)
  67. RET_ENDP
  68. #undef v
  69. #define v %ecx
  70. BEGIN(sub)
  71. subl %eax, (v)
  72. sbbl %edx, 4(v)
  73. RET_ENDP
  74. #undef v
  75. #define v %ecx
  76. BEGIN(sub_return)
  77. negl %edx
  78. negl %eax
  79. sbbl $0, %edx
  80. addl (v), %eax
  81. adcl 4(v), %edx
  82. movl %eax, (v)
  83. movl %edx, 4(v)
  84. RET_ENDP
  85. #undef v
  86. #define v %esi
  87. BEGIN(inc)
  88. addl $1, (v)
  89. adcl $0, 4(v)
  90. RET_ENDP
  91. #undef v
  92. #define v %esi
  93. BEGIN(inc_return)
  94. movl (v), %eax
  95. movl 4(v), %edx
  96. addl $1, %eax
  97. adcl $0, %edx
  98. movl %eax, (v)
  99. movl %edx, 4(v)
  100. RET_ENDP
  101. #undef v
  102. #define v %esi
  103. BEGIN(dec)
  104. subl $1, (v)
  105. sbbl $0, 4(v)
  106. RET_ENDP
  107. #undef v
  108. #define v %esi
  109. BEGIN(dec_return)
  110. movl (v), %eax
  111. movl 4(v), %edx
  112. subl $1, %eax
  113. sbbl $0, %edx
  114. movl %eax, (v)
  115. movl %edx, 4(v)
  116. RET_ENDP
  117. #undef v
  118. #define v %esi
  119. BEGIN(add_unless)
  120. addl %eax, %ecx
  121. adcl %edx, %edi
  122. addl (v), %eax
  123. adcl 4(v), %edx
  124. cmpl %eax, %ecx
  125. je 3f
  126. 1:
  127. movl %eax, (v)
  128. movl %edx, 4(v)
  129. movl $1, %eax
  130. 2:
  131. RET
  132. 3:
  133. cmpl %edx, %edi
  134. jne 1b
  135. xorl %eax, %eax
  136. jmp 2b
  137. ENDP
  138. #undef v
  139. #define v %esi
  140. BEGIN(inc_not_zero)
  141. movl (v), %eax
  142. movl 4(v), %edx
  143. testl %eax, %eax
  144. je 3f
  145. 1:
  146. addl $1, %eax
  147. adcl $0, %edx
  148. movl %eax, (v)
  149. movl %edx, 4(v)
  150. movl $1, %eax
  151. 2:
  152. RET
  153. 3:
  154. testl %edx, %edx
  155. jne 1b
  156. jmp 2b
  157. ENDP
  158. #undef v
  159. #define v %esi
  160. BEGIN(dec_if_positive)
  161. movl (v), %eax
  162. movl 4(v), %edx
  163. subl $1, %eax
  164. sbbl $0, %edx
  165. js 1f
  166. movl %eax, (v)
  167. movl %edx, 4(v)
  168. 1:
  169. RET_ENDP
  170. #undef v