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
00040
00041
00042 #ifndef QATOMIC_SH4A_H
00043 #define QATOMIC_SH4A_H
00044
00045 QT_BEGIN_HEADER
00046
00047 QT_BEGIN_NAMESPACE
00048
00049
00050 QT_END_NAMESPACE
00051
00052 QT_END_HEADER
00053
00054 #define Q_ATOMIC_INT_REFERENCE_COUNTING_IS_ALWAYS_NATIVE
00055
00056 inline bool QBasicAtomicInt::isReferenceCountingNative()
00057 { return true; }
00058 inline bool QBasicAtomicInt::isReferenceCountingWaitFree()
00059 { return false; }
00060
00061 #define Q_ATOMIC_INT_TEST_AND_SET_IS_ALWAYS_NATIVE
00062
00063 inline bool QBasicAtomicInt::isTestAndSetNative()
00064 { return true; }
00065 inline bool QBasicAtomicInt::isTestAndSetWaitFree()
00066 { return false; }
00067
00068 #define Q_ATOMIC_INT_FETCH_AND_STORE_IS_ALWAYS_NATIVE
00069
00070 inline bool QBasicAtomicInt::isFetchAndStoreNative()
00071 { return true; }
00072 inline bool QBasicAtomicInt::isFetchAndStoreWaitFree()
00073 { return false; }
00074
00075 #define Q_ATOMIC_INT_FETCH_AND_ADD_IS_ALWAYS_NATIVE
00076
00077 inline bool QBasicAtomicInt::isFetchAndAddNative()
00078 { return true; }
00079 inline bool QBasicAtomicInt::isFetchAndAddWaitFree()
00080 { return false; }
00081
00082 #define Q_ATOMIC_POINTER_TEST_AND_SET_IS_ALWAYS_NATIVE
00083
00084 template <typename T>
00085 Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::isTestAndSetNative()
00086 { return true; }
00087 template <typename T>
00088 Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::isTestAndSetWaitFree()
00089 { return false; }
00090
00091 #define Q_ATOMIC_POINTER_FETCH_AND_STORE_IS_ALWAYS_NATIVE
00092
00093 template <typename T>
00094 Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::isFetchAndStoreNative()
00095 { return true; }
00096 template <typename T>
00097 Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::isFetchAndStoreWaitFree()
00098 { return false; }
00099
00100 #define Q_ATOMIC_POINTER_FETCH_AND_ADD_IS_ALWAYS_NATIVE
00101
00102 template <typename T>
00103 Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::isFetchAndAddNative()
00104 { return true; }
00105 template <typename T>
00106 Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::isFetchAndAddWaitFree()
00107 { return false; }
00108
00109 QT_BEGIN_NAMESPACE
00110
00111 #if !defined(Q_CC_GNU)
00112 # error "SH-4A support has not been added for this compiler"
00113 #else
00114
00115 inline bool QBasicAtomicInt::ref()
00116 {
00117 register int newValue asm("r0");
00118 asm volatile("0:\n"
00119 "movli.l @%[_q_value], %[newValue]\n"
00120 "add #1,%[newValue]\n"
00121 "movco.l %[newValue], @%[_q_value]\n"
00122 "bf 0b\n"
00123 : [newValue] "=&r" (newValue),
00124 "+m" (_q_value)
00125 : [_q_value] "r" (&_q_value)
00126 : "cc", "memory");
00127 return newValue != 0;
00128 }
00129
00130 inline bool QBasicAtomicInt::deref()
00131 {
00132 register int newValue asm("r0");
00133 asm volatile("0:\n"
00134 "movli.l @%[_q_value], %[newValue]\n"
00135 "add #-1,%[newValue]\n"
00136 "movco.l %[newValue], @%[_q_value]\n"
00137 "bf 0b\n"
00138 : [newValue] "=&r" (newValue),
00139 "+m" (_q_value)
00140 : [_q_value] "r" (&_q_value)
00141 : "cc", "memory");
00142 return newValue != 0;
00143 }
00144
00145 inline bool QBasicAtomicInt::testAndSetRelaxed(int expectedValue, int newValue)
00146 {
00147 register int result;
00148 asm volatile("0:\n"
00149 "movli.l @%[_q_value], r0\n"
00150 "xor %[expectedValue], r0\n"
00151 "cmp/eq #0, r0\n"
00152 "bf/s 0f\n"
00153 "mov r0, %[result]\n"
00154 "mov %[newValue], r0\n"
00155 "movco.l r0, @%[_q_value]\n"
00156 "bf 0b\n"
00157 "0:\n"
00158 : [result] "=&r" (result),
00159 "+m" (_q_value)
00160 : [_q_value] "r" (&_q_value),
00161 [expectedValue] "r" (expectedValue),
00162 [newValue] "r" (newValue)
00163 : "r0", "cc", "memory");
00164 return result == 0;
00165 }
00166
00167 inline bool QBasicAtomicInt::testAndSetAcquire(int expectedValue, int newValue)
00168 {
00169 register int result;
00170 asm volatile("0:\n"
00171 "movli.l @%[_q_value], r0\n"
00172 "xor %[expectedValue], r0\n"
00173 "cmp/eq #0, r0\n"
00174 "bf/s 0f\n"
00175 "mov r0, %[result]\n"
00176 "mov %[newValue], r0\n"
00177 "movco.l r0, @%[_q_value]\n"
00178 "bf 0b\n"
00179 "synco\n"
00180 "0:\n"
00181 : [result] "=&r" (result),
00182 "+m" (_q_value)
00183 : [_q_value] "r" (&_q_value),
00184 [expectedValue] "r" (expectedValue),
00185 [newValue] "r" (newValue)
00186 : "r0", "cc", "memory");
00187 return result == 0;
00188 }
00189
00190 inline bool QBasicAtomicInt::testAndSetRelease(int expectedValue, int newValue)
00191 {
00192 register int result;
00193 asm volatile("synco\n"
00194 "0:\n"
00195 "movli.l @%[_q_value], r0\n"
00196 "xor %[expectedValue], r0\n"
00197 "cmp/eq #0, r0\n"
00198 "bf/s 0f\n"
00199 "mov r0, %[result]\n"
00200 "mov %[newValue], r0\n"
00201 "movco.l r0, @%[_q_value]\n"
00202 "bf 0b\n"
00203 "0:\n"
00204 : [result] "=&r" (result),
00205 "+m" (_q_value)
00206 : [_q_value] "r" (&_q_value),
00207 [expectedValue] "r" (expectedValue),
00208 [newValue] "r" (newValue)
00209 : "r0", "cc", "memory");
00210 return result == 0;
00211 }
00212
00213 inline bool QBasicAtomicInt::testAndSetOrdered(int expectedValue, int newValue)
00214 {
00215 return testAndSetAcquire(expectedValue, newValue);
00216 }
00217
00218 inline int QBasicAtomicInt::fetchAndStoreRelaxed(int newValue)
00219 {
00220 register int originalValue;
00221 asm volatile("0:\n"
00222 "movli.l @%[_q_value], r0\n"
00223 "mov r0, %[originalValue]\n"
00224 "mov %[newValue], r0\n"
00225 "movco.l r0, @%[_q_value]\n"
00226 "bf 0b\n"
00227 : [originalValue] "=&r" (originalValue),
00228 "+m" (_q_value)
00229 : [_q_value] "r" (&_q_value),
00230 [newValue] "r" (newValue)
00231 : "r0", "cc", "memory");
00232 return originalValue;
00233 }
00234
00235 inline int QBasicAtomicInt::fetchAndStoreAcquire(int newValue)
00236 {
00237 register int originalValue;
00238 asm volatile("0:\n"
00239 "movli.l @%[_q_value], r0\n"
00240 "mov r0, %[originalValue]\n"
00241 "mov %[newValue], r0\n"
00242 "movco.l r0, @%[_q_value]\n"
00243 "bf 0b\n"
00244 "synco\n"
00245 : [originalValue] "=&r" (originalValue),
00246 "+m" (_q_value)
00247 : [_q_value] "r" (&_q_value),
00248 [newValue] "r" (newValue)
00249 : "r0", "cc", "memory");
00250 return originalValue;
00251 }
00252
00253 inline int QBasicAtomicInt::fetchAndStoreRelease(int newValue)
00254 {
00255 register int originalValue;
00256 asm volatile("synco\n"
00257 "0:\n"
00258 "movli.l @%[_q_value], r0\n"
00259 "mov r0, %[originalValue]\n"
00260 "mov %[newValue], r0\n"
00261 "movco.l r0, @%[_q_value]\n"
00262 "bf 0b\n"
00263 : [originalValue] "=&r" (originalValue),
00264 "+m" (_q_value)
00265 : [_q_value] "r" (&_q_value),
00266 [newValue] "r" (newValue)
00267 : "r0", "cc", "memory");
00268 return originalValue;
00269 }
00270
00271 inline int QBasicAtomicInt::fetchAndStoreOrdered(int newValue)
00272 {
00273 return fetchAndStoreAcquire(newValue);
00274 }
00275
00276 inline int QBasicAtomicInt::fetchAndAddRelaxed(int valueToAdd)
00277 {
00278 register int originalValue;
00279 asm volatile("0:\n"
00280 "movli.l @%[_q_value], r0\n"
00281 "mov r0, %[originalValue]\n"
00282 "add %[valueToAdd], r0\n"
00283 "movco.l r0, @%[_q_value]\n"
00284 "bf 0b\n"
00285 : [originalValue] "=&r" (originalValue),
00286 "+m" (_q_value)
00287 : [_q_value] "r" (&_q_value),
00288 [valueToAdd] "r" (valueToAdd)
00289 : "r0", "cc", "memory");
00290 return originalValue;
00291 }
00292
00293 inline int QBasicAtomicInt::fetchAndAddAcquire(int valueToAdd)
00294 {
00295 register int originalValue;
00296 asm volatile("0:\n"
00297 "movli.l @%[_q_value], r0\n"
00298 "mov r0, %[originalValue]\n"
00299 "add %[valueToAdd], r0\n"
00300 "movco.l r0, @%[_q_value]\n"
00301 "bf 0b\n"
00302 "synco\n"
00303 : [originalValue] "=&r" (originalValue),
00304 "+m" (_q_value)
00305 : [_q_value] "r" (&_q_value),
00306 [valueToAdd] "r" (valueToAdd)
00307 : "r0", "cc", "memory");
00308 return originalValue;
00309 }
00310
00311 inline int QBasicAtomicInt::fetchAndAddRelease(int valueToAdd)
00312 {
00313 register int originalValue;
00314 asm volatile("synco\n"
00315 "0:\n"
00316 "movli.l @%[_q_value], r0\n"
00317 "mov r0, %[originalValue]\n"
00318 "add %[valueToAdd], r0\n"
00319 "movco.l r0, @%[_q_value]\n"
00320 "bf 0b\n"
00321 : [originalValue] "=&r" (originalValue),
00322 "+m" (_q_value)
00323 : [_q_value] "r" (&_q_value),
00324 [valueToAdd] "r" (valueToAdd)
00325 : "r0", "cc", "memory");
00326 return originalValue;
00327 }
00328
00329 inline int QBasicAtomicInt::fetchAndAddOrdered(int valueToAdd)
00330 {
00331 return fetchAndAddAcquire(valueToAdd);
00332 }
00333
00334 template <typename T>
00335 Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::testAndSetRelaxed(T *expectedValue, T *newValue)
00336 {
00337 register T *result;
00338 asm volatile("0:\n"
00339 "movli.l @%[_q_value], r0\n"
00340 "xor %[expectedValue], r0\n"
00341 "cmp/eq #0, r0\n"
00342 "bf/s 0f\n"
00343 "mov r0, %[result]\n"
00344 "mov %[newValue], r0\n"
00345 "movco.l r0, @%[_q_value]\n"
00346 "bf 0b\n"
00347 "0:\n"
00348 : [result] "=&r" (result),
00349 "+m" (_q_value)
00350 : [_q_value] "r" (&_q_value),
00351 [expectedValue] "r" (expectedValue),
00352 [newValue] "r" (newValue)
00353 : "r0", "cc", "memory");
00354 return result == 0;
00355 }
00356
00357 template <typename T>
00358 Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::testAndSetAcquire(T *expectedValue, T *newValue)
00359 {
00360 register T *result;
00361 asm volatile("0:\n"
00362 "movli.l @%[_q_value], r0\n"
00363 "xor %[expectedValue], r0\n"
00364 "cmp/eq #0, r0\n"
00365 "bf/s 0f\n"
00366 "mov r0, %[result]\n"
00367 "mov %[newValue], r0\n"
00368 "movco.l r0, @%[_q_value]\n"
00369 "bf 0b\n"
00370 "synco\n"
00371 "0:\n"
00372 : [result] "=&r" (result),
00373 "+m" (_q_value)
00374 : [_q_value] "r" (&_q_value),
00375 [expectedValue] "r" (expectedValue),
00376 [newValue] "r" (newValue)
00377 : "r0", "cc", "memory");
00378 return result == 0;
00379 }
00380
00381 template <typename T>
00382 Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::testAndSetRelease(T *expectedValue, T *newValue)
00383 {
00384 register T *result;
00385 asm volatile("synco\n"
00386 "0:\n"
00387 "movli.l @%[_q_value], r0\n"
00388 "xor %[expectedValue], r0\n"
00389 "cmp/eq #0, r0\n"
00390 "bf/s 0f\n"
00391 "mov r0, %[result]\n"
00392 "mov %[newValue], r0\n"
00393 "movco.l r0, @%[_q_value]\n"
00394 "bf 0b\n"
00395 "0:\n"
00396 : [result] "=&r" (result),
00397 "+m" (_q_value)
00398 : [_q_value] "r" (&_q_value),
00399 [expectedValue] "r" (expectedValue),
00400 [newValue] "r" (newValue)
00401 : "r0", "cc", "memory");
00402 return result == 0;
00403 }
00404
00405 template <typename T>
00406 Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::testAndSetOrdered(T *expectedValue, T *newValue)
00407 {
00408 return testAndSetAcquire(expectedValue, newValue);
00409 }
00410
00411 template <typename T>
00412 Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndStoreRelaxed(T *newValue)
00413 {
00414 register T *originalValue;
00415 asm volatile("0:\n"
00416 "movli.l @%[_q_value], r0\n"
00417 "mov r0, %[originalValue]\n"
00418 "mov %[newValue], r0\n"
00419 "movco.l r0, @%[_q_value]\n"
00420 "bf 0b\n"
00421 : [originalValue] "=&r" (originalValue),
00422 "+m" (_q_value)
00423 : [_q_value] "r" (&_q_value),
00424 [newValue] "r" (newValue)
00425 : "r0", "cc", "memory");
00426 return originalValue;
00427 }
00428
00429 template <typename T>
00430 Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndStoreAcquire(T *newValue)
00431 {
00432 register T *originalValue;
00433 asm volatile("0:\n"
00434 "movli.l @%[_q_value], r0\n"
00435 "mov r0, %[originalValue]\n"
00436 "mov %[newValue], r0\n"
00437 "movco.l r0, @%[_q_value]\n"
00438 "bf 0b\n"
00439 "synco\n"
00440 : [originalValue] "=&r" (originalValue),
00441 "+m" (_q_value)
00442 : [_q_value] "r" (&_q_value),
00443 [newValue] "r" (newValue)
00444 : "r0", "cc", "memory");
00445 return originalValue;
00446 }
00447
00448 template <typename T>
00449 Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndStoreRelease(T *newValue)
00450 {
00451 register T *originalValue;
00452 asm volatile("synco\n"
00453 "0:\n"
00454 "movli.l @%[_q_value], r0\n"
00455 "mov r0, %[originalValue]\n"
00456 "mov %[newValue], r0\n"
00457 "movco.l r0, @%[_q_value]\n"
00458 "bf 0b\n"
00459 : [originalValue] "=&r" (originalValue),
00460 "+m" (_q_value)
00461 : [_q_value] "r" (&_q_value),
00462 [newValue] "r" (newValue)
00463 : "r0", "cc", "memory");
00464 return originalValue;
00465 }
00466
00467 template <typename T>
00468 Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndStoreOrdered(T *newValue)
00469 {
00470 return fetchAndStoreAcquire(newValue);
00471 }
00472
00473 template <typename T>
00474 Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndAddRelaxed(qptrdiff valueToAdd)
00475 {
00476 register T *originalValue;
00477 asm volatile("0:\n"
00478 "movli.l @%[_q_value], r0\n"
00479 "mov r0, %[originalValue]\n"
00480 "add %[valueToAdd], r0\n"
00481 "movco.l r0, @%[_q_value]\n"
00482 "bf 0b\n"
00483 : [originalValue] "=&r" (originalValue),
00484 "+m" (_q_value)
00485 : [_q_value] "r" (&_q_value),
00486 [valueToAdd] "r" (valueToAdd * sizeof(T))
00487 : "r0", "cc", "memory");
00488 return originalValue;
00489 }
00490
00491 template <typename T>
00492 Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndAddAcquire(qptrdiff valueToAdd)
00493 {
00494 register T *originalValue;
00495 asm volatile("0:\n"
00496 "movli.l @%[_q_value], r0\n"
00497 "mov r0, %[originalValue]\n"
00498 "add %[valueToAdd], r0\n"
00499 "movco.l r0, @%[_q_value]\n"
00500 "bf 0b\n"
00501 "synco\n"
00502 : [originalValue] "=&r" (originalValue),
00503 "+m" (_q_value)
00504 : [_q_value] "r" (&_q_value),
00505 [valueToAdd] "r" (valueToAdd * sizeof(T))
00506 : "r0", "cc", "memory");
00507 return originalValue;
00508 }
00509
00510 template <typename T>
00511 Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndAddRelease(qptrdiff valueToAdd)
00512 {
00513 register T *originalValue;
00514 asm volatile("synco\n"
00515 "0:\n"
00516 "movli.l @%[_q_value], r0\n"
00517 "mov r0, %[originalValue]\n"
00518 "add %[valueToAdd], r0\n"
00519 "movco.l r0, @%[_q_value]\n"
00520 "bf 0b\n"
00521 : [originalValue] "=&r" (originalValue),
00522 "+m" (_q_value)
00523 : [_q_value] "r" (&_q_value),
00524 [valueToAdd] "r" (valueToAdd * sizeof(T))
00525 : "r0", "cc", "memory");
00526 return originalValue;
00527 }
00528
00529 template <typename T>
00530 Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndAddOrdered(qptrdiff valueToAdd)
00531 {
00532 return fetchAndAddAcquire(valueToAdd);
00533 }
00534
00535 #endif // Q_CC_GNU
00536
00537 #endif // QATOMIC_SH4A_H