bitops.h 1.3 KB

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