2009-12-19 Ivan Maidanski <ivmai@mail.ru>
[platform/upstream/libatomic_ops.git] / src / atomic_ops / sysdeps / ibmc / powerpc.h
1 /* FIXME.  This is only a placeholder for the AIX compiler.             */
2 /* It doesn't work.  Please send a patch.                               */
3 /* Memory model documented at http://www-106.ibm.com/developerworks/    */
4 /* eserver/articles/archguide.html and (clearer)                        */
5 /* http://www-106.ibm.com/developerworks/eserver/articles/powerpc.html. */
6 /* There appears to be no implicit ordering between any kind of         */
7 /* independent memory references.                                       */
8 /* Architecture enforces some ordering based on control dependence.     */
9 /* I don't know if that could help.                                     */
10 /* Data-dependent loads are always ordered.                             */
11 /* Based on the above references, eieio is intended for use on          */
12 /* uncached memory, which we don't support.  It does not order loads    */
13 /* from cached memory.                                                  */
14 /* Thanks to Maged Michael, Doug Lea, and Roger Hoover for helping to   */
15 /* track some of this down and correcting my misunderstandings. -HB     */
16
17 #include "../all_aligned_atomic_load_store.h"
18
19 void AO_sync(void);
20 #pragma mc_func AO_sync { "7c0004ac" }
21
22 #ifdef __NO_LWSYNC__
23 # define AO_lwsync AO_sync
24 #else
25   void AO_lwsync(void);
26 #pragma mc_func AO_lwsync { "7c2004ac" }
27 #endif
28
29 #define AO_nop_write() AO_lwsync()
30 #define AO_HAVE_nop_write
31
32 #define AO_nop_read() AO_lwsync()
33 #define AO_HAVE_nop_read
34
35 /* We explicitly specify load_acquire and store_release, since these    */
36 /* rely on the fact that lwsync is also a LoadStore barrier.            */
37 AO_INLINE AO_t
38 AO_load_acquire(const volatile AO_t *addr)
39 {
40   AO_t result = *addr;
41   AO_lwsync();
42   return result;
43 }
44
45 #define AO_HAVE_load_acquire
46
47 AO_INLINE void
48 AO_store_release(volatile AO_t *addr, AO_t value)
49 {
50   AO_lwsync();
51   *addr = value;
52 }
53
54 #define AO_HAVE_load_acquire
55
56 /* This is similar to the code in the garbage collector.  Deleting      */
57 /* this and having it synthesized from compare_and_swap would probably  */
58 /* only cost us a load immediate instruction.                           */
59 /*AO_INLINE AO_TS_VAL_t
60 AO_test_and_set(volatile AO_TS_t *addr) {
61 # error FIXME Implement me
62 }
63
64 #define AO_HAVE_test_and_set*/
65
66 AO_INLINE AO_TS_VAL_t
67 AO_test_and_set_acquire(volatile AO_TS_t *addr) {
68   AO_TS_VAL_t result = AO_test_and_set(addr);
69   AO_lwsync();
70   return result;
71 }
72
73 #define AO_HAVE_test_and_set_acquire
74
75 AO_INLINE AO_TS_VAL_t
76 AO_test_and_set_release(volatile AO_TS_t *addr) {
77   AO_lwsync();
78   return AO_test_and_set(addr);
79 }
80
81 #define AO_HAVE_test_and_set_release
82
83 AO_INLINE AO_TS_VAL_t
84 AO_test_and_set_full(volatile AO_TS_t *addr) {
85   AO_TS_VAL_t result;
86   AO_lwsync();
87   result = AO_test_and_set(addr);
88   AO_lwsync();
89   return result;
90 }
91
92 #define AO_HAVE_test_and_set_full
93
94 /*AO_INLINE AO_t
95 AO_compare_and_swap(volatile AO_t *addr, AO_t old, AO_t new_val) {
96 # error FIXME Implement me
97 }
98
99 #define AO_HAVE_compare_and_swap*/
100
101 AO_INLINE AO_t
102 AO_compare_and_swap_acquire(volatile AO_t *addr, AO_t old, AO_t new_val) {
103   AO_t result = AO_compare_and_swap(addr, old, new_val);
104   AO_lwsync();
105   return result;
106 }
107
108 #define AO_HAVE_compare_and_swap_acquire
109
110 AO_INLINE AO_t
111 AO_compare_and_swap_release(volatile AO_t *addr, AO_t old, AO_t new_val) {
112   AO_lwsync();
113   return AO_compare_and_swap(addr, old, new_val);
114 }
115
116 #define AO_HAVE_compare_and_swap_release
117
118 AO_INLINE AO_t
119 AO_compare_and_swap_full(volatile AO_t *addr, AO_t old, AO_t new_val) {
120   AO_t result;
121   AO_lwsync();
122   result = AO_compare_and_swap(addr, old, new_val);
123   AO_lwsync();
124   return result;
125 }
126
127 #define AO_HAVE_compare_and_swap_full
128
129 /* FIXME: We should also implement fetch_and_add and or primitives      */
130 /* directly.                                                            */