- Main Page
- Related Pages
- Modules
- Namespaces
- Classes
- Files
- Directories
- Examples

- File List
- File Members

# 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