bitops.h 1.3 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465
  1. #if __LINUX_ARM_ARCH__ >= 6 && defined(CONFIG_CPU_32v6K)
  2. .macro bitop, instr
  3. mov r2, #1
  4. and r3, r0, #7 @ Get bit offset
  5. add r1, r1, r0, lsr #3 @ Get byte offset
  6. mov r3, r2, lsl r3
  7. 1: ldrexb r2, [r1]
  8. \instr r2, r2, r3
  9. strexb r0, r2, [r1]
  10. cmp r0, #0
  11. bne 1b
  12. mov pc, lr
  13. .endm
  14. .macro testop, instr, store
  15. and r3, r0, #7 @ Get bit offset
  16. mov r2, #1
  17. add r1, r1, r0, lsr #3 @ Get byte offset
  18. mov r3, r2, lsl r3 @ create mask
  19. 1: ldrexb r2, [r1]
  20. ands r0, r2, r3 @ save old value of bit
  21. \instr r2, r2, r3 @ toggle bit
  22. strexb ip, r2, [r1]
  23. cmp ip, #0
  24. bne 1b
  25. cmp r0, #0
  26. movne r0, #1
  27. 2: mov pc, lr
  28. .endm
  29. #else
  30. .macro bitop, instr
  31. and r2, r0, #7
  32. mov r3, #1
  33. mov r3, r3, lsl r2
  34. save_and_disable_irqs ip
  35. ldrb r2, [r1, r0, lsr #3]
  36. \instr r2, r2, r3
  37. strb r2, [r1, r0, lsr #3]
  38. restore_irqs ip
  39. mov pc, lr
  40. .endm
  41. /**
  42. * testop - implement a test_and_xxx_bit operation.
  43. * @instr: operational instruction
  44. * @store: store instruction
  45. *
  46. * Note: we can trivially conditionalise the store instruction
  47. * to avoid dirting the data cache.
  48. */
  49. .macro testop, instr, store
  50. add r1, r1, r0, lsr #3
  51. and r3, r0, #7
  52. mov r0, #1
  53. save_and_disable_irqs ip
  54. ldrb r2, [r1]
  55. tst r2, r0, lsl r3
  56. \instr r2, r2, r0, lsl r3
  57. \store r2, [r1]
  58. restore_irqs ip
  59. moveq r0, #0
  60. mov pc, lr
  61. .endm
  62. #endif