qatomic_sh4a.h

Go to the documentation of this file.
00001 /****************************************************************************
00002 **
00003 ** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
00004 ** All rights reserved.
00005 ** Contact: Nokia Corporation (qt-info@nokia.com)
00006 **
00007 ** This file is part of the QtCore module of the Qt Toolkit.
00008 **
00009 ** $QT_BEGIN_LICENSE:LGPL$
00010 ** Commercial Usage
00011 ** Licensees holding valid Qt Commercial licenses may use this file in
00012 ** accordance with the Qt Commercial License Agreement provided with the
00013 ** Software or, alternatively, in accordance with the terms contained in
00014 ** a written agreement between you and Nokia.
00015 **
00016 ** GNU Lesser General Public License Usage
00017 ** Alternatively, this file may be used under the terms of the GNU Lesser
00018 ** General Public License version 2.1 as published by the Free Software
00019 ** Foundation and appearing in the file LICENSE.LGPL included in the
00020 ** packaging of this file.  Please review the following information to
00021 ** ensure the GNU Lesser General Public License version 2.1 requirements
00022 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
00023 **
00024 ** In addition, as a special exception, Nokia gives you certain additional
00025 ** rights.  These rights are described in the Nokia Qt LGPL Exception
00026 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this module.
00027 **
00028 ** GNU General Public License Usage
00029 ** Alternatively, this file may be used under the terms of the GNU
00030 ** General Public License version 3.0 as published by the Free Software
00031 ** Foundation and appearing in the file LICENSE.GPL included in the
00032 ** packaging of this file.  Please review the following information to
00033 ** ensure the GNU General Public License version 3.0 requirements will be
00034 ** met: http://www.gnu.org/copyleft/gpl.html.
00035 **
00036 ** If you have questions regarding the use of this file, please contact
00037 ** Nokia at qt-info@nokia.com.
00038 ** $QT_END_LICENSE$
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