diff options
Diffstat (limited to 'arch/sh/include/asm/atomic-llsc.h')
-rw-r--r-- | arch/sh/include/asm/atomic-llsc.h | 101 |
1 files changed, 41 insertions, 60 deletions
diff --git a/arch/sh/include/asm/atomic-llsc.h b/arch/sh/include/asm/atomic-llsc.h index 4b00b78e3f4f..8575dccb9ef7 100644 --- a/arch/sh/include/asm/atomic-llsc.h +++ b/arch/sh/include/asm/atomic-llsc.h | |||
@@ -2,39 +2,6 @@ | |||
2 | #define __ASM_SH_ATOMIC_LLSC_H | 2 | #define __ASM_SH_ATOMIC_LLSC_H |
3 | 3 | ||
4 | /* | 4 | /* |
5 | * To get proper branch prediction for the main line, we must branch | ||
6 | * forward to code at the end of this object's .text section, then | ||
7 | * branch back to restart the operation. | ||
8 | */ | ||
9 | static inline void atomic_add(int i, atomic_t *v) | ||
10 | { | ||
11 | unsigned long tmp; | ||
12 | |||
13 | __asm__ __volatile__ ( | ||
14 | "1: movli.l @%2, %0 ! atomic_add \n" | ||
15 | " add %1, %0 \n" | ||
16 | " movco.l %0, @%2 \n" | ||
17 | " bf 1b \n" | ||
18 | : "=&z" (tmp) | ||
19 | : "r" (i), "r" (&v->counter) | ||
20 | : "t"); | ||
21 | } | ||
22 | |||
23 | static inline void atomic_sub(int i, atomic_t *v) | ||
24 | { | ||
25 | unsigned long tmp; | ||
26 | |||
27 | __asm__ __volatile__ ( | ||
28 | "1: movli.l @%2, %0 ! atomic_sub \n" | ||
29 | " sub %1, %0 \n" | ||
30 | " movco.l %0, @%2 \n" | ||
31 | " bf 1b \n" | ||
32 | : "=&z" (tmp) | ||
33 | : "r" (i), "r" (&v->counter) | ||
34 | : "t"); | ||
35 | } | ||
36 | |||
37 | /* | ||
38 | * SH-4A note: | 5 | * SH-4A note: |
39 | * | 6 | * |
40 | * We basically get atomic_xxx_return() for free compared with | 7 | * We basically get atomic_xxx_return() for free compared with |
@@ -42,39 +9,53 @@ static inline void atomic_sub(int i, atomic_t *v) | |||
42 | * encoding, so the retval is automatically set without having to | 9 | * encoding, so the retval is automatically set without having to |
43 | * do any special work. | 10 | * do any special work. |
44 | */ | 11 | */ |
45 | static inline int atomic_add_return(int i, atomic_t *v) | 12 | /* |
46 | { | 13 | * To get proper branch prediction for the main line, we must branch |
47 | unsigned long temp; | 14 | * forward to code at the end of this object's .text section, then |
15 | * branch back to restart the operation. | ||
16 | */ | ||
48 | 17 | ||
49 | __asm__ __volatile__ ( | 18 | #define ATOMIC_OP(op) \ |
50 | "1: movli.l @%2, %0 ! atomic_add_return \n" | 19 | static inline void atomic_##op(int i, atomic_t *v) \ |
51 | " add %1, %0 \n" | 20 | { \ |
52 | " movco.l %0, @%2 \n" | 21 | unsigned long tmp; \ |
53 | " bf 1b \n" | 22 | \ |
54 | " synco \n" | 23 | __asm__ __volatile__ ( \ |
55 | : "=&z" (temp) | 24 | "1: movli.l @%2, %0 ! atomic_" #op "\n" \ |
56 | : "r" (i), "r" (&v->counter) | 25 | " " #op " %1, %0 \n" \ |
57 | : "t"); | 26 | " movco.l %0, @%2 \n" \ |
27 | " bf 1b \n" \ | ||
28 | : "=&z" (tmp) \ | ||
29 | : "r" (i), "r" (&v->counter) \ | ||
30 | : "t"); \ | ||
31 | } | ||
58 | 32 | ||
59 | return temp; | 33 | #define ATOMIC_OP_RETURN(op) \ |
34 | static inline int atomic_##op##_return(int i, atomic_t *v) \ | ||
35 | { \ | ||
36 | unsigned long temp; \ | ||
37 | \ | ||
38 | __asm__ __volatile__ ( \ | ||
39 | "1: movli.l @%2, %0 ! atomic_" #op "_return \n" \ | ||
40 | " " #op " %1, %0 \n" \ | ||
41 | " movco.l %0, @%2 \n" \ | ||
42 | " bf 1b \n" \ | ||
43 | " synco \n" \ | ||
44 | : "=&z" (temp) \ | ||
45 | : "r" (i), "r" (&v->counter) \ | ||
46 | : "t"); \ | ||
47 | \ | ||
48 | return temp; \ | ||
60 | } | 49 | } |
61 | 50 | ||
62 | static inline int atomic_sub_return(int i, atomic_t *v) | 51 | #define ATOMIC_OPS(op) ATOMIC_OP(op) ATOMIC_OP_RETURN(op) |
63 | { | ||
64 | unsigned long temp; | ||
65 | 52 | ||
66 | __asm__ __volatile__ ( | 53 | ATOMIC_OPS(add) |
67 | "1: movli.l @%2, %0 ! atomic_sub_return \n" | 54 | ATOMIC_OPS(sub) |
68 | " sub %1, %0 \n" | ||
69 | " movco.l %0, @%2 \n" | ||
70 | " bf 1b \n" | ||
71 | " synco \n" | ||
72 | : "=&z" (temp) | ||
73 | : "r" (i), "r" (&v->counter) | ||
74 | : "t"); | ||
75 | 55 | ||
76 | return temp; | 56 | #undef ATOMIC_OPS |
77 | } | 57 | #undef ATOMIC_OP_RETURN |
58 | #undef ATOMIC_OP | ||
78 | 59 | ||
79 | static inline void atomic_clear_mask(unsigned int mask, atomic_t *v) | 60 | static inline void atomic_clear_mask(unsigned int mask, atomic_t *v) |
80 | { | 61 | { |