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

- File List
- File Members

# qatomic_mips.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_MIPS_H
    00043 #define QATOMIC_MIPS_H
    00044
    00045 QT_BEGIN_HEADER
    00046
    00047 QT_BEGIN_NAMESPACE
    00048
    00049 #define Q_ATOMIC_INT_REFERENCE_COUNTING_IS_ALWAYS_NATIVE
    00050
    00051 inline bool QBasicAtomicInt::isReferenceCountingNative()
    00052 { return true; }
    00053 inline bool QBasicAtomicInt::isReferenceCountingWaitFree()
    00054 { return false; }
    00055
    00056 #define Q_ATOMIC_INT_TEST_AND_SET_IS_ALWAYS_NATIVE
    00057
    00058 inline bool QBasicAtomicInt::isTestAndSetNative()
    00059 { return true; }
    00060 inline bool QBasicAtomicInt::isTestAndSetWaitFree()
    00061 { return false; }
    00062
    00063 #define Q_ATOMIC_INT_FETCH_AND_STORE_IS_ALWAYS_NATIVE
    00064
    00065 inline bool QBasicAtomicInt::isFetchAndStoreNative()
    00066 { return true; }
    00067 inline bool QBasicAtomicInt::isFetchAndStoreWaitFree()
    00068 { return false; }
    00069
    00070 #define Q_ATOMIC_INT_FETCH_AND_ADD_IS_ALWAYS_NATIVE
    00071
    00072 inline bool QBasicAtomicInt::isFetchAndAddNative()
    00073 { return true; }
    00074 inline bool QBasicAtomicInt::isFetchAndAddWaitFree()
    00075 { return false; }
    00076
    00077 #define Q_ATOMIC_POINTER_TEST_AND_SET_IS_ALWAYS_NATIVE
    00078
    00079 template <typename T>
    00080 Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::isTestAndSetNative()
    00081 { return true; }
    00082 template <typename T>
    00083 Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::isTestAndSetWaitFree()
    00084 { return false; }
    00085
    00086 #define Q_ATOMIC_POINTER_FETCH_AND_STORE_IS_ALWAYS_NATIVE
    00087
    00088 template <typename T>
    00089 Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::isFetchAndStoreNative()
    00090 { return true; }
    00091 template <typename T>
    00092 Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::isFetchAndStoreWaitFree()
    00093 { return false; }
    00094
    00095 #define Q_ATOMIC_POINTER_FETCH_AND_ADD_IS_ALWAYS_NATIVE
    00096
    00097 template <typename T>
    00098 Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::isFetchAndAddNative()
    00099 { return true; }
    00100 template <typename T>
    00101 Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::isFetchAndAddWaitFree()
    00102 { return false; }
    00103
    00104 #if defined(Q_CC_GNU) && !defined(Q_OS_IRIX)
    00105
    00106 #if _MIPS_SIM == _ABIO32
    00107 #define SET_MIPS2 ".set mips2\n\t"
    00108 #else
    00109 #define SET_MIPS2
    00110 #endif
    00111
    00112 inline bool QBasicAtomicInt::ref()
    00113 {
    00114     register int originalValue;
    00115     register int newValue;
    00116     asm volatile(".set push\n"
    00117                  SET_MIPS2
    00118                  "0:\n"
    00119                  "ll %[originalValue], %[_q_value]\n"
    00120                  "addiu %[newValue], %[originalValue], %[one]\n"
    00121                  "sc %[newValue], %[_q_value]\n"
    00122                  "beqz %[newValue], 0b\n"
    00123                  "nop\n"
    00124                  ".set pop\n"
    00125                  : [originalValue] "=&r" (originalValue),
    00126                    [_q_value] "+m" (_q_value),
    00127                    [newValue] "=&r" (newValue)
    00128                  : [one] "i" (1)
    00129                  : "cc", "memory");
    00130     return originalValue != -1;
    00131 }
    00132
    00133 inline bool QBasicAtomicInt::deref()
    00134 {
    00135     register int originalValue;
    00136     register int newValue;
    00137     asm volatile(".set push\n"
    00138                  SET_MIPS2
    00139                  "0:\n"
    00140                  "ll %[originalValue], %[_q_value]\n"
    00141                  "addiu %[newValue], %[originalValue], %[minusOne]\n"
    00142                  "sc %[newValue], %[_q_value]\n"
    00143                  "beqz %[newValue], 0b\n"
    00144                  "nop\n"
    00145                  ".set pop\n"
    00146                  : [originalValue] "=&r" (originalValue),
    00147                    [_q_value] "+m" (_q_value),
    00148                    [newValue] "=&r" (newValue)
    00149                  : [minusOne] "i" (-1)
    00150                  : "cc", "memory");
    00151     return originalValue != 1;
    00152 }
    00153
    00154 inline bool QBasicAtomicInt::testAndSetRelaxed(int expectedValue, int newValue)
    00155 {
    00156     register int result;
    00157     register int tempValue;
    00158     asm volatile(".set push\n"
    00159                  SET_MIPS2
    00160                  "0:\n"
    00161                  "ll %[result], %[_q_value]\n"
    00162                  "xor %[result], %[result], %[expectedValue]\n"
    00163                  "bnez %[result], 0f\n"
    00164                  "nop\n"
    00165                  "move %[tempValue], %[newValue]\n"
    00166                  "sc %[tempValue], %[_q_value]\n"
    00167                  "beqz %[tempValue], 0b\n"
    00168                  "nop\n"
    00169                  "0:\n"
    00170                  ".set pop\n"
    00171                  : [result] "=&r" (result),
    00172                    [tempValue] "=&r" (tempValue),
    00173                    [_q_value] "+m" (_q_value)
    00174                  : [expectedValue] "r" (expectedValue),
    00175                    [newValue] "r" (newValue)
    00176                  : "cc", "memory");
    00177     return result == 0;
    00178 }
    00179
    00180 inline bool QBasicAtomicInt::testAndSetAcquire(int expectedValue, int newValue)
    00181 {
    00182     register int result;
    00183     register int tempValue;
    00184     asm volatile(".set push\n"
    00185                  SET_MIPS2
    00186                  "0:\n"
    00187                  "ll %[result], %[_q_value]\n"
    00188                  "xor %[result], %[result], %[expectedValue]\n"
    00189                  "bnez %[result], 0f\n"
    00190                  "nop\n"
    00191                  "move %[tempValue], %[newValue]\n"
    00192                  "sc %[tempValue], %[_q_value]\n"
    00193                  "beqz %[tempValue], 0b\n"
    00194                  "nop\n"
    00195                  "sync\n"
    00196                  "0:\n"
    00197                  ".set pop\n"
    00198                  : [result] "=&r" (result),
    00199                    [tempValue] "=&r" (tempValue),
    00200                    [_q_value] "+m" (_q_value)
    00201                  : [expectedValue] "r" (expectedValue),
    00202                    [newValue] "r" (newValue)
    00203                  : "cc", "memory");
    00204     return result == 0;
    00205 }
    00206
    00207 inline bool QBasicAtomicInt::testAndSetRelease(int expectedValue, int newValue)
    00208 {
    00209     register int result;
    00210     register int tempValue;
    00211     asm volatile(".set push\n"
    00212                  SET_MIPS2
    00213                  "sync\n"
    00214                  "0:\n"
    00215                  "ll %[result], %[_q_value]\n"
    00216                  "xor %[result], %[result], %[expectedValue]\n"
    00217                  "bnez %[result], 0f\n"
    00218                  "nop\n"
    00219                  "move %[tempValue], %[newValue]\n"
    00220                  "sc %[tempValue], %[_q_value]\n"
    00221                  "beqz %[tempValue], 0b\n"
    00222                  "nop\n"
    00223                  "0:\n"
    00224                  ".set pop\n"
    00225                  : [result] "=&r" (result),
    00226                    [tempValue] "=&r" (tempValue),
    00227                    [_q_value] "+m" (_q_value)
    00228                  : [expectedValue] "r" (expectedValue),
    00229                    [newValue] "r" (newValue)
    00230                  : "cc", "memory");
    00231     return result == 0;
    00232 }
    00233
    00234 inline bool QBasicAtomicInt::testAndSetOrdered(int expectedValue, int newValue)
    00235 {
    00236     return testAndSetAcquire(expectedValue, newValue);
    00237 }
    00238
    00239 inline int QBasicAtomicInt::fetchAndStoreRelaxed(int newValue)
    00240 {
    00241     register int originalValue;
    00242     register int tempValue;
    00243     asm volatile(".set push\n"
    00244                  SET_MIPS2
    00245                  "0:\n"
    00246                  "ll %[originalValue], %[_q_value]\n"
    00247                  "move %[tempValue], %[newValue]\n"
    00248                  "sc %[tempValue], %[_q_value]\n"
    00249                  "beqz %[tempValue], 0b\n"
    00250                  "nop\n"
    00251                  ".set pop\n"
    00252                  : [originalValue] "=&r" (originalValue),
    00253                    [tempValue] "=&r" (tempValue),
    00254                    [_q_value] "+m" (_q_value)
    00255                  : [newValue] "r" (newValue)
    00256                  : "cc", "memory");
    00257     return originalValue;
    00258 }
    00259
    00260 inline int QBasicAtomicInt::fetchAndStoreAcquire(int newValue)
    00261 {
    00262     register int originalValue;
    00263     register int tempValue;
    00264     asm volatile(".set push\n"
    00265                  SET_MIPS2
    00266                  "0:\n"
    00267                  "ll %[originalValue], %[_q_value]\n"
    00268                  "move %[tempValue], %[newValue]\n"
    00269                  "sc %[tempValue], %[_q_value]\n"
    00270                  "beqz %[tempValue], 0b\n"
    00271                  "nop\n"
    00272                  "sync\n"
    00273                  ".set pop\n"
    00274                  : [originalValue] "=&r" (originalValue),
    00275                    [tempValue] "=&r" (tempValue),
    00276                    [_q_value] "+m" (_q_value)
    00277                  : [newValue] "r" (newValue)
    00278                  : "cc", "memory");
    00279     return originalValue;
    00280 }
    00281
    00282 inline int QBasicAtomicInt::fetchAndStoreRelease(int newValue)
    00283 {
    00284     register int originalValue;
    00285     register int tempValue;
    00286     asm volatile(".set push\n"
    00287                  SET_MIPS2
    00288                  "sync\n"
    00289                  "0:\n"
    00290                  "ll %[originalValue], %[_q_value]\n"
    00291                  "move %[tempValue], %[newValue]\n"
    00292                  "sc %[tempValue], %[_q_value]\n"
    00293                  "beqz %[tempValue], 0b\n"
    00294                  "nop\n"
    00295                  ".set pop\n"
    00296                  : [originalValue] "=&r" (originalValue),
    00297                    [tempValue] "=&r" (tempValue),
    00298                    [_q_value] "+m" (_q_value)
    00299                  : [newValue] "r" (newValue)
    00300                  : "cc", "memory");
    00301     return originalValue;
    00302 }
    00303
    00304 inline int QBasicAtomicInt::fetchAndStoreOrdered(int newValue)
    00305 {
    00306     return fetchAndStoreAcquire(newValue);
    00307 }
    00308
    00309 inline int QBasicAtomicInt::fetchAndAddRelaxed(int valueToAdd)
    00310 {
    00311     register int originalValue;
    00312     register int newValue;
    00313     asm volatile(".set push\n"
    00314                  SET_MIPS2
    00315                  "0:\n"
    00316                  "ll %[originalValue], %[_q_value]\n"
    00317                  "addu %[newValue], %[originalValue], %[valueToAdd]\n"
    00318                  "sc %[newValue], %[_q_value]\n"
    00319                  "beqz %[newValue], 0b\n"
    00320                  "nop\n"
    00321                  ".set pop\n"
    00322                  : [originalValue] "=&r" (originalValue),
    00323                    [_q_value] "+m" (_q_value),
    00324                    [newValue] "=&r" (newValue)
    00325                  : [valueToAdd] "r" (valueToAdd)
    00326                  : "cc", "memory");
    00327     return originalValue;
    00328 }
    00329
    00330 inline int QBasicAtomicInt::fetchAndAddAcquire(int valueToAdd)
    00331 {
    00332     register int originalValue;
    00333     register int newValue;
    00334     asm volatile(".set push\n"
    00335                  SET_MIPS2
    00336                  "0:\n"
    00337                  "ll %[originalValue], %[_q_value]\n"
    00338                  "addu %[newValue], %[originalValue], %[valueToAdd]\n"
    00339                  "sc %[newValue], %[_q_value]\n"
    00340                  "beqz %[newValue], 0b\n"
    00341                  "nop\n"
    00342                  "sync\n"
    00343                  ".set pop\n"
    00344                  : [originalValue] "=&r" (originalValue),
    00345                    [_q_value] "+m" (_q_value),
    00346                    [newValue] "=&r" (newValue)
    00347                  : [valueToAdd] "r" (valueToAdd)
    00348                  : "cc", "memory");
    00349     return originalValue;
    00350 }
    00351
    00352 inline int QBasicAtomicInt::fetchAndAddRelease(int valueToAdd)
    00353 {
    00354     register int originalValue;
    00355     register int newValue;
    00356     asm volatile(".set push\n"
    00357                  SET_MIPS2
    00358                  "sync\n"
    00359                  "0:\n"
    00360                  "ll %[originalValue], %[_q_value]\n"
    00361                  "addu %[newValue], %[originalValue], %[valueToAdd]\n"
    00362                  "sc %[newValue], %[_q_value]\n"
    00363                  "beqz %[newValue], 0b\n"
    00364                  "nop\n"
    00365                  ".set pop\n"
    00366                  : [originalValue] "=&r" (originalValue),
    00367                    [_q_value] "+m" (_q_value),
    00368                    [newValue] "=&r" (newValue)
    00369                  : [valueToAdd] "r" (valueToAdd)
    00370                  : "cc", "memory");
    00371     return originalValue;
    00372 }
    00373
    00374 inline int QBasicAtomicInt::fetchAndAddOrdered(int valueToAdd)
    00375 {
    00376     return fetchAndAddAcquire(valueToAdd);
    00377 }
    00378
    00379 #if defined(__LP64__)
    00380 #  define LLP "lld"
    00381 #  define SCP "scd"
    00382 #else
    00383 #  define LLP "ll"
    00384 #  define SCP "sc"
    00385 #endif
    00386
    00387 template <typename T>
    00388 Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::testAndSetRelaxed(T *expectedValue, T *newValue)
    00389 {
    00390     register T *result;
    00391     register T *tempValue;
    00392     asm volatile(".set push\n"
    00393                  SET_MIPS2
    00394                  "0:\n"
    00395                  LLP" %[result], %[_q_value]\n"
    00396                  "xor %[result], %[result], %[expectedValue]\n"
    00397                  "bnez %[result], 0f\n"
    00398                  "nop\n"
    00399                  "move %[tempValue], %[newValue]\n"
    00400                  SCP" %[tempValue], %[_q_value]\n"
    00401                  "beqz %[tempValue], 0b\n"
    00402                  "nop\n"
    00403                  "0:\n"
    00404                  ".set pop\n"
    00405                  : [result] "=&r" (result),
    00406                    [tempValue] "=&r" (tempValue),
    00407                    [_q_value] "+m" (_q_value)
    00408                  : [expectedValue] "r" (expectedValue),
    00409                    [newValue] "r" (newValue)
    00410                  : "cc", "memory");
    00411     return result == 0;
    00412 }
    00413
    00414 template <typename T>
    00415 Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::testAndSetAcquire(T *expectedValue, T *newValue)
    00416 {
    00417     register T *result;
    00418     register T *tempValue;
    00419     asm volatile(".set push\n"
    00420                  SET_MIPS2
    00421                  "0:\n"
    00422                  LLP" %[result], %[_q_value]\n"
    00423                  "xor %[result], %[result], %[expectedValue]\n"
    00424                  "bnez %[result], 0f\n"
    00425                  "nop\n"
    00426                  "move %[tempValue], %[newValue]\n"
    00427                  SCP" %[tempValue], %[_q_value]\n"
    00428                  "beqz %[tempValue], 0b\n"
    00429                  "nop\n"
    00430                  "sync\n"
    00431                  "0:\n"
    00432                  ".set pop\n"
    00433                  : [result] "=&r" (result),
    00434                    [tempValue] "=&r" (tempValue),
    00435                    [_q_value] "+m" (_q_value)
    00436                  : [expectedValue] "r" (expectedValue),
    00437                    [newValue] "r" (newValue)
    00438                  : "cc", "memory");
    00439     return result == 0;
    00440 }
    00441
    00442 template <typename T>
    00443 Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::testAndSetRelease(T *expectedValue, T *newValue)
    00444 {
    00445     register T *result;
    00446     register T *tempValue;
    00447     asm volatile(".set push\n"
    00448                  SET_MIPS2
    00449                  "sync\n"
    00450                  "0:\n"
    00451                  LLP" %[result], %[_q_value]\n"
    00452                  "xor %[result], %[result], %[expectedValue]\n"
    00453                  "bnez %[result], 0f\n"
    00454                  "nop\n"
    00455                  "move %[tempValue], %[newValue]\n"
    00456                  SCP" %[tempValue], %[_q_value]\n"
    00457                  "beqz %[tempValue], 0b\n"
    00458                  "nop\n"
    00459                  "0:\n"
    00460                  ".set pop\n"
    00461                  : [result] "=&r" (result),
    00462                    [tempValue] "=&r" (tempValue),
    00463                    [_q_value] "+m" (_q_value)
    00464                  : [expectedValue] "r" (expectedValue),
    00465                    [newValue] "r" (newValue)
    00466                  : "cc", "memory");
    00467     return result == 0;
    00468 }
    00469
    00470 template <typename T>
    00471 Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::testAndSetOrdered(T *expectedValue, T *newValue)
    00472 {
    00473     return testAndSetAcquire(expectedValue, newValue);
    00474 }
    00475
    00476 template <typename T>
    00477 Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndStoreRelaxed(T *newValue)
    00478 {
    00479     register T *originalValue;
    00480     register T *tempValue;
    00481     asm volatile(".set push\n"
    00482                  SET_MIPS2
    00483                  "0:\n"
    00484                  LLP" %[originalValue], %[_q_value]\n"
    00485                  "move %[tempValue], %[newValue]\n"
    00486                  SCP" %[tempValue], %[_q_value]\n"
    00487                  "beqz %[tempValue], 0b\n"
    00488                  "nop\n"
    00489                  ".set pop\n"
    00490                  : [originalValue] "=&r" (originalValue),
    00491                    [tempValue] "=&r" (tempValue),
    00492                    [_q_value] "+m" (_q_value)
    00493                  : [newValue] "r" (newValue)
    00494                  : "cc", "memory");
    00495     return originalValue;
    00496 }
    00497
    00498 template <typename T>
    00499 Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndStoreAcquire(T *newValue)
    00500 {
    00501     register T *originalValue;
    00502     register T *tempValue;
    00503     asm volatile(".set push\n"
    00504                  SET_MIPS2
    00505                  "0:\n"
    00506                  LLP" %[originalValue], %[_q_value]\n"
    00507                  "move %[tempValue], %[newValue]\n"
    00508                  SCP" %[tempValue], %[_q_value]\n"
    00509                  "beqz %[tempValue], 0b\n"
    00510                  "nop\n"
    00511                  "sync\n"
    00512                  ".set pop\n"
    00513                  : [originalValue] "=&r" (originalValue),
    00514                    [tempValue] "=&r" (tempValue),
    00515                    [_q_value] "+m" (_q_value)
    00516                  : [newValue] "r" (newValue)
    00517                  : "cc", "memory");
    00518     return originalValue;
    00519 }
    00520
    00521 template <typename T>
    00522 Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndStoreRelease(T *newValue)
    00523 {
    00524     register T *originalValue;
    00525     register T *tempValue;
    00526     asm volatile(".set push\n"
    00527                  SET_MIPS2
    00528                  "sync\n"
    00529                  "0:\n"
    00530                  LLP" %[originalValue], %[_q_value]\n"
    00531                  "move %[tempValue], %[newValue]\n"
    00532                  SCP" %[tempValue], %[_q_value]\n"
    00533                  "beqz %[tempValue], 0b\n"
    00534                  "nop\n"
    00535                  ".set pop\n"
    00536                  : [originalValue] "=&r" (originalValue),
    00537                    [tempValue] "=&r" (tempValue),
    00538                    [_q_value] "+m" (_q_value)
    00539                  : [newValue] "r" (newValue)
    00540                  : "cc", "memory");
    00541     return originalValue;
    00542 }
    00543
    00544 template <typename T>
    00545 Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndStoreOrdered(T *newValue)
    00546 {
    00547     return fetchAndStoreAcquire(newValue);
    00548 }
    00549
    00550 template <typename T>
    00551 Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndAddRelaxed(qptrdiff valueToAdd)
    00552 {
    00553     register T *originalValue;
    00554     register T *newValue;
    00555     asm volatile(".set push\n"
    00556                  SET_MIPS2
    00557                  "0:\n"
    00558                  LLP" %[originalValue], %[_q_value]\n"
    00559                  "addu %[newValue], %[originalValue], %[valueToAdd]\n"
    00560                  SCP" %[newValue], %[_q_value]\n"
    00561                  "beqz %[newValue], 0b\n"
    00562                  "nop\n"
    00563                  ".set pop\n"
    00564                  : [originalValue] "=&r" (originalValue),
    00565                    [_q_value] "+m" (_q_value),
    00566                    [newValue] "=&r" (newValue)
    00567                  : [valueToAdd] "r" (valueToAdd * sizeof(T))
    00568                  : "cc", "memory");
    00569     return originalValue;
    00570 }
    00571
    00572 template <typename T>
    00573 Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndAddAcquire(qptrdiff valueToAdd)
    00574 {
    00575     register T *originalValue;
    00576     register T *newValue;
    00577     asm volatile(".set push\n"
    00578                  SET_MIPS2
    00579                  "0:\n"
    00580                  LLP" %[originalValue], %[_q_value]\n"
    00581                  "addu %[newValue], %[originalValue], %[valueToAdd]\n"
    00582                  SCP" %[newValue], %[_q_value]\n"
    00583                  "beqz %[newValue], 0b\n"
    00584                  "nop\n"
    00585                  "sync\n"
    00586                  ".set pop\n"
    00587                  : [originalValue] "=&r" (originalValue),
    00588                    [_q_value] "+m" (_q_value),
    00589                    [newValue] "=&r" (newValue)
    00590                  : [valueToAdd] "r" (valueToAdd * sizeof(T))
    00591                  : "cc", "memory");
    00592     return originalValue;
    00593 }
    00594
    00595 template <typename T>
    00596 Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndAddRelease(qptrdiff valueToAdd)
    00597 {
    00598     register T *originalValue;
    00599     register T *newValue;
    00600     asm volatile(".set push\n"
    00601                  SET_MIPS2
    00602                  "sync\n"
    00603                  "0:\n"
    00604                  LLP" %[originalValue], %[_q_value]\n"
    00605                  "addu %[newValue], %[originalValue], %[valueToAdd]\n"
    00606                  SCP" %[newValue], %[_q_value]\n"
    00607                  "beqz %[newValue], 0b\n"
    00608                  "nop\n"
    00609                  ".set pop\n"
    00610                  : [originalValue] "=&r" (originalValue),
    00611                    [_q_value] "+m" (_q_value),
    00612                    [newValue] "=&r" (newValue)
    00613                  : [valueToAdd] "r" (valueToAdd * sizeof(T))
    00614                  : "cc", "memory");
    00615     return originalValue;
    00616 }
    00617
    00618 template <typename T>
    00619 Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndAddOrdered(qptrdiff valueToAdd)
    00620 {
    00621     return fetchAndAddAcquire(valueToAdd);
    00622 }
    00623
    00624 #else // !Q_CC_GNU
    00625
    00626 extern "C" {
    00627     Q_CORE_EXPORT int q_atomic_test_and_set_int(volatile int *ptr, int expected, int newval);
    00628     Q_CORE_EXPORT int q_atomic_test_and_set_acquire_int(volatile int *ptr, int expected, int newval);
    00629     Q_CORE_EXPORT int q_atomic_test_and_set_release_int(volatile int *ptr, int expected, int newval);
    00630     Q_CORE_EXPORT int q_atomic_test_and_set_ptr(volatile void *ptr, void *expected, void *newval);
    00631     Q_CORE_EXPORT int q_atomic_test_and_set_acquire_ptr(volatile void *ptr, void *expected, void *newval);
    00632     Q_CORE_EXPORT int q_atomic_test_and_set_release_ptr(volatile void *ptr, void *expected, void *newval);
    00633 } // extern "C"
    00634
    00635 inline bool QBasicAtomicInt::ref()
    00636 {
    00637     register int expected;
    00638     for (;;) {
    00639         expected = _q_value;
    00640         if (q_atomic_test_and_set_int(&_q_value, expected, expected + 1))
    00641             break;
    00642     }
    00643     return expected != -1;
    00644 }
    00645
    00646 inline bool QBasicAtomicInt::deref()
    00647 {
    00648     register int expected;
    00649     for (;;) {
    00650         expected = _q_value;
    00651         if (q_atomic_test_and_set_int(&_q_value, expected, expected - 1))
    00652             break;
    00653     }
    00654     return expected != 1;
    00655 }
    00656
    00657 inline bool QBasicAtomicInt::testAndSetRelaxed(int expectedValue, int newValue)
    00658 {
    00659     return q_atomic_test_and_set_int(&_q_value, expectedValue, newValue) != 0;
    00660 }
    00661
    00662 inline bool QBasicAtomicInt::testAndSetAcquire(int expectedValue, int newValue)
    00663 {
    00664     return q_atomic_test_and_set_acquire_int(&_q_value, expectedValue, newValue) != 0;
    00665 }
    00666
    00667 inline bool QBasicAtomicInt::testAndSetRelease(int expectedValue, int newValue)
    00668 {
    00669     return q_atomic_test_and_set_release_int(&_q_value, expectedValue, newValue) != 0;
    00670 }
    00671
    00672 inline bool QBasicAtomicInt::testAndSetOrdered(int expectedValue, int newValue)
    00673 {
    00674     return q_atomic_test_and_set_acquire_int(&_q_value, expectedValue, newValue) != 0;
    00675 }
    00676
    00677 inline int QBasicAtomicInt::fetchAndStoreRelaxed(int newValue)
    00678 {
    00679     int returnValue;
    00680     for (;;) {
    00681         returnValue = _q_value;
    00682         if (testAndSetRelaxed(returnValue, newValue))
    00683             break;
    00684     }
    00685     return returnValue;
    00686 }
    00687
    00688 inline int QBasicAtomicInt::fetchAndStoreAcquire(int newValue)
    00689 {
    00690     int returnValue;
    00691     for (;;) {
    00692         returnValue = _q_value;
    00693         if (testAndSetAcquire(returnValue, newValue))
    00694             break;
    00695     }
    00696     return returnValue;
    00697 }
    00698
    00699 inline int QBasicAtomicInt::fetchAndStoreRelease(int newValue)
    00700 {
    00701     int returnValue;
    00702     for (;;) {
    00703         returnValue = _q_value;
    00704         if (testAndSetRelease(returnValue, newValue))
    00705             break;
    00706     }
    00707     return returnValue;
    00708 }
    00709
    00710 inline int QBasicAtomicInt::fetchAndStoreOrdered(int newValue)
    00711 {
    00712     int returnValue;
    00713     for (;;) {
    00714         returnValue = _q_value;
    00715         if (testAndSetOrdered(returnValue, newValue))
    00716             break;
    00717     }
    00718     return returnValue;
    00719 }
    00720
    00721 inline int QBasicAtomicInt::fetchAndAddRelaxed(int valueToAdd)
    00722 {
    00723     int returnValue;
    00724     for (;;) {
    00725         returnValue = _q_value;
    00726         if (testAndSetRelaxed(returnValue, returnValue + valueToAdd))
    00727             break;
    00728     }
    00729     return returnValue;
    00730 }
    00731
    00732 inline int QBasicAtomicInt::fetchAndAddAcquire(int valueToAdd)
    00733 {
    00734     int returnValue;
    00735     for (;;) {
    00736         returnValue = _q_value;
    00737         if (testAndSetAcquire(returnValue, returnValue + valueToAdd))
    00738             break;
    00739     }
    00740     return returnValue;
    00741 }
    00742
    00743 inline int QBasicAtomicInt::fetchAndAddRelease(int valueToAdd)
    00744 {
    00745     int returnValue;
    00746     for (;;) {
    00747         returnValue = _q_value;
    00748         if (testAndSetRelease(returnValue, returnValue + valueToAdd))
    00749             break;
    00750     }
    00751     return returnValue;
    00752 }
    00753
    00754 inline int QBasicAtomicInt::fetchAndAddOrdered(int valueToAdd)
    00755 {
    00756     int returnValue;
    00757     for (;;) {
    00758         returnValue = _q_value;
    00759         if (testAndSetOrdered(returnValue, returnValue + valueToAdd))
    00760             break;
    00761     }
    00762     return returnValue;
    00763 }
    00764
    00765 template <typename T>
    00766 Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::testAndSetRelaxed(T *expectedValue, T *newValue)
    00767 {
    00768     return q_atomic_test_and_set_ptr(&_q_value, expectedValue, newValue) != 0;
    00769 }
    00770
    00771 template <typename T>
    00772 Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::testAndSetAcquire(T *expectedValue, T *newValue)
    00773 {
    00774     return q_atomic_test_and_set_acquire_ptr(&_q_value, expectedValue, newValue) != 0;
    00775 }
    00776
    00777 template <typename T>
    00778 Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::testAndSetRelease(T *expectedValue, T *newValue)
    00779 {
    00780     return q_atomic_test_and_set_release_ptr(&_q_value, expectedValue, newValue) != 0;
    00781 }
    00782
    00783 template <typename T>
    00784 Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::testAndSetOrdered(T *expectedValue, T *newValue)
    00785 {
    00786     return q_atomic_test_and_set_acquire_ptr(&_q_value, expectedValue, newValue) != 0;
    00787 }
    00788
    00789 template <typename T>
    00790 Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndStoreRelaxed(T *newValue)
    00791 {
    00792     T *returnValue;
    00793     for (;;) {
    00794         returnValue = (_q_value);
    00795         if (testAndSetRelaxed(returnValue, newValue))
    00796             break;
    00797     }
    00798     return returnValue;
    00799 }
    00800
    00801 template <typename T>
    00802 Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndStoreAcquire(T *newValue)
    00803 {
    00804     T *returnValue;
    00805     for (;;) {
    00806         returnValue = (_q_value);
    00807         if (testAndSetAcquire(returnValue, newValue))
    00808             break;
    00809     }
    00810     return returnValue;
    00811 }
    00812
    00813 template <typename T>
    00814 Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndStoreRelease(T *newValue)
    00815 {
    00816     T *returnValue;
    00817     for (;;) {
    00818         returnValue = (_q_value);
    00819         if (testAndSetRelease(returnValue, newValue))
    00820             break;
    00821     }
    00822     return returnValue;
    00823 }
    00824
    00825 template <typename T>
    00826 Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndStoreOrdered(T *newValue)
    00827 {
    00828     T *returnValue;
    00829     for (;;) {
    00830         returnValue = (_q_value);
    00831         if (testAndSetOrdered(returnValue, newValue))
    00832             break;
    00833     }
    00834     return returnValue;
    00835 }
    00836
    00837 template <typename T>
    00838 Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndAddRelaxed(qptrdiff valueToAdd)
    00839 {
    00840     T *returnValue;
    00841     for (;;) {
    00842         returnValue = (_q_value);
    00843         if (testAndSetRelaxed(returnValue, returnValue + valueToAdd))
    00844             break;
    00845     }
    00846     return returnValue;
    00847 }
    00848
    00849 template <typename T>
    00850 Q_INLINE_TEMPLATE
    00851 T *QBasicAtomicPointer<T>::fetchAndAddAcquire(qptrdiff valueToAdd)
    00852 {
    00853     T *returnValue;
    00854     for (;;) {
    00855         returnValue = (_q_value);
    00856         if (testAndSetAcquire(returnValue, returnValue + valueToAdd))
    00857             break;
    00858     }
    00859     return returnValue;
    00860 }
    00861
    00862 template <typename T>
    00863 Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndAddRelease(qptrdiff valueToAdd)
    00864 {
    00865     T *returnValue;
    00866     for (;;) {
    00867         returnValue = (_q_value);
    00868         if (testAndSetRelease(returnValue, returnValue + valueToAdd))
    00869             break;
    00870     }
    00871     return returnValue;
    00872 }
    00873
    00874 template <typename T>
    00875 Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndAddOrdered(qptrdiff valueToAdd)
    00876 {
    00877     T *returnValue;
    00878     for (;;) {
    00879         returnValue = (_q_value);
    00880         if (testAndSetOrdered(returnValue, returnValue + valueToAdd))
    00881             break;
    00882     }
    00883     return returnValue;
    00884 }
    00885
    00886 #endif // Q_CC_GNU
    00887
    00888 QT_END_NAMESPACE
    00889
    00890 QT_END_HEADER
    00891
    00892 #endif // QATOMIC_MIPS_H