atomic-grb.h 2.8 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394
  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_OPS(op) ATOMIC_OP(op) ATOMIC_OP_RETURN(op)
  44. ATOMIC_OPS(add)
  45. ATOMIC_OPS(sub)
  46. #undef ATOMIC_OPS
  47. #undef ATOMIC_OP_RETURN
  48. #undef ATOMIC_OP
  49. static inline void atomic_clear_mask(unsigned int mask, atomic_t *v)
  50. {
  51. int tmp;
  52. unsigned int _mask = ~mask;
  53. __asm__ __volatile__ (
  54. " .align 2 \n\t"
  55. " mova 1f, r0 \n\t" /* r0 = end point */
  56. " mov r15, r1 \n\t" /* r1 = saved sp */
  57. " mov #-6, r15 \n\t" /* LOGIN: r15 = size */
  58. " mov.l @%1, %0 \n\t" /* load old value */
  59. " and %2, %0 \n\t" /* add */
  60. " mov.l %0, @%1 \n\t" /* store new value */
  61. "1: mov r1, r15 \n\t" /* LOGOUT */
  62. : "=&r" (tmp),
  63. "+r" (v)
  64. : "r" (_mask)
  65. : "memory" , "r0", "r1");
  66. }
  67. static inline void atomic_set_mask(unsigned int mask, atomic_t *v)
  68. {
  69. int tmp;
  70. __asm__ __volatile__ (
  71. " .align 2 \n\t"
  72. " mova 1f, r0 \n\t" /* r0 = end point */
  73. " mov r15, r1 \n\t" /* r1 = saved sp */
  74. " mov #-6, r15 \n\t" /* LOGIN: r15 = size */
  75. " mov.l @%1, %0 \n\t" /* load old value */
  76. " or %2, %0 \n\t" /* or */
  77. " mov.l %0, @%1 \n\t" /* store new value */
  78. "1: mov r1, r15 \n\t" /* LOGOUT */
  79. : "=&r" (tmp),
  80. "+r" (v)
  81. : "r" (mask)
  82. : "memory" , "r0", "r1");
  83. }
  84. #endif /* __ASM_SH_ATOMIC_GRB_H */