bitops.h 1.3 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667
  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. smp_dmb
  20. 1: ldrexb r2, [r1]
  21. ands r0, r2, r3 @ save old value of bit
  22. \instr r2, r2, r3 @ toggle bit
  23. strexb ip, r2, [r1]
  24. cmp ip, #0
  25. bne 1b
  26. smp_dmb
  27. cmp r0, #0
  28. movne r0, #1
  29. 2: mov pc, lr
  30. .endm
  31. #else
  32. .macro bitop, instr
  33. and r2, r0, #7
  34. mov r3, #1
  35. mov r3, r3, lsl r2
  36. save_and_disable_irqs ip
  37. ldrb r2, [r1, r0, lsr #3]
  38. \instr r2, r2, r3
  39. strb r2, [r1, r0, lsr #3]
  40. restore_irqs ip
  41. mov pc, lr
  42. .endm
  43. /**
  44. * testop - implement a test_and_xxx_bit operation.
  45. * @instr: operational instruction
  46. * @store: store instruction
  47. *
  48. * Note: we can trivially conditionalise the store instruction
  49. * to avoid dirtying the data cache.
  50. */
  51. .macro testop, instr, store
  52. add r1, r1, r0, lsr #3
  53. and r3, r0, #7
  54. mov r0, #1
  55. save_and_disable_irqs ip
  56. ldrb r2, [r1]
  57. tst r2, r0, lsl r3
  58. \instr r2, r2, r0, lsl r3
  59. \store r2, [r1]
  60. restore_irqs ip
  61. moveq r0, #0
  62. mov pc, lr
  63. .endm
  64. #endif