atomic-llsc.h 2.1 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788
  1. #ifndef __ASM_SH_ATOMIC_LLSC_H
  2. #define __ASM_SH_ATOMIC_LLSC_H
  3. /*
  4. * SH-4A note:
  5. *
  6. * We basically get atomic_xxx_return() for free compared with
  7. * atomic_xxx(). movli.l/movco.l require r0 due to the instruction
  8. * encoding, so the retval is automatically set without having to
  9. * do any special work.
  10. */
  11. /*
  12. * To get proper branch prediction for the main line, we must branch
  13. * forward to code at the end of this object's .text section, then
  14. * branch back to restart the operation.
  15. */
  16. #define ATOMIC_OP(op) \
  17. static inline void atomic_##op(int i, atomic_t *v) \
  18. { \
  19. unsigned long tmp; \
  20. \
  21. __asm__ __volatile__ ( \
  22. "1: movli.l @%2, %0 ! atomic_" #op "\n" \
  23. " " #op " %1, %0 \n" \
  24. " movco.l %0, @%2 \n" \
  25. " bf 1b \n" \
  26. : "=&z" (tmp) \
  27. : "r" (i), "r" (&v->counter) \
  28. : "t"); \
  29. }
  30. #define ATOMIC_OP_RETURN(op) \
  31. static inline int atomic_##op##_return(int i, atomic_t *v) \
  32. { \
  33. unsigned long temp; \
  34. \
  35. __asm__ __volatile__ ( \
  36. "1: movli.l @%2, %0 ! atomic_" #op "_return \n" \
  37. " " #op " %1, %0 \n" \
  38. " movco.l %0, @%2 \n" \
  39. " bf 1b \n" \
  40. " synco \n" \
  41. : "=&z" (temp) \
  42. : "r" (i), "r" (&v->counter) \
  43. : "t"); \
  44. \
  45. return temp; \
  46. }
  47. #define ATOMIC_FETCH_OP(op) \
  48. static inline int atomic_fetch_##op(int i, atomic_t *v) \
  49. { \
  50. unsigned long res, temp; \
  51. \
  52. __asm__ __volatile__ ( \
  53. "1: movli.l @%3, %0 ! atomic_fetch_" #op " \n" \
  54. " mov %0, %1 \n" \
  55. " " #op " %2, %0 \n" \
  56. " movco.l %0, @%3 \n" \
  57. " bf 1b \n" \
  58. " synco \n" \
  59. : "=&z" (temp), "=&r" (res) \
  60. : "r" (i), "r" (&v->counter) \
  61. : "t"); \
  62. \
  63. return res; \
  64. }
  65. #define ATOMIC_OPS(op) ATOMIC_OP(op) ATOMIC_OP_RETURN(op) ATOMIC_FETCH_OP(op)
  66. ATOMIC_OPS(add)
  67. ATOMIC_OPS(sub)
  68. #undef ATOMIC_OPS
  69. #define ATOMIC_OPS(op) ATOMIC_OP(op) ATOMIC_FETCH_OP(op)
  70. ATOMIC_OPS(and)
  71. ATOMIC_OPS(or)
  72. ATOMIC_OPS(xor)
  73. #undef ATOMIC_OPS
  74. #undef ATOMIC_FETCH_OP
  75. #undef ATOMIC_OP_RETURN
  76. #undef ATOMIC_OP
  77. #endif /* __ASM_SH_ATOMIC_LLSC_H */