atomic-grb.h 2.6 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485
  1. #ifndef __ASM_SH_ATOMIC_GRB_H
  2. #define __ASM_SH_ATOMIC_GRB_H
  3. #define ATOMIC_OP(op) \
  4. static inline void atomic_##op(int i, atomic_t *v) \
  5. { \
  6. int tmp; \
  7. \
  8. __asm__ __volatile__ ( \
  9. " .align 2 \n\t" \
  10. " mova 1f, r0 \n\t" /* r0 = end point */ \
  11. " mov r15, r1 \n\t" /* r1 = saved sp */ \
  12. " mov #-6, r15 \n\t" /* LOGIN: r15 = size */ \
  13. " mov.l @%1, %0 \n\t" /* load old value */ \
  14. " " #op " %2, %0 \n\t" /* $op */ \
  15. " mov.l %0, @%1 \n\t" /* store new value */ \
  16. "1: mov r1, r15 \n\t" /* LOGOUT */ \
  17. : "=&r" (tmp), \
  18. "+r" (v) \
  19. : "r" (i) \
  20. : "memory" , "r0", "r1"); \
  21. } \
  22. #define ATOMIC_OP_RETURN(op) \
  23. static inline int atomic_##op##_return(int i, atomic_t *v) \
  24. { \
  25. int tmp; \
  26. \
  27. __asm__ __volatile__ ( \
  28. " .align 2 \n\t" \
  29. " mova 1f, r0 \n\t" /* r0 = end point */ \
  30. " mov r15, r1 \n\t" /* r1 = saved sp */ \
  31. " mov #-6, r15 \n\t" /* LOGIN: r15 = size */ \
  32. " mov.l @%1, %0 \n\t" /* load old value */ \
  33. " " #op " %2, %0 \n\t" /* $op */ \
  34. " mov.l %0, @%1 \n\t" /* store new value */ \
  35. "1: mov r1, r15 \n\t" /* LOGOUT */ \
  36. : "=&r" (tmp), \
  37. "+r" (v) \
  38. : "r" (i) \
  39. : "memory" , "r0", "r1"); \
  40. \
  41. return tmp; \
  42. }
  43. #define ATOMIC_FETCH_OP(op) \
  44. static inline int atomic_fetch_##op(int i, atomic_t *v) \
  45. { \
  46. int res, tmp; \
  47. \
  48. __asm__ __volatile__ ( \
  49. " .align 2 \n\t" \
  50. " mova 1f, r0 \n\t" /* r0 = end point */ \
  51. " mov r15, r1 \n\t" /* r1 = saved sp */ \
  52. " mov #-6, r15 \n\t" /* LOGIN: r15 = size */ \
  53. " mov.l @%2, %0 \n\t" /* load old value */ \
  54. " mov %0, %1 \n\t" /* save old value */ \
  55. " " #op " %3, %0 \n\t" /* $op */ \
  56. " mov.l %0, @%2 \n\t" /* store new value */ \
  57. "1: mov r1, r15 \n\t" /* LOGOUT */ \
  58. : "=&r" (tmp), "=&r" (res), "+r" (v) \
  59. : "r" (i) \
  60. : "memory" , "r0", "r1"); \
  61. \
  62. return res; \
  63. }
  64. #define ATOMIC_OPS(op) ATOMIC_OP(op) ATOMIC_OP_RETURN(op) ATOMIC_FETCH_OP(op)
  65. ATOMIC_OPS(add)
  66. ATOMIC_OPS(sub)
  67. #undef ATOMIC_OPS
  68. #define ATOMIC_OPS(op) ATOMIC_OP(op) ATOMIC_FETCH_OP(op)
  69. ATOMIC_OPS(and)
  70. ATOMIC_OPS(or)
  71. ATOMIC_OPS(xor)
  72. #undef ATOMIC_OPS
  73. #undef ATOMIC_FETCH_OP
  74. #undef ATOMIC_OP_RETURN
  75. #undef ATOMIC_OP
  76. #endif /* __ASM_SH_ATOMIC_GRB_H */