bitops.S 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130
  1. /* bitops.S: Sparc64 atomic bit operations.
  2. *
  3. * Copyright (C) 2000, 2007 David S. Miller (davem@davemloft.net)
  4. */
  5. #include <linux/linkage.h>
  6. #include <asm/asi.h>
  7. #include <asm/backoff.h>
  8. .text
  9. ENTRY(test_and_set_bit) /* %o0=nr, %o1=addr */
  10. BACKOFF_SETUP(%o3)
  11. srlx %o0, 6, %g1
  12. mov 1, %o2
  13. sllx %g1, 3, %g3
  14. and %o0, 63, %g2
  15. sllx %o2, %g2, %o2
  16. add %o1, %g3, %o1
  17. 1: ldx [%o1], %g7
  18. or %g7, %o2, %g1
  19. casx [%o1], %g7, %g1
  20. cmp %g7, %g1
  21. bne,pn %xcc, BACKOFF_LABEL(2f, 1b)
  22. and %g7, %o2, %g2
  23. clr %o0
  24. movrne %g2, 1, %o0
  25. retl
  26. nop
  27. 2: BACKOFF_SPIN(%o3, %o4, 1b)
  28. ENDPROC(test_and_set_bit)
  29. ENTRY(test_and_clear_bit) /* %o0=nr, %o1=addr */
  30. BACKOFF_SETUP(%o3)
  31. srlx %o0, 6, %g1
  32. mov 1, %o2
  33. sllx %g1, 3, %g3
  34. and %o0, 63, %g2
  35. sllx %o2, %g2, %o2
  36. add %o1, %g3, %o1
  37. 1: ldx [%o1], %g7
  38. andn %g7, %o2, %g1
  39. casx [%o1], %g7, %g1
  40. cmp %g7, %g1
  41. bne,pn %xcc, BACKOFF_LABEL(2f, 1b)
  42. and %g7, %o2, %g2
  43. clr %o0
  44. movrne %g2, 1, %o0
  45. retl
  46. nop
  47. 2: BACKOFF_SPIN(%o3, %o4, 1b)
  48. ENDPROC(test_and_clear_bit)
  49. ENTRY(test_and_change_bit) /* %o0=nr, %o1=addr */
  50. BACKOFF_SETUP(%o3)
  51. srlx %o0, 6, %g1
  52. mov 1, %o2
  53. sllx %g1, 3, %g3
  54. and %o0, 63, %g2
  55. sllx %o2, %g2, %o2
  56. add %o1, %g3, %o1
  57. 1: ldx [%o1], %g7
  58. xor %g7, %o2, %g1
  59. casx [%o1], %g7, %g1
  60. cmp %g7, %g1
  61. bne,pn %xcc, BACKOFF_LABEL(2f, 1b)
  62. and %g7, %o2, %g2
  63. clr %o0
  64. movrne %g2, 1, %o0
  65. retl
  66. nop
  67. 2: BACKOFF_SPIN(%o3, %o4, 1b)
  68. ENDPROC(test_and_change_bit)
  69. ENTRY(set_bit) /* %o0=nr, %o1=addr */
  70. BACKOFF_SETUP(%o3)
  71. srlx %o0, 6, %g1
  72. mov 1, %o2
  73. sllx %g1, 3, %g3
  74. and %o0, 63, %g2
  75. sllx %o2, %g2, %o2
  76. add %o1, %g3, %o1
  77. 1: ldx [%o1], %g7
  78. or %g7, %o2, %g1
  79. casx [%o1], %g7, %g1
  80. cmp %g7, %g1
  81. bne,pn %xcc, BACKOFF_LABEL(2f, 1b)
  82. nop
  83. retl
  84. nop
  85. 2: BACKOFF_SPIN(%o3, %o4, 1b)
  86. ENDPROC(set_bit)
  87. ENTRY(clear_bit) /* %o0=nr, %o1=addr */
  88. BACKOFF_SETUP(%o3)
  89. srlx %o0, 6, %g1
  90. mov 1, %o2
  91. sllx %g1, 3, %g3
  92. and %o0, 63, %g2
  93. sllx %o2, %g2, %o2
  94. add %o1, %g3, %o1
  95. 1: ldx [%o1], %g7
  96. andn %g7, %o2, %g1
  97. casx [%o1], %g7, %g1
  98. cmp %g7, %g1
  99. bne,pn %xcc, BACKOFF_LABEL(2f, 1b)
  100. nop
  101. retl
  102. nop
  103. 2: BACKOFF_SPIN(%o3, %o4, 1b)
  104. ENDPROC(clear_bit)
  105. ENTRY(change_bit) /* %o0=nr, %o1=addr */
  106. BACKOFF_SETUP(%o3)
  107. srlx %o0, 6, %g1
  108. mov 1, %o2
  109. sllx %g1, 3, %g3
  110. and %o0, 63, %g2
  111. sllx %o2, %g2, %o2
  112. add %o1, %g3, %o1
  113. 1: ldx [%o1], %g7
  114. xor %g7, %o2, %g1
  115. casx [%o1], %g7, %g1
  116. cmp %g7, %g1
  117. bne,pn %xcc, BACKOFF_LABEL(2f, 1b)
  118. nop
  119. retl
  120. nop
  121. 2: BACKOFF_SPIN(%o3, %o4, 1b)
  122. ENDPROC(change_bit)