]> git.kernelconcepts.de Git - karo-tx-linux.git/blob - arch/sh/include/asm/atomic-grb.h
Merge branch 'for-4.8/core' of git://git.kernel.dk/linux-block
[karo-tx-linux.git] / arch / sh / include / asm / atomic-grb.h
1 #ifndef __ASM_SH_ATOMIC_GRB_H
2 #define __ASM_SH_ATOMIC_GRB_H
3
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
24 #define ATOMIC_OP_RETURN(op)                                            \
25 static inline int atomic_##op##_return(int i, atomic_t *v)              \
26 {                                                                       \
27         int tmp;                                                        \
28                                                                         \
29         __asm__ __volatile__ (                                          \
30                 "   .align 2              \n\t"                         \
31                 "   mova    1f,   r0      \n\t" /* r0 = end point */    \
32                 "   mov    r15,   r1      \n\t" /* r1 = saved sp */     \
33                 "   mov    #-6,   r15     \n\t" /* LOGIN: r15 = size */ \
34                 "   mov.l  @%1,   %0      \n\t" /* load  old value */   \
35                 " " #op "   %2,   %0      \n\t" /* $op */               \
36                 "   mov.l   %0,   @%1     \n\t" /* store new value */   \
37                 "1: mov     r1,   r15     \n\t" /* LOGOUT */            \
38                 : "=&r" (tmp),                                          \
39                   "+r"  (v)                                             \
40                 : "r"   (i)                                             \
41                 : "memory" , "r0", "r1");                               \
42                                                                         \
43         return tmp;                                                     \
44 }
45
46 #define ATOMIC_FETCH_OP(op)                                             \
47 static inline int atomic_fetch_##op(int i, atomic_t *v)                 \
48 {                                                                       \
49         int res, tmp;                                                   \
50                                                                         \
51         __asm__ __volatile__ (                                          \
52                 "   .align 2              \n\t"                         \
53                 "   mova    1f,   r0      \n\t" /* r0 = end point */    \
54                 "   mov    r15,   r1      \n\t" /* r1 = saved sp */     \
55                 "   mov    #-6,   r15     \n\t" /* LOGIN: r15 = size */ \
56                 "   mov.l  @%2,   %0      \n\t" /* load old value */    \
57                 "   mov     %0,   %1      \n\t" /* save old value */    \
58                 " " #op "   %3,   %0      \n\t" /* $op */               \
59                 "   mov.l   %0,   @%2     \n\t" /* store new value */   \
60                 "1: mov     r1,   r15     \n\t" /* LOGOUT */            \
61                 : "=&r" (tmp), "=&r" (res), "+r"  (v)                   \
62                 : "r"   (i)                                             \
63                 : "memory" , "r0", "r1");                               \
64                                                                         \
65         return res;                                                     \
66 }
67
68 #define ATOMIC_OPS(op) ATOMIC_OP(op) ATOMIC_OP_RETURN(op) ATOMIC_FETCH_OP(op)
69
70 ATOMIC_OPS(add)
71 ATOMIC_OPS(sub)
72
73 #undef ATOMIC_OPS
74 #define ATOMIC_OPS(op) ATOMIC_OP(op) ATOMIC_FETCH_OP(op)
75
76 ATOMIC_OPS(and)
77 ATOMIC_OPS(or)
78 ATOMIC_OPS(xor)
79
80 #undef ATOMIC_OPS
81 #undef ATOMIC_FETCH_OP
82 #undef ATOMIC_OP_RETURN
83 #undef ATOMIC_OP
84
85 #endif /* __ASM_SH_ATOMIC_GRB_H */