00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039 #ifndef _OASYS_ATOMIC_PPC_H_
00040 #define _OASYS_ATOMIC_PPC_H_
00041
00042 #include "../debug/DebugUtils.h"
00043
00044 namespace oasys {
00045
00051 struct atomic_t {
00052 atomic_t(u_int32_t v = 0) : value(v) {}
00053
00054 volatile u_int32_t value;
00055 };
00056
00064 static inline u_int32_t
00065 atomic_add_ret(volatile atomic_t* v, u_int32_t i)
00066 {
00067 register u_int32_t ret;
00068
00069 __asm__ __volatile__(
00070 "1: lwarx %0, 0, %2\n"
00071 " add %0, %3, %0\n"
00072 " stwcx. %0, 0, %2\n"
00073 " bne- 1b\n"
00074 : "=&r" (ret), "=m" (v->value)
00075 : "r" (v), "r" (i), "m" (v->value)
00076 : "cc", "memory");
00077
00078 return ret;
00079 }
00080
00087 static inline u_int32_t
00088 atomic_sub_ret(volatile atomic_t* v, u_int32_t i)
00089 {
00090 register u_int32_t ret;
00091
00092 __asm__ __volatile__(
00093 "1: lwarx %0, 0, %2\n"
00094 " subfc %0, %3, %0\n"
00095 " stwcx. %0, 0, %2\n"
00096 " bne- 1b\n"
00097 : "=&r" (ret), "=m" (v->value)
00098 : "r" (v), "r" (i), "m" (v->value)
00099 : "cc", "memory");
00100
00101 return ret;
00102 }
00103
00106
00107 static inline void
00108 atomic_add(volatile atomic_t* v, u_int32_t i)
00109 {
00110 atomic_add_ret(v, i);
00111 }
00112
00113 static inline void
00114 atomic_sub(volatile atomic_t* v, u_int32_t i)
00115 {
00116 atomic_sub_ret(v, i);
00117 }
00118
00119 static inline void
00120 atomic_incr(volatile atomic_t* v)
00121 {
00122 atomic_add(v, 1);
00123 }
00124
00125 static inline void
00126 atomic_decr(volatile atomic_t* v)
00127 {
00128 atomic_sub(v, 1);
00129 }
00130
00131 static inline u_int32_t
00132 atomic_incr_ret(volatile atomic_t* v)
00133 {
00134 return atomic_add_ret(v, 1);
00135 }
00136
00137 static inline u_int32_t
00138 atomic_decr_ret(volatile atomic_t* v)
00139 {
00140 return atomic_sub_ret(v, 1);
00141 }
00142
00143 static inline bool
00144 atomic_decr_test(volatile atomic_t* v)
00145 {
00146 return (atomic_sub_ret(v, 1) == 0);
00147 }
00148
00150
00161 static inline u_int32_t
00162 atomic_cmpxchg32(volatile atomic_t* v, u_int32_t o, u_int32_t n)
00163 {
00164 register u_int32_t ret;
00165
00166 __asm __volatile (
00167 "1: lwarx %0, 0, %2\n"
00168 " cmplw %3, %0\n"
00169 " bne 2f\n"
00170 " stwcx. %4, 0, %2\n"
00171 " bne- 1b\n"
00172 " b 3f\n"
00173 " 2:\n"
00174 " stwcx. %0, 0, %2\n"
00175 " 3:\n"
00176 : "=&r" (ret), "=m" (v->value)
00177 : "r" (v), "r" (o), "r" (n), "m" (v->value)
00178 : "cc", "memory");
00179
00180 return (ret);
00181 }
00182
00183 }
00184
00185 #endif