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 #ifndef _BARRIER_H
00034 #define _BARRIER_H
00035
00036 #define DECLARE_READ_BARRIER(NAME, T, LOCK) \
00037 _ITM_TYPE_##T _ITM_CALL_CONVENTION \
00038 mtm_##NAME##_##LOCK##T(mtm_tx_t *tx, \
00039 const _ITM_TYPE_##T *ptr);
00040
00041 #define DECLARE_WRITE_BARRIER(NAME, T, LOCK) \
00042 void _ITM_CALL_CONVENTION mtm_##NAME##_##LOCK##T(mtm_tx_t *tx, \
00043 _ITM_TYPE_##T *addr, \
00044 _ITM_TYPE_##T value);
00045
00046
00047 #define DECLARE_READ_BARRIERS(name, type, encoding) \
00048 DECLARE_READ_BARRIER(name, encoding, R) \
00049 DECLARE_READ_BARRIER(name, encoding, RaR) \
00050 DECLARE_READ_BARRIER(name, encoding, RaW) \
00051 DECLARE_READ_BARRIER(name, encoding, RfW) \
00052
00053
00054 #define DECLARE_WRITE_BARRIERS(name, type, encoding) \
00055 DECLARE_WRITE_BARRIER(name, encoding, W) \
00056 DECLARE_WRITE_BARRIER(name, encoding, WaR) \
00057 DECLARE_WRITE_BARRIER(name, encoding, WaW)
00058
00059 typedef union convert_u {
00060 mtm_word_t w;
00061 uint8_t b[sizeof(mtm_word_t)];
00062 } convert_t;
00063
00064 #if 0
00065 # define DEFINE_LOAD_BYTES(NAME) \
00066 DEFINE_IDENTITY_LOAD_BYTES(NAME)
00067
00068 # define DEFINE_STORE_BYTES(NAME) \
00069 DEFINE_IDENTITY_STORE_BYTES(NAME)
00070 #else
00071 # define DEFINE_LOAD_BYTES(NAME) \
00072 DEFINE_TM_LOAD_BYTES(NAME)
00073
00074 # define DEFINE_STORE_BYTES(NAME) \
00075 DEFINE_TM_STORE_BYTES(NAME)
00076
00077 #endif
00078
00079
00080 #define DEFINE_IDENTITY_LOAD_BYTES(NAME) \
00081 void mtm_##NAME##_load_bytes(mtm_tx_t *tx, \
00082 volatile uint8_t *addr, \
00083 uint8_t *buf, \
00084 size_t size) \
00085 { \
00086 convert_t val; \
00087 unsigned int i; \
00088 mtm_word_t *a; \
00089 \
00090 if (size == 0) { \
00091 return; \
00092 } \
00093 for (i=0; i < size; i++) { \
00094 buf[i] = addr[i]; \
00095 } \
00096 }
00097
00098 #define DEFINE_TM_LOAD_BYTES(NAME) \
00099 void mtm_##NAME##_load_bytes(mtm_tx_t *tx, \
00100 volatile uint8_t *addr, \
00101 uint8_t *buf, \
00102 size_t size) \
00103 { \
00104 convert_t val; \
00105 unsigned int i; \
00106 mtm_word_t *a; \
00107 \
00108 if (size == 0) { \
00109 return; \
00110 } \
00111 i = (uintptr_t)addr & (sizeof(mtm_word_t) - 1); \
00112 if (i != 0) { \
00113 \
00114 a = (mtm_word_t *)((uintptr_t)addr & ~(uintptr_t)(sizeof(mtm_word_t) - 1));\
00115 val.w = mtm_##NAME##_load(tx, a++); \
00116 for (; i < sizeof(mtm_word_t) && size > 0; i++, size--) { \
00117 *buf++ = val.b[i]; \
00118 } \
00119 } else { \
00120 a = (mtm_word_t *)addr; \
00121 } \
00122 \
00123 while (size >= sizeof(mtm_word_t)) { \
00124 *((mtm_word_t *)buf) = mtm_##NAME##_load(tx, a++); \
00125 buf += sizeof(mtm_word_t); \
00126 size -= sizeof(mtm_word_t); \
00127 } \
00128 if (size > 0) { \
00129 \
00130 val.w = mtm_##NAME##_load(tx, a); \
00131 i = 0; \
00132 for (i = 0; size > 0; i++, size--) { \
00133 *buf++ = val.b[i]; \
00134 } \
00135 } \
00136 }
00137
00138
00139 #define DEFINE_IDENTITY_STORE_BYTES(NAME) \
00140 void mtm_##NAME##_store_bytes(mtm_tx_t *tx, \
00141 volatile uint8_t *addr, \
00142 uint8_t *buf, \
00143 size_t size) \
00144 { \
00145 convert_t val; \
00146 convert_t mask; \
00147 unsigned int i; \
00148 mtm_word_t *a; \
00149 \
00150 if (size == 0) { \
00151 return; \
00152 } \
00153 for (i=0; i < size; i++) { \
00154 addr[i] = buf[i]; \
00155 } \
00156 }
00157
00158
00159 #define DEFINE_TM_STORE_BYTES(NAME) \
00160 void mtm_##NAME##_store_bytes(mtm_tx_t *tx, \
00161 volatile uint8_t *addr, \
00162 uint8_t *buf, \
00163 size_t size) \
00164 { \
00165 convert_t val; \
00166 convert_t mask; \
00167 unsigned int i; \
00168 mtm_word_t *a; \
00169 \
00170 if (size == 0) { \
00171 return; \
00172 } \
00173 i = (uintptr_t)addr & (sizeof(mtm_word_t) - 1); \
00174 if (i != 0) { \
00175 \
00176 a = (mtm_word_t *)((uintptr_t)addr & ~(uintptr_t)(sizeof(mtm_word_t) - 1));\
00177 val.w = mask.w = 0; \
00178 for (; i < sizeof(mtm_word_t) && size > 0; i++, size--) { \
00179 mask.b[i] = 0xFF; \
00180 val.b[i] = *buf++; \
00181 } \
00182 mtm_##NAME##_store2(tx, a++, val.w, mask.w); \
00183 } else { \
00184 a = (mtm_word_t *)addr; \
00185 } \
00186 \
00187 while (size >= sizeof(mtm_word_t)) { \
00188 mtm_##NAME##_store(tx, a++, *((mtm_word_t *)buf)); \
00189 buf += sizeof(mtm_word_t); \
00190 size -= sizeof(mtm_word_t); \
00191 } \
00192 if (size > 0) { \
00193 \
00194 val.w = mask.w = 0; \
00195 for (i = 0; size > 0; i++, size--) { \
00196 mask.b[i] = 0xFF; \
00197 val.b[i] = *buf++; \
00198 } \
00199 mtm_##NAME##_store2(tx, a, val.w, mask.w); \
00200 } \
00201 }
00202
00203 #define READ_BARRIER(NAME, T, LOCK) \
00204 _ITM_TYPE_##T _ITM_CALL_CONVENTION \
00205 mtm_##NAME##_##LOCK##T(mtm_tx_t *tx, \
00206 const _ITM_TYPE_##T *addr) \
00207 { \
00208 _ITM_TYPE_##T val; \
00209 mtm_##NAME##_load_bytes(tx, \
00210 (volatile uint8_t *)addr, \
00211 (uint8_t *)&val, \
00212 sizeof(_ITM_TYPE_##T)); \
00213 return val; \
00214 }
00215
00216
00217 #define WRITE_BARRIER(NAME, T, LOCK) \
00218 void _ITM_CALL_CONVENTION mtm_##NAME##_##LOCK##T(mtm_tx_t *tx, \
00219 _ITM_TYPE_##T *addr, \
00220 _ITM_TYPE_##T value) \
00221 { \
00222 mtm_##NAME##_store_bytes(tx, \
00223 (volatile uint8_t *)addr, \
00224 (uint8_t *)&value, \
00225 sizeof(_ITM_TYPE_##T)); \
00226 }
00227
00228
00229 #define DEFINE_READ_BARRIERS(name, type, encoding) \
00230 READ_BARRIER(name, encoding, R) \
00231 READ_BARRIER(name, encoding, RaR) \
00232 READ_BARRIER(name, encoding, RaW) \
00233 READ_BARRIER(name, encoding, RfW) \
00234
00235
00236 #define DEFINE_WRITE_BARRIERS(name, type, encoding) \
00237 WRITE_BARRIER(name, encoding, W) \
00238 WRITE_BARRIER(name, encoding, WaR) \
00239 WRITE_BARRIER(name, encoding, WaW)
00240
00241
00242
00243
00244
00245
00246 #if 0
00247
00248 typedef union convert_U32_u convert_CE_t;
00249 typedef union convert_U16_u convert_E_t;
00250 typedef union convert_U16_u convert_M128_t;
00251 typedef union convert_U16_u convert_CD_t;
00252 typedef union convert_U8_u convert_U8_t;
00253 typedef union convert_U8_u convert_D_t;
00254 typedef union convert_U8_u convert_M64_t;
00255 typedef union convert_U8_u convert_CF_t;
00256 typedef union convert_U4_u convert_U4_t;
00257 typedef union convert_U4_u convert_F_t;
00258 typedef union convert_U2_u convert_U2_t;
00259 typedef union convert_U1_u convert_U1_t;
00260
00261 union convert_U32_u {
00262 _ITM_TYPE_U8 U8[2];
00263 _ITM_TYPE_U4 U4[4];
00264 _ITM_TYPE_U2 U2[8];
00265 _ITM_TYPE_U1 U1[16];
00266 _ITM_TYPE_CE CE;
00267 };
00268
00269 union convert_U16_u {
00270 _ITM_TYPE_U8 U8[2];
00271 _ITM_TYPE_U4 U4[4];
00272 _ITM_TYPE_U2 U2[8];
00273 _ITM_TYPE_U1 U1[16];
00274 _ITM_TYPE_E E;
00275 _ITM_TYPE_M128 M128;
00276 _ITM_TYPE_CD CD;
00277 };
00278
00279 union convert_U8_u {
00280 _ITM_TYPE_U8 U8;
00281 _ITM_TYPE_U4 U4[2];
00282 _ITM_TYPE_U2 U2[4];
00283 _ITM_TYPE_U1 U1[8];
00284 _ITM_TYPE_D D;
00285 _ITM_TYPE_M64 M64;
00286 _ITM_TYPE_CF CF;
00287 };
00288
00289 union convert_U4_u {
00290 _ITM_TYPE_U4 U4;
00291 _ITM_TYPE_U2 U2[2];
00292 _ITM_TYPE_U1 U1[4];
00293 _ITM_TYPE_F F;
00294 };
00295
00296 union convert_U2_u {
00297 _ITM_TYPE_U2 U2;
00298 _ITM_TYPE_U1 U1[2];
00299 };
00300
00301 union convert_U1_u {
00302 _ITM_TYPE_U1 U1;
00303 };
00304
00305
00306 #define WRITE_BARRIER(NAME, T, LOCK) \
00307 void _ITM_CALL_CONVENTION mtm_##NAME##LOCK##T(mtm_tx_t *tx, \
00308 volatile _ITM_TYPE_##T *addr, \
00309 _ITM_TYPE_##T value) \
00310 { \
00311 if (((uintptr_t)addr & (sizeof(_ITM_TYPE_##T))-1) != 0) { \
00312 stm_store_bytes(tx, \
00313 (volatile uint8_t *)addr, \
00314 (uint8_t *)&value, \
00315 sizeof(_ITM_TYPE_##T)); \
00316 } else if (sizeof(mtm_word_t) == 4) { \
00317 if (sizeof(_ITM_TYPE_##T) >= 4) { \
00318 int i; \
00319 convert_##T##_t val; \
00320 val.#T = value; \
00321 for (i=0; i<sizeof(_ITM_TYPE_##T)/4; i++) { \
00322 stm_store(tx, (volatile mtm_word_t *)addr+i, (mtm_word_t)val.U4[i]);\
00323 } \
00324 } else { \
00325 convert_U4_t val, mask; \
00326 val.#T[((uintptr_t)addr & 0x03) >> (sizeof(_ITM_TYPE_##T)-1)] = value; \
00327 mask.U4 = 0; \
00328 mask.#T[((uintptr_t)addr & 0x03) >> (sizeof(_ITM_TYPE_##T)-1)] = ~(_ITM_TYPE_##T)0; \
00329 stm_store2(tx, \
00330 (volatile mtm_word_t *)((uintptr_t)addr & ~(uintptr_t)0x03), \
00331 (mtm_word_t)val.U4, (mtm_word_t)mask.U4); \
00332 } \
00333 } else { \
00334 } \
00335 }
00336 #endif
00337
00338
00339
00340 #endif