bitops.h 2.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100
  1. #include <asm/unwind.h>
  2. #if __LINUX_ARM_ARCH__ >= 6
  3. .macro bitop, name, instr
  4. ENTRY( \name )
  5. UNWIND( .fnstart )
  6. ands ip, r1, #3
  7. strneb r1, [ip] @ assert word-aligned
  8. mov r2, #1
  9. and r3, r0, #31 @ Get bit offset
  10. mov r0, r0, lsr #5
  11. add r1, r1, r0, lsl #2 @ Get word offset
  12. #if __LINUX_ARM_ARCH__ >= 7 && defined(CONFIG_SMP)
  13. .arch_extension mp
  14. ALT_SMP(W(pldw) [r1])
  15. ALT_UP(W(nop))
  16. #endif
  17. mov r3, r2, lsl r3
  18. 1: ldrex r2, [r1]
  19. \instr r2, r2, r3
  20. strex r0, r2, [r1]
  21. cmp r0, #0
  22. bne 1b
  23. bx lr
  24. UNWIND( .fnend )
  25. ENDPROC(\name )
  26. .endm
  27. .macro testop, name, instr, store
  28. ENTRY( \name )
  29. UNWIND( .fnstart )
  30. ands ip, r1, #3
  31. strneb r1, [ip] @ assert word-aligned
  32. mov r2, #1
  33. and r3, r0, #31 @ Get bit offset
  34. mov r0, r0, lsr #5
  35. add r1, r1, r0, lsl #2 @ Get word offset
  36. mov r3, r2, lsl r3 @ create mask
  37. smp_dmb
  38. 1: ldrex r2, [r1]
  39. ands r0, r2, r3 @ save old value of bit
  40. \instr r2, r2, r3 @ toggle bit
  41. strex ip, r2, [r1]
  42. cmp ip, #0
  43. bne 1b
  44. smp_dmb
  45. cmp r0, #0
  46. movne r0, #1
  47. 2: bx lr
  48. UNWIND( .fnend )
  49. ENDPROC(\name )
  50. .endm
  51. #else
  52. .macro bitop, name, instr
  53. ENTRY( \name )
  54. UNWIND( .fnstart )
  55. ands ip, r1, #3
  56. strneb r1, [ip] @ assert word-aligned
  57. and r2, r0, #31
  58. mov r0, r0, lsr #5
  59. mov r3, #1
  60. mov r3, r3, lsl r2
  61. save_and_disable_irqs ip
  62. ldr r2, [r1, r0, lsl #2]
  63. \instr r2, r2, r3
  64. str r2, [r1, r0, lsl #2]
  65. restore_irqs ip
  66. mov pc, lr
  67. UNWIND( .fnend )
  68. ENDPROC(\name )
  69. .endm
  70. /**
  71. * testop - implement a test_and_xxx_bit operation.
  72. * @instr: operational instruction
  73. * @store: store instruction
  74. *
  75. * Note: we can trivially conditionalise the store instruction
  76. * to avoid dirtying the data cache.
  77. */
  78. .macro testop, name, instr, store
  79. ENTRY( \name )
  80. UNWIND( .fnstart )
  81. ands ip, r1, #3
  82. strneb r1, [ip] @ assert word-aligned
  83. and r3, r0, #31
  84. mov r0, r0, lsr #5
  85. save_and_disable_irqs ip
  86. ldr r2, [r1, r0, lsl #2]!
  87. mov r0, #1
  88. tst r2, r0, lsl r3
  89. \instr r2, r2, r0, lsl r3
  90. \store r2, [r1]
  91. moveq r0, #0
  92. restore_irqs ip
  93. mov pc, lr
  94. UNWIND( .fnend )
  95. ENDPROC(\name )
  96. .endm
  97. #endif