atomic-grb.h 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687
  1. /* SPDX-License-Identifier: GPL-2.0 */
  2. #ifndef __ASM_SH_ATOMIC_GRB_H
  3. #define __ASM_SH_ATOMIC_GRB_H
  4. #define ATOMIC_OP(op) \
  5. static inline void atomic_##op(int i, atomic_t *v) \
  6. { \
  7. int tmp; \
  8. \
  9. __asm__ __volatile__ ( \
  10. " .align 2 \n\t" \
  11. " mova 1f, r0 \n\t" /* r0 = end point */ \
  12. " mov r15, r1 \n\t" /* r1 = saved sp */ \
  13. " mov #-6, r15 \n\t" /* LOGIN: r15 = size */ \
  14. " mov.l @%1, %0 \n\t" /* load old value */ \
  15. " " #op " %2, %0 \n\t" /* $op */ \
  16. " mov.l %0, @%1 \n\t" /* store new value */ \
  17. "1: mov r1, r15 \n\t" /* LOGOUT */ \
  18. : "=&r" (tmp), \
  19. "+r" (v) \
  20. : "r" (i) \
  21. : "memory" , "r0", "r1"); \
  22. } \
  23. #define ATOMIC_OP_RETURN(op) \
  24. static inline int atomic_##op##_return(int i, atomic_t *v) \
  25. { \
  26. int tmp; \
  27. \
  28. __asm__ __volatile__ ( \
  29. " .align 2 \n\t" \
  30. " mova 1f, r0 \n\t" /* r0 = end point */ \
  31. " mov r15, r1 \n\t" /* r1 = saved sp */ \
  32. " mov #-6, r15 \n\t" /* LOGIN: r15 = size */ \
  33. " mov.l @%1, %0 \n\t" /* load old value */ \
  34. " " #op " %2, %0 \n\t" /* $op */ \
  35. " mov.l %0, @%1 \n\t" /* store new value */ \
  36. "1: mov r1, r15 \n\t" /* LOGOUT */ \
  37. : "=&r" (tmp), \
  38. "+r" (v) \
  39. : "r" (i) \
  40. : "memory" , "r0", "r1"); \
  41. \
  42. return tmp; \
  43. }
  44. #define ATOMIC_FETCH_OP(op) \
  45. static inline int atomic_fetch_##op(int i, atomic_t *v) \
  46. { \
  47. int res, tmp; \
  48. \
  49. __asm__ __volatile__ ( \
  50. " .align 2 \n\t" \
  51. " mova 1f, r0 \n\t" /* r0 = end point */ \
  52. " mov r15, r1 \n\t" /* r1 = saved sp */ \
  53. " mov #-6, r15 \n\t" /* LOGIN: r15 = size */ \
  54. " mov.l @%2, %0 \n\t" /* load old value */ \
  55. " mov %0, %1 \n\t" /* save old value */ \
  56. " " #op " %3, %0 \n\t" /* $op */ \
  57. " mov.l %0, @%2 \n\t" /* store new value */ \
  58. "1: mov r1, r15 \n\t" /* LOGOUT */ \
  59. : "=&r" (tmp), "=&r" (res), "+r" (v) \
  60. : "r" (i) \
  61. : "memory" , "r0", "r1"); \
  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_GRB_H */