00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 #ifndef _OASYS_ATOMIC_PPC_H_
00019 #define _OASYS_ATOMIC_PPC_H_
00020
00021 #include "../debug/DebugUtils.h"
00022
00023 namespace oasys {
00024
00030 struct atomic_t {
00031 atomic_t(u_int32_t v = 0) : value(v) {}
00032
00033 volatile u_int32_t value;
00034 };
00035
00043 static inline u_int32_t
00044 atomic_add_ret(volatile atomic_t* v, u_int32_t i)
00045 {
00046 register u_int32_t ret;
00047
00048 __asm__ __volatile__(
00049 "1: lwarx %0, 0, %2\n"
00050 " add %0, %3, %0\n"
00051 " stwcx. %0, 0, %2\n"
00052 " bne- 1b\n"
00053 : "=&r" (ret), "=m" (v->value)
00054 : "r" (v), "r" (i), "m" (v->value)
00055 : "cc", "memory");
00056
00057 return ret;
00058 }
00059
00066 static inline u_int32_t
00067 atomic_sub_ret(volatile atomic_t* v, u_int32_t i)
00068 {
00069 register u_int32_t ret;
00070
00071 __asm__ __volatile__(
00072 "1: lwarx %0, 0, %2\n"
00073 " subfc %0, %3, %0\n"
00074 " stwcx. %0, 0, %2\n"
00075 " bne- 1b\n"
00076 : "=&r" (ret), "=m" (v->value)
00077 : "r" (v), "r" (i), "m" (v->value)
00078 : "cc", "memory");
00079
00080 return ret;
00081 }
00082
00085
00086 static inline void
00087 atomic_add(volatile atomic_t* v, u_int32_t i)
00088 {
00089 atomic_add_ret(v, i);
00090 }
00091
00092 static inline void
00093 atomic_sub(volatile atomic_t* v, u_int32_t i)
00094 {
00095 atomic_sub_ret(v, i);
00096 }
00097
00098 static inline void
00099 atomic_incr(volatile atomic_t* v)
00100 {
00101 atomic_add(v, 1);
00102 }
00103
00104 static inline void
00105 atomic_decr(volatile atomic_t* v)
00106 {
00107 atomic_sub(v, 1);
00108 }
00109
00110 static inline u_int32_t
00111 atomic_incr_ret(volatile atomic_t* v)
00112 {
00113 return atomic_add_ret(v, 1);
00114 }
00115
00116 static inline u_int32_t
00117 atomic_decr_ret(volatile atomic_t* v)
00118 {
00119 return atomic_sub_ret(v, 1);
00120 }
00121
00122 static inline bool
00123 atomic_decr_test(volatile atomic_t* v)
00124 {
00125 return (atomic_sub_ret(v, 1) == 0);
00126 }
00127
00129
00140 static inline u_int32_t
00141 atomic_cmpxchg32(volatile atomic_t* v, u_int32_t o, u_int32_t n)
00142 {
00143 register u_int32_t ret;
00144
00145 __asm __volatile (
00146 "1: lwarx %0, 0, %2\n"
00147 " cmplw %3, %0\n"
00148 " bne 2f\n"
00149 " stwcx. %4, 0, %2\n"
00150 " bne- 1b\n"
00151 " b 3f\n"
00152 " 2:\n"
00153 " stwcx. %0, 0, %2\n"
00154 " 3:\n"
00155 : "=&r" (ret), "=m" (v->value)
00156 : "r" (v), "r" (o), "r" (n), "m" (v->value)
00157 : "cc", "memory");
00158
00159 return (ret);
00160 }
00161
00162 }
00163
00164 #endif