summaryrefslogtreecommitdiffstats
path: root/src/corelib/arch
diff options
context:
space:
mode:
Diffstat (limited to 'src/corelib/arch')
-rw-r--r--src/corelib/arch/alpha/arch.pri4
-rw-r--r--src/corelib/arch/alpha/qatomic_alpha.s199
-rw-r--r--src/corelib/arch/arch.pri26
-rw-r--r--src/corelib/arch/arm/arch.pri4
-rw-r--r--src/corelib/arch/arm/qatomic_arm.cpp72
-rw-r--r--src/corelib/arch/armv6/arch.pri3
-rw-r--r--src/corelib/arch/avr32/arch.pri3
-rw-r--r--src/corelib/arch/bfin/arch.pri3
-rw-r--r--src/corelib/arch/generic/arch.pri6
-rw-r--r--src/corelib/arch/generic/qatomic_generic_unix.cpp118
-rw-r--r--src/corelib/arch/generic/qatomic_generic_windows.cpp131
-rw-r--r--src/corelib/arch/i386/arch.pri4
-rw-r--r--src/corelib/arch/i386/qatomic_i386.s103
-rw-r--r--src/corelib/arch/ia64/arch.pri4
-rw-r--r--src/corelib/arch/ia64/qatomic_ia64.s34
-rw-r--r--src/corelib/arch/macosx/arch.pri7
-rw-r--r--src/corelib/arch/macosx/qatomic32_ppc.s129
-rw-r--r--src/corelib/arch/mips/arch.pri8
-rw-r--r--src/corelib/arch/mips/qatomic_mips32.s110
-rw-r--r--src/corelib/arch/mips/qatomic_mips64.s98
-rw-r--r--src/corelib/arch/parisc/arch.pri5
-rw-r--r--src/corelib/arch/parisc/q_ldcw.s22
-rw-r--r--src/corelib/arch/parisc/qatomic_parisc.cpp88
-rw-r--r--src/corelib/arch/powerpc/arch.pri10
-rw-r--r--src/corelib/arch/powerpc/qatomic32.s485
-rw-r--r--src/corelib/arch/powerpc/qatomic64.s493
-rw-r--r--src/corelib/arch/qatomic_alpha.h642
-rw-r--r--src/corelib/arch/qatomic_arch.h93
-rw-r--r--src/corelib/arch/qatomic_arm.h401
-rw-r--r--src/corelib/arch/qatomic_armv6.h360
-rw-r--r--src/corelib/arch/qatomic_avr32.h252
-rw-r--r--src/corelib/arch/qatomic_bfin.h343
-rw-r--r--src/corelib/arch/qatomic_bootstrap.h99
-rw-r--r--src/corelib/arch/qatomic_generic.h282
-rw-r--r--src/corelib/arch/qatomic_i386.h361
-rw-r--r--src/corelib/arch/qatomic_ia64.h813
-rw-r--r--src/corelib/arch/qatomic_macosx.h57
-rw-r--r--src/corelib/arch/qatomic_mips.h826
-rw-r--r--src/corelib/arch/qatomic_parisc.h305
-rw-r--r--src/corelib/arch/qatomic_powerpc.h650
-rw-r--r--src/corelib/arch/qatomic_s390.h430
-rw-r--r--src/corelib/arch/qatomic_sh.h330
-rw-r--r--src/corelib/arch/qatomic_sh4a.h537
-rw-r--r--src/corelib/arch/qatomic_sparc.h525
-rw-r--r--src/corelib/arch/qatomic_windows.h564
-rw-r--r--src/corelib/arch/qatomic_windowsce.h56
-rw-r--r--src/corelib/arch/qatomic_x86_64.h363
-rw-r--r--src/corelib/arch/s390/arch.pri3
-rw-r--r--src/corelib/arch/sh/arch.pri4
-rw-r--r--src/corelib/arch/sh/qatomic_sh.cpp72
-rw-r--r--src/corelib/arch/sh4a/arch.pri3
-rw-r--r--src/corelib/arch/sparc/arch.pri10
-rw-r--r--src/corelib/arch/sparc/qatomic32.s63
-rw-r--r--src/corelib/arch/sparc/qatomic64.s287
-rw-r--r--src/corelib/arch/sparc/qatomic_sparc.cpp92
-rw-r--r--src/corelib/arch/windows/arch.pri3
-rw-r--r--src/corelib/arch/x86_64/arch.pri4
-rw-r--r--src/corelib/arch/x86_64/qatomic_sun.s91
58 files changed, 11090 insertions, 0 deletions
diff --git a/src/corelib/arch/alpha/arch.pri b/src/corelib/arch/alpha/arch.pri
new file mode 100644
index 0000000000..448a531f07
--- /dev/null
+++ b/src/corelib/arch/alpha/arch.pri
@@ -0,0 +1,4 @@
+#
+# Alpha architecture
+#
+!*-g++*:SOURCES += $$QT_ARCH_CPP/qatomic_alpha.s
diff --git a/src/corelib/arch/alpha/qatomic_alpha.s b/src/corelib/arch/alpha/qatomic_alpha.s
new file mode 100644
index 0000000000..9363b35daf
--- /dev/null
+++ b/src/corelib/arch/alpha/qatomic_alpha.s
@@ -0,0 +1,199 @@
+ .set noreorder
+ .set volatile
+ .set noat
+ .arch ev4
+ .text
+ .align 2
+ .align 4
+ .globl q_atomic_test_and_set_int
+ .ent q_atomic_test_and_set_int
+q_atomic_test_and_set_int:
+ .frame $30,0,$26,0
+ .prologue 0
+1: ldl_l $0,0($16)
+ cmpeq $0,$17,$0
+ beq $0,3f
+ mov $18,$0
+ stl_c $0,0($16)
+ beq $0,2f
+ br 3f
+2: br 1b
+3: addl $31,$0,$0
+ ret $31,($26),1
+ .end q_atomic_test_and_set_int
+ .align 2
+ .align 4
+ .globl q_atomic_test_and_set_acquire_int
+ .ent q_atomic_test_and_set_acquire_int
+q_atomic_test_and_set_acquire_int:
+ .frame $30,0,$26,0
+ .prologue 0
+1: ldl_l $0,0($16)
+ cmpeq $0,$17,$0
+ beq $0,3f
+ mov $18,$0
+ stl_c $0,0($16)
+ beq $0,2f
+ br 3f
+2: br 1b
+3: mb
+ addl $31,$0,$0
+ ret $31,($26),1
+ .end q_atomic_test_and_set_acquire_int
+ .align 2
+ .align 4
+ .globl q_atomic_test_and_set_release_int
+ .ent q_atomic_test_and_set_release_int
+q_atomic_test_and_set_release_int:
+ .frame $30,0,$26,0
+ .prologue 0
+ mb
+1: ldl_l $0,0($16)
+ cmpeq $0,$17,$0
+ beq $0,3f
+ mov $18,$0
+ stl_c $0,0($16)
+ beq $0,2f
+ br 3f
+2: br 1b
+3: addl $31,$0,$0
+ ret $31,($26),1
+ .end q_atomic_test_and_set_release_int
+ .align 2
+ .align 4
+ .globl q_atomic_test_and_set_ptr
+ .ent q_atomic_test_and_set_ptr
+q_atomic_test_and_set_ptr:
+ .frame $30,0,$26,0
+ .prologue 0
+1: ldq_l $0,0($16)
+ cmpeq $0,$17,$0
+ beq $0,3f
+ mov $18,$0
+ stq_c $0,0($16)
+ beq $0,2f
+ br 3f
+2: br 1b
+3: addl $31,$0,$0
+ ret $31,($26),1
+ .end q_atomic_test_and_set_ptr
+ .align 2
+ .align 4
+ .globl q_atomic_increment
+ .ent q_atomic_increment
+q_atomic_increment:
+ .frame $30,0,$26,0
+ .prologue 0
+1: ldl_l $0,0($16)
+ addl $0,1,$1
+ stl_c $1,0($16)
+ beq $1,2f
+ br 3f
+2: br 1b
+3: addl $31,$0,$0
+ cmpeq $0,$1,$0
+ xor $0,1,$0
+ ret $31,($26),1
+ .end q_atomic_increment
+ .align 2
+ .align 4
+ .globl q_atomic_decrement
+ .ent q_atomic_decrement
+q_atomic_decrement:
+ .frame $30,0,$26,0
+ .prologue 0
+1: ldl_l $0,0($16)
+ subl $0,1,$1
+ stl_c $1,0($16)
+ beq $1,2f
+ br 3f
+2: br 1b
+3: addl $31,$0,$0
+ cmpeq $0,1,$0
+ xor $0,1,$0
+ ret $31,($26),1
+ .end q_atomic_decrement
+ .align 2
+ .align 4
+ .globl q_atomic_set_int
+ .ent q_atomic_set_int
+q_atomic_set_int:
+ .frame $30,0,$26,0
+ .prologue 0
+1: ldl_l $0,0($16)
+ mov $17,$1
+ stl_c $1,0($16)
+ beq $1,2f
+ br 3f
+2: br 1b
+3: addl $31,$0,$0
+ ret $31,($26),1
+ .end q_atomic_set_int
+ .align 2
+ .align 4
+ .globl q_atomic_set_ptr
+ .ent q_atomic_set_ptr
+q_atomic_set_ptr:
+ .frame $30,0,$26,0
+ .prologue 0
+1: ldq_l $0,0($16)
+ mov $17,$1
+ stq_c $1,0($16)
+ beq $1,2f
+ br 3f
+2: br 1b
+3: ret $31,($26),1
+ .end q_atomic_set_ptr
+
+ .align 2
+ .align 4
+ .globl q_atomic_fetch_and_add_int
+ .ent q_atomic_fetch_and_add_int
+q_atomic_fetch_and_add_int:
+ .frame $30,0,$26,0
+ .prologue 0
+1: ldl_l $0,0($16)
+ addl $0,$17,$1
+ stl_c $1,0($16)
+ beq $1,2f
+ br 3f
+2: br 1b
+3: addl $31,$0,$0
+ ret $31,($26),1
+ .end q_atomic_fetch_and_add_int
+
+ .align 2
+ .align 4
+ .globl q_atomic_fetch_and_add_acquire_int
+ .ent q_atomic_fetch_and_add_acquire_int
+q_atomic_fetch_and_add_acquire_int:
+ .frame $30,0,$26,0
+ .prologue 0
+1: ldl_l $0,0($16)
+ addl $0,$17,$1
+ stl_c $1,0($16)
+ beq $1,2f
+ br 3f
+2: br 1b
+3: mb
+ addl $31,$0,$0
+ ret $31,($26),1
+ .end q_atomic_fetch_and_add_acquire_int
+
+ .align 2
+ .align 4
+ .globl q_atomic_fetch_and_add_release_int
+ .ent q_atomic_fetch_and_add_release_int
+q_atomic_fetch_and_add_release_int:
+ .frame $30,0,$26,0
+ .prologue 0
+ mb
+1: ldl_l $0,0($16)
+ addl $0,$17,$1
+ stl_c $1,0($16)
+ beq $1,2f
+ br 3f
+2: br 1b
+3: addl $31,$0,$0
+ ret $31,($26),1
+ .end q_atomic_fetch_and_add_release_int
diff --git a/src/corelib/arch/arch.pri b/src/corelib/arch/arch.pri
new file mode 100644
index 0000000000..20b9227ee7
--- /dev/null
+++ b/src/corelib/arch/arch.pri
@@ -0,0 +1,26 @@
+win32:HEADERS += arch/qatomic_windows.h \
+ arch/qatomic_generic.h
+
+mac:HEADERS += arch/qatomic_macosx.h \
+ arch/qatomic_generic.h
+
+!wince*:!win32:!mac:HEADERS += arch/qatomic_alpha.h \
+ arch/qatomic_avr32.h \
+ arch/qatomic_ia64.h \
+ arch/qatomic_parisc.h \
+ arch/qatomic_sparc.h \
+ arch/qatomic_arch.h \
+ arch/qatomic_generic.h \
+ arch/qatomic_powerpc.h \
+ arch/qatomic_arm.h \
+ arch/qatomic_armv6.h \
+ arch/qatomic_i386.h \
+ arch/qatomic_mips.h \
+ arch/qatomic_s390.h \
+ arch/qatomic_x86_64.h \
+ arch/qatomic_sh.h \
+ arch/qatomic_sh4a.h
+
+QT_ARCH_CPP = $$QT_SOURCE_TREE/src/corelib/arch/$$QT_ARCH
+DEPENDPATH += $$QT_ARCH_CPP
+include($$QT_ARCH_CPP/arch.pri)
diff --git a/src/corelib/arch/arm/arch.pri b/src/corelib/arch/arm/arch.pri
new file mode 100644
index 0000000000..79e4bfc115
--- /dev/null
+++ b/src/corelib/arch/arm/arch.pri
@@ -0,0 +1,4 @@
+#
+# ARM architecture
+#
+SOURCES += $$QT_ARCH_CPP/qatomic_arm.cpp
diff --git a/src/corelib/arch/arm/qatomic_arm.cpp b/src/corelib/arch/arm/qatomic_arm.cpp
new file mode 100644
index 0000000000..901c181b01
--- /dev/null
+++ b/src/corelib/arch/arm/qatomic_arm.cpp
@@ -0,0 +1,72 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtCore module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QtCore/qglobal.h>
+
+#include <unistd.h>
+#ifdef _POSIX_PRIORITY_SCHEDULING
+# include <sched.h>
+#endif
+#include <time.h>
+
+QT_BEGIN_NAMESPACE
+
+QT_USE_NAMESPACE
+
+Q_CORE_EXPORT char q_atomic_lock = 0;
+
+Q_CORE_EXPORT void qt_atomic_yield(int *count)
+{
+#ifdef _POSIX_PRIORITY_SCHEDULING
+ if((*count)++ < 50) {
+ sched_yield();
+ } else
+#endif
+ {
+ struct timespec tm;
+ tm.tv_sec = 0;
+ tm.tv_nsec = 2000001;
+ nanosleep(&tm, NULL);
+ *count = 0;
+ }
+}
+
+QT_END_NAMESPACE
diff --git a/src/corelib/arch/armv6/arch.pri b/src/corelib/arch/armv6/arch.pri
new file mode 100644
index 0000000000..fd0cce1520
--- /dev/null
+++ b/src/corelib/arch/armv6/arch.pri
@@ -0,0 +1,3 @@
+#
+# ARMv6
+#
diff --git a/src/corelib/arch/avr32/arch.pri b/src/corelib/arch/avr32/arch.pri
new file mode 100644
index 0000000000..37f231ee61
--- /dev/null
+++ b/src/corelib/arch/avr32/arch.pri
@@ -0,0 +1,3 @@
+#
+# AVR32 architecture
+#
diff --git a/src/corelib/arch/bfin/arch.pri b/src/corelib/arch/bfin/arch.pri
new file mode 100644
index 0000000000..fa198ae8bb
--- /dev/null
+++ b/src/corelib/arch/bfin/arch.pri
@@ -0,0 +1,3 @@
+#
+# Blackfin architecture
+#
diff --git a/src/corelib/arch/generic/arch.pri b/src/corelib/arch/generic/arch.pri
new file mode 100644
index 0000000000..8fee63fa5d
--- /dev/null
+++ b/src/corelib/arch/generic/arch.pri
@@ -0,0 +1,6 @@
+#
+# 'generic' architecture
+#
+
+unix:SOURCES += qatomic_generic_unix.cpp
+win32:SOURCES += qatomic_generic_windows.cpp
diff --git a/src/corelib/arch/generic/qatomic_generic_unix.cpp b/src/corelib/arch/generic/qatomic_generic_unix.cpp
new file mode 100644
index 0000000000..15918bec87
--- /dev/null
+++ b/src/corelib/arch/generic/qatomic_generic_unix.cpp
@@ -0,0 +1,118 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtCore module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qplatformdefs.h"
+
+#include <QtCore/qatomic.h>
+
+static pthread_mutex_t qAtomicMutex = PTHREAD_MUTEX_INITIALIZER;
+
+Q_CORE_EXPORT
+bool QBasicAtomicInt_testAndSetOrdered(volatile int *_q_value, int expectedValue, int newValue)
+{
+ bool returnValue = false;
+ pthread_mutex_lock(&qAtomicMutex);
+ if (*_q_value == expectedValue) {
+ *_q_value = newValue;
+ returnValue = true;
+ }
+ pthread_mutex_unlock(&qAtomicMutex);
+ return returnValue;
+}
+
+Q_CORE_EXPORT
+int QBasicAtomicInt_fetchAndStoreOrdered(volatile int *_q_value, int newValue)
+{
+ int returnValue;
+ pthread_mutex_lock(&qAtomicMutex);
+ returnValue = *_q_value;
+ *_q_value = newValue;
+ pthread_mutex_unlock(&qAtomicMutex);
+ return returnValue;
+}
+
+Q_CORE_EXPORT
+int QBasicAtomicInt_fetchAndAddOrdered(volatile int *_q_value, int valueToAdd)
+{
+ int returnValue;
+ pthread_mutex_lock(&qAtomicMutex);
+ returnValue = *_q_value;
+ *_q_value += valueToAdd;
+ pthread_mutex_unlock(&qAtomicMutex);
+ return returnValue;
+}
+
+Q_CORE_EXPORT
+bool QBasicAtomicPointer_testAndSetOrdered(void * volatile *_q_value,
+ void *expectedValue,
+ void *newValue)
+{
+ bool returnValue = false;
+ pthread_mutex_lock(&qAtomicMutex);
+ if (*_q_value == expectedValue) {
+ *_q_value = newValue;
+ returnValue = true;
+ }
+ pthread_mutex_unlock(&qAtomicMutex);
+ return returnValue;
+}
+
+Q_CORE_EXPORT
+void *QBasicAtomicPointer_fetchAndStoreOrdered(void * volatile *_q_value, void *newValue)
+{
+ void *returnValue;
+ pthread_mutex_lock(&qAtomicMutex);
+ returnValue = *_q_value;
+ *_q_value = newValue;
+ pthread_mutex_unlock(&qAtomicMutex);
+ return returnValue;
+}
+
+Q_CORE_EXPORT
+void *QBasicAtomicPointer_fetchAndAddOrdered(void * volatile *_q_value, qptrdiff valueToAdd)
+{
+ void *returnValue;
+ pthread_mutex_lock(&qAtomicMutex);
+ returnValue = *_q_value;
+ *_q_value = reinterpret_cast<char *>(returnValue) + valueToAdd;
+ pthread_mutex_unlock(&qAtomicMutex);
+ return returnValue;
+}
diff --git a/src/corelib/arch/generic/qatomic_generic_windows.cpp b/src/corelib/arch/generic/qatomic_generic_windows.cpp
new file mode 100644
index 0000000000..13ef767728
--- /dev/null
+++ b/src/corelib/arch/generic/qatomic_generic_windows.cpp
@@ -0,0 +1,131 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtCore module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qplatformdefs.h"
+
+#include <QtCore/qatomic.h>
+
+
+class QCriticalSection
+{
+public:
+ QCriticalSection() { InitializeCriticalSection(&section); }
+ ~QCriticalSection() { DeleteCriticalSection(&section); }
+ void lock() { EnterCriticalSection(&section); }
+ void unlock() { LeaveCriticalSection(&section); }
+
+private:
+ CRITICAL_SECTION section;
+};
+
+static QCriticalSection qAtomicCriticalSection;
+
+Q_CORE_EXPORT
+bool QBasicAtomicInt_testAndSetOrdered(volatile int *_q_value, int expectedValue, int newValue)
+{
+ bool returnValue = false;
+ qAtomicCriticalSection.lock();
+ if (*_q_value == expectedValue) {
+ *_q_value = newValue;
+ returnValue = true;
+ }
+ qAtomicCriticalSection.unlock();
+ return returnValue;
+}
+
+Q_CORE_EXPORT
+int QBasicAtomicInt_fetchAndStoreOrdered(volatile int *_q_value, int newValue)
+{
+ int returnValue;
+ qAtomicCriticalSection.lock();
+ returnValue = *_q_value;
+ *_q_value = newValue;
+ qAtomicCriticalSection.unlock();
+ return returnValue;
+}
+
+Q_CORE_EXPORT
+int QBasicAtomicInt_fetchAndAddOrdered(volatile int *_q_value, int valueToAdd)
+{
+ int returnValue;
+ qAtomicCriticalSection.lock();
+ returnValue = *_q_value;
+ *_q_value += valueToAdd;
+ qAtomicCriticalSection.unlock();
+ return returnValue;
+}
+
+Q_CORE_EXPORT
+bool QBasicAtomicPointer_testAndSetOrdered(void * volatile *_q_value,
+ void *expectedValue,
+ void *newValue)
+{
+ bool returnValue = false;
+ qAtomicCriticalSection.lock();
+ if (*_q_value == expectedValue) {
+ *_q_value = newValue;
+ returnValue = true;
+ }
+ qAtomicCriticalSection.unlock();
+ return returnValue;
+}
+
+Q_CORE_EXPORT
+void *QBasicAtomicPointer_fetchAndStoreOrdered(void * volatile *_q_value, void *newValue)
+{
+ void *returnValue;
+ qAtomicCriticalSection.lock();
+ returnValue = *_q_value;
+ *_q_value = newValue;
+ qAtomicCriticalSection.unlock();
+ return returnValue;
+}
+
+Q_CORE_EXPORT
+void *QBasicAtomicPointer_fetchAndAddOrdered(void * volatile *_q_value, qptrdiff valueToAdd)
+{
+ void *returnValue;
+ qAtomicCriticalSection.lock();
+ returnValue = *_q_value;
+ *_q_value = reinterpret_cast<char *>(returnValue) + valueToAdd;
+ qAtomicCriticalSection.unlock();
+ return returnValue;
+}
diff --git a/src/corelib/arch/i386/arch.pri b/src/corelib/arch/i386/arch.pri
new file mode 100644
index 0000000000..3101dae01b
--- /dev/null
+++ b/src/corelib/arch/i386/arch.pri
@@ -0,0 +1,4 @@
+#
+# i386 architecture
+#
+!*-g++*:!*-icc*:SOURCES += $$QT_ARCH_CPP/qatomic_i386.s
diff --git a/src/corelib/arch/i386/qatomic_i386.s b/src/corelib/arch/i386/qatomic_i386.s
new file mode 100644
index 0000000000..08158f926b
--- /dev/null
+++ b/src/corelib/arch/i386/qatomic_i386.s
@@ -0,0 +1,103 @@
+ .text
+
+ .align 4,0x90
+ .globl q_atomic_test_and_set_int
+q_atomic_test_and_set_int:
+ movl 4(%esp),%ecx
+ movl 8(%esp),%eax
+ movl 12(%esp),%edx
+ lock
+ cmpxchgl %edx,(%ecx)
+ mov $0,%eax
+ sete %al
+ ret
+ .align 4,0x90
+ .type q_atomic_test_and_set_int,@function
+ .size q_atomic_test_and_set_int,.-q_atomic_test_and_set_int
+
+ .align 4,0x90
+ .globl q_atomic_test_and_set_ptr
+q_atomic_test_and_set_ptr:
+ movl 4(%esp),%ecx
+ movl 8(%esp),%eax
+ movl 12(%esp),%edx
+ lock
+ cmpxchgl %edx,(%ecx)
+ mov $0,%eax
+ sete %al
+ ret
+ .align 4,0x90
+ .type q_atomic_test_and_set_ptr,@function
+ .size q_atomic_test_and_set_ptr,.-q_atomic_test_and_set_ptr
+
+ .align 4,0x90
+ .globl q_atomic_increment
+q_atomic_increment:
+ movl 4(%esp), %ecx
+ lock
+ incl (%ecx)
+ mov $0,%eax
+ setne %al
+ ret
+ .align 4,0x90
+ .type q_atomic_increment,@function
+ .size q_atomic_increment,.-q_atomic_increment
+
+ .align 4,0x90
+ .globl q_atomic_decrement
+q_atomic_decrement:
+ movl 4(%esp), %ecx
+ lock
+ decl (%ecx)
+ mov $0,%eax
+ setne %al
+ ret
+ .align 4,0x90
+ .type q_atomic_decrement,@function
+ .size q_atomic_decrement,.-q_atomic_decrement
+
+ .align 4,0x90
+ .globl q_atomic_set_int
+q_atomic_set_int:
+ mov 4(%esp),%ecx
+ mov 8(%esp),%eax
+ xchgl %eax,(%ecx)
+ ret
+ .align 4,0x90
+ .type q_atomic_set_int,@function
+ .size q_atomic_set_int,.-q_atomic_set_int
+
+ .align 4,0x90
+ .globl q_atomic_set_ptr
+q_atomic_set_ptr:
+ mov 4(%esp),%ecx
+ mov 8(%esp),%eax
+ xchgl %eax,(%ecx)
+ ret
+ .align 4,0x90
+ .type q_atomic_set_ptr,@function
+ .size q_atomic_set_ptr,.-q_atomic_set_ptr
+
+ .align 4,0x90
+ .globl q_atomic_fetch_and_add_int
+q_atomic_fetch_and_add_int:
+ mov 4(%esp),%ecx
+ mov 8(%esp),%eax
+ lock
+ xadd %eax,(%ecx)
+ ret
+ .align 4,0x90
+ .type q_atomic_fetch_and_add_int,@function
+ .size q_atomic_fetch_and_add_int,.-q_atomic_fetch_and_add_int
+
+ .align 4,0x90
+ .globl q_atomic_fetch_and_add_ptr
+q_atomic_fetch_and_add_ptr:
+ mov 4(%esp),%ecx
+ mov 8(%esp),%eax
+ lock
+ xadd %eax,(%ecx)
+ ret
+ .align 4,0x90
+ .type q_atomic_fetch_and_add_ptr,@function
+ .size q_atomic_fetch_and_add_ptr,.-q_atomic_fetch_and_add_ptr
diff --git a/src/corelib/arch/ia64/arch.pri b/src/corelib/arch/ia64/arch.pri
new file mode 100644
index 0000000000..63afa967a4
--- /dev/null
+++ b/src/corelib/arch/ia64/arch.pri
@@ -0,0 +1,4 @@
+#
+# Intel Itanium architecture
+#
+!*-g++:!*-icc:!hpuxi-acc-*:SOURCES += $$QT_ARCH_CPP/qatomic_ia64.s
diff --git a/src/corelib/arch/ia64/qatomic_ia64.s b/src/corelib/arch/ia64/qatomic_ia64.s
new file mode 100644
index 0000000000..6b8a204427
--- /dev/null
+++ b/src/corelib/arch/ia64/qatomic_ia64.s
@@ -0,0 +1,34 @@
+ .pred.safe_across_calls p1-p5,p16-p63
+.text
+ .align 16
+ .global q_atomic_test_and_set_int#
+ .proc q_atomic_test_and_set_int#
+q_atomic_test_and_set_int:
+ .prologue
+ .body
+ mov ar.ccv=r33
+ ;;
+ cmpxchg4.acq r34=[r32],r34,ar.ccv
+ ;;
+ cmp4.eq p6, p7 = r33, r34
+ ;;
+ (p6) addl r8 = 1, r0
+ (p7) mov r8 = r0
+ br.ret.sptk.many b0
+ .endp q_atomic_test_and_set_int#
+ .align 16
+ .global q_atomic_test_and_set_ptr#
+ .proc q_atomic_test_and_set_ptr#
+q_atomic_test_and_set_ptr:
+ .prologue
+ .body
+ mov ar.ccv=r33
+ ;;
+ cmpxchg8.acq r34=[r32],r34,ar.ccv
+ ;;
+ cmp.eq p6, p7 = r33, r34
+ ;;
+ (p6) addl r8 = 1, r0
+ (p7) mov r8 = r0
+ br.ret.sptk.many b0
+ .endp q_atomic_test_and_set_ptr#
diff --git a/src/corelib/arch/macosx/arch.pri b/src/corelib/arch/macosx/arch.pri
new file mode 100644
index 0000000000..e42a9622aa
--- /dev/null
+++ b/src/corelib/arch/macosx/arch.pri
@@ -0,0 +1,7 @@
+#
+# Mac OS X architecture
+#
+!*-icc*:!*-g++* {
+ contains($$list($$system(uname -m)), .*86):SOURCES += $$QT_ARCH_CPP/../i386/qatomic.s
+ else:SOURCES += $$QT_ARCH_CPP/../powerpc/qatomic32.s
+}
diff --git a/src/corelib/arch/macosx/qatomic32_ppc.s b/src/corelib/arch/macosx/qatomic32_ppc.s
new file mode 100644
index 0000000000..13fff67522
--- /dev/null
+++ b/src/corelib/arch/macosx/qatomic32_ppc.s
@@ -0,0 +1,129 @@
+ .section __TEXT,__text,regular,pure_instructions
+ .section __TEXT,__picsymbolstub1,symbol_stubs,pure_instructions,32
+ .section __TEXT,__text,regular,pure_instructions
+ .align 2
+ .align 2
+ .globl _q_atomic_test_and_set_int
+ .section __TEXT,__text,regular,pure_instructions
+ .align 2
+_q_atomic_test_and_set_int:
+ lwarx r6,0,r3
+ cmpw r6,r4
+ bne- $+20
+ stwcx. r5,0,r3
+ bne- $-16
+ addi r3,0,1
+ blr
+ addi r3,0,0
+ blr
+
+ .align 2
+ .globl _q_atomic_test_and_set_acquire_int
+ .section __TEXT,__text,regular,pure_instructions
+ .align 2
+_q_atomic_test_and_set_acquire_int:
+ lwarx r6,0,r3
+ cmpw r6,r4
+ bne- $+20
+ stwcx. r5,0,r3
+ bne- $-16
+ addi r3,0,1
+ b $+8
+ addi r3,0,0
+ eieio
+ blr
+
+ .align 2
+ .globl _q_atomic_test_and_set_release_int
+ .section __TEXT,__text,regular,pure_instructions
+ .align 2
+_q_atomic_test_and_set_release_int:
+ eieio
+ lwarx r6,0,r3
+ cmpw r6,r4
+ bne- $+20
+ stwcx. r5,0,r3
+ bne- $-16
+ addi r3,0,1
+ blr
+ addi r3,0,0
+ blr
+
+ .align 2
+ .globl _q_atomic_test_and_set_ptr
+ .section __TEXT,__text,regular,pure_instructions
+ .align 2
+_q_atomic_test_and_set_ptr:
+ lwarx r6,0,r3
+ cmpw r6,r4
+ bne- $+20
+ stwcx. r5,0,r3
+ bne- $-16
+ addi r3,0,1
+ blr
+ addi r3,0,0
+ blr
+
+ .align 2
+ .globl _q_atomic_increment
+ .section __TEXT,__text,regular,pure_instructions
+ .align 2
+_q_atomic_increment:
+ lwarx r4,0,r3
+ addi r4,r4,1
+ stwcx. r4,0,r3
+ bne- $-12
+ mr r3,r4
+ blr
+
+ .align 2
+ .globl _q_atomic_decrement
+ .section __TEXT,__text,regular,pure_instructions
+ .align 2
+_q_atomic_decrement:
+ lwarx r4,0,r3
+ subi r4,r4,1
+ stwcx. r4,0,r3
+ bne- $-12
+ mr r3,r4
+ blr
+
+ .align 2
+ .globl _q_atomic_set_int
+ .section __TEXT,__text,regular,pure_instructions
+ .align 2
+_q_atomic_set_int:
+ lwarx r5,0,r3
+ stwcx. r4,0,r3
+ bne- $-8
+ mr r3,r5
+ blr
+
+ .align 2
+ .globl _q_atomic_set_ptr
+ .section __TEXT,__text,regular,pure_instructions
+ .align 2
+_q_atomic_set_ptr:
+ lwarx r5,0,r3
+ stwcx. r4,0,r3
+ bne- $-8
+ mr r3,r5
+ blr
+
+.globl q_atomic_test_and_set_int.eh
+ q_atomic_test_and_set_int.eh = 0
+.globl q_atomic_test_and_set_ptr.eh
+ q_atomic_test_and_set_ptr.eh = 0
+.globl q_atomic_increment.eh
+ q_atomic_increment.eh = 0
+.globl q_atomic_decrement.eh
+ q_atomic_decrement.eh = 0
+.globl q_atomic_set_int.eh
+ q_atomic_set_int.eh = 0
+.globl q_atomic_set_ptr.eh
+ q_atomic_set_ptr.eh = 0
+.data
+.constructor
+.data
+.destructor
+.align 1
diff --git a/src/corelib/arch/mips/arch.pri b/src/corelib/arch/mips/arch.pri
new file mode 100644
index 0000000000..296c845ab3
--- /dev/null
+++ b/src/corelib/arch/mips/arch.pri
@@ -0,0 +1,8 @@
+#
+# MIPS 3/4 architecture
+#
+
+# note: even though we use inline assembler with gcc, we always
+# include the compiled version to keep binary compatibility
+*-64:SOURCES += $$QT_ARCH_CPP/qatomic_mips64.s
+else:SOURCES += $$QT_ARCH_CPP/qatomic_mips32.s
diff --git a/src/corelib/arch/mips/qatomic_mips32.s b/src/corelib/arch/mips/qatomic_mips32.s
new file mode 100644
index 0000000000..e7a449bc96
--- /dev/null
+++ b/src/corelib/arch/mips/qatomic_mips32.s
@@ -0,0 +1,110 @@
+ .set nobopt
+ .set noreorder
+ .option pic2
+ .text
+
+ .globl q_atomic_test_and_set_int
+ .ent q_atomic_test_and_set_int
+ .set mips2
+q_atomic_test_and_set_int:
+1: ll $8,0($4)
+ bne $8,$5,2f
+ move $2,$6
+ sc $2,0($4)
+ beqz $2,1b
+ nop
+ jr $31
+ nop
+2: jr $31
+ move $2,$0
+ .set mips0
+ .end q_atomic_test_and_set_int
+
+ .globl q_atomic_test_and_set_acquire_int
+ .ent q_atomic_test_and_set_acquire_int
+ .set mips2
+q_atomic_test_and_set_acquire_int:
+1: ll $8,0($4)
+ bne $8,$5,2f
+ move $2,$6
+ sc $2,0($4)
+ beqz $2,1b
+ nop
+ jr $31
+ nop
+2: sync
+ jr $31
+ move $2,$0
+ .set mips0
+ .end q_atomic_test_and_set_acquire_int
+
+ .globl q_atomic_test_and_set_release_int
+ .ent q_atomic_test_and_set_release_int
+ .set mips2
+q_atomic_test_and_set_release_int:
+ sync
+1: ll $8,0($4)
+ bne $8,$5,2f
+ move $2,$6
+ sc $2,0($4)
+ beqz $2,1b
+ nop
+ jr $31
+ nop
+2: jr $31
+ move $2,$0
+ .set mips0
+ .end q_atomic_test_and_set_release_int
+
+ .globl q_atomic_test_and_set_ptr
+ .ent q_atomic_test_and_set_ptr
+ .set mips2
+q_atomic_test_and_set_ptr:
+1: ll $8,0($4)
+ bne $8,$5,2f
+ move $2,$6
+ sc $2,0($4)
+ beqz $2,1b
+ nop
+ jr $31
+ nop
+2: jr $31
+ move $2,$0
+ .set mips0
+ .end q_atomic_test_and_set_ptr
+
+ .globl q_atomic_test_and_set_acquire_ptr
+ .ent q_atomic_test_and_set_acquire_ptr
+ .set mips2
+q_atomic_test_and_set_acquire_ptr:
+1: ll $8,0($4)
+ bne $8,$5,2f
+ move $2,$6
+ sc $2,0($4)
+ beqz $2,1b
+ nop
+ jr $31
+ nop
+2: sync
+ jr $31
+ move $2,$0
+ .set mips0
+ .end q_atomic_test_and_set_acquire_ptr
+
+ .globl q_atomic_test_and_set_release_ptr
+ .ent q_atomic_test_and_set_release_ptr
+ .set mips2
+q_atomic_test_and_set_release_ptr:
+ sync
+1: ll $8,0($4)
+ bne $8,$5,2f
+ move $2,$6
+ sc $2,0($4)
+ beqz $2,1b
+ nop
+ jr $31
+ nop
+2: jr $31
+ move $2,$0
+ .set mips0
+ .end q_atomic_test_and_set_release_ptr
diff --git a/src/corelib/arch/mips/qatomic_mips64.s b/src/corelib/arch/mips/qatomic_mips64.s
new file mode 100644
index 0000000000..d2bd8fe65a
--- /dev/null
+++ b/src/corelib/arch/mips/qatomic_mips64.s
@@ -0,0 +1,98 @@
+ .set nobopt
+ .set noreorder
+ .option pic2
+ .text
+
+ .globl q_atomic_test_and_set_int
+ .ent q_atomic_test_and_set_int
+q_atomic_test_and_set_int:
+1: ll $8,0($4)
+ bne $8,$5,2f
+ move $2,$6
+ sc $2,0($4)
+ beqz $2,1b
+ nop
+ jr $31
+ nop
+2: jr $31
+ move $2,$0
+ .end q_atomic_test_and_set_int
+
+ .globl q_atomic_test_and_set_acquire_int
+ .ent q_atomic_test_and_set_acquire_int
+q_atomic_test_and_set_acquire_int:
+1: ll $8,0($4)
+ bne $8,$5,2f
+ move $2,$6
+ sc $2,0($4)
+ beqz $2,1b
+ nop
+ jr $31
+ nop
+2: sync
+ jr $31
+ move $2,$0
+ .end q_atomic_test_and_set_acquire_int
+
+ .globl q_atomic_test_and_set_release_int
+ .ent q_atomic_test_and_set_release_int
+q_atomic_test_and_set_release_int:
+ sync
+1: ll $8,0($4)
+ bne $8,$5,2f
+ move $2,$6
+ sc $2,0($4)
+ beqz $2,1b
+ nop
+ jr $31
+ nop
+2: jr $31
+ move $2,$0
+ .end q_atomic_test_and_set_release_int
+
+ .globl q_atomic_test_and_set_ptr
+ .ent q_atomic_test_and_set_ptr
+q_atomic_test_and_set_ptr:
+1: lld $8,0($4)
+ bne $8,$5,2f
+ move $2,$6
+ scd $2,0($4)
+ beqz $2,1b
+ nop
+ jr $31
+ nop
+2: jr $31
+ move $2,$0
+ .end q_atomic_test_and_set_ptr
+
+ .globl q_atomic_test_and_set_acquire_ptr
+ .ent q_atomic_test_and_set_acquire_ptr
+q_atomic_test_and_set_acquire_ptr:
+1: lld $8,0($4)
+ bne $8,$5,2f
+ move $2,$6
+ scd $2,0($4)
+ beqz $2,1b
+ nop
+ jr $31
+ nop
+2: sync
+ jr $31
+ move $2,$0
+ .end q_atomic_test_and_set_acquire_ptr
+
+ .globl q_atomic_test_and_set_release_ptr
+ .ent q_atomic_test_and_set_release_ptr
+q_atomic_test_and_set_release_ptr:
+ sync
+1: lld $8,0($4)
+ bne $8,$5,2f
+ move $2,$6
+ scd $2,0($4)
+ beqz $2,1b
+ nop
+ jr $31
+ nop
+2: jr $31
+ move $2,$0
+ .end q_atomic_test_and_set_release_ptr
diff --git a/src/corelib/arch/parisc/arch.pri b/src/corelib/arch/parisc/arch.pri
new file mode 100644
index 0000000000..fab2897f04
--- /dev/null
+++ b/src/corelib/arch/parisc/arch.pri
@@ -0,0 +1,5 @@
+#
+# HP PA-RISC architecture
+#
+SOURCES += $$QT_ARCH_CPP/q_ldcw.s \
+ $$QT_ARCH_CPP/qatomic_parisc.cpp
diff --git a/src/corelib/arch/parisc/q_ldcw.s b/src/corelib/arch/parisc/q_ldcw.s
new file mode 100644
index 0000000000..f901ad9115
--- /dev/null
+++ b/src/corelib/arch/parisc/q_ldcw.s
@@ -0,0 +1,22 @@
+ .SPACE $PRIVATE$
+ .SUBSPA $DATA$,QUAD=1,ALIGN=8,ACCESS=31
+ .SUBSPA $BSS$,QUAD=1,ALIGN=8,ACCESS=31,ZERO,SORT=82
+ .SPACE $TEXT$
+ .SUBSPA $LIT$,QUAD=0,ALIGN=8,ACCESS=44
+ .SUBSPA $CODE$,QUAD=0,ALIGN=8,ACCESS=44,CODE_ONLY
+ .IMPORT $global$,DATA
+ .IMPORT $$dyncall,MILLICODE
+ .SPACE $TEXT$
+ .SUBSPA $CODE$
+
+ .align 4
+ .EXPORT q_ldcw,ENTRY,PRIV_LEV=3,ARGW0=GR,RTNVAL=GR
+q_ldcw
+ .PROC
+ .CALLINFO FRAME=0,CALLS,SAVE_RP
+ .ENTRY
+ ldcw 0(%r26),%r1
+ bv %r0(%r2)
+ copy %r1,%r28
+ .EXIT
+ .PROCEND
diff --git a/src/corelib/arch/parisc/qatomic_parisc.cpp b/src/corelib/arch/parisc/qatomic_parisc.cpp
new file mode 100644
index 0000000000..580838e9aa
--- /dev/null
+++ b/src/corelib/arch/parisc/qatomic_parisc.cpp
@@ -0,0 +1,88 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtCore module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QtCore/qglobal.h>
+#include <QtCore/qhash.h>
+
+QT_BEGIN_NAMESPACE
+
+QT_USE_NAMESPACE
+
+#define UNLOCKED {-1,-1,-1,-1}
+#define UNLOCKED2 UNLOCKED,UNLOCKED
+#define UNLOCKED4 UNLOCKED2,UNLOCKED2
+#define UNLOCKED8 UNLOCKED4,UNLOCKED4
+#define UNLOCKED16 UNLOCKED8,UNLOCKED8
+#define UNLOCKED32 UNLOCKED16,UNLOCKED16
+#define UNLOCKED64 UNLOCKED32,UNLOCKED32
+#define UNLOCKED128 UNLOCKED64,UNLOCKED64
+#define UNLOCKED256 UNLOCKED128,UNLOCKED128
+
+// use a 4k page for locks
+static int locks[256][4] = { UNLOCKED256 };
+
+int *getLock(volatile void *addr)
+{ return locks[qHash(const_cast<void *>(addr)) % 256]; }
+
+static int *align16(int *lock)
+{
+ ulong off = (((ulong) lock) % 16);
+ return off ? (int *)(ulong(lock) + 16 - off) : lock;
+}
+
+extern "C" {
+
+ int q_ldcw(volatile int *addr);
+
+ void q_atomic_lock(int *lock)
+ {
+ // ldcw requires a 16-byte aligned address
+ volatile int *x = align16(lock);
+ while (q_ldcw(x) == 0)
+ ;
+ }
+
+ void q_atomic_unlock(int *lock)
+ { lock[0] = lock[1] = lock[2] = lock[3] = -1; }
+}
+
+
+QT_END_NAMESPACE
diff --git a/src/corelib/arch/powerpc/arch.pri b/src/corelib/arch/powerpc/arch.pri
new file mode 100644
index 0000000000..1989ac73a7
--- /dev/null
+++ b/src/corelib/arch/powerpc/arch.pri
@@ -0,0 +1,10 @@
+#
+# PowerPC architecture
+#
+!*-g++* {
+ *-64 {
+ SOURCES += $$QT_ARCH_CPP/qatomic64.s
+ } else {
+ SOURCES += $$QT_ARCH_CPP/qatomic32.s
+ }
+}
diff --git a/src/corelib/arch/powerpc/qatomic32.s b/src/corelib/arch/powerpc/qatomic32.s
new file mode 100644
index 0000000000..811ba842d5
--- /dev/null
+++ b/src/corelib/arch/powerpc/qatomic32.s
@@ -0,0 +1,485 @@
+ .machine "ppc"
+ .toc
+ .csect .text[PR]
+
+ .align 2
+ .globl q_atomic_test_and_set_int
+ .globl .q_atomic_test_and_set_int
+ .csect q_atomic_test_and_set_int[DS],3
+q_atomic_test_and_set_int:
+ .long .q_atomic_test_and_set_int,TOC[tc0],0
+ .csect .text[PR]
+.q_atomic_test_and_set_int:
+ lwarx 6,0,3
+ xor. 6,6,4
+ bne $+12
+ stwcx. 5,0,3
+ bne- $-16
+ subfic 3,6,0
+ adde 3,3,6
+ blr
+LT..q_atomic_test_and_set_int:
+ .long 0
+ .byte 0,9,32,64,0,0,3,0
+ .long 0
+ .long LT..q_atomic_test_and_set_int-.q_atomic_test_and_set_int
+ .short 25
+ .byte "q_atomic_test_and_set_int"
+ .align 2
+
+ .align 2
+ .globl q_atomic_test_and_set_acquire_int
+ .globl .q_atomic_test_and_set_acquire_int
+ .csect q_atomic_test_and_set_acquire_int[DS],3
+q_atomic_test_and_set_acquire_int:
+ .long .q_atomic_test_and_set_acquire_int,TOC[tc0],0
+ .csect .text[PR]
+.q_atomic_test_and_set_acquire_int:
+ lwarx 6,0,3
+ xor. 6,6,4
+ bne $+16
+ stwcx. 5,0,3
+ bne- $-16
+ isync
+ subfic 3,6,0
+ adde 3,3,6
+ blr
+LT..q_atomic_test_and_set_acquire_int:
+ .long 0
+ .byte 0,9,32,64,0,0,3,0
+ .long 0
+ .long LT..q_atomic_test_and_set_acquire_int-.q_atomic_test_and_set_acquire_int
+ .short 33
+ .byte "q_atomic_test_and_set_acquire_int"
+ .align 2
+
+ .align 2
+ .globl q_atomic_test_and_set_release_int
+ .globl .q_atomic_test_and_set_release_int
+ .csect q_atomic_test_and_set_release_int[DS],3
+q_atomic_test_and_set_release_int:
+ .long .q_atomic_test_and_set_release_int,TOC[tc0],0
+ .csect .text[PR]
+.q_atomic_test_and_set_release_int:
+ eieio
+ lwarx 6,0,3
+ xor. 6,6,4
+ bne $+12
+ stwcx. 5,0,3
+ bne- $-16
+ subfic 3,6,0
+ adde 3,3,6
+ blr
+LT..q_atomic_test_and_set_release_int:
+ .long 0
+ .byte 0,9,32,64,0,0,3,0
+ .long 0
+ .long LT..q_atomic_test_and_set_release_int-.q_atomic_test_and_set_release_int
+ .short 33
+ .byte "q_atomic_test_and_set_release_int"
+ .align 2
+
+ .align 2
+ .globl q_atomic_test_and_set_ptr
+ .globl .q_atomic_test_and_set_ptr
+ .csect q_atomic_test_and_set_ptr[DS],3
+q_atomic_test_and_set_ptr:
+ .long .q_atomic_test_and_set_ptr,TOC[tc0],0
+ .csect .text[PR]
+.q_atomic_test_and_set_ptr:
+ lwarx 6,0,3
+ xor. 6,6,4
+ bne $+12
+ stwcx. 5,0,3
+ bne- $-16
+ subfic 3,6,0
+ adde 3,3,6
+ blr
+LT..q_atomic_test_and_set_ptr:
+ .long 0
+ .byte 0,9,32,64,0,0,3,0
+ .long 0
+ .long LT..q_atomic_test_and_set_ptr-.q_atomic_test_and_set_ptr
+ .short 25
+ .byte "q_atomic_test_and_set_ptr"
+ .align 2
+
+ .align 2
+ .globl q_atomic_test_and_set_acquire_ptr
+ .globl .q_atomic_test_and_set_acquire_ptr
+ .csect q_atomic_test_and_set_acquire_ptr[DS],3
+q_atomic_test_and_set_acquire_ptr:
+ .long .q_atomic_test_and_set_acquire_ptr,TOC[tc0],0
+ .csect .text[PR]
+.q_atomic_test_and_set_acquire_ptr:
+ lwarx 6,0,3
+ xor. 6,6,4
+ bne $+16
+ stwcx. 5,0,3
+ bne- $-16
+ isync
+ subfic 3,6,0
+ adde 3,3,6
+ blr
+LT..q_atomic_test_and_set_acquire_ptr:
+ .long 0
+ .byte 0,9,32,64,0,0,3,0
+ .long 0
+ .long LT..q_atomic_test_and_set_acquire_ptr-.q_atomic_test_and_set_acquire_ptr
+ .short 25
+ .byte "q_atomic_test_and_set_acquire_ptr"
+ .align 2
+
+ .align 2
+ .globl q_atomic_test_and_set_release_ptr
+ .globl .q_atomic_test_and_set_release_ptr
+ .csect q_atomic_test_and_set_release_ptr[DS],3
+q_atomic_test_and_set_release_ptr:
+ .long .q_atomic_test_and_set_release_ptr,TOC[tc0],0
+ .csect .text[PR]
+.q_atomic_test_and_set_release_ptr:
+ eieio
+ lwarx 6,0,3
+ xor. 6,6,4
+ bne $+12
+ stwcx. 5,0,3
+ bne- $-16
+ subfic 3,6,0
+ adde 3,3,6
+ blr
+LT..q_atomic_test_and_set_release_ptr:
+ .long 0
+ .byte 0,9,32,64,0,0,3,0
+ .long 0
+ .long LT..q_atomic_test_and_set_release_ptr-.q_atomic_test_and_set_release_ptr
+ .short 33
+ .byte "q_atomic_test_and_set_release_ptr"
+ .align 2
+
+ .align 2
+ .globl q_atomic_increment
+ .globl .q_atomic_increment
+ .csect q_atomic_increment[DS],3
+q_atomic_increment:
+ .long .q_atomic_increment,TOC[tc0],0
+ .csect .text[PR]
+.q_atomic_increment:
+ lwarx 4,0,3
+ addi 4,4,1
+ stwcx. 4,0,3
+ bne- $-12
+ mr 3,4
+ blr
+LT..q_atomic_increment:
+ .long 0
+ .byte 0,9,32,64,0,0,1,0
+ .long 0
+ .long LT..q_atomic_increment-.q_atomic_increment
+ .short 18
+ .byte "q_atomic_increment"
+ .align 2
+
+ .align 2
+ .globl q_atomic_decrement
+ .globl .q_atomic_decrement
+ .csect q_atomic_decrement[DS],3
+q_atomic_decrement:
+ .long .q_atomic_decrement,TOC[tc0],0
+ .csect .text[PR]
+.q_atomic_decrement:
+ lwarx 4,0,3
+ subi 4,4,1
+ stwcx. 4,0,3
+ bne- $-12
+ mr 3,4
+ blr
+LT..q_atomic_decrement:
+ .long 0
+ .byte 0,9,32,64,0,0,1,0
+ .long 0
+ .long LT..q_atomic_decrement-.q_atomic_decrement
+ .short 18
+ .byte "q_atomic_decrement"
+ .align 2
+
+ .align 2
+ .globl q_atomic_set_int
+ .globl .q_atomic_set_int
+ .csect q_atomic_set_int[DS],3
+q_atomic_set_int:
+ .long .q_atomic_set_int,TOC[tc0],0
+ .csect .text[PR]
+.q_atomic_set_int:
+ lwarx 5,0,3
+ stwcx. 4,0,3
+ bne- $-8
+ mr 3,5
+ blr
+LT..q_atomic_set_int:
+ .long 0
+ .byte 0,9,32,64,0,0,2,0
+ .long 0
+ .long LT..q_atomic_set_int-.q_atomic_set_int
+ .short 16
+ .byte "q_atomic_set_int"
+ .align 2
+
+ .align 2
+ .globl q_atomic_fetch_and_store_acquire_int
+ .globl .q_atomic_fetch_and_store_acquire_int
+ .csect q_atomic_fetch_and_store_acquire_int[DS],3
+q_atomic_fetch_and_store_acquire_int:
+ .long .q_atomic_fetch_and_store_acquire_int,TOC[tc0],0
+ .csect .text[PR]
+.q_atomic_fetch_and_store_acquire_int:
+ lwarx 5,0,3
+ stwcx. 4,0,3
+ bne- $-8
+ isync
+ mr 3,5
+ blr
+LT..q_atomic_fetch_and_store_acquire_int:
+ .long 0
+ .byte 0,9,32,64,0,0,2,0
+ .long 0
+ .long LT..q_atomic_fetch_and_store_acquire_int-.q_atomic_fetch_and_store_acquire_int
+ .short 16
+ .byte "q_atomic_fetch_and_store_acquire_int"
+ .align 2
+
+ .align 2
+ .globl q_atomic_fetch_and_store_release_int
+ .globl .q_atomic_fetch_and_store_release_int
+ .csect q_atomic_fetch_and_store_release_int[DS],3
+q_atomic_fetch_and_store_release_int:
+ .long .q_atomic_fetch_and_store_release_int,TOC[tc0],0
+ .csect .text[PR]
+.q_atomic_fetch_and_store_release_int:
+ eieio
+ lwarx 5,0,3
+ stwcx. 4,0,3
+ bne- $-8
+ mr 3,5
+ blr
+LT..q_atomic_fetch_and_store_release_int:
+ .long 0
+ .byte 0,9,32,64,0,0,2,0
+ .long 0
+ .long LT..q_atomic_fetch_and_store_release_int-.q_atomic_fetch_and_store_release_int
+ .short 16
+ .byte "q_atomic_fetch_and_store_release_int"
+ .align 2
+
+ .align 2
+ .globl q_atomic_set_ptr
+ .globl .q_atomic_set_ptr
+ .csect q_atomic_set_ptr[DS],3
+q_atomic_set_ptr:
+ .long .q_atomic_set_ptr,TOC[tc0],0
+ .csect .text[PR]
+.q_atomic_set_ptr:
+ lwarx 5,0,3
+ stwcx. 4,0,3
+ bne- $-8
+ mr 3,5
+ blr
+LT..q_atomic_set_ptr:
+ .long 0
+ .byte 0,9,32,64,0,0,2,0
+ .long 0
+ .long LT..q_atomic_set_ptr-.q_atomic_set_ptr
+ .short 16
+ .byte "q_atomic_set_ptr"
+ .align 2
+
+ .align 2
+ .globl q_atomic_fetch_and_store_acquire_ptr
+ .globl .q_atomic_fetch_and_store_acquire_ptr
+ .csect q_atomic_fetch_and_store_acquire_ptr[DS],3
+q_atomic_fetch_and_store_acquire_ptr:
+ .long .q_atomic_fetch_and_store_acquire_ptr,TOC[tc0],0
+ .csect .text[PR]
+.q_atomic_fetch_and_store_acquire_ptr:
+ lwarx 5,0,3
+ stwcx. 4,0,3
+ bne- $-8
+ isync
+ mr 3,5
+ blr
+LT..q_atomic_fetch_and_store_acquire_ptr:
+ .long 0
+ .byte 0,9,32,64,0,0,2,0
+ .long 0
+ .long LT..q_atomic_fetch_and_store_acquire_ptr-.q_atomic_fetch_and_store_acquire_ptr
+ .short 16
+ .byte "q_atomic_fetch_and_store_acquire_ptr"
+ .align 2
+
+ .align 2
+ .globl q_atomic_fetch_and_store_release_ptr
+ .globl .q_atomic_fetch_and_store_release_ptr
+ .csect q_atomic_fetch_and_store_release_ptr[DS],3
+q_atomic_fetch_and_store_release_ptr:
+ .long .q_atomic_fetch_and_store_release_ptr,TOC[tc0],0
+ .csect .text[PR]
+.q_atomic_fetch_and_store_release_ptr:
+ eieio
+ lwarx 5,0,3
+ stwcx. 4,0,3
+ bne- $-8
+ mr 3,5
+ blr
+LT..q_atomic_fetch_and_store_release_ptr:
+ .long 0
+ .byte 0,9,32,64,0,0,2,0
+ .long 0
+ .long LT..q_atomic_fetch_and_store_release_ptr-.q_atomic_fetch_and_store_release_ptr
+ .short 16
+ .byte "q_atomic_fetch_and_store_release_ptr"
+ .align 2
+
+ .align 2
+ .globl q_atomic_fetch_and_add_int
+ .globl .q_atomic_fetch_and_add_int
+ .csect q_atomic_fetch_and_add_int[DS],3
+q_atomic_fetch_and_add_int:
+ .long .q_atomic_fetch_and_add_int,TOC[tc0],0
+ .csect .text[PR]
+.q_atomic_fetch_and_add_int:
+ lwarx 5,0,3
+ add 6,4,5
+ stwcx. 6,0,3
+ bne- $-12
+ mr 3,5
+ blr
+LT..q_atomic_fetch_and_add_int:
+ .long 0
+ .byte 0,9,32,64,0,0,1,0
+ .long 0
+ .long LT..q_atomic_fetch_and_add_int-.q_atomic_fetch_and_add_int
+ .short 18
+ .byte "q_atomic_fetch_and_add_int"
+ .align 2
+
+ .align 2
+ .globl q_atomic_fetch_and_add_acquire_int
+ .globl .q_atomic_fetch_and_add_acquire_int
+ .csect q_atomic_fetch_and_add_acquire_int[DS],3
+q_atomic_fetch_and_add_acquire_int:
+ .long .q_atomic_fetch_and_add_acquire_int,TOC[tc0],0
+ .csect .text[PR]
+.q_atomic_fetch_and_add_acquire_int:
+ lwarx 5,0,3
+ add 6,4,5
+ stwcx. 6,0,3
+ bne- $-12
+ isync
+ mr 3,5
+ blr
+LT..q_atomic_fetch_and_add_acquire_int:
+ .long 0
+ .byte 0,9,32,64,0,0,1,0
+ .long 0
+ .long LT..q_atomic_fetch_and_add_acquire_int-.q_atomic_fetch_and_add_acquire_int
+ .short 18
+ .byte "q_atomic_fetch_and_add_acquire_int"
+ .align 2
+
+ .align 2
+ .globl q_atomic_fetch_and_add_release_int
+ .globl .q_atomic_fetch_and_add_release_int
+ .csect q_atomic_fetch_and_add_release_int[DS],3
+q_atomic_fetch_and_add_release_int:
+ .long .q_atomic_fetch_and_add_release_int,TOC[tc0],0
+ .csect .text[PR]
+.q_atomic_fetch_and_add_release_int:
+ eieio
+ lwarx 5,0,3
+ add 6,4,5
+ stwcx. 6,0,3
+ bne- $-12
+ mr 3,5
+ blr
+LT..q_atomic_fetch_and_add_release_int:
+ .long 0
+ .byte 0,9,32,64,0,0,1,0
+ .long 0
+ .long LT..q_atomic_fetch_and_add_release_int-.q_atomic_fetch_and_add_release_int
+ .short 34
+ .byte "q_atomic_fetch_and_add_release_int"
+ .align 2
+
+ .align 2
+ .globl q_atomic_fetch_and_add_ptr
+ .globl .q_atomic_fetch_and_add_ptr
+ .csect q_atomic_fetch_and_add_ptr[DS],3
+q_atomic_fetch_and_add_ptr:
+ .long .q_atomic_fetch_and_add_ptr,TOC[tc0],0
+ .csect .text[PR]
+.q_atomic_fetch_and_add_ptr:
+ lwarx 5,0,3
+ add 6,4,5
+ stwcx. 6,0,3
+ bne- $-12
+ mr 3,5
+ blr
+LT..q_atomic_fetch_and_add_ptr:
+ .long 0
+ .byte 0,9,32,64,0,0,1,0
+ .long 0
+ .long LT..q_atomic_fetch_and_add_ptr-.q_atomic_fetch_and_add_ptr
+ .short 26
+ .byte "q_atomic_fetch_and_add_ptr"
+ .align 2
+
+ .align 2
+ .globl q_atomic_fetch_and_add_acquire_ptr
+ .globl .q_atomic_fetch_and_add_acquire_ptr
+ .csect q_atomic_fetch_and_add_acquire_ptr[DS],3
+q_atomic_fetch_and_add_acquire_ptr:
+ .long .q_atomic_fetch_and_add_acquire_ptr,TOC[tc0],0
+ .csect .text[PR]
+.q_atomic_fetch_and_add_acquire_ptr:
+ lwarx 5,0,3
+ add 6,4,5
+ stwcx. 6,0,3
+ bne- $-12
+ isync
+ mr 3,5
+ blr
+LT..q_atomic_fetch_and_add_acquire_ptr:
+ .long 0
+ .byte 0,9,32,64,0,0,1,0
+ .long 0
+ .long LT..q_atomic_fetch_and_add_acquire_ptr-.q_atomic_fetch_and_add_acquire_ptr
+ .short 34
+ .byte "q_atomic_fetch_and_add_acquire_ptr"
+ .align 2
+
+ .align 2
+ .globl q_atomic_fetch_and_add_release_ptr
+ .globl .q_atomic_fetch_and_add_release_ptr
+ .csect q_atomic_fetch_and_add_release_ptr[DS],3
+q_atomic_fetch_and_add_release_ptr:
+ .long .q_atomic_fetch_and_add_release_ptr,TOC[tc0],0
+ .csect .text[PR]
+.q_atomic_fetch_and_add_release_ptr:
+ eieio
+ lwarx 5,0,3
+ add 6,4,5
+ stwcx. 6,0,3
+ bne- $-12
+ mr 3,5
+ blr
+LT..q_atomic_fetch_and_add_release_ptr:
+ .long 0
+ .byte 0,9,32,64,0,0,1,0
+ .long 0
+ .long LT..q_atomic_fetch_and_add_release_ptr-.q_atomic_fetch_and_add_release_ptr
+ .short 34
+ .byte "q_atomic_fetch_and_add_release_ptr"
+ .align 2
+
+_section_.text:
+ .csect .data[RW],3
+ .long _section_.text
diff --git a/src/corelib/arch/powerpc/qatomic64.s b/src/corelib/arch/powerpc/qatomic64.s
new file mode 100644
index 0000000000..88c2bbd6ad
--- /dev/null
+++ b/src/corelib/arch/powerpc/qatomic64.s
@@ -0,0 +1,493 @@
+ .machine "ppc64"
+ .toc
+ .csect .text[PR]
+
+ .align 2
+ .globl q_atomic_test_and_set_int
+ .globl .q_atomic_test_and_set_int
+ .csect q_atomic_test_and_set_int[DS],3
+q_atomic_test_and_set_int:
+ .llong .q_atomic_test_and_set_int,TOC[tc0],0
+ .csect .text[PR]
+.q_atomic_test_and_set_int:
+ lwarx 6,0,3
+ xor. 6,6,4
+ bne $+12
+ stwcx. 5,0,3
+ bne- $-16
+ subfic 3,6,0
+ adde 3,3,6
+ extsw 3,3
+ blr
+LT..q_atomic_test_and_set_int:
+ .long 0
+ .byte 0,9,32,64,0,0,3,0
+ .long 0
+ .long LT..q_atomic_test_and_set_int-.q_atomic_test_and_set_int
+ .short 25
+ .byte "q_atomic_test_and_set_int"
+ .align 2
+
+ .align 2
+ .globl q_atomic_test_and_set_acquire_int
+ .globl .q_atomic_test_and_set_acquire_int
+ .csect q_atomic_test_and_set_acquire_int[DS],3
+q_atomic_test_and_set_acquire_int:
+ .llong .q_atomic_test_and_set_acquire_int,TOC[tc0],0
+ .csect .text[PR]
+.q_atomic_test_and_set_acquire_int:
+ lwarx 6,0,3
+ xor. 6,6,4
+ bne $+16
+ stwcx. 5,0,3
+ bne- $-16
+ isync
+ subfic 3,6,0
+ adde 3,3,6
+ extsw 3,3
+ blr
+LT..q_atomic_test_and_set_acquire_int:
+ .long 0
+ .byte 0,9,32,64,0,0,3,0
+ .long 0
+ .long LT..q_atomic_test_and_set_acquire_int-.q_atomic_test_and_set_acquire_int
+ .short 33
+ .byte "q_atomic_test_and_set_acquire_int"
+ .align 2
+
+ .align 2
+ .globl q_atomic_test_and_set_release_int
+ .globl .q_atomic_test_and_set_release_int
+ .csect q_atomic_test_and_set_release_int[DS],3
+q_atomic_test_and_set_release_int:
+ .llong .q_atomic_test_and_set_release_int,TOC[tc0],0
+ .csect .text[PR]
+.q_atomic_test_and_set_release_int:
+ eieio
+ lwarx 6,0,3
+ xor. 6,6,4
+ bne $+12
+ stwcx. 5,0,3
+ bne- $-16
+ subfic 3,6,0
+ adde 3,3,6
+ extsw 3,3
+ blr
+LT..q_atomic_test_and_set_release_int:
+ .long 0
+ .byte 0,9,32,64,0,0,3,0
+ .long 0
+ .long LT..q_atomic_test_and_set_release_int-.q_atomic_test_and_set_release_int
+ .short 33
+ .byte "q_atomic_test_and_set_release_int"
+ .align 2
+
+ .align 2
+ .globl q_atomic_test_and_set_ptr
+ .globl .q_atomic_test_and_set_ptr
+ .csect q_atomic_test_and_set_ptr[DS],3
+q_atomic_test_and_set_ptr:
+ .llong .q_atomic_test_and_set_ptr,TOC[tc0],0
+ .csect .text[PR]
+.q_atomic_test_and_set_ptr:
+ ldarx 6,0,3
+ xor. 6,6,4
+ bne $+12
+ stdcx. 5,0,3
+ bne- $-16
+ subfic 3,6,0
+ adde 3,3,6
+ blr
+LT..q_atomic_test_and_set_ptr:
+ .long 0
+ .byte 0,9,32,64,0,0,3,0
+ .long 0
+ .long LT..q_atomic_test_and_set_ptr-.q_atomic_test_and_set_ptr
+ .short 25
+ .byte "q_atomic_test_and_set_ptr"
+ .align 2
+
+ .align 2
+ .globl q_atomic_test_and_set_acquire_ptr
+ .globl .q_atomic_test_and_set_acquire_ptr
+ .csect q_atomic_test_and_set_acquire_ptr[DS],3
+q_atomic_test_and_set_acquire_ptr:
+ .llong .q_atomic_test_and_set_acquire_ptr,TOC[tc0],0
+ .csect .text[PR]
+.q_atomic_test_and_set_acquire_ptr:
+ ldarx 6,0,3
+ xor. 6,6,4
+ bne $+16
+ stdcx. 5,0,3
+ bne- $-16
+ isync
+ subfic 3,6,0
+ adde 3,3,6
+ blr
+LT..q_atomic_test_and_set_acquire_ptr:
+ .long 0
+ .byte 0,9,32,64,0,0,3,0
+ .long 0
+ .long LT..q_atomic_test_and_set_acquire_ptr-.q_atomic_test_and_set_acquire_ptr
+ .short 33
+ .byte "q_atomic_test_and_set_acquire_ptr"
+ .align 2
+
+ .align 2
+ .globl q_atomic_test_and_set_release_ptr
+ .globl .q_atomic_test_and_set_release_ptr
+ .csect q_atomic_test_and_set_release_ptr[DS],3
+q_atomic_test_and_set_release_ptr:
+ .llong .q_atomic_test_and_set_release_ptr,TOC[tc0],0
+ .csect .text[PR]
+.q_atomic_test_and_set_release_ptr:
+ eieio
+ ldarx 6,0,3
+ xor. 6,6,4
+ bne $+12
+ stdcx. 5,0,3
+ bne- $-16
+ subfic 3,6,0
+ adde 3,3,6
+ blr
+LT..q_atomic_test_and_set_release_ptr:
+ .long 0
+ .byte 0,9,32,64,0,0,3,0
+ .long 0
+ .long LT..q_atomic_test_and_set_release_ptr-.q_atomic_test_and_set_release_ptr
+ .short 33
+ .byte "q_atomic_test_and_set_release_ptr"
+ .align 2
+
+ .align 2
+ .globl q_atomic_increment
+ .globl .q_atomic_increment
+ .csect q_atomic_increment[DS],3
+q_atomic_increment:
+ .llong .q_atomic_increment,TOC[tc0],0
+ .csect .text[PR]
+.q_atomic_increment:
+ lwarx 4,0,3
+ addi 5,4,1
+ extsw 4,5
+ stwcx. 4,0,3
+ bne- $-16
+ mr 3,4
+ blr
+LT..q_atomic_increment:
+ .long 0
+ .byte 0,9,32,64,0,0,1,0
+ .long 0
+ .long LT..q_atomic_increment-.q_atomic_increment
+ .short 18
+ .byte "q_atomic_increment"
+ .align 2
+
+ .align 2
+ .globl q_atomic_decrement
+ .globl .q_atomic_decrement
+ .csect q_atomic_decrement[DS],3
+q_atomic_decrement:
+ .llong .q_atomic_decrement,TOC[tc0],0
+ .csect .text[PR]
+.q_atomic_decrement:
+ lwarx 4,0,3
+ subi 5,4,1
+ extsw 4,5
+ stwcx. 4,0,3
+ bne- $-16
+ mr 3,4
+ blr
+LT..q_atomic_decrement:
+ .long 0
+ .byte 0,9,32,64,0,0,1,0
+ .long 0
+ .long LT..q_atomic_decrement-.q_atomic_decrement
+ .short 18
+ .byte "q_atomic_decrement"
+ .align 2
+
+ .align 2
+ .globl q_atomic_set_int
+ .globl .q_atomic_set_int
+ .csect q_atomic_set_int[DS],3
+q_atomic_set_int:
+ .llong .q_atomic_set_int,TOC[tc0],0
+ .csect .text[PR]
+.q_atomic_set_int:
+ lwarx 5,0,3
+ stwcx. 4,0,3
+ bne- $-8
+ extsw 3,5
+ blr
+LT..q_atomic_set_int:
+ .long 0
+ .byte 0,9,32,64,0,0,2,0
+ .long 0
+ .long LT..q_atomic_set_int-.q_atomic_set_int
+ .short 16
+ .byte "q_atomic_set_int"
+ .align 2
+
+ .align 2
+ .globl q_atomic_fetch_and_store_acquire_int
+ .globl .q_atomic_fetch_and_store_acquire_int
+ .csect q_atomic_fetch_and_store_acquire_int[DS],3
+q_atomic_fetch_and_store_acquire_int:
+ .llong .q_atomic_fetch_and_store_acquire_int,TOC[tc0],0
+ .csect .text[PR]
+.q_atomic_fetch_and_store_acquire_int:
+ lwarx 5,0,3
+ stwcx. 4,0,3
+ bne- $-8
+ isync
+ extsw 3,5
+ blr
+LT..q_atomic_fetch_and_store_acquire_int:
+ .long 0
+ .byte 0,9,32,64,0,0,2,0
+ .long 0
+ .long LT..q_atomic_fetch_and_store_acquire_int-.q_atomic_fetch_and_store_acquire_int
+ .short 36
+ .byte "q_atomic_fetch_and_store_acquire_int"
+ .align 2
+
+ .align 2
+ .globl q_atomic_fetch_and_store_release_int
+ .globl .q_atomic_fetch_and_store_release_int
+ .csect q_atomic_fetch_and_store_release_int[DS],3
+q_atomic_fetch_and_store_release_int:
+ .llong .q_atomic_fetch_and_store_release_int,TOC[tc0],0
+ .csect .text[PR]
+.q_atomic_fetch_and_store_release_int:
+ eieio
+ lwarx 5,0,3
+ stwcx. 4,0,3
+ bne- $-8
+ extsw 3,5
+ blr
+LT..q_atomic_fetch_and_store_release_int:
+ .long 0
+ .byte 0,9,32,64,0,0,2,0
+ .long 0
+ .long LT..q_atomic_fetch_and_store_release_int-.q_atomic_fetch_and_store_release_int
+ .short 36
+ .byte "q_atomic_fetch_and_store_release_int"
+ .align 2
+
+ .align 2
+ .globl q_atomic_set_ptr
+ .globl .q_atomic_set_ptr
+ .csect q_atomic_set_ptr[DS],3
+q_atomic_set_ptr:
+ .llong .q_atomic_set_ptr,TOC[tc0],0
+ .csect .text[PR]
+.q_atomic_set_ptr:
+ ldarx 5,0,3
+ stdcx. 4,0,3
+ bne- $-8
+ mr 3,5
+ blr
+LT..q_atomic_set_ptr:
+ .long 0
+ .byte 0,9,32,64,0,0,2,0
+ .long 0
+ .long LT..q_atomic_set_ptr-.q_atomic_set_ptr
+ .short 16
+ .byte "q_atomic_set_ptr"
+ .align 2
+
+ .align 2
+ .globl q_atomic_fetch_and_store_acquire_ptr
+ .globl .q_atomic_fetch_and_store_acquire_ptr
+ .csect q_atomic_fetch_and_store_acquire_ptr[DS],3
+q_atomic_fetch_and_store_acquire_ptr:
+ .llong .q_atomic_fetch_and_store_acquire_ptr,TOC[tc0],0
+ .csect .text[PR]
+.q_atomic_fetch_and_store_acquire_ptr:
+ ldarx 5,0,3
+ stdcx. 4,0,3
+ bne- $-8
+ isync
+ mr 3,5
+ blr
+LT..q_atomic_fetch_and_store_acquire_ptr:
+ .long 0
+ .byte 0,9,32,64,0,0,2,0
+ .long 0
+ .long LT..q_atomic_fetch_and_store_acquire_ptr-.q_atomic_fetch_and_store_acquire_ptr
+ .short 36
+ .byte "q_atomic_fetch_and_store_acquire_ptr"
+ .align 2
+
+ .align 2
+ .globl q_atomic_fetch_and_store_release_ptr
+ .globl .q_atomic_fetch_and_store_release_ptr
+ .csect q_atomic_fetch_and_store_release_ptr[DS],3
+q_atomic_fetch_and_store_release_ptr:
+ .llong .q_atomic_fetch_and_store_release_ptr,TOC[tc0],0
+ .csect .text[PR]
+.q_atomic_fetch_and_store_release_ptr:
+ eieio
+ ldarx 5,0,3
+ stdcx. 4,0,3
+ bne- $-8
+ mr 3,5
+ blr
+LT..q_atomic_fetch_and_store_release_ptr:
+ .long 0
+ .byte 0,9,32,64,0,0,2,0
+ .long 0
+ .long LT..q_atomic_fetch_and_store_release_ptr-.q_atomic_fetch_and_store_release_ptr
+ .short 36
+ .byte "q_atomic_fetch_and_store_release_ptr"
+ .align 2
+
+ .align 2
+ .globl q_atomic_fetch_and_add_int
+ .globl .q_atomic_fetch_and_add_int
+ .csect q_atomic_fetch_and_add_int[DS],3
+q_atomic_fetch_and_add_int:
+ .llong .q_atomic_fetch_and_add_int,TOC[tc0],0
+ .csect .text[PR]
+.q_atomic_fetch_and_add_int:
+ lwarx 5,0,3
+ add 6,4,5
+ extsw 7,6
+ stwcx. 7,0,3
+ bne- $-16
+ extsw 3,5
+ blr
+LT..q_atomic_fetch_and_add_int:
+ .long 0
+ .byte 0,9,32,64,0,0,1,0
+ .long 0
+ .long LT..q_atomic_fetch_and_add_int-.q_atomic_fetch_and_add_int
+ .short 26
+ .byte "q_atomic_fetch_and_add_int"
+ .align 2
+
+ .align 2
+ .globl q_atomic_fetch_and_add_acquire_int
+ .globl .q_atomic_fetch_and_add_acquire_int
+ .csect q_atomic_fetch_and_add_acquire_int[DS],3
+q_atomic_fetch_and_add_acquire_int:
+ .llong .q_atomic_fetch_and_add_acquire_int,TOC[tc0],0
+ .csect .text[PR]
+.q_atomic_fetch_and_add_acquire_int:
+ lwarx 5,0,3
+ add 6,4,5
+ extsw 7,6
+ stwcx. 7,0,3
+ bne- $-16
+ isync
+ extsw 3,5
+ blr
+LT..q_atomic_fetch_and_add_acquire_int:
+ .long 0
+ .byte 0,9,32,64,0,0,1,0
+ .long 0
+ .long LT..q_atomic_fetch_and_add_acquire_int-.q_atomic_fetch_and_add_acquire_int
+ .short 34
+ .byte "q_atomic_fetch_and_add_acquire_int"
+ .align 2
+
+ .align 2
+ .globl q_atomic_fetch_and_add_release_int
+ .globl .q_atomic_fetch_and_add_release_int
+ .csect q_atomic_fetch_and_add_release_int[DS],3
+q_atomic_fetch_and_add_release_int:
+ .llong .q_atomic_fetch_and_add_release_int,TOC[tc0],0
+ .csect .text[PR]
+.q_atomic_fetch_and_add_release_int:
+ eieio
+ lwarx 5,0,3
+ add 6,4,5
+ extsw 7,6
+ stwcx. 7,0,3
+ bne- $-16
+ extsw 3,5
+ blr
+LT..q_atomic_fetch_and_add_release_int:
+ .long 0
+ .byte 0,9,32,64,0,0,1,0
+ .long 0
+ .long LT..q_atomic_fetch_and_add_release_int-.q_atomic_fetch_and_add_release_int
+ .short 34
+ .byte "q_atomic_fetch_and_add_release_int"
+ .align 2
+
+ .align 2
+ .globl q_atomic_fetch_and_add_ptr
+ .globl .q_atomic_fetch_and_add_ptr
+ .csect q_atomic_fetch_and_add_ptr[DS],3
+q_atomic_fetch_and_add_ptr:
+ .llong .q_atomic_fetch_and_add_ptr,TOC[tc0],0
+ .csect .text[PR]
+.q_atomic_fetch_and_add_ptr:
+ ldarx 5,0,3
+ add 6,4,5
+ stdcx. 6,0,3
+ bne- $-12
+ mr 3,5
+ blr
+LT..q_atomic_fetch_and_add_ptr:
+ .long 0
+ .byte 0,9,32,64,0,0,1,0
+ .long 0
+ .long LT..q_atomic_fetch_and_add_ptr-.q_atomic_fetch_and_add_ptr
+ .short 26
+ .byte "q_atomic_fetch_and_add_ptr"
+ .align 2
+
+ .align 2
+ .globl q_atomic_fetch_and_add_acquire_ptr
+ .globl .q_atomic_fetch_and_add_acquire_ptr
+ .csect q_atomic_fetch_and_add_acquire_ptr[DS],3
+q_atomic_fetch_and_add_acquire_ptr:
+ .llong .q_atomic_fetch_and_add_acquire_ptr,TOC[tc0],0
+ .csect .text[PR]
+.q_atomic_fetch_and_add_acquire_ptr:
+ ldarx 5,0,3
+ add 6,4,5
+ stdcx. 6,0,3
+ bne- $-12
+ isync
+ mr 3,5
+ blr
+LT..q_atomic_fetch_and_add_acquire_ptr:
+ .long 0
+ .byte 0,9,32,64,0,0,1,0
+ .long 0
+ .long LT..q_atomic_fetch_and_add_acquire_ptr-.q_atomic_fetch_and_add_acquire_ptr
+ .short 34
+ .byte "q_atomic_fetch_and_add_acquire_ptr"
+ .align 2
+
+ .align 2
+ .globl q_atomic_fetch_and_add_release_ptr
+ .globl .q_atomic_fetch_and_add_release_ptr
+ .csect q_atomic_fetch_and_add_release_ptr[DS],3
+q_atomic_fetch_and_add_release_ptr:
+ .llong .q_atomic_fetch_and_add_release_ptr,TOC[tc0],0
+ .csect .text[PR]
+.q_atomic_fetch_and_add_release_ptr:
+ eieio
+ ldarx 5,0,3
+ add 6,4,5
+ stdcx. 6,0,3
+ bne- $-12
+ mr 3,5
+ blr
+LT..q_atomic_fetch_and_add_release_ptr:
+ .long 0
+ .byte 0,9,32,64,0,0,1,0
+ .long 0
+ .long LT..q_atomic_fetch_and_add_release_ptr-.q_atomic_fetch_and_add_release_ptr
+ .short 34
+ .byte "q_atomic_fetch_and_add_release_ptr"
+ .align 2
+
+_section_.text:
+ .csect .data[RW],3
+ .llong _section_.text
diff --git a/src/corelib/arch/qatomic_alpha.h b/src/corelib/arch/qatomic_alpha.h
new file mode 100644
index 0000000000..0387baf3bc
--- /dev/null
+++ b/src/corelib/arch/qatomic_alpha.h
@@ -0,0 +1,642 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtCore module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QATOMIC_ALPHA_H
+#define QATOMIC_ALPHA_H
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+#define Q_ATOMIC_INT_REFERENCE_COUNTING_IS_ALWAYS_NATIVE
+
+inline bool QBasicAtomicInt::isReferenceCountingNative()
+{ return true; }
+inline bool QBasicAtomicInt::isReferenceCountingWaitFree()
+{ return false; }
+
+#define Q_ATOMIC_INT_TEST_AND_SET_IS_ALWAYS_NATIVE
+
+inline bool QBasicAtomicInt::isTestAndSetNative()
+{ return true; }
+inline bool QBasicAtomicInt::isTestAndSetWaitFree()
+{ return false; }
+
+#define Q_ATOMIC_INT_FETCH_AND_STORE_IS_ALWAYS_NATIVE
+
+inline bool QBasicAtomicInt::isFetchAndStoreNative()
+{ return true; }
+inline bool QBasicAtomicInt::isFetchAndStoreWaitFree()
+{ return false; }
+
+#define Q_ATOMIC_INT_FETCH_AND_ADD_IS_ALWAYS_NATIVE
+
+inline bool QBasicAtomicInt::isFetchAndAddNative()
+{ return true; }
+inline bool QBasicAtomicInt::isFetchAndAddWaitFree()
+{ return false; }
+
+#define Q_ATOMIC_POINTER_TEST_AND_SET_IS_ALWAYS_NATIVE
+
+template <typename T>
+Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::isTestAndSetNative()
+{ return true; }
+template <typename T>
+Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::isTestAndSetWaitFree()
+{ return false; }
+
+#define Q_ATOMIC_POINTER_FETCH_AND_STORE_IS_ALWAYS_NATIVE
+
+template <typename T>
+Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::isFetchAndStoreNative()
+{ return true; }
+template <typename T>
+Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::isFetchAndStoreWaitFree()
+{ return false; }
+
+#define Q_ATOMIC_POINTER_FETCH_AND_ADD_IS_ALWAYS_NATIVE
+
+template <typename T>
+Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::isFetchAndAddNative()
+{ return true; }
+template <typename T>
+Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::isFetchAndAddWaitFree()
+{ return false; }
+
+#if defined(Q_CC_GNU)
+
+inline bool QBasicAtomicInt::ref()
+{
+ register int old, tmp;
+ asm volatile("1:\n"
+ "ldl_l %0,%2\n" /* old=*ptr; */
+ "addl %0,1,%1\n" /* tmp=old+1; */
+ "stl_c %1,%2\n" /* if ((*ptr=tmp)!=tmp) tmp=0; else tmp=1; */
+ "beq %1,2f\n" /* if (tmp == 0) goto 2; */
+ "br 3f\n" /* goto 3; */
+ "2: br 1b\n" /* goto 1; */
+ "3:\n"
+ : "=&r" (old), "=&r" (tmp), "+m"(_q_value)
+ :
+ : "memory");
+ return old != -1;
+}
+
+inline bool QBasicAtomicInt::deref()
+{
+ register int old, tmp;
+ asm volatile("1:\n"
+ "ldl_l %0,%2\n" /* old=*ptr; */
+ "subl %0,1,%1\n" /* tmp=old-1; */
+ "stl_c %1,%2\n" /* if ((*ptr=tmp)!=tmp) tmp=0; else tmp=1; */
+ "beq %1,2f\n" /* if (tmp==0) goto 2; */
+ "br 3f\n" /* goto 3; */
+ "2: br 1b\n" /* goto 1; */
+ "3:\n"
+ : "=&r" (old), "=&r" (tmp), "+m"(_q_value)
+ :
+ : "memory");
+ return old != 1;
+}
+
+inline bool QBasicAtomicInt::testAndSetRelaxed(int expectedValue, int newValue)
+{
+ register int ret;
+ asm volatile("1:\n"
+ "ldl_l %0,%1\n" /* ret=*ptr; */
+ "cmpeq %0,%2,%0\n"/* if (ret==expected) ret=0; else ret=1; */
+ "beq %0,3f\n" /* if (ret==0) goto 3; */
+ "mov %3,%0\n" /* ret=newval; */
+ "stl_c %0,%1\n" /* if ((*ptr=ret)!=ret) ret=0; else ret=1; */
+ "beq %0,2f\n" /* if (ret==0) goto 2; */
+ "br 3f\n" /* goto 3; */
+ "2: br 1b\n" /* goto 1; */
+ "3:\n"
+ : "=&r" (ret), "+m" (_q_value)
+ : "r" (expectedValue), "r" (newValue)
+ : "memory");
+ return ret != 0;
+}
+
+inline bool QBasicAtomicInt::testAndSetAcquire(int expectedValue, int newValue)
+{
+ register int ret;
+ asm volatile("1:\n"
+ "ldl_l %0,%1\n" /* ret=*ptr; */
+ "cmpeq %0,%2,%0\n"/* if (ret==expected) ret=0; else ret=1; */
+ "beq %0,3f\n" /* if (ret==0) goto 3; */
+ "mov %3,%0\n" /* ret=newval; */
+ "stl_c %0,%1\n" /* if ((*ptr=ret)!=ret) ret=0; else ret=1; */
+ "beq %0,2f\n" /* if (ret==0) goto 2; */
+ "br 3f\n" /* goto 3; */
+ "2: br 1b\n" /* goto 1; */
+ "3:\n"
+ "mb\n"
+ : "=&r" (ret), "+m" (_q_value)
+ : "r" (expectedValue), "r" (newValue)
+ : "memory");
+ return ret != 0;
+}
+
+inline bool QBasicAtomicInt::testAndSetRelease(int expectedValue, int newValue)
+{
+ register int ret;
+ asm volatile("mb\n"
+ "1:\n"
+ "ldl_l %0,%1\n" /* ret=*ptr; */
+ "cmpeq %0,%2,%0\n"/* if (ret==expected) ret=0; else ret=1; */
+ "beq %0,3f\n" /* if (ret==0) goto 3; */
+ "mov %3,%0\n" /* ret=newval; */
+ "stl_c %0,%1\n" /* if ((*ptr=ret)!=ret) ret=0; else ret=1; */
+ "beq %0,2f\n" /* if (ret==0) goto 2; */
+ "br 3f\n" /* goto 3; */
+ "2: br 1b\n" /* goto 1; */
+ "3:\n"
+ : "=&r" (ret), "+m" (_q_value)
+ : "r" (expectedValue), "r" (newValue)
+ : "memory");
+ return ret != 0;
+}
+
+inline int QBasicAtomicInt::fetchAndStoreRelaxed(int newValue)
+{
+ register int old, tmp;
+ asm volatile("1:\n"
+ "ldl_l %0,%2\n" /* old=*ptr; */
+ "mov %3,%1\n" /* tmp=newval; */
+ "stl_c %1,%2\n" /* if ((*ptr=tmp)!=tmp) tmp=0; else tmp=1; */
+ "beq %1,2f\n" /* if (tmp==0) goto 2; */
+ "br 3f\n" /* goto 3; */
+ "2: br 1b\n" /* goto 1; */
+ "3:\n"
+ : "=&r" (old), "=&r" (tmp), "+m" (_q_value)
+ : "r" (newValue)
+ : "memory");
+ return old;
+}
+
+inline int QBasicAtomicInt::fetchAndStoreAcquire(int newValue)
+{
+ register int old, tmp;
+ asm volatile("1:\n"
+ "ldl_l %0,%2\n" /* old=*ptr; */
+ "mov %3,%1\n" /* tmp=newval; */
+ "stl_c %1,%2\n" /* if ((*ptr=tmp)!=tmp) tmp=0; else tmp=1; */
+ "beq %1,2f\n" /* if (tmp==0) goto 2; */
+ "br 3f\n" /* goto 3; */
+ "2: br 1b\n" /* goto 1; */
+ "3:\n"
+ "mb\n"
+ : "=&r" (old), "=&r" (tmp), "+m" (_q_value)
+ : "r" (newValue)
+ : "memory");
+ return old;
+}
+
+inline int QBasicAtomicInt::fetchAndStoreRelease(int newValue)
+{
+ register int old, tmp;
+ asm volatile("mb\n"
+ "1:\n"
+ "ldl_l %0,%2\n" /* old=*ptr; */
+ "mov %3,%1\n" /* tmp=newval; */
+ "stl_c %1,%2\n" /* if ((*ptr=tmp)!=tmp) tmp=0; else tmp=1; */
+ "beq %1,2f\n" /* if (tmp==0) goto 2; */
+ "br 3f\n" /* goto 3; */
+ "2: br 1b\n" /* goto 1; */
+ "3:\n"
+ : "=&r" (old), "=&r" (tmp), "+m" (_q_value)
+ : "r" (newValue)
+ : "memory");
+ return old;
+}
+
+inline int QBasicAtomicInt::fetchAndAddRelaxed(int valueToAdd)
+{
+ register int old, tmp;
+ asm volatile("1:\n"
+ "ldl_l %0,%2\n" /* old=*ptr; */
+ "addl %0,%3,%1\n"/* tmp=old+value; */
+ "stl_c %1,%2\n" /* if ((*ptr=tmp)!=tmp) tmp=0; else tmp=1; */
+ "beq %1,2f\n" /* if (tmp == 0) goto 2; */
+ "br 3f\n" /* goto 3; */
+ "2: br 1b\n" /* goto 1; */
+ "3:\n"
+ : "=&r" (old), "=&r" (tmp), "+m"(_q_value)
+ : "r" (valueToAdd)
+ : "memory");
+ return old;
+}
+
+inline int QBasicAtomicInt::fetchAndAddAcquire(int valueToAdd)
+{
+ register int old, tmp;
+ asm volatile("1:\n"
+ "ldl_l %0,%2\n" /* old=*ptr; */
+ "addl %0,%3,%1\n"/* tmp=old+value; */
+ "stl_c %1,%2\n" /* if ((*ptr=tmp)!=tmp) tmp=0; else tmp=1; */
+ "beq %1,2f\n" /* if (tmp == 0) goto 2; */
+ "br 3f\n" /* goto 3; */
+ "2: br 1b\n" /* goto 1; */
+ "3:\n"
+ "mb\n"
+ : "=&r" (old), "=&r" (tmp), "+m"(_q_value)
+ : "r" (valueToAdd)
+ : "memory");
+ return old;
+}
+
+inline int QBasicAtomicInt::fetchAndAddRelease(int valueToAdd)
+{
+ register int old, tmp;
+ asm volatile("mb\n"
+ "1:\n"
+ "ldl_l %0,%2\n" /* old=*ptr; */
+ "addl %0,%3,%1\n"/* tmp=old+value; */
+ "stl_c %1,%2\n" /* if ((*ptr=tmp)!=tmp) tmp=0; else tmp=1; */
+ "beq %1,2f\n" /* if (tmp == 0) goto 2; */
+ "br 3f\n" /* goto 3; */
+ "2: br 1b\n" /* goto 1; */
+ "3:\n"
+ : "=&r" (old), "=&r" (tmp), "+m"(_q_value)
+ : "r" (valueToAdd)
+ : "memory");
+ return old;
+}
+
+template <typename T>
+Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::testAndSetRelaxed(T *expectedValue, T *newValue)
+{
+ register void *ret;
+ asm volatile("1:\n"
+ "ldq_l %0,%1\n" /* ret=*ptr; */
+ "cmpeq %0,%2,%0\n"/* if (ret==expected) tmp=0; else tmp=1; */
+ "beq %0,3f\n" /* if (tmp==0) goto 3; */
+ "mov %3,%0\n" /* tmp=newval; */
+ "stq_c %0,%1\n" /* if ((*ptr=tmp)!=tmp) tmp=0; else tmp=1; */
+ "beq %0,2f\n" /* if (ret==0) goto 2; */
+ "br 3f\n" /* goto 3; */
+ "2: br 1b\n" /* goto 1; */
+ "3:\n"
+ : "=&r" (ret), "+m" (_q_value)
+ : "r" (expectedValue), "r" (newValue)
+ : "memory");
+ return ret != 0;
+}
+
+template <typename T>
+Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::testAndSetAcquire(T *expectedValue, T *newValue)
+{
+ register void *ret;
+ asm volatile("1:\n"
+ "ldq_l %0,%1\n" /* ret=*ptr; */
+ "cmpeq %0,%2,%0\n"/* if (ret==expected) tmp=0; else tmp=1; */
+ "beq %0,3f\n" /* if (tmp==0) goto 3; */
+ "mov %3,%0\n" /* tmp=newval; */
+ "stq_c %0,%1\n" /* if ((*ptr=tmp)!=tmp) tmp=0; else tmp=1; */
+ "beq %0,2f\n" /* if (ret==0) goto 2; */
+ "br 3f\n" /* goto 3; */
+ "2: br 1b\n" /* goto 1; */
+ "3:\n"
+ "mb\n"
+ : "=&r" (ret), "+m" (_q_value)
+ : "r" (expectedValue), "r" (newValue)
+ : "memory");
+ return ret != 0;
+}
+
+template <typename T>
+Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::testAndSetRelease(T *expectedValue, T *newValue)
+{
+ register void *ret;
+ asm volatile("mb\n"
+ "1:\n"
+ "ldq_l %0,%1\n" /* ret=*ptr; */
+ "cmpeq %0,%2,%0\n"/* if (ret==expected) tmp=0; else tmp=1; */
+ "beq %0,3f\n" /* if (tmp==0) goto 3; */
+ "mov %3,%0\n" /* tmp=newval; */
+ "stq_c %0,%1\n" /* if ((*ptr=tmp)!=tmp) tmp=0; else tmp=1; */
+ "beq %0,2f\n" /* if (ret==0) goto 2; */
+ "br 3f\n" /* goto 3; */
+ "2: br 1b\n" /* goto 1; */
+ "3:\n"
+ : "=&r" (ret), "+m" (_q_value)
+ : "r" (expectedValue), "r" (newValue)
+ : "memory");
+ return ret != 0;
+}
+
+template <typename T>
+Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndStoreRelaxed(T *newValue)
+{
+ register void *old, *tmp;
+ asm volatile("1:\n"
+ "ldq_l %0,%2\n" /* old=*ptr; */
+ "mov %3,%1\n" /* tmp=newval; */
+ "stq_c %1,%2\n" /* if ((*ptr=tmp)!=tmp) tmp=0; else tmp=1; */
+ "beq %1,2f\n" /* if (tmp==0) goto 2; */
+ "br 3f\n" /* goto 3; */
+ "2: br 1b\n" /* goto 1; */
+ "3:\n"
+ : "=&r" (old), "=&r" (tmp), "+m" (_q_value)
+ : "r" (newValue)
+ : "memory");
+ return old;
+}
+
+template <typename T>
+Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndStoreAcquire(T *newValue)
+{
+ register void *old, *tmp;
+ asm volatile("1:\n"
+ "ldq_l %0,%2\n" /* old=*ptr; */
+ "mov %3,%1\n" /* tmp=newval; */
+ "stq_c %1,%2\n" /* if ((*ptr=tmp)!=tmp) tmp=0; else tmp=1; */
+ "beq %1,2f\n" /* if (tmp==0) goto 2; */
+ "br 3f\n" /* goto 3; */
+ "2: br 1b\n" /* goto 1; */
+ "3:\n"
+ "mb\n"
+ : "=&r" (old), "=&r" (tmp), "+m" (_q_value)
+ : "r" (newValue)
+ : "memory");
+ return old;
+}
+
+template <typename T>
+Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndStoreRelease(T *newValue)
+{
+ register void *old, *tmp;
+ asm volatile("mb\n"
+ "1:\n"
+ "ldq_l %0,%2\n" /* old=*ptr; */
+ "mov %3,%1\n" /* tmp=newval; */
+ "stq_c %1,%2\n" /* if ((*ptr=tmp)!=tmp) tmp=0; else tmp=1; */
+ "beq %1,2f\n" /* if (tmp==0) goto 2; */
+ "br 3f\n" /* goto 3; */
+ "2: br 1b\n" /* goto 1; */
+ "3:\n"
+ : "=&r" (old), "=&r" (tmp), "+m" (_q_value)
+ : "r" (newValue)
+ : "memory");
+ return old;
+}
+
+template <typename T>
+Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndAddRelaxed(qptrdiff valueToAdd)
+{
+ register void *old, *tmp;
+ asm volatile("1:\n"
+ "ldq_l %0,%2\n" /* old=*ptr; */
+ "addq %0,%3,%1\n"/* tmp=old+value; */
+ "stq_c %1,%2\n" /* if ((*ptr=tmp)!=tmp) tmp=0; else tmp=1; */
+ "beq %1,2f\n" /* if (tmp == 0) goto 2; */
+ "br 3f\n" /* goto 3; */
+ "2: br 1b\n" /* goto 1; */
+ "3:\n"
+ : "=&r" (old), "=&r" (tmp), "+m"(_q_value)
+ : "r" (valueToAdd)
+ : "memory");
+ return reinterpret_cast<T *>(old);
+}
+
+template <typename T>
+Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndAddAcquire(qptrdiff valueToAdd)
+{
+ register void *old, *tmp;
+ asm volatile("1:\n"
+ "ldq_l %0,%2\n" /* old=*ptr; */
+ "addq %0,%3,%1\n"/* tmp=old+value; */
+ "stq_c %1,%2\n" /* if ((*ptr=tmp)!=tmp) tmp=0; else tmp=1; */
+ "beq %1,2f\n" /* if (tmp == 0) goto 2; */
+ "br 3f\n" /* goto 3; */
+ "2: br 1b\n" /* goto 1; */
+ "3:\n"
+ "mb\n"
+ : "=&r" (old), "=&r" (tmp), "+m"(_q_value)
+ : "r" (valueToAdd)
+ : "memory");
+ return reinterpret_cast<T *>(old);
+}
+
+template <typename T>
+Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndAddRelease(qptrdiff valueToAdd)
+{
+ register void *old, *tmp;
+ asm volatile("mb\n"
+ "1:\n"
+ "ldq_l %0,%2\n" /* old=*ptr; */
+ "addq %0,%3,%1\n"/* tmp=old+value; */
+ "stq_c %1,%2\n" /* if ((*ptr=tmp)!=tmp) tmp=0; else tmp=1; */
+ "beq %1,2f\n" /* if (tmp == 0) goto 2; */
+ "br 3f\n" /* goto 3; */
+ "2: br 1b\n" /* goto 1; */
+ "3:\n"
+ : "=&r" (old), "=&r" (tmp), "+m"(_q_value)
+ : "r" (valueToAdd)
+ : "memory");
+ return reinterpret_cast<T *>(old);
+}
+
+#else // !Q_CC_GNU
+
+extern "C" {
+ Q_CORE_EXPORT int q_atomic_test_and_set_int(volatile int *ptr, int expected, int newval);
+ Q_CORE_EXPORT int q_atomic_test_and_set_acquire_int(volatile int *ptr, int expected, int newval);
+ Q_CORE_EXPORT int q_atomic_test_and_set_release_int(volatile int *ptr, int expected, int newval);
+ Q_CORE_EXPORT int q_atomic_test_and_set_ptr(volatile void *ptr, void *expected, void *newval);
+ Q_CORE_EXPORT int q_atomic_increment(volatile int *ptr);
+ Q_CORE_EXPORT int q_atomic_decrement(volatile int *ptr);
+ Q_CORE_EXPORT int q_atomic_set_int(volatile int *ptr, int newval);
+ Q_CORE_EXPORT void *q_atomic_set_ptr(volatile void *ptr, void *newval);
+ Q_CORE_EXPORT int q_atomic_fetch_and_add_int(volatile int *ptr, int value);
+ Q_CORE_EXPORT int q_atomic_fetch_and_add_acquire_int(volatile int *ptr, int value);
+ Q_CORE_EXPORT int q_atomic_fetch_and_add_release_int(volatile int *ptr, int value);
+} // extern "C"
+
+inline bool QBasicAtomicInt::ref()
+{
+ return q_atomic_increment(&_q_value) != 0;
+}
+
+inline bool QBasicAtomicInt::deref()
+{
+ return q_atomic_decrement(&_q_value) != 0;
+}
+
+inline bool QBasicAtomicInt::testAndSetRelaxed(int expectedValue, int newValue)
+{
+ return q_atomic_test_and_set_int(&_q_value, expectedValue, newValue) != 0;
+}
+
+inline bool QBasicAtomicInt::testAndSetAcquire(int expectedValue, int newValue)
+{
+ return q_atomic_test_and_set_acquire_int(&_q_value, expectedValue, newValue) != 0;
+}
+
+inline bool QBasicAtomicInt::testAndSetRelease(int expectedValue, int newValue)
+{
+ return q_atomic_test_and_set_release_int(&_q_value, expectedValue, newValue) != 0;
+}
+
+inline int QBasicAtomicInt::fetchAndStoreRelaxed(int newValue)
+{
+ return q_atomic_set_int(&_q_value, newValue);
+}
+
+inline int QBasicAtomicInt::fetchAndStoreAcquire(int newValue)
+{
+ return q_atomic_fetch_and_store_acquire_int(&_q_value, newValue);
+}
+
+inline int QBasicAtomicInt::fetchAndStoreRelease(int newValue)
+{
+ return q_atomic_fetch_and_store_release_int(&_q_value, newValue);
+}
+
+inline int QBasicAtomicInt::fetchAndAddRelaxed(int valueToAdd)
+{
+ return q_atomic_fetch_and_add_int(&_q_value, valueToAdd);
+}
+
+inline int QBasicAtomicInt::fetchAndAddAcquire(int valueToAdd)
+{
+ return q_atomic_fetch_and_add_acquire_int(&_q_value, valueToAdd);
+}
+
+inline int QBasicAtomicInt::fetchAndAddRelease(int valueToAdd)
+{
+ return q_atomic_fetch_and_add_release_int(&_q_value, valueToAdd);
+}
+
+template <typename T>
+Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::testAndSetRelaxed(T *expectedValue, T *newValue)
+{
+ return q_atomic_test_and_set_ptr(&_q_value, expectedValue, newValue) != 0;
+}
+
+template <typename T>
+Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::testAndSetAcquire(T *expectedValue, T *newValue)
+{
+ return q_atomic_test_and_set_acquire_ptr(&_q_value, expectedValue, newValue) != 0;
+}
+
+template <typename T>
+Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::testAndSetRelease(T *expectedValue, T *newValue)
+{
+ return q_atomic_test_and_set_release_ptr(&_q_value, expectedValue, newValue) != 0;
+}
+
+template <typename T>
+Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndStoreRelaxed(T *newValue)
+{
+ return reinterpret_cast<T *>(q_atomic_set_ptr(&_q_value, newValue));
+}
+
+template <typename T>
+Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndStoreAcquire(T *newValue)
+{
+ return reinterpret_cast<T *>(q_atomic_fetch_and_store_acquire_ptr(&_q_value, newValue));
+}
+
+template <typename T>
+Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndStoreRelease(T *newValue)
+{
+ return reinterpret_cast<T *>(q_atomic_fetch_and_store_release_ptr(&_q_value, newValue));
+}
+
+template <typename T>
+Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndAddRelaxed(qptrdiff valueToAdd)
+{
+ return reinterpret_cast<T *>(q_atomic_fetch_and_add_ptr(&_q_value, newValue));
+}
+template <typename T>
+Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndAddAcquire(qptrdiff valueToAdd)
+{
+ return reinterpret_cast<T *>(q_atomic_fetch_and_add_acquire_ptr(&_q_value, newValue));
+}
+
+template <typename T>
+Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndAddRelease(qptrdiff valueToAdd)
+{
+ return reinterpret_cast<T *>(q_atomic_fetch_and_add_release_ptr(&_q_value, newValue));
+}
+
+#endif // Q_CC_GNU
+
+inline bool QBasicAtomicInt::testAndSetOrdered(int expectedValue, int newValue)
+{
+ return testAndSetAcquire(expectedValue, newValue);
+}
+
+inline int QBasicAtomicInt::fetchAndStoreOrdered(int newValue)
+{
+ return fetchAndStoreAcquire(newValue);
+}
+
+inline int QBasicAtomicInt::fetchAndAddOrdered(int valueToAdd)
+{
+ return fetchAndAddAcquire(valueToAdd);
+}
+
+template <typename T>
+Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::testAndSetOrdered(T *expectedValue, T *newValue)
+{
+ return testAndSetAcquire(expectedValue, newValue);
+}
+
+template <typename T>
+Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndStoreOrdered(T *newValue)
+{
+ return fetchAndStoreAcquire(newValue);
+}
+
+template <typename T>
+Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndAddOrdered(qptrdiff valueToAdd)
+{
+ return fetchAndAddAcquire(valueToAdd);
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // QATOMIC_ALPHA_H
diff --git a/src/corelib/arch/qatomic_arch.h b/src/corelib/arch/qatomic_arch.h
new file mode 100644
index 0000000000..33641fc3d3
--- /dev/null
+++ b/src/corelib/arch/qatomic_arch.h
@@ -0,0 +1,93 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtCore module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QATOMIC_ARCH_H
+#define QATOMIC_ARCH_H
+
+QT_BEGIN_HEADER
+
+#include "QtCore/qglobal.h"
+
+#if defined(QT_ARCH_ALPHA)
+# include "QtCore/qatomic_alpha.h"
+#elif defined(QT_ARCH_ARM)
+# include "QtCore/qatomic_arm.h"
+#elif defined(QT_ARCH_ARMV6)
+# include "QtCore/qatomic_armv6.h"
+#elif defined(QT_ARCH_AVR32)
+# include "QtCore/qatomic_avr32.h"
+#elif defined(QT_ARCH_BFIN)
+# include "QtCore/qatomic_bfin.h"
+#elif defined(QT_ARCH_GENERIC)
+# include "QtCore/qatomic_generic.h"
+#elif defined(QT_ARCH_I386)
+# include "QtCore/qatomic_i386.h"
+#elif defined(QT_ARCH_IA64)
+# include "QtCore/qatomic_ia64.h"
+#elif defined(QT_ARCH_MACOSX)
+# include "QtCore/qatomic_macosx.h"
+#elif defined(QT_ARCH_MIPS)
+# include "QtCore/qatomic_mips.h"
+#elif defined(QT_ARCH_PARISC)
+# include "QtCore/qatomic_parisc.h"
+#elif defined(QT_ARCH_POWERPC)
+# include "QtCore/qatomic_powerpc.h"
+#elif defined(QT_ARCH_S390)
+# include "QtCore/qatomic_s390.h"
+#elif defined(QT_ARCH_SPARC)
+# include "QtCore/qatomic_sparc.h"
+#elif defined(QT_ARCH_WINDOWS)
+# include "QtCore/qatomic_windows.h"
+#elif defined(QT_ARCH_WINDOWSCE)
+# include "QtCore/qatomic_windowsce.h"
+#elif defined(QT_ARCH_X86_64)
+# include "QtCore/qatomic_x86_64.h"
+#elif defined(QT_ARCH_SH)
+# include "QtCore/qatomic_sh.h"
+#elif defined(QT_ARCH_SH4A)
+# include "QtCore/qatomic_sh4a.h"
+#else
+# error "Qt has not been ported to this architecture"
+#endif
+
+QT_END_HEADER
+
+#endif // QATOMIC_ARCH_H
diff --git a/src/corelib/arch/qatomic_arm.h b/src/corelib/arch/qatomic_arm.h
new file mode 100644
index 0000000000..07ad70ca50
--- /dev/null
+++ b/src/corelib/arch/qatomic_arm.h
@@ -0,0 +1,401 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtCore module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QATOMIC_ARM_H
+#define QATOMIC_ARM_H
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+#define Q_ATOMIC_INT_REFERENCE_COUNTING_IS_NOT_NATIVE
+
+inline bool QBasicAtomicInt::isReferenceCountingNative()
+{ return false; }
+inline bool QBasicAtomicInt::isReferenceCountingWaitFree()
+{ return false; }
+
+#define Q_ATOMIC_INT_TEST_AND_SET_IS_NOT_NATIVE
+
+inline bool QBasicAtomicInt::isTestAndSetNative()
+{ return false; }
+inline bool QBasicAtomicInt::isTestAndSetWaitFree()
+{ return false; }
+
+#define Q_ATOMIC_INT_FETCH_AND_STORE_IS_ALWAYS_NATIVE
+#define Q_ATOMIC_INT_FETCH_AND_STORE_IS_WAIT_FREE
+
+inline bool QBasicAtomicInt::isFetchAndStoreNative()
+{ return true; }
+inline bool QBasicAtomicInt::isFetchAndStoreWaitFree()
+{ return true; }
+
+#define Q_ATOMIC_INT_FETCH_AND_ADD_IS_NOT_NATIVE
+
+inline bool QBasicAtomicInt::isFetchAndAddNative()
+{ return false; }
+inline bool QBasicAtomicInt::isFetchAndAddWaitFree()
+{ return false; }
+
+#define Q_ATOMIC_POINTER_TEST_AND_SET_IS_NOT_NATIVE
+
+template <typename T>
+Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::isTestAndSetNative()
+{ return false; }
+template <typename T>
+Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::isTestAndSetWaitFree()
+{ return false; }
+
+#define Q_ATOMIC_POINTER_FETCH_AND_STORE_IS_ALWAYS_NATIVE
+#define Q_ATOMIC_POINTER_FETCH_AND_STORE_IS_WAIT_FREE
+
+template <typename T>
+Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::isFetchAndStoreNative()
+{ return true; }
+template <typename T>
+Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::isFetchAndStoreWaitFree()
+{ return true; }
+
+#define Q_ATOMIC_POINTER_FETCH_AND_ADD_IS_NOT_NATIVE
+
+template <typename T>
+Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::isFetchAndAddNative()
+{ return false; }
+template <typename T>
+Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::isFetchAndAddWaitFree()
+{ return false; }
+
+#ifndef QT_NO_ARM_EABI
+
+// kernel places a restartable cmpxchg implementation at a fixed address
+extern "C" typedef int (qt_atomic_eabi_cmpxchg_int_t)(int oldval, int newval, volatile int *ptr);
+extern "C" typedef int (qt_atomic_eabi_cmpxchg_ptr_t)(void *oldval, void *newval, volatile void *ptr);
+#define qt_atomic_eabi_cmpxchg_int (*(qt_atomic_eabi_cmpxchg_int_t *)0xffff0fc0)
+#define qt_atomic_eabi_cmpxchg_ptr (*(qt_atomic_eabi_cmpxchg_ptr_t *)0xffff0fc0)
+
+#else
+
+extern Q_CORE_EXPORT char q_atomic_lock;
+Q_CORE_EXPORT void qt_atomic_yield(int *);
+
+inline char q_atomic_swp(volatile char *ptr, char newval)
+{
+ register char ret;
+ asm volatile("swpb %0,%2,[%3]"
+ : "=&r"(ret), "=m" (*ptr)
+ : "r"(newval), "r"(ptr)
+ : "cc", "memory");
+ return ret;
+}
+
+#endif
+
+// Reference counting
+
+inline bool QBasicAtomicInt::ref()
+{
+#ifndef QT_NO_ARM_EABI
+ register int originalValue;
+ register int newValue;
+ do {
+ originalValue = _q_value;
+ newValue = originalValue + 1;
+ } while (qt_atomic_eabi_cmpxchg_int(originalValue, newValue, &_q_value) != 0);
+ return newValue != 0;
+#else
+ int count = 0;
+ while (q_atomic_swp(&q_atomic_lock, ~0) != 0)
+ qt_atomic_yield(&count);
+ int originalValue = _q_value++;
+ q_atomic_swp(&q_atomic_lock, 0);
+ return originalValue != -1;
+#endif
+}
+
+inline bool QBasicAtomicInt::deref()
+{
+#ifndef QT_NO_ARM_EABI
+ register int originalValue;
+ register int newValue;
+ do {
+ originalValue = _q_value;
+ newValue = originalValue - 1;
+ } while (qt_atomic_eabi_cmpxchg_int(originalValue, newValue, &_q_value) != 0);
+ return newValue != 0;
+#else
+ int count = 0;
+ while (q_atomic_swp(&q_atomic_lock, ~0) != 0)
+ qt_atomic_yield(&count);
+ int originalValue = _q_value--;
+ q_atomic_swp(&q_atomic_lock, 0);
+ return originalValue != 1;
+#endif
+}
+
+// Test and set for integers
+
+inline bool QBasicAtomicInt::testAndSetOrdered(int expectedValue, int newValue)
+{
+#ifndef QT_NO_ARM_EABI
+ register int originalValue;
+ do {
+ originalValue = _q_value;
+ if (originalValue != expectedValue)
+ return false;
+ } while (qt_atomic_eabi_cmpxchg_int(expectedValue, newValue, &_q_value) != 0);
+ return true;
+#else
+ bool returnValue = false;
+ int count = 0;
+ while (q_atomic_swp(&q_atomic_lock, ~0) != 0)
+ qt_atomic_yield(&count);
+ if (_q_value == expectedValue) {
+ _q_value = newValue;
+ returnValue = true;
+ }
+ q_atomic_swp(&q_atomic_lock, 0);
+ return returnValue;
+#endif
+}
+
+inline bool QBasicAtomicInt::testAndSetRelaxed(int expectedValue, int newValue)
+{
+ return testAndSetOrdered(expectedValue, newValue);
+}
+
+inline bool QBasicAtomicInt::testAndSetAcquire(int expectedValue, int newValue)
+{
+ return testAndSetOrdered(expectedValue, newValue);
+}
+
+inline bool QBasicAtomicInt::testAndSetRelease(int expectedValue, int newValue)
+{
+ return testAndSetOrdered(expectedValue, newValue);
+}
+
+// Fetch and store for integers
+
+inline int QBasicAtomicInt::fetchAndStoreOrdered(int newValue)
+{
+ int originalValue;
+ asm volatile("swp %0,%2,[%3]"
+ : "=&r"(originalValue), "=m" (_q_value)
+ : "r"(newValue), "r"(&_q_value)
+ : "cc", "memory");
+ return originalValue;
+}
+
+inline int QBasicAtomicInt::fetchAndStoreRelaxed(int newValue)
+{
+ return fetchAndStoreOrdered(newValue);
+}
+
+inline int QBasicAtomicInt::fetchAndStoreAcquire(int newValue)
+{
+ return fetchAndStoreOrdered(newValue);
+}
+
+inline int QBasicAtomicInt::fetchAndStoreRelease(int newValue)
+{
+ return fetchAndStoreOrdered(newValue);
+}
+
+// Fetch and add for integers
+
+inline int QBasicAtomicInt::fetchAndAddOrdered(int valueToAdd)
+{
+#ifndef QT_NO_ARM_EABI
+ register int originalValue;
+ register int newValue;
+ do {
+ originalValue = _q_value;
+ newValue = originalValue + valueToAdd;
+ } while (qt_atomic_eabi_cmpxchg_int(originalValue, newValue, &_q_value) != 0);
+ return originalValue;
+#else
+ int count = 0;
+ while (q_atomic_swp(&q_atomic_lock, ~0) != 0)
+ qt_atomic_yield(&count);
+ int originalValue = _q_value;
+ _q_value += valueToAdd;
+ q_atomic_swp(&q_atomic_lock, 0);
+ return originalValue;
+#endif
+}
+
+inline int QBasicAtomicInt::fetchAndAddRelaxed(int valueToAdd)
+{
+ return fetchAndAddOrdered(valueToAdd);
+}
+
+inline int QBasicAtomicInt::fetchAndAddAcquire(int valueToAdd)
+{
+ return fetchAndAddOrdered(valueToAdd);
+}
+
+inline int QBasicAtomicInt::fetchAndAddRelease(int valueToAdd)
+{
+ return fetchAndAddOrdered(valueToAdd);
+}
+
+// Test and set for pointers
+
+template <typename T>
+Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::testAndSetOrdered(T *expectedValue, T *newValue)
+{
+#ifndef QT_NO_ARM_EABI
+ register T *originalValue;
+ do {
+ originalValue = _q_value;
+ if (originalValue != expectedValue)
+ return false;
+ } while (qt_atomic_eabi_cmpxchg_ptr(expectedValue, newValue, &_q_value) != 0);
+ return true;
+#else
+ bool returnValue = false;
+ int count = 0;
+ while (q_atomic_swp(&q_atomic_lock, ~0) != 0)
+ qt_atomic_yield(&count);
+ if (_q_value == expectedValue) {
+ _q_value = newValue;
+ returnValue = true;
+ }
+ q_atomic_swp(&q_atomic_lock, 0);
+ return returnValue;
+#endif
+}
+
+template <typename T>
+Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::testAndSetRelaxed(T *expectedValue, T *newValue)
+{
+ return testAndSetOrdered(expectedValue, newValue);
+}
+
+template <typename T>
+Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::testAndSetAcquire(T *expectedValue, T *newValue)
+{
+ return testAndSetOrdered(expectedValue, newValue);
+}
+
+template <typename T>
+Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::testAndSetRelease(T *expectedValue, T *newValue)
+{
+ return testAndSetOrdered(expectedValue, newValue);
+}
+
+// Fetch and store for pointers
+
+template <typename T>
+Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndStoreOrdered(T *newValue)
+{
+ T *originalValue;
+ asm volatile("swp %0,%2,[%3]"
+ : "=&r"(originalValue), "=m" (_q_value)
+ : "r"(newValue), "r"(&_q_value)
+ : "cc", "memory");
+ return originalValue;
+}
+
+template <typename T>
+Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndStoreRelaxed(T *newValue)
+{
+ return fetchAndStoreOrdered(newValue);
+}
+
+template <typename T>
+Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndStoreAcquire(T *newValue)
+{
+ return fetchAndStoreOrdered(newValue);
+}
+
+template <typename T>
+Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndStoreRelease(T *newValue)
+{
+ return fetchAndStoreOrdered(newValue);
+}
+
+// Fetch and add for pointers
+
+template <typename T>
+Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndAddOrdered(qptrdiff valueToAdd)
+{
+#ifndef QT_NO_ARM_EABI
+ register T *originalValue;
+ register T *newValue;
+ do {
+ originalValue = _q_value;
+ newValue = originalValue + valueToAdd;
+ } while (qt_atomic_eabi_cmpxchg_ptr(originalValue, newValue, &_q_value) != 0);
+ return originalValue;
+#else
+ int count = 0;
+ while (q_atomic_swp(&q_atomic_lock, ~0) != 0)
+ qt_atomic_yield(&count);
+ T *originalValue = (_q_value);
+ _q_value += valueToAdd;
+ q_atomic_swp(&q_atomic_lock, 0);
+ return originalValue;
+#endif
+}
+
+template <typename T>
+Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndAddRelaxed(qptrdiff valueToAdd)
+{
+ return fetchAndAddOrdered(valueToAdd);
+}
+
+template <typename T>
+Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndAddAcquire(qptrdiff valueToAdd)
+{
+ return fetchAndAddOrdered(valueToAdd);
+}
+
+template <typename T>
+Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndAddRelease(qptrdiff valueToAdd)
+{
+ return fetchAndAddOrdered(valueToAdd);
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // QATOMIC_ARM_H
diff --git a/src/corelib/arch/qatomic_armv6.h b/src/corelib/arch/qatomic_armv6.h
new file mode 100644
index 0000000000..2dd38fdd82
--- /dev/null
+++ b/src/corelib/arch/qatomic_armv6.h
@@ -0,0 +1,360 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtCore module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QATOMIC_ARMV6_H
+#define QATOMIC_ARMV6_H
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+#define Q_ATOMIC_INT_REFERENCE_COUNTING_IS_ALWAYS_NATIVE
+
+inline bool QBasicAtomicInt::isReferenceCountingNative()
+{ return true; }
+inline bool QBasicAtomicInt::isReferenceCountingWaitFree()
+{ return false; }
+
+#define Q_ATOMIC_INT_TEST_AND_SET_IS_ALWAYS_NATIVE
+
+inline bool QBasicAtomicInt::isTestAndSetNative()
+{ return true; }
+inline bool QBasicAtomicInt::isTestAndSetWaitFree()
+{ return false; }
+
+#define Q_ATOMIC_INT_FETCH_AND_STORE_IS_ALWAYS_NATIVE
+
+inline bool QBasicAtomicInt::isFetchAndStoreNative()
+{ return true; }
+inline bool QBasicAtomicInt::isFetchAndStoreWaitFree()
+{ return false; }
+
+#define Q_ATOMIC_INT_FETCH_AND_ADD_IS_ALWAYS_NATIVE
+
+inline bool QBasicAtomicInt::isFetchAndAddNative()
+{ return true; }
+inline bool QBasicAtomicInt::isFetchAndAddWaitFree()
+{ return false; }
+
+#define Q_ATOMIC_POINTER_TEST_AND_SET_IS_ALWAYS_NATIVE
+
+template <typename T>
+Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::isTestAndSetNative()
+{ return true; }
+template <typename T>
+Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::isTestAndSetWaitFree()
+{ return false; }
+
+#define Q_ATOMIC_POINTER_FETCH_AND_STORE_IS_ALWAYS_NATIVE
+
+template <typename T>
+Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::isFetchAndStoreNative()
+{ return true; }
+template <typename T>
+Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::isFetchAndStoreWaitFree()
+{ return false; }
+
+#define Q_ATOMIC_POINTER_FETCH_AND_ADD_IS_ALWAYS_NATIVE
+
+template <typename T>
+Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::isFetchAndAddNative()
+{ return true; }
+template <typename T>
+Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::isFetchAndAddWaitFree()
+{ return false; }
+
+inline bool QBasicAtomicInt::ref()
+{
+ register int newValue;
+ register int result;
+ asm volatile("0:\n"
+ "ldrex %[newValue], [%[_q_value]]\n"
+ "add %[newValue], %[newValue], #1\n"
+ "strex %[result], %[newValue], [%[_q_value]]\n"
+ "teq %[result], #0\n"
+ "bne 0b\n"
+ : [newValue] "=&r" (newValue),
+ [result] "=&r" (result),
+ "+m" (_q_value)
+ : [_q_value] "r" (&_q_value)
+ : "cc", "memory");
+ return newValue != 0;
+}
+
+inline bool QBasicAtomicInt::deref()
+{
+ register int newValue;
+ register int result;
+ asm volatile("0:\n"
+ "ldrex %[newValue], [%[_q_value]]\n"
+ "sub %[newValue], %[newValue], #1\n"
+ "strex %[result], %[newValue], [%[_q_value]]\n"
+ "teq %[result], #0\n"
+ "bne 0b\n"
+ : [newValue] "=&r" (newValue),
+ [result] "=&r" (result),
+ "+m" (_q_value)
+ : [_q_value] "r" (&_q_value)
+ : "cc", "memory");
+ return newValue != 0;
+}
+
+inline bool QBasicAtomicInt::testAndSetOrdered(int expectedValue, int newValue)
+{
+ register int result;
+ asm volatile("0:\n"
+ "ldrex %[result], [%[_q_value]]\n"
+ "eors %[result], %[result], %[expectedValue]\n"
+ "strexeq %[result], %[newValue], [%[_q_value]]\n"
+ "teqeq %[result], #1\n"
+ "beq 0b\n"
+ : [result] "=&r" (result),
+ "+m" (_q_value)
+ : [expectedValue] "r" (expectedValue),
+ [newValue] "r" (newValue),
+ [_q_value] "r" (&_q_value)
+ : "cc", "memory");
+ return result == 0;
+}
+
+inline bool QBasicAtomicInt::testAndSetRelaxed(int expectedValue, int newValue)
+{
+ return testAndSetOrdered(expectedValue, newValue);
+}
+
+inline bool QBasicAtomicInt::testAndSetAcquire(int expectedValue, int newValue)
+{
+ return testAndSetOrdered(expectedValue, newValue);
+}
+
+inline bool QBasicAtomicInt::testAndSetRelease(int expectedValue, int newValue)
+{
+ return testAndSetOrdered(expectedValue, newValue);
+}
+
+inline int QBasicAtomicInt::fetchAndStoreOrdered(int newValue)
+{
+ register int originalValue;
+ register int result;
+ asm volatile("0:\n"
+ "ldrex %[originalValue], [%[_q_value]]\n"
+ "strex %[result], %[newValue], [%[_q_value]]\n"
+ "teq %[result], #0\n"
+ "bne 0b\n"
+ : [originalValue] "=&r" (originalValue),
+ [result] "=&r" (result),
+ "+m" (_q_value)
+ : [newValue] "r" (newValue),
+ [_q_value] "r" (&_q_value)
+ : "cc", "memory");
+ return originalValue;
+}
+
+inline int QBasicAtomicInt::fetchAndStoreRelaxed(int newValue)
+{
+ return fetchAndStoreOrdered(newValue);
+}
+
+inline int QBasicAtomicInt::fetchAndStoreAcquire(int newValue)
+{
+ return fetchAndStoreOrdered(newValue);
+}
+
+inline int QBasicAtomicInt::fetchAndStoreRelease(int newValue)
+{
+ return fetchAndStoreOrdered(newValue);
+}
+
+inline int QBasicAtomicInt::fetchAndAddOrdered(int valueToAdd)
+{
+ register int originalValue;
+ register int newValue;
+ register int result;
+ asm volatile("0:\n"
+ "ldrex %[originalValue], [%[_q_value]]\n"
+ "add %[newValue], %[originalValue], %[valueToAdd]\n"
+ "strex %[result], %[newValue], [%[_q_value]]\n"
+ "teq %[result], #0\n"
+ "bne 0b\n"
+ : [originalValue] "=&r" (originalValue),
+ [newValue] "=&r" (newValue),
+ [result] "=&r" (result),
+ "+m" (_q_value)
+ : [valueToAdd] "r" (valueToAdd),
+ [_q_value] "r" (&_q_value)
+ : "cc", "memory");
+ return originalValue;
+}
+
+inline int QBasicAtomicInt::fetchAndAddRelaxed(int valueToAdd)
+{
+ return fetchAndAddOrdered(valueToAdd);
+}
+
+inline int QBasicAtomicInt::fetchAndAddAcquire(int valueToAdd)
+{
+ return fetchAndAddOrdered(valueToAdd);
+}
+
+inline int QBasicAtomicInt::fetchAndAddRelease(int valueToAdd)
+{
+ return fetchAndAddOrdered(valueToAdd);
+}
+
+template <typename T>
+Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::testAndSetOrdered(T *expectedValue, T *newValue)
+{
+ register T *result;
+ asm volatile("0:\n"
+ "ldrex %[result], [%[_q_value]]\n"
+ "eors %[result], %[result], %[expectedValue]\n"
+ "strexeq %[result], %[newValue], [%[_q_value]]\n"
+ "teqeq %[result], #1\n"
+ "beq 0b\n"
+ : [result] "=&r" (result),
+ "+m" (_q_value)
+ : [expectedValue] "r" (expectedValue),
+ [newValue] "r" (newValue),
+ [_q_value] "r" (&_q_value)
+ : "cc", "memory");
+ return result == 0;
+}
+
+template <typename T>
+Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::testAndSetRelaxed(T *expectedValue, T *newValue)
+{
+ return testAndSetOrdered(expectedValue, newValue);
+}
+
+template <typename T>
+Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::testAndSetAcquire(T *expectedValue, T *newValue)
+{
+ return testAndSetOrdered(expectedValue, newValue);
+}
+
+template <typename T>
+Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::testAndSetRelease(T *expectedValue, T *newValue)
+{
+ return testAndSetOrdered(expectedValue, newValue);
+}
+
+template <typename T>
+Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndStoreOrdered(T *newValue)
+{
+ register T *originalValue;
+ register int result;
+ asm volatile("0:\n"
+ "ldrex %[originalValue], [%[_q_value]]\n"
+ "strex %[result], %[newValue], [%[_q_value]]\n"
+ "teq %[result], #0\n"
+ "bne 0b\n"
+ : [originalValue] "=&r" (originalValue),
+ [result] "=&r" (result),
+ "+m" (_q_value)
+ : [newValue] "r" (newValue),
+ [_q_value] "r" (&_q_value)
+ : "cc", "memory");
+ return originalValue;
+}
+
+template <typename T>
+Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndStoreRelaxed(T *newValue)
+{
+ return fetchAndStoreOrdered(newValue);
+}
+
+template <typename T>
+Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndStoreAcquire(T *newValue)
+{
+ return fetchAndStoreOrdered(newValue);
+}
+
+template <typename T>
+Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndStoreRelease(T *newValue)
+{
+ return fetchAndStoreOrdered(newValue);
+}
+
+template <typename T>
+Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndAddOrdered(qptrdiff valueToAdd)
+{
+ register T *originalValue;
+ register T *newValue;
+ register int result;
+ asm volatile("0:\n"
+ "ldrex %[originalValue], [%[_q_value]]\n"
+ "add %[newValue], %[originalValue], %[valueToAdd]\n"
+ "strex %[result], %[newValue], [%[_q_value]]\n"
+ "teq %[result], #0\n"
+ "bne 0b\n"
+ : [originalValue] "=&r" (originalValue),
+ [newValue] "=&r" (newValue),
+ [result] "=&r" (result),
+ "+m" (_q_value)
+ : [valueToAdd] "r" (valueToAdd * sizeof(T)),
+ [_q_value] "r" (&_q_value)
+ : "cc", "memory");
+ return originalValue;
+}
+
+template <typename T>
+Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndAddRelaxed(qptrdiff valueToAdd)
+{
+ return fetchAndAddOrdered(valueToAdd);
+}
+
+template <typename T>
+Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndAddAcquire(qptrdiff valueToAdd)
+{
+ return fetchAndAddOrdered(valueToAdd);
+}
+
+template <typename T>
+Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndAddRelease(qptrdiff valueToAdd)
+{
+ return fetchAndAddOrdered(valueToAdd);
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // QATOMIC_ARMV6_H
diff --git a/src/corelib/arch/qatomic_avr32.h b/src/corelib/arch/qatomic_avr32.h
new file mode 100644
index 0000000000..7efbb39272
--- /dev/null
+++ b/src/corelib/arch/qatomic_avr32.h
@@ -0,0 +1,252 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtCore module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QATOMIC_AVR32_H
+#define QATOMIC_AVR32_H
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+#define Q_ATOMIC_INT_REFERENCE_COUNTING_IS_ALWAYS_NATIVE
+
+inline bool QBasicAtomicInt::isReferenceCountingNative()
+{ return true; }
+inline bool QBasicAtomicInt::isReferenceCountingWaitFree()
+{ return false; }
+
+#define Q_ATOMIC_INT_TEST_AND_SET_IS_ALWAYS_NATIVE
+
+inline bool QBasicAtomicInt::isTestAndSetNative()
+{ return true; }
+inline bool QBasicAtomicInt::isTestAndSetWaitFree()
+{ return false; }
+
+#define Q_ATOMIC_INT_FETCH_AND_STORE_IS_ALWAYS_NATIVE
+#define Q_ATOMIC_INT_FETCH_AND_STORE_IS_WAIT_FREE
+
+inline bool QBasicAtomicInt::isFetchAndStoreNative()
+{ return true; }
+inline bool QBasicAtomicInt::isFetchAndStoreWaitFree()
+{ return true; }
+
+#define Q_ATOMIC_INT_FETCH_AND_ADD_IS_ALWAYS_NATIVE
+
+inline bool QBasicAtomicInt::isFetchAndAddNative()
+{ return true; }
+inline bool QBasicAtomicInt::isFetchAndAddWaitFree()
+{ return false; }
+
+#define Q_ATOMIC_POINTER_TEST_AND_SET_IS_ALWAYS_NATIVE
+
+template <typename T>
+Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::isTestAndSetNative()
+{ return true; }
+template <typename T>
+Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::isTestAndSetWaitFree()
+{ return false; }
+
+#define Q_ATOMIC_POINTER_FETCH_AND_STORE_IS_ALWAYS_NATIVE
+#define Q_ATOMIC_POINTER_FETCH_AND_STORE_IS_WAIT_FREE
+
+template <typename T>
+Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::isFetchAndStoreNative()
+{ return true; }
+template <typename T>
+Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::isFetchAndStoreWaitFree()
+{ return true; }
+
+#define Q_ATOMIC_POINTER_FETCH_AND_ADD_IS_ALWAYS_NATIVE
+
+template <typename T>
+Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::isFetchAndAddNative()
+{ return true; }
+template <typename T>
+Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::isFetchAndAddWaitFree()
+{ return false; }
+
+inline bool QBasicAtomicInt::ref()
+{
+ return __sync_add_and_fetch(&_q_value, 1);
+}
+
+inline bool QBasicAtomicInt::deref()
+{
+ return __sync_sub_and_fetch(&_q_value, 1);
+}
+
+inline bool QBasicAtomicInt::testAndSetOrdered(int expectedValue, int newValue)
+{
+ return __sync_bool_compare_and_swap(&_q_value, expectedValue, newValue);
+}
+
+inline bool QBasicAtomicInt::testAndSetRelaxed(int expectedValue, int newValue)
+{
+ return testAndSetOrdered(expectedValue, newValue);
+}
+
+inline bool QBasicAtomicInt::testAndSetAcquire(int expectedValue, int newValue)
+{
+ return testAndSetOrdered(expectedValue, newValue);
+}
+
+inline bool QBasicAtomicInt::testAndSetRelease(int expectedValue, int newValue)
+{
+ return testAndSetOrdered(expectedValue, newValue);
+}
+
+inline int QBasicAtomicInt::fetchAndStoreOrdered(int newValue)
+{
+ return __sync_lock_test_and_set(&_q_value, newValue);
+}
+
+inline int QBasicAtomicInt::fetchAndStoreRelaxed(int newValue)
+{
+ return fetchAndStoreOrdered(newValue);
+}
+
+inline int QBasicAtomicInt::fetchAndStoreAcquire(int newValue)
+{
+ return fetchAndStoreOrdered(newValue);
+}
+
+inline int QBasicAtomicInt::fetchAndStoreRelease(int newValue)
+{
+ return fetchAndStoreOrdered(newValue);
+}
+
+inline int QBasicAtomicInt::fetchAndAddOrdered(int valueToAdd)
+{
+ return __sync_fetch_and_add(&_q_value, valueToAdd);
+}
+
+inline int QBasicAtomicInt::fetchAndAddRelaxed(int valueToAdd)
+{
+ return fetchAndAddOrdered(valueToAdd);
+}
+
+inline int QBasicAtomicInt::fetchAndAddAcquire(int valueToAdd)
+{
+ return fetchAndAddOrdered(valueToAdd);
+}
+
+inline int QBasicAtomicInt::fetchAndAddRelease(int valueToAdd)
+{
+ return fetchAndAddOrdered(valueToAdd);
+}
+
+template <typename T>
+Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::testAndSetOrdered(T *expectedValue, T *newValue)
+{
+ return __sync_bool_compare_and_swap(&_q_value, expectedValue, newValue);
+}
+
+template <typename T>
+Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::testAndSetRelaxed(T *expectedValue, T *newValue)
+{
+ return testAndSetOrdered(expectedValue, newValue);
+}
+
+template <typename T>
+Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::testAndSetAcquire(T *expectedValue, T *newValue)
+{
+ return testAndSetOrdered(expectedValue, newValue);
+}
+
+template <typename T>
+Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::testAndSetRelease(T *expectedValue, T *newValue)
+{
+ return testAndSetOrdered(expectedValue, newValue);
+}
+
+template <typename T>
+Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndStoreOrdered(T *newValue)
+{
+ return __sync_lock_test_and_set(&_q_value, newValue);
+}
+
+template <typename T>
+Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndStoreRelaxed(T *newValue)
+{
+ return fetchAndStoreOrdered(newValue);
+}
+
+template <typename T>
+Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndStoreAcquire(T *newValue)
+{
+ return fetchAndStoreOrdered(newValue);
+}
+
+template <typename T>
+Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndStoreRelease(T *newValue)
+{
+ return fetchAndStoreOrdered(newValue);
+}
+
+template <typename T>
+Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndAddOrdered(qptrdiff valueToAdd)
+{
+ return __sync_fetch_and_add(&_q_value, valueToAdd * sizeof(T));
+}
+
+template <typename T>
+Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndAddRelaxed(qptrdiff valueToAdd)
+{
+ return fetchAndAddOrdered(valueToAdd);
+}
+
+template <typename T>
+Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndAddAcquire(qptrdiff valueToAdd)
+{
+ return fetchAndAddOrdered(valueToAdd);
+}
+
+template <typename T>
+Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndAddRelease(qptrdiff valueToAdd)
+{
+ return fetchAndAddOrdered(valueToAdd);
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // QATOMIC_AVR32_H
diff --git a/src/corelib/arch/qatomic_bfin.h b/src/corelib/arch/qatomic_bfin.h
new file mode 100644
index 0000000000..d1d4c91559
--- /dev/null
+++ b/src/corelib/arch/qatomic_bfin.h
@@ -0,0 +1,343 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtCore module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QATOMIC_BFIN_H
+#define QATOMIC_BFIN_H
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+#define Q_ATOMIC_INT_REFERENCE_COUNTING_IS_NOT_NATIVE
+
+inline bool QBasicAtomicInt::isReferenceCountingNative()
+{ return false; }
+inline bool QBasicAtomicInt::isReferenceCountingWaitFree()
+{ return false; }
+
+#define Q_ATOMIC_INT_TEST_AND_SET_IS_NOT_NATIVE
+
+inline bool QBasicAtomicInt::isTestAndSetNative()
+{ return false; }
+inline bool QBasicAtomicInt::isTestAndSetWaitFree()
+{ return false; }
+
+#define Q_ATOMIC_INT_FETCH_AND_STORE_IS_NOT_NATIVE
+
+inline bool QBasicAtomicInt::isFetchAndStoreNative()
+{ return false; }
+inline bool QBasicAtomicInt::isFetchAndStoreWaitFree()
+{ return false; }
+
+#define Q_ATOMIC_INT_FETCH_AND_ADD_IS_NOT_NATIVE
+
+inline bool QBasicAtomicInt::isFetchAndAddNative()
+{ return false; }
+inline bool QBasicAtomicInt::isFetchAndAddWaitFree()
+{ return false; }
+
+#define Q_ATOMIC_POINTER_TEST_AND_SET_IS_NOT_NATIVE
+
+template <typename T>
+Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::isTestAndSetNative()
+{ return false; }
+template <typename T>
+Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::isTestAndSetWaitFree()
+{ return false; }
+
+#define Q_ATOMIC_POINTER_FETCH_AND_STORE_IS_NOT_NATIVE
+
+template <typename T>
+Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::isFetchAndStoreNative()
+{ return false; }
+template <typename T>
+Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::isFetchAndStoreWaitFree()
+{ return false; }
+
+#define Q_ATOMIC_POINTER_FETCH_AND_ADD_IS_NOT_NATIVE
+
+template <typename T>
+Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::isFetchAndAddNative()
+{ return false; }
+template <typename T>
+Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::isFetchAndAddWaitFree()
+{ return false; }
+
+#if defined(Q_OS_LINUX) && defined(Q_CC_GNU)
+
+QT_BEGIN_INCLUDE_NAMESPACE
+#include <asm/fixed_code.h>
+QT_END_INCLUDE_NAMESPACE
+
+inline bool QBasicAtomicInt::ref()
+{
+ int ret;
+ asm volatile("R0 = 1;\n\t"
+ "P0 = %3;\n\t"
+ "CALL (%2);\n\t"
+ "%0 = R0;"
+ : "=da" (ret), "=m" (_q_value)
+ : "a" (ATOMIC_ADD32), "da" (&_q_value), "m" (_q_value)
+ : "R0", "R1", "P0", "RETS", "memory");
+ return ret != 0;
+}
+
+inline bool QBasicAtomicInt::deref()
+{
+ int ret;
+ asm volatile("R0 = 1;\n\t"
+ "P0 = %3;\n\t"
+ "CALL (%2);\n\t"
+ "%0 = R0;"
+ : "=da" (ret), "=m" (_q_value)
+ : "a" (ATOMIC_SUB32), "da" (&_q_value), "m" (_q_value)
+ : "R0", "R1", "P0", "RETS", "memory");
+ return ret != 0;
+}
+
+inline bool QBasicAtomicInt::testAndSetOrdered(int expectedValue, int newValue)
+{
+ long int readval;
+ asm volatile ("P0 = %2;\n\t"
+ "R1 = %3;\n\t"
+ "R2 = %4;\n\t"
+ "CALL (%5);\n\t"
+ "%0 = R0;\n\t"
+ : "=da" (readval), "=m" (_q_value)
+ : "da" (&_q_value),
+ "da" (expectedValue),
+ "da" (newValue),
+ "a" (ATOMIC_CAS32),
+ "m" (_q_value)
+ : "P0", "R0", "R1", "R2", "RETS", "memory", "cc");
+ return readval == expectedValue;
+}
+
+inline int QBasicAtomicInt::fetchAndStoreOrdered(int newValue)
+{
+ asm volatile("R1 = %2;\n\t"
+ "P0 = %4;\n\t"
+ "CALL (%3);\n\t"
+ "%0 = R0;"
+ : "=da" (newValue), "=m" (_q_value)
+ : "da" (newValue), "a" (ATOMIC_XCHG32), "da" (&_q_value), "m" (_q_value)
+ : "R0", "R1", "P0", "RETS", "memory");
+ return newValue;
+}
+
+inline int QBasicAtomicInt::fetchAndAddOrdered(int valueToAdd)
+{
+ int ret;
+ asm volatile("R0 = %[val];\n\t"
+ "P0 = %[qvalp];\n\t"
+ "CALL (%[addr]);\n\t"
+ "%[ret] = R1;"
+ : [ret] "=da" (ret), "=m" (_q_value)
+ : [addr] "a" (ATOMIC_ADD32), [qvalp] "da" (&_q_value), "m" (_q_value), [val] "da" (valueToAdd)
+ : "R0", "R1", "P0", "RETS", "memory");
+ return ret;
+}
+
+template <typename T>
+Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::testAndSetOrdered(T *expectedValue, T *newValue)
+{
+ T *readval;
+ asm volatile ("P0 = %2;\n\t"
+ "R1 = %3;\n\t"
+ "R2 = %4;\n\t"
+ "CALL (%5);\n\t"
+ "%0 = R0;\n\t"
+ : "=da" (readval), "=m" (_q_value)
+ : "da" (&_q_value),
+ "da" (expectedValue),
+ "da" (newValue),
+ "a" (ATOMIC_CAS32),
+ "m" (_q_value)
+ : "P0", "R0", "R1", "R2", "RETS", "memory", "cc");
+ return readval == expectedValue;
+}
+
+template <typename T>
+Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndStoreOrdered(T *newValue)
+{
+ asm volatile("R1 = %2;\n\t"
+ "P0 = %4;\n\t"
+ "CALL (%3);\n\t"
+ "%0 = R0;"
+ : "=da" (newValue), "=m" (_q_value)
+ : "da" (newValue), "a" (ATOMIC_XCHG32), "da" (&_q_value), "m" (_q_value)
+ : "R0", "R1", "P0", "RETS", "memory");
+ return newValue;
+}
+
+template <typename T>
+Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndAddOrdered(qptrdiff valueToAdd)
+{
+ T* ret;
+ asm volatile("R0 = %[val];\n\t"
+ "P0 = %[qvalp];\n\t"
+ "CALL (%[addr]);\n\t"
+ "%[ret] = R1;"
+ : [ret] "=da" (ret), "=m" (_q_value)
+ : [addr] "a" (ATOMIC_ADD32), [qvalp] "da" (&_q_value), "m" (_q_value), [val] "da" (valueToAdd * sizeof(T))
+ : "R0", "R1", "P0", "RETS", "memory");
+ return ret;
+}
+
+
+#endif // Q_OS_LINUX && Q_CC_GNU
+
+// Test and set for integers
+
+inline bool QBasicAtomicInt::testAndSetRelaxed(int expectedValue, int newValue)
+{
+ return testAndSetOrdered(expectedValue, newValue);
+}
+
+inline bool QBasicAtomicInt::testAndSetAcquire(int expectedValue, int newValue)
+{
+ return testAndSetOrdered(expectedValue, newValue);
+}
+
+inline bool QBasicAtomicInt::testAndSetRelease(int expectedValue, int newValue)
+{
+ return testAndSetOrdered(expectedValue, newValue);
+}
+
+// Fetch and store for integers
+
+inline int QBasicAtomicInt::fetchAndStoreRelaxed(int newValue)
+{
+ return fetchAndStoreOrdered(newValue);
+}
+
+inline int QBasicAtomicInt::fetchAndStoreAcquire(int newValue)
+{
+ return fetchAndStoreOrdered(newValue);
+}
+
+inline int QBasicAtomicInt::fetchAndStoreRelease(int newValue)
+{
+ return fetchAndStoreOrdered(newValue);
+}
+
+// Fetch and add for integers
+
+inline int QBasicAtomicInt::fetchAndAddRelaxed(int valueToAdd)
+{
+ return fetchAndAddOrdered(valueToAdd);
+}
+
+inline int QBasicAtomicInt::fetchAndAddAcquire(int valueToAdd)
+{
+ return fetchAndAddOrdered(valueToAdd);
+}
+
+inline int QBasicAtomicInt::fetchAndAddRelease(int valueToAdd)
+{
+ return fetchAndAddOrdered(valueToAdd);
+}
+
+// Test and set for pointers
+
+template <typename T>
+Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::testAndSetRelaxed(T *expectedValue, T *newValue)
+{
+ return testAndSetOrdered(expectedValue, newValue);
+}
+
+template <typename T>
+Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::testAndSetAcquire(T *expectedValue, T *newValue)
+{
+ return testAndSetOrdered(expectedValue, newValue);
+}
+
+template <typename T>
+Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::testAndSetRelease(T *expectedValue, T *newValue)
+{
+ return testAndSetOrdered(expectedValue, newValue);
+}
+
+// Fetch and store for pointers
+
+template <typename T>
+Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndStoreRelaxed(T *newValue)
+{
+ return fetchAndStoreOrdered(newValue);
+}
+
+template <typename T>
+Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndStoreAcquire(T *newValue)
+{
+ return fetchAndStoreOrdered(newValue);
+}
+
+template <typename T>
+Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndStoreRelease(T *newValue)
+{
+ return fetchAndStoreOrdered(newValue);
+}
+
+// Fetch and add for pointers
+
+template <typename T>
+Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndAddRelaxed(qptrdiff valueToAdd)
+{
+ return fetchAndAddOrdered(valueToAdd);
+}
+
+template <typename T>
+Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndAddAcquire(qptrdiff valueToAdd)
+{
+ return fetchAndAddOrdered(valueToAdd);
+}
+
+template <typename T>
+Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndAddRelease(qptrdiff valueToAdd)
+{
+ return fetchAndAddOrdered(valueToAdd);
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // QATOMIC_BFIN_H
diff --git a/src/corelib/arch/qatomic_bootstrap.h b/src/corelib/arch/qatomic_bootstrap.h
new file mode 100644
index 0000000000..7584b84db1
--- /dev/null
+++ b/src/corelib/arch/qatomic_bootstrap.h
@@ -0,0 +1,99 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtCore module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QATOMIC_BOOTSTRAP_H
+#define QATOMIC_BOOTSTRAP_H
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+inline bool QBasicAtomicInt::ref()
+{
+ return ++_q_value != 0;
+}
+
+inline bool QBasicAtomicInt::deref()
+{
+ return --_q_value != 0;
+}
+
+inline bool QBasicAtomicInt::testAndSetOrdered(int expectedValue, int newValue)
+{
+ if (_q_value == expectedValue) {
+ _q_value = newValue;
+ return true;
+ }
+ return false;
+}
+
+inline bool QBasicAtomicInt::testAndSetAcquire(int expectedValue, int newValue)
+{
+ return testAndSetOrdered(expectedValue, newValue);
+}
+
+inline bool QBasicAtomicInt::testAndSetRelease(int expectedValue, int newValue)
+{
+ return testAndSetOrdered(expectedValue, newValue);
+}
+
+inline int QBasicAtomicInt::fetchAndAddRelaxed(int valueToAdd)
+{
+ int returnValue = _q_value;
+ _q_value += valueToAdd;
+ return returnValue;
+}
+
+template <typename T>
+Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::testAndSetOrdered(T *expectedValue, T *newValue)
+{
+ if (_q_value == expectedValue) {
+ _q_value = newValue;
+ return true;
+ }
+ return false;
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // QATOMIC_BOOTSTRAP_H
diff --git a/src/corelib/arch/qatomic_generic.h b/src/corelib/arch/qatomic_generic.h
new file mode 100644
index 0000000000..f6e6a28085
--- /dev/null
+++ b/src/corelib/arch/qatomic_generic.h
@@ -0,0 +1,282 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtCore module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QATOMIC_GENERIC_H
+#define QATOMIC_GENERIC_H
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+#define Q_ATOMIC_INT_REFERENCE_COUNTING_IS_NOT_NATIVE
+
+inline bool QBasicAtomicInt::isReferenceCountingNative()
+{ return false; }
+inline bool QBasicAtomicInt::isReferenceCountingWaitFree()
+{ return false; }
+
+#define Q_ATOMIC_INT_TEST_AND_SET_IS_NOT_NATIVE
+
+inline bool QBasicAtomicInt::isTestAndSetNative()
+{ return false; }
+inline bool QBasicAtomicInt::isTestAndSetWaitFree()
+{ return false; }
+
+#define Q_ATOMIC_INT_FETCH_AND_STORE_IS_NOT_NATIVE
+
+inline bool QBasicAtomicInt::isFetchAndStoreNative()
+{ return false; }
+inline bool QBasicAtomicInt::isFetchAndStoreWaitFree()
+{ return false; }
+
+#define Q_ATOMIC_INT_FETCH_AND_ADD_IS_NOT_NATIVE
+
+inline bool QBasicAtomicInt::isFetchAndAddNative()
+{ return false; }
+inline bool QBasicAtomicInt::isFetchAndAddWaitFree()
+{ return false; }
+
+#define Q_ATOMIC_POINTER_TEST_AND_SET_IS_NOT_NATIVE
+
+template <typename T>
+Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::isTestAndSetNative()
+{ return false; }
+template <typename T>
+Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::isTestAndSetWaitFree()
+{ return false; }
+
+#define Q_ATOMIC_POINTER_FETCH_AND_STORE_IS_NOT_NATIVE
+
+template <typename T>
+Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::isFetchAndStoreNative()
+{ return false; }
+template <typename T>
+Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::isFetchAndStoreWaitFree()
+{ return false; }
+
+#define Q_ATOMIC_POINTER_FETCH_AND_ADD_IS_NOT_NATIVE
+
+template <typename T>
+Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::isFetchAndAddNative()
+{ return false; }
+template <typename T>
+Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::isFetchAndAddWaitFree()
+{ return false; }
+
+Q_CORE_EXPORT bool QBasicAtomicInt_testAndSetOrdered(volatile int *, int, int);
+Q_CORE_EXPORT int QBasicAtomicInt_fetchAndStoreOrdered(volatile int *, int);
+Q_CORE_EXPORT int QBasicAtomicInt_fetchAndAddOrdered(volatile int *, int);
+
+Q_CORE_EXPORT bool QBasicAtomicPointer_testAndSetOrdered(void * volatile *, void *, void *);
+Q_CORE_EXPORT void *QBasicAtomicPointer_fetchAndStoreOrdered(void * volatile *, void *);
+Q_CORE_EXPORT void *QBasicAtomicPointer_fetchAndAddOrdered(void * volatile *, qptrdiff);
+
+// Reference counting
+
+inline bool QBasicAtomicInt::ref()
+{
+ return QBasicAtomicInt_fetchAndAddOrdered(&_q_value, 1) != -1;
+}
+
+inline bool QBasicAtomicInt::deref()
+{
+ return QBasicAtomicInt_fetchAndAddOrdered(&_q_value, -1) != 1;
+}
+
+// Test and set for integers
+
+inline bool QBasicAtomicInt::testAndSetOrdered(int expectedValue, int newValue)
+{
+ return QBasicAtomicInt_testAndSetOrdered(&_q_value, expectedValue, newValue);
+}
+
+inline bool QBasicAtomicInt::testAndSetRelaxed(int expectedValue, int newValue)
+{
+ return testAndSetOrdered(expectedValue, newValue);
+}
+
+inline bool QBasicAtomicInt::testAndSetAcquire(int expectedValue, int newValue)
+{
+ return testAndSetOrdered(expectedValue, newValue);
+}
+
+inline bool QBasicAtomicInt::testAndSetRelease(int expectedValue, int newValue)
+{
+ return testAndSetOrdered(expectedValue, newValue);
+}
+
+// Fetch and store for integers
+
+inline int QBasicAtomicInt::fetchAndStoreOrdered(int newValue)
+{
+ return QBasicAtomicInt_fetchAndStoreOrdered(&_q_value, newValue);
+}
+
+inline int QBasicAtomicInt::fetchAndStoreRelaxed(int newValue)
+{
+ return fetchAndStoreOrdered(newValue);
+}
+
+inline int QBasicAtomicInt::fetchAndStoreAcquire(int newValue)
+{
+ return fetchAndStoreOrdered(newValue);
+}
+
+inline int QBasicAtomicInt::fetchAndStoreRelease(int newValue)
+{
+ return fetchAndStoreOrdered(newValue);
+}
+
+// Fetch and add for integers
+
+inline int QBasicAtomicInt::fetchAndAddOrdered(int valueToAdd)
+{
+ return QBasicAtomicInt_fetchAndAddOrdered(&_q_value, valueToAdd);
+}
+
+inline int QBasicAtomicInt::fetchAndAddRelaxed(int valueToAdd)
+{
+ return fetchAndAddOrdered(valueToAdd);
+}
+
+inline int QBasicAtomicInt::fetchAndAddAcquire(int valueToAdd)
+{
+ return fetchAndAddOrdered(valueToAdd);
+}
+
+inline int QBasicAtomicInt::fetchAndAddRelease(int valueToAdd)
+{
+ return fetchAndAddOrdered(valueToAdd);
+}
+
+// Test and set for pointers
+
+template <typename T>
+Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::testAndSetOrdered(T *expectedValue, T *newValue)
+{
+ union { T * volatile * typed; void * volatile * voidp; } pointer;
+ pointer.typed = &_q_value;
+ return QBasicAtomicPointer_testAndSetOrdered(pointer.voidp, expectedValue, newValue);
+}
+
+template <typename T>
+Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::testAndSetRelaxed(T *expectedValue, T *newValue)
+{
+ return testAndSetOrdered(expectedValue, newValue);
+}
+
+template <typename T>
+Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::testAndSetAcquire(T *expectedValue, T *newValue)
+{
+ return testAndSetOrdered(expectedValue, newValue);
+}
+
+template <typename T>
+Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::testAndSetRelease(T *expectedValue, T *newValue)
+{
+ return testAndSetOrdered(expectedValue, newValue);
+}
+
+// Fetch and store for pointers
+
+template <typename T>
+Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndStoreOrdered(T *newValue)
+{
+ union { T * volatile * typed; void * volatile * voidp; } pointer;
+ union { T *typed; void *voidp; } returnValue;
+ pointer.typed = &_q_value;
+ returnValue.voidp = QBasicAtomicPointer_fetchAndStoreOrdered(pointer.voidp, newValue);
+ return returnValue.typed;
+}
+
+template <typename T>
+Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndStoreRelaxed(T *newValue)
+{
+ return fetchAndStoreOrdered(newValue);
+}
+
+template <typename T>
+Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndStoreAcquire(T *newValue)
+{
+ return fetchAndStoreOrdered(newValue);
+}
+
+template <typename T>
+Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndStoreRelease(T *newValue)
+{
+ return fetchAndStoreOrdered(newValue);
+}
+
+// Fetch and add for pointers
+
+template <typename T>
+Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndAddOrdered(qptrdiff valueToAdd)
+{
+ union { T * volatile *typed; void * volatile *voidp; } pointer;
+ union { T *typed; void *voidp; } returnValue;
+ pointer.typed = &_q_value;
+ returnValue.voidp = QBasicAtomicPointer_fetchAndAddOrdered(pointer.voidp, valueToAdd * sizeof(T));
+ return returnValue.typed;
+}
+
+template <typename T>
+Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndAddRelaxed(qptrdiff valueToAdd)
+{
+ return fetchAndAddOrdered(valueToAdd);
+}
+
+template <typename T>
+Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndAddAcquire(qptrdiff valueToAdd)
+{
+ return fetchAndAddOrdered(valueToAdd);
+}
+
+template <typename T>
+Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndAddRelease(qptrdiff valueToAdd)
+{
+ return fetchAndAddOrdered(valueToAdd);
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // QATOMIC_GENERIC_H
diff --git a/src/corelib/arch/qatomic_i386.h b/src/corelib/arch/qatomic_i386.h
new file mode 100644
index 0000000000..f8d3708092
--- /dev/null
+++ b/src/corelib/arch/qatomic_i386.h
@@ -0,0 +1,361 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtCore module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QATOMIC_I386_H
+#define QATOMIC_I386_H
+
+QT_BEGIN_HEADER
+QT_BEGIN_NAMESPACE
+
+#define Q_ATOMIC_INT_REFERENCE_COUNTING_IS_ALWAYS_NATIVE
+#define Q_ATOMIC_INT_REFERENCE_COUNTING_IS_WAIT_FREE
+
+inline bool QBasicAtomicInt::isReferenceCountingNative()
+{ return true; }
+inline bool QBasicAtomicInt::isReferenceCountingWaitFree()
+{ return true; }
+
+#define Q_ATOMIC_INT_TEST_AND_SET_IS_ALWAYS_NATIVE
+#define Q_ATOMIC_INT_TEST_AND_SET_IS_WAIT_FREE
+
+inline bool QBasicAtomicInt::isTestAndSetNative()
+{ return true; }
+inline bool QBasicAtomicInt::isTestAndSetWaitFree()
+{ return true; }
+
+#define Q_ATOMIC_INT_FETCH_AND_STORE_IS_ALWAYS_NATIVE
+#define Q_ATOMIC_INT_FETCH_AND_STORE_IS_WAIT_FREE
+
+inline bool QBasicAtomicInt::isFetchAndStoreNative()
+{ return true; }
+inline bool QBasicAtomicInt::isFetchAndStoreWaitFree()
+{ return true; }
+
+#define Q_ATOMIC_INT_FETCH_AND_ADD_IS_ALWAYS_NATIVE
+#define Q_ATOMIC_INT_FETCH_AND_ADD_IS_WAIT_FREE
+
+inline bool QBasicAtomicInt::isFetchAndAddNative()
+{ return true; }
+inline bool QBasicAtomicInt::isFetchAndAddWaitFree()
+{ return true; }
+
+#define Q_ATOMIC_POINTER_TEST_AND_SET_IS_ALWAYS_NATIVE
+#define Q_ATOMIC_POINTER_TEST_AND_SET_IS_WAIT_FREE
+
+template <typename T>
+Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::isTestAndSetNative()
+{ return true; }
+template <typename T>
+Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::isTestAndSetWaitFree()
+{ return true; }
+
+#define Q_ATOMIC_POINTER_FETCH_AND_STORE_IS_ALWAYS_NATIVE
+#define Q_ATOMIC_POINTER_FETCH_AND_STORE_IS_WAIT_FREE
+
+template <typename T>
+Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::isFetchAndStoreNative()
+{ return true; }
+template <typename T>
+Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::isFetchAndStoreWaitFree()
+{ return true; }
+
+#define Q_ATOMIC_POINTER_FETCH_AND_ADD_IS_ALWAYS_NATIVE
+#define Q_ATOMIC_POINTER_FETCH_AND_ADD_IS_WAIT_FREE
+
+template <typename T>
+Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::isFetchAndAddNative()
+{ return true; }
+template <typename T>
+Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::isFetchAndAddWaitFree()
+{ return true; }
+
+#if defined(Q_CC_GNU) || defined(Q_CC_INTEL)
+
+inline bool QBasicAtomicInt::ref()
+{
+ unsigned char ret;
+ asm volatile("lock\n"
+ "incl %0\n"
+ "setne %1"
+ : "=m" (_q_value), "=qm" (ret)
+ : "m" (_q_value)
+ : "memory");
+ return ret != 0;
+}
+
+inline bool QBasicAtomicInt::deref()
+{
+ unsigned char ret;
+ asm volatile("lock\n"
+ "decl %0\n"
+ "setne %1"
+ : "=m" (_q_value), "=qm" (ret)
+ : "m" (_q_value)
+ : "memory");
+ return ret != 0;
+}
+
+inline bool QBasicAtomicInt::testAndSetOrdered(int expectedValue, int newValue)
+{
+ unsigned char ret;
+ asm volatile("lock\n"
+ "cmpxchgl %3,%2\n"
+ "sete %1\n"
+ : "=a" (newValue), "=qm" (ret), "+m" (_q_value)
+ : "r" (newValue), "0" (expectedValue)
+ : "memory");
+ return ret != 0;
+}
+
+inline int QBasicAtomicInt::fetchAndStoreOrdered(int newValue)
+{
+ asm volatile("xchgl %0,%1"
+ : "=r" (newValue), "+m" (_q_value)
+ : "0" (newValue)
+ : "memory");
+ return newValue;
+}
+
+inline int QBasicAtomicInt::fetchAndAddOrdered(int valueToAdd)
+{
+ asm volatile("lock\n"
+ "xaddl %0,%1"
+ : "=r" (valueToAdd), "+m" (_q_value)
+ : "0" (valueToAdd)
+ : "memory");
+ return valueToAdd;
+}
+
+template <typename T>
+Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::testAndSetOrdered(T *expectedValue, T *newValue)
+{
+ unsigned char ret;
+ asm volatile("lock\n"
+ "cmpxchgl %3,%2\n"
+ "sete %1\n"
+ : "=a" (newValue), "=qm" (ret), "+m" (_q_value)
+ : "r" (newValue), "0" (expectedValue)
+ : "memory");
+ return ret != 0;
+}
+
+template <typename T>
+Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndStoreOrdered(T *newValue)
+{
+ asm volatile("xchgl %0,%1"
+ : "=r" (newValue), "+m" (_q_value)
+ : "0" (newValue)
+ : "memory");
+ return newValue;
+}
+
+template <typename T>
+Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndAddOrdered(qptrdiff valueToAdd)
+{
+ asm volatile("lock\n"
+ "xaddl %0,%1"
+ : "=r" (valueToAdd), "+m" (_q_value)
+ : "0" (valueToAdd * sizeof(T))
+ : "memory");
+ return reinterpret_cast<T *>(valueToAdd);
+}
+
+#else
+
+extern "C" {
+ Q_CORE_EXPORT int q_atomic_test_and_set_int(volatile int *ptr, int expected, int newval);
+ Q_CORE_EXPORT int q_atomic_test_and_set_ptr(volatile void *ptr, void *expected, void *newval);
+ Q_CORE_EXPORT int q_atomic_increment(volatile int *ptr);
+ Q_CORE_EXPORT int q_atomic_decrement(volatile int *ptr);
+ Q_CORE_EXPORT int q_atomic_set_int(volatile int *ptr, int newval);
+ Q_CORE_EXPORT void *q_atomic_set_ptr(volatile void *ptr, void *newval);
+ Q_CORE_EXPORT int q_atomic_fetch_and_add_int(volatile int *ptr, int value);
+ Q_CORE_EXPORT void *q_atomic_fetch_and_add_ptr(volatile void *ptr, int value);
+} // extern "C"
+
+inline bool QBasicAtomicInt::ref()
+{
+ return q_atomic_increment(&_q_value) != 0;
+}
+
+inline bool QBasicAtomicInt::deref()
+{
+ return q_atomic_decrement(&_q_value) != 0;
+}
+
+inline bool QBasicAtomicInt::testAndSetOrdered(int expectedValue, int newValue)
+{
+ return q_atomic_test_and_set_int(&_q_value, expectedValue, newValue) != 0;
+}
+
+inline int QBasicAtomicInt::fetchAndStoreOrdered(int newValue)
+{
+ return q_atomic_set_int(&_q_value, newValue);
+}
+
+inline int QBasicAtomicInt::fetchAndAddOrdered(int valueToAdd)
+{
+ return q_atomic_fetch_and_add_int(&_q_value, valueToAdd);
+}
+
+template <typename T>
+Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::testAndSetOrdered(T *expectedValue, T *newValue)
+{
+ return q_atomic_test_and_set_ptr(&_q_value, expectedValue, newValue);
+}
+
+template <typename T>
+Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndStoreOrdered(T *newValue)
+{
+ return reinterpret_cast<T *>(q_atomic_set_ptr(&_q_value, newValue));
+}
+
+template <typename T>
+Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndAddOrdered(qptrdiff valueToAdd)
+{
+ return reinterpret_cast<T *>(q_atomic_fetch_and_add_ptr(&_q_value, valueToAdd * sizeof(T)));
+}
+
+#endif
+
+inline bool QBasicAtomicInt::testAndSetRelaxed(int expectedValue, int newValue)
+{
+ return testAndSetOrdered(expectedValue, newValue);
+}
+
+inline bool QBasicAtomicInt::testAndSetAcquire(int expectedValue, int newValue)
+{
+ return testAndSetOrdered(expectedValue, newValue);
+}
+
+inline bool QBasicAtomicInt::testAndSetRelease(int expectedValue, int newValue)
+{
+ return testAndSetOrdered(expectedValue, newValue);
+}
+
+inline int QBasicAtomicInt::fetchAndStoreRelaxed(int newValue)
+{
+ return fetchAndStoreOrdered(newValue);
+}
+
+inline int QBasicAtomicInt::fetchAndStoreAcquire(int newValue)
+{
+ return fetchAndStoreOrdered(newValue);
+}
+
+inline int QBasicAtomicInt::fetchAndStoreRelease(int newValue)
+{
+ return fetchAndStoreOrdered(newValue);
+}
+
+inline int QBasicAtomicInt::fetchAndAddRelaxed(int valueToAdd)
+{
+ return fetchAndAddOrdered(valueToAdd);
+}
+
+inline int QBasicAtomicInt::fetchAndAddAcquire(int valueToAdd)
+{
+ return fetchAndAddOrdered(valueToAdd);
+}
+
+inline int QBasicAtomicInt::fetchAndAddRelease(int valueToAdd)
+{
+ return fetchAndAddOrdered(valueToAdd);
+}
+
+template <typename T>
+Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::testAndSetRelaxed(T *expectedValue, T *newValue)
+{
+ return testAndSetOrdered(expectedValue, newValue);
+}
+
+template <typename T>
+Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::testAndSetAcquire(T *expectedValue, T *newValue)
+{
+ return testAndSetOrdered(expectedValue, newValue);
+}
+
+template <typename T>
+Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::testAndSetRelease(T *expectedValue, T *newValue)
+{
+ return testAndSetOrdered(expectedValue, newValue);
+}
+
+template <typename T>
+Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndStoreRelaxed(T *newValue)
+{
+ return fetchAndStoreOrdered(newValue);
+}
+
+template <typename T>
+Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndStoreAcquire(T *newValue)
+{
+ return fetchAndStoreOrdered(newValue);
+}
+
+template <typename T>
+Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndStoreRelease(T *newValue)
+{
+ return fetchAndStoreOrdered(newValue);
+}
+
+template <typename T>
+Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndAddRelaxed(qptrdiff valueToAdd)
+{
+ return fetchAndAddOrdered(valueToAdd);
+}
+
+template <typename T>
+Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndAddAcquire(qptrdiff valueToAdd)
+{
+ return fetchAndAddOrdered(valueToAdd);
+}
+
+template <typename T>
+Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndAddRelease(qptrdiff valueToAdd)
+{
+ return fetchAndAddOrdered(valueToAdd);
+}
+
+QT_END_NAMESPACE
+QT_END_HEADER
+
+#endif // QATOMIC_I386_H
diff --git a/src/corelib/arch/qatomic_ia64.h b/src/corelib/arch/qatomic_ia64.h
new file mode 100644
index 0000000000..1803c854af
--- /dev/null
+++ b/src/corelib/arch/qatomic_ia64.h
@@ -0,0 +1,813 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtCore module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QATOMIC_IA64_H
+#define QATOMIC_IA64_H
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+#define Q_ATOMIC_INT_REFERENCE_COUNTING_IS_ALWAYS_NATIVE
+#define Q_ATOMIC_INT_REFERENCE_COUNTING_IS_WAIT_FREE
+
+inline bool QBasicAtomicInt::isReferenceCountingNative()
+{ return true; }
+inline bool QBasicAtomicInt::isReferenceCountingWaitFree()
+{ return true; }
+
+#define Q_ATOMIC_INT_TEST_AND_SET_IS_ALWAYS_NATIVE
+#define Q_ATOMIC_INT_TEST_AND_SET_IS_WAIT_FREE
+
+inline bool QBasicAtomicInt::isTestAndSetNative()
+{ return true; }
+inline bool QBasicAtomicInt::isTestAndSetWaitFree()
+{ return true; }
+
+#define Q_ATOMIC_INT_FETCH_AND_STORE_IS_ALWAYS_NATIVE
+#define Q_ATOMIC_INT_FETCH_AND_STORE_IS_WAIT_FREE
+
+inline bool QBasicAtomicInt::isFetchAndStoreNative()
+{ return true; }
+inline bool QBasicAtomicInt::isFetchAndStoreWaitFree()
+{ return true; }
+
+#define Q_ATOMIC_INT_FETCH_AND_ADD_IS_ALWAYS_NATIVE
+
+inline bool QBasicAtomicInt::isFetchAndAddNative()
+{ return true; }
+inline bool QBasicAtomicInt::isFetchAndAddWaitFree()
+{ return false; }
+
+#define Q_ATOMIC_POINTER_TEST_AND_SET_IS_ALWAYS_NATIVE
+#define Q_ATOMIC_POINTER_TEST_AND_SET_IS_WAIT_FREE
+
+template <typename T>
+Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::isTestAndSetNative()
+{ return true; }
+template <typename T>
+Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::isTestAndSetWaitFree()
+{ return true; }
+
+#define Q_ATOMIC_POINTER_FETCH_AND_STORE_IS_ALWAYS_NATIVE
+#define Q_ATOMIC_POINTER_FETCH_AND_STORE_IS_WAIT_FREE
+
+template <typename T>
+Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::isFetchAndStoreNative()
+{ return true; }
+template <typename T>
+Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::isFetchAndStoreWaitFree()
+{ return true; }
+
+#define Q_ATOMIC_POINTER_FETCH_AND_ADD_IS_ALWAYS_NATIVE
+
+template <typename T>
+Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::isFetchAndAddNative()
+{ return true; }
+template <typename T>
+Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::isFetchAndAddWaitFree()
+{ return false; }
+
+inline bool _q_ia64_fetchadd_immediate(register int value)
+{
+ return value == 1 || value == -1
+ || value == 4 || value == -4
+ || value == 8 || value == -8
+ || value == 16 || value == -16;
+}
+
+#if defined(Q_CC_INTEL)
+
+// intrinsics provided by the Intel C++ Compiler
+#include <ia64intrin.h>
+
+inline int QBasicAtomicInt::fetchAndStoreAcquire(int newValue)
+{
+ return static_cast<int>(_InterlockedExchange(&_q_value, newValue));
+}
+
+inline int QBasicAtomicInt::fetchAndStoreRelease(int newValue)
+{
+ __memory_barrier();
+ return static_cast<int>(_InterlockedExchange(&_q_value, newValue));
+}
+
+inline bool QBasicAtomicInt::testAndSetRelaxed(int expectedValue, int newValue)
+{
+ register int expectedValueCopy = expectedValue;
+ return (static_cast<int>(_InterlockedCompareExchange(&_q_value,
+ newValue,
+ expectedValueCopy))
+ == expectedValue);
+}
+
+inline bool QBasicAtomicInt::testAndSetAcquire(int expectedValue, int newValue)
+{
+ register int expectedValueCopy = expectedValue;
+ return (static_cast<int>(_InterlockedCompareExchange_acq(reinterpret_cast<volatile uint *>(&_q_value),
+ newValue,
+ expectedValueCopy))
+ == expectedValue);
+}
+
+inline bool QBasicAtomicInt::testAndSetRelease(int expectedValue, int newValue)
+{
+ register int expectedValueCopy = expectedValue;
+ return (static_cast<int>(_InterlockedCompareExchange_rel(reinterpret_cast<volatile uint *>(&_q_value),
+ newValue,
+ expectedValueCopy))
+ == expectedValue);
+}
+
+inline bool QBasicAtomicInt::testAndSetOrdered(int expectedValue, int newValue)
+{
+ __memory_barrier();
+ return testAndSetAcquire(expectedValue, newValue);
+}
+
+inline int QBasicAtomicInt::fetchAndAddAcquire(int valueToAdd)
+{
+ if (__builtin_constant_p(valueToAdd)) {
+ if (valueToAdd == 1)
+ return __fetchadd4_acq((unsigned int *)&_q_value, 1);
+ if (valueToAdd == -1)
+ return __fetchadd4_acq((unsigned int *)&_q_value, -1);
+ }
+ return _InterlockedExchangeAdd(&_q_value, valueToAdd);
+}
+
+inline int QBasicAtomicInt::fetchAndAddRelease(int valueToAdd)
+{
+ if (__builtin_constant_p(valueToAdd)) {
+ if (valueToAdd == 1)
+ return __fetchadd4_rel((unsigned int *)&_q_value, 1);
+ if (valueToAdd == -1)
+ return __fetchadd4_rel((unsigned int *)&_q_value, -1);
+ }
+ __memory_barrier();
+ return _InterlockedExchangeAdd(&_q_value, valueToAdd);
+}
+
+inline int QBasicAtomicInt::fetchAndAddOrdered(int valueToAdd)
+{
+ __memory_barrier();
+ return fetchAndAddAcquire(valueToAdd);
+}
+
+inline bool QBasicAtomicInt::ref()
+{
+ return _InterlockedIncrement(&_q_value) != 0;
+}
+
+inline bool QBasicAtomicInt::deref()
+{
+ return _InterlockedDecrement(&_q_value) != 0;
+}
+
+template <typename T>
+Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndStoreAcquire(T *newValue)
+{
+ return (T *)_InterlockedExchangePointer(&_q_value, newValue);
+}
+
+template <typename T>
+Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndStoreRelease(T *newValue)
+{
+ __memory_barrier();
+ return fetchAndStoreAcquire(newValue);
+}
+
+template <typename T>
+Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::testAndSetRelaxed(T *expectedValue, T *newValue)
+{
+ register T *expectedValueCopy = expectedValue;
+ return (_InterlockedCompareExchangePointer(reinterpret_cast<void * volatile*>(&_q_value),
+ newValue,
+ expectedValueCopy)
+ == expectedValue);
+}
+
+template <typename T>
+Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::testAndSetAcquire(T *expectedValue, T *newValue)
+{
+ union {
+ volatile void *x;
+ volatile unsigned long *p;
+ };
+ x = &_q_value;
+ register T *expectedValueCopy = expectedValue;
+ return (_InterlockedCompareExchange64_acq(p, quintptr(newValue), quintptr(expectedValueCopy))
+ == quintptr(expectedValue));
+}
+
+template <typename T>
+Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::testAndSetRelease(T *expectedValue, T *newValue)
+{
+ union {
+ volatile void *x;
+ volatile unsigned long *p;
+ };
+ x = &_q_value;
+ register T *expectedValueCopy = expectedValue;
+ return (_InterlockedCompareExchange64_rel(p, quintptr(newValue), quintptr(expectedValueCopy))
+ == quintptr(expectedValue));
+}
+
+template <typename T>
+Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::testAndSetOrdered(T *expectedValue, T *newValue)
+{
+ __memory_barrier();
+ return testAndSetAcquire(expectedValue, newValue);
+}
+
+template <typename T>
+Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndAddAcquire(qptrdiff valueToAdd)
+{
+ return (T *)_InterlockedExchangeAdd64((volatile long *)&_q_value,
+ valueToAdd * sizeof(T));
+}
+
+template <typename T>
+Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndAddRelease(qptrdiff valueToAdd)
+{
+ __memory_barrier();
+ return (T *)_InterlockedExchangeAdd64((volatile long *)&_q_value,
+ valueToAdd * sizeof(T));
+}
+
+template <typename T>
+Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndAddOrdered(qptrdiff valueToAdd)
+{
+ __memory_barrier();
+ return fetchAndAddAcquire(valueToAdd);
+}
+
+#else // !Q_CC_INTEL
+
+# if defined(Q_CC_GNU)
+
+inline int QBasicAtomicInt::fetchAndStoreAcquire(int newValue)
+{
+ int ret;
+ asm volatile("xchg4 %0=%1,%2\n"
+ : "=r" (ret), "+m" (_q_value)
+ : "r" (newValue)
+ : "memory");
+ return ret;
+}
+
+inline int QBasicAtomicInt::fetchAndStoreRelease(int newValue)
+{
+ int ret;
+ asm volatile("mf\n"
+ "xchg4 %0=%1,%2\n"
+ : "=r" (ret), "+m" (_q_value)
+ : "r" (newValue)
+ : "memory");
+ return ret;
+}
+
+inline bool QBasicAtomicInt::testAndSetAcquire(int expectedValue, int newValue)
+{
+ int ret;
+ asm volatile("mov ar.ccv=%2\n"
+ ";;\n"
+ "cmpxchg4.acq %0=%1,%3,ar.ccv\n"
+ : "=r" (ret), "+m" (_q_value)
+ : "r" (expectedValue), "r" (newValue)
+ : "memory");
+ return ret == expectedValue;
+}
+
+inline bool QBasicAtomicInt::testAndSetRelease(int expectedValue, int newValue)
+{
+ int ret;
+ asm volatile("mov ar.ccv=%2\n"
+ ";;\n"
+ "cmpxchg4.rel %0=%1,%3,ar.ccv\n"
+ : "=r" (ret), "+m" (_q_value)
+ : "r" (expectedValue), "r" (newValue)
+ : "memory");
+ return ret == expectedValue;
+}
+
+inline int QBasicAtomicInt::fetchAndAddAcquire(int valueToAdd)
+{
+ int ret;
+
+#if (__GNUC__ >= 4)
+ // We implement a fast fetch-and-add when we can
+ if (__builtin_constant_p(valueToAdd) && _q_ia64_fetchadd_immediate(valueToAdd)) {
+ asm volatile("fetchadd4.acq %0=%1,%2\n"
+ : "=r" (ret), "+m" (_q_value)
+ : "i" (valueToAdd)
+ : "memory");
+ return ret;
+ }
+#endif
+
+ // otherwise, use a loop around test-and-set
+ ret = _q_value;
+ asm volatile("0:\n"
+ " mov r9=%0\n"
+ " mov ar.ccv=%0\n"
+ " add %0=%0, %2\n"
+ " ;;\n"
+ " cmpxchg4.acq %0=%1,%0,ar.ccv\n"
+ " ;;\n"
+ " cmp.ne p6,p0 = %0, r9\n"
+ "(p6) br.dptk 0b\n"
+ "1:\n"
+ : "+r" (ret), "+m" (_q_value)
+ : "r" (valueToAdd)
+ : "r9", "p6", "memory");
+ return ret;
+}
+
+inline int QBasicAtomicInt::fetchAndAddRelease(int valueToAdd)
+{
+ int ret;
+
+#if (__GNUC__ >= 4)
+ // We implement a fast fetch-and-add when we can
+ if (__builtin_constant_p(valueToAdd) && _q_ia64_fetchadd_immediate(valueToAdd)) {
+ asm volatile("fetchadd4.rel %0=%1,%2\n"
+ : "=r" (ret), "+m" (_q_value)
+ : "i" (valueToAdd)
+ : "memory");
+ return ret;
+ }
+#endif
+
+ // otherwise, use a loop around test-and-set
+ ret = _q_value;
+ asm volatile("0:\n"
+ " mov r9=%0\n"
+ " mov ar.ccv=%0\n"
+ " add %0=%0, %2\n"
+ " ;;\n"
+ " cmpxchg4.rel %0=%1,%0,ar.ccv\n"
+ " ;;\n"
+ " cmp.ne p6,p0 = %0, r9\n"
+ "(p6) br.dptk 0b\n"
+ "1:\n"
+ : "+r" (ret), "+m" (_q_value)
+ : "r" (valueToAdd)
+ : "r9", "p6", "memory");
+ return ret;
+}
+
+inline int QBasicAtomicInt::fetchAndAddOrdered(int valueToAdd)
+{
+ asm volatile("mf" ::: "memory");
+ return fetchAndAddRelease(valueToAdd);
+}
+
+inline bool QBasicAtomicInt::ref()
+{
+ int ret;
+ asm volatile("fetchadd4.acq %0=%1,1\n"
+ : "=r" (ret), "+m" (_q_value)
+ :
+ : "memory");
+ return ret != -1;
+}
+
+inline bool QBasicAtomicInt::deref()
+{
+ int ret;
+ asm volatile("fetchadd4.rel %0=%1,-1\n"
+ : "=r" (ret), "+m" (_q_value)
+ :
+ : "memory");
+ return ret != 1;
+}
+
+template <typename T>
+Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndStoreAcquire(T *newValue)
+{
+ T *ret;
+ asm volatile("xchg8 %0=%1,%2\n"
+ : "=r" (ret), "+m" (_q_value)
+ : "r" (newValue)
+ : "memory");
+ return ret;
+}
+
+template <typename T>
+Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndStoreRelease(T *newValue)
+{
+ T *ret;
+ asm volatile("mf\n"
+ "xchg8 %0=%1,%2\n"
+ : "=r" (ret), "+m" (_q_value)
+ : "r" (newValue)
+ : "memory");
+ return ret;
+}
+
+template <typename T>
+Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::testAndSetAcquire(T *expectedValue, T *newValue)
+{
+ T *ret;
+ asm volatile("mov ar.ccv=%2\n"
+ ";;\n"
+ "cmpxchg8.acq %0=%1,%3,ar.ccv\n"
+ : "=r" (ret), "+m" (_q_value)
+ : "r" (expectedValue), "r" (newValue)
+ : "memory");
+ return ret == expectedValue;
+}
+
+template <typename T>
+Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::testAndSetRelease(T *expectedValue, T *newValue)
+{
+ T *ret;
+ asm volatile("mov ar.ccv=%2\n"
+ ";;\n"
+ "cmpxchg8.rel %0=%1,%3,ar.ccv\n"
+ : "=r" (ret), "+m" (_q_value)
+ : "r" (expectedValue), "r" (newValue)
+ : "memory");
+ return ret == expectedValue;
+}
+
+template <typename T>
+Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndAddAcquire(qptrdiff valueToAdd)
+{
+ T *ret;
+
+#if (__GNUC__ >= 4)
+ // We implement a fast fetch-and-add when we can
+ if (__builtin_constant_p(valueToAdd) && _q_ia64_fetchadd_immediate(valueToAdd * sizeof(T))) {
+ asm volatile("fetchadd8.acq %0=%1,%2\n"
+ : "=r" (ret), "+m" (_q_value)
+ : "i" (valueToAdd * sizeof(T))
+ : "memory");
+ return ret;
+ }
+#endif
+
+ // otherwise, use a loop around test-and-set
+ ret = _q_value;
+ asm volatile("0:\n"
+ " mov r9=%0\n"
+ " mov ar.ccv=%0\n"
+ " add %0=%0, %2\n"
+ " ;;\n"
+ " cmpxchg8.acq %0=%1,%0,ar.ccv\n"
+ " ;;\n"
+ " cmp.ne p6,p0 = %0, r9\n"
+ "(p6) br.dptk 0b\n"
+ "1:\n"
+ : "+r" (ret), "+m" (_q_value)
+ : "r" (valueToAdd * sizeof(T))
+ : "r9", "p6", "memory");
+ return ret;
+}
+
+template <typename T>
+Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndAddRelease(qptrdiff valueToAdd)
+{
+ T *ret;
+
+#if (__GNUC__ >= 4)
+ // We implement a fast fetch-and-add when we can
+ if (__builtin_constant_p(valueToAdd) && _q_ia64_fetchadd_immediate(valueToAdd * sizeof(T))) {
+ asm volatile("fetchadd8.rel %0=%1,%2\n"
+ : "=r" (ret), "+m" (_q_value)
+ : "i" (valueToAdd * sizeof(T))
+ : "memory");
+ return ret;
+ }
+#endif
+
+ // otherwise, use a loop around test-and-set
+ ret = _q_value;
+ asm volatile("0:\n"
+ " mov r9=%0\n"
+ " mov ar.ccv=%0\n"
+ " add %0=%0, %2\n"
+ " ;;\n"
+ " cmpxchg8.rel %0=%1,%0,ar.ccv\n"
+ " ;;\n"
+ " cmp.ne p6,p0 = %0, r9\n"
+ "(p6) br.dptk 0b\n"
+ "1:\n"
+ : "+r" (ret), "+m" (_q_value)
+ : "r" (valueToAdd * sizeof(T))
+ : "r9", "p6", "memory");
+ return ret;
+}
+
+template <typename T>
+Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndAddOrdered(qptrdiff valueToAdd)
+{
+ asm volatile("mf" ::: "memory");
+ return fetchAndAddRelease(valueToAdd);
+}
+
+#elif defined Q_CC_HPACC
+
+QT_BEGIN_INCLUDE_NAMESPACE
+#include <ia64/sys/inline.h>
+QT_END_INCLUDE_NAMESPACE
+
+#define FENCE (_Asm_fence)(_UP_CALL_FENCE | _UP_SYS_FENCE | _DOWN_CALL_FENCE | _DOWN_SYS_FENCE)
+
+inline int QBasicAtomicInt::fetchAndStoreAcquire(int newValue)
+{
+ return _Asm_xchg((_Asm_sz)_SZ_W, &_q_value, (unsigned)newValue,
+ (_Asm_ldhint)_LDHINT_NONE, FENCE);
+}
+
+inline int QBasicAtomicInt::fetchAndStoreRelease(int newValue)
+{
+ _Asm_mf(FENCE);
+ return _Asm_xchg((_Asm_sz)_SZ_W, &_q_value, (unsigned)newValue,
+ (_Asm_ldhint)_LDHINT_NONE, FENCE);
+}
+
+inline bool QBasicAtomicInt::testAndSetAcquire(int expectedValue, int newValue)
+{
+ _Asm_mov_to_ar((_Asm_app_reg)_AREG_CCV, (unsigned)expectedValue, FENCE);
+ int ret = _Asm_cmpxchg((_Asm_sz)_SZ_W, (_Asm_sem)_SEM_ACQ,
+ &_q_value, (unsigned)newValue, (_Asm_ldhint)_LDHINT_NONE);
+ return ret == expectedValue;
+}
+
+inline bool QBasicAtomicInt::testAndSetRelease(int expectedValue, int newValue)
+{
+ _Asm_mov_to_ar((_Asm_app_reg)_AREG_CCV, (unsigned)expectedValue, FENCE);
+ int ret = _Asm_cmpxchg((_Asm_sz)_SZ_W, (_Asm_sem)_SEM_REL,
+ &_q_value, newValue, (_Asm_ldhint)_LDHINT_NONE);
+ return ret == expectedValue;
+}
+
+inline int QBasicAtomicInt::fetchAndAddAcquire(int valueToAdd)
+{
+ if (valueToAdd == 1)
+ return _Asm_fetchadd((_Asm_fasz)_FASZ_W, (_Asm_sem)_SEM_ACQ,
+ &_q_value, 1, (_Asm_ldhint)_LDHINT_NONE, FENCE);
+ else if (valueToAdd == -1)
+ return _Asm_fetchadd((_Asm_fasz)_FASZ_W, (_Asm_sem)_SEM_ACQ,
+ &_q_value, -1, (_Asm_ldhint)_LDHINT_NONE, FENCE);
+
+ // implement the test-and-set loop
+ register int old, ret;
+ do {
+ old = _q_value;
+ _Asm_mov_to_ar((_Asm_app_reg)_AREG_CCV, (unsigned)old, FENCE);
+ ret = _Asm_cmpxchg((_Asm_sz)_SZ_W, (_Asm_sem)_SEM_ACQ,
+ &_q_value, old + valueToAdd, (_Asm_ldhint)_LDHINT_NONE);
+ } while (ret != old);
+ return old;
+}
+
+inline int QBasicAtomicInt::fetchAndAddRelease(int valueToAdd)
+{
+ if (valueToAdd == 1)
+ return _Asm_fetchadd((_Asm_fasz)_FASZ_W, (_Asm_sem)_SEM_REL,
+ &_q_value, 1, (_Asm_ldhint)_LDHINT_NONE, FENCE);
+ else if (valueToAdd == -1)
+ return _Asm_fetchadd((_Asm_fasz)_FASZ_W, (_Asm_sem)_SEM_REL,
+ &_q_value, -1, (_Asm_ldhint)_LDHINT_NONE, FENCE);
+
+ // implement the test-and-set loop
+ register int old, ret;
+ do {
+ old = _q_value;
+ _Asm_mov_to_ar((_Asm_app_reg)_AREG_CCV, (unsigned)old, FENCE);
+ ret = _Asm_cmpxchg((_Asm_sz)_SZ_W, (_Asm_sem)_SEM_REL,
+ &_q_value, old + valueToAdd, (_Asm_ldhint)_LDHINT_NONE);
+ } while (ret != old);
+ return old;
+}
+
+inline int QBasicAtomicInt::fetchAndAddOrdered(int valueToAdd)
+{
+ _Asm_mf(FENCE);
+ return fetchAndAddAcquire(valueToAdd);
+}
+
+inline bool QBasicAtomicInt::ref()
+{
+ return (int)_Asm_fetchadd((_Asm_fasz)_FASZ_W, (_Asm_sem)_SEM_ACQ,
+ &_q_value, 1, (_Asm_ldhint)_LDHINT_NONE, FENCE) != -1;
+}
+
+inline bool QBasicAtomicInt::deref()
+{
+ return (int)_Asm_fetchadd((_Asm_fasz)_FASZ_W, (_Asm_sem)_SEM_REL,
+ &_q_value, -1, (_Asm_ldhint)_LDHINT_NONE, FENCE) != 1;
+}
+
+template <typename T>
+Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndStoreAcquire(T *newValue)
+{
+#ifdef __LP64__
+ return (T *)_Asm_xchg((_Asm_sz)_SZ_D, &_q_value, (quint64)newValue,
+ (_Asm_ldhint)_LDHINT_NONE, FENCE);
+#else
+ return (T *)_Asm_xchg((_Asm_sz)_SZ_W, &_q_value, (quint32)newValue,
+ (_Asm_ldhint)_LDHINT_NONE, FENCE);
+#endif
+}
+
+template <typename T>
+Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndStoreRelease(T *newValue)
+{
+ _Asm_mf(FENCE);
+ return fetchAndStoreAcquire(newValue);
+}
+
+template <typename T>
+Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::testAndSetAcquire(T *expectedValue, T *newValue)
+{
+#ifdef __LP64__
+ _Asm_mov_to_ar((_Asm_app_reg)_AREG_CCV, (quint64)expectedValue, FENCE);
+ T *ret = (T *)_Asm_cmpxchg((_Asm_sz)_SZ_D, (_Asm_sem)_SEM_ACQ,
+ &_q_value, (quint64)newValue, (_Asm_ldhint)_LDHINT_NONE);
+#else
+ _Asm_mov_to_ar((_Asm_app_reg)_AREG_CCV, (quint32)expectedValue, FENCE);
+ T *ret = (T *)_Asm_cmpxchg((_Asm_sz)_SZ_W, (_Asm_sem)_SEM_ACQ,
+ &_q_value, (quint32)newValue, (_Asm_ldhint)_LDHINT_NONE);
+#endif
+ return ret == expectedValue;
+}
+
+template <typename T>
+Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::testAndSetRelease(T *expectedValue, T *newValue)
+{
+#ifdef __LP64__
+ _Asm_mov_to_ar((_Asm_app_reg)_AREG_CCV, (quint64)expectedValue, FENCE);
+ T *ret = (T *)_Asm_cmpxchg((_Asm_sz)_SZ_D, (_Asm_sem)_SEM_REL,
+ &_q_value, (quint64)newValue, (_Asm_ldhint)_LDHINT_NONE);
+#else
+ _Asm_mov_to_ar((_Asm_app_reg)_AREG_CCV, (quint32)expectedValue, FENCE);
+ T *ret = (T *)_Asm_cmpxchg((_Asm_sz)_SZ_W, (_Asm_sem)_SEM_REL,
+ &_q_value, (quint32)newValue, (_Asm_ldhint)_LDHINT_NONE);
+#endif
+ return ret == expectedValue;
+}
+
+template <typename T>
+Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndAddAcquire(qptrdiff valueToAdd)
+{
+ // implement the test-and-set loop
+ register T *old, *ret;
+ do {
+ old = _q_value;
+#ifdef __LP64__
+ _Asm_mov_to_ar((_Asm_app_reg)_AREG_CCV, (quint64)old, FENCE);
+ ret = (T *)_Asm_cmpxchg((_Asm_sz)_SZ_D, (_Asm_sem)_SEM_ACQ,
+ &_q_value, (quint64)(old + valueToAdd),
+ (_Asm_ldhint)_LDHINT_NONE);
+#else
+ _Asm_mov_to_ar((_Asm_app_reg)_AREG_CCV, (quint32)old, FENCE);
+ ret = (T *)_Asm_cmpxchg((_Asm_sz)_SZ_W, (_Asm_sem)_SEM_ACQ,
+ &_q_value, (quint32)(old + valueToAdd),
+ (_Asm_ldhint)_LDHINT_NONE);
+#endif
+ } while (old != ret);
+ return old;
+}
+
+template <typename T>
+Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndAddRelease(qptrdiff valueToAdd)
+{
+ // implement the test-and-set loop
+ register T *old, *ret;
+ do {
+ old = _q_value;
+#ifdef __LP64__
+ _Asm_mov_to_ar((_Asm_app_reg)_AREG_CCV, (quint64)old, FENCE);
+ ret = (T *)_Asm_cmpxchg((_Asm_sz)_SZ_D, (_Asm_sem)_SEM_REL,
+ &_q_value, (quint64)(old + valueToAdd),
+ (_Asm_ldhint)_LDHINT_NONE);
+#else
+ _Asm_mov_to_ar((_Asm_app_reg)_AREG_CCV, (quint32)old, FENCE);
+ ret = (T *)_Asm_cmpxchg((_Asm_sz)_SZ_W, (_Asm_sem)_SEM_REL,
+ &_q_value, (quint32)(old + valueToAdd),
+ (_Asm_ldhint)_LDHINT_NONE);
+#endif
+ } while (old != ret);
+ return old;
+}
+
+template <typename T>
+Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndAddOrdered(qptrdiff valueToAdd)
+{
+ _Asm_mf(FENCE);
+ return fetchAndAddAcquire(valueToAdd);
+}
+
+#else
+
+extern "C" {
+ Q_CORE_EXPORT int q_atomic_test_and_set_int(volatile int *ptr, int expected, int newval);
+ Q_CORE_EXPORT int q_atomic_test_and_set_ptr(volatile void *ptr, void *expected, void *newval);
+} // extern "C"
+
+#endif
+
+inline bool QBasicAtomicInt::testAndSetRelaxed(int expectedValue, int newValue)
+{
+ return testAndSetAcquire(expectedValue, newValue);
+}
+
+inline bool QBasicAtomicInt::testAndSetOrdered(int expectedValue, int newValue)
+{
+ return testAndSetAcquire(expectedValue, newValue);
+}
+
+template <typename T>
+Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::testAndSetRelaxed(T *expectedValue, T *newValue)
+{
+ return testAndSetAcquire(expectedValue, newValue);
+}
+
+template <typename T>
+Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::testAndSetOrdered(T *expectedValue, T *newValue)
+{
+ return testAndSetAcquire(expectedValue, newValue);
+}
+
+#endif // Q_CC_INTEL
+
+inline int QBasicAtomicInt::fetchAndStoreRelaxed(int newValue)
+{
+ return fetchAndStoreAcquire(newValue);
+}
+
+inline int QBasicAtomicInt::fetchAndStoreOrdered(int newValue)
+{
+ return fetchAndStoreRelease(newValue);
+}
+
+inline int QBasicAtomicInt::fetchAndAddRelaxed(int valueToAdd)
+{
+ return fetchAndAddAcquire(valueToAdd);
+}
+
+template <typename T>
+Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndStoreRelaxed(T *newValue)
+{
+ return fetchAndStoreAcquire(newValue);
+}
+
+template <typename T>
+Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndStoreOrdered(T *newValue)
+{
+ return fetchAndStoreRelaxed(newValue);
+}
+
+template <typename T>
+Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndAddRelaxed(qptrdiff valueToAdd)
+{
+ return fetchAndAddAcquire(valueToAdd);
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // QATOMIC_IA64_H
diff --git a/src/corelib/arch/qatomic_macosx.h b/src/corelib/arch/qatomic_macosx.h
new file mode 100644
index 0000000000..b343e413f0
--- /dev/null
+++ b/src/corelib/arch/qatomic_macosx.h
@@ -0,0 +1,57 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtCore module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QATOMIC_MACOSX_H
+#define QATOMIC_MACOSX_H
+
+QT_BEGIN_HEADER
+
+#if defined(__x86_64__)
+# include <QtCore/qatomic_x86_64.h>
+#elif defined(__i386__)
+# include <QtCore/qatomic_i386.h>
+#else // !__x86_64 && !__i386__
+# include <QtCore/qatomic_powerpc.h>
+#endif // !__x86_64__ && !__i386__
+
+QT_END_HEADER
+
+#endif // QATOMIC_MACOSX_H
diff --git a/src/corelib/arch/qatomic_mips.h b/src/corelib/arch/qatomic_mips.h
new file mode 100644
index 0000000000..b263aab9fe
--- /dev/null
+++ b/src/corelib/arch/qatomic_mips.h
@@ -0,0 +1,826 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtCore module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QATOMIC_MIPS_H
+#define QATOMIC_MIPS_H
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+#define Q_ATOMIC_INT_REFERENCE_COUNTING_IS_ALWAYS_NATIVE
+
+inline bool QBasicAtomicInt::isReferenceCountingNative()
+{ return true; }
+inline bool QBasicAtomicInt::isReferenceCountingWaitFree()
+{ return false; }
+
+#define Q_ATOMIC_INT_TEST_AND_SET_IS_ALWAYS_NATIVE
+
+inline bool QBasicAtomicInt::isTestAndSetNative()
+{ return true; }
+inline bool QBasicAtomicInt::isTestAndSetWaitFree()
+{ return false; }
+
+#define Q_ATOMIC_INT_FETCH_AND_STORE_IS_ALWAYS_NATIVE
+
+inline bool QBasicAtomicInt::isFetchAndStoreNative()
+{ return true; }
+inline bool QBasicAtomicInt::isFetchAndStoreWaitFree()
+{ return false; }
+
+#define Q_ATOMIC_INT_FETCH_AND_ADD_IS_ALWAYS_NATIVE
+
+inline bool QBasicAtomicInt::isFetchAndAddNative()
+{ return true; }
+inline bool QBasicAtomicInt::isFetchAndAddWaitFree()
+{ return false; }
+
+#define Q_ATOMIC_POINTER_TEST_AND_SET_IS_ALWAYS_NATIVE
+
+template <typename T>
+Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::isTestAndSetNative()
+{ return true; }
+template <typename T>
+Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::isTestAndSetWaitFree()
+{ return false; }
+
+#define Q_ATOMIC_POINTER_FETCH_AND_STORE_IS_ALWAYS_NATIVE
+
+template <typename T>
+Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::isFetchAndStoreNative()
+{ return true; }
+template <typename T>
+Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::isFetchAndStoreWaitFree()
+{ return false; }
+
+#define Q_ATOMIC_POINTER_FETCH_AND_ADD_IS_ALWAYS_NATIVE
+
+template <typename T>
+Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::isFetchAndAddNative()
+{ return true; }
+template <typename T>
+Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::isFetchAndAddWaitFree()
+{ return false; }
+
+#if defined(Q_CC_GNU) && !defined(Q_OS_IRIX)
+
+inline bool QBasicAtomicInt::ref()
+{
+ register int originalValue;
+ register int newValue;
+ asm volatile("0:\n"
+ "ll %[originalValue], %[_q_value]\n"
+ "addiu %[newValue], %[originalValue], %[one]\n"
+ "sc %[newValue], %[_q_value]\n"
+ "beqz %[newValue], 0b\n"
+ "nop\n"
+ : [originalValue] "=&r" (originalValue),
+ [_q_value] "+m" (_q_value),
+ [newValue] "=&r" (newValue)
+ : [one] "i" (1)
+ : "cc", "memory");
+ return originalValue != -1;
+}
+
+inline bool QBasicAtomicInt::deref()
+{
+ register int originalValue;
+ register int newValue;
+ asm volatile("0:\n"
+ "ll %[originalValue], %[_q_value]\n"
+ "addiu %[newValue], %[originalValue], %[minusOne]\n"
+ "sc %[newValue], %[_q_value]\n"
+ "beqz %[newValue], 0b\n"
+ "nop\n"
+ : [originalValue] "=&r" (originalValue),
+ [_q_value] "+m" (_q_value),
+ [newValue] "=&r" (newValue)
+ : [minusOne] "i" (-1)
+ : "cc", "memory");
+ return originalValue != 1;
+}
+
+inline bool QBasicAtomicInt::testAndSetRelaxed(int expectedValue, int newValue)
+{
+ register int result;
+ register int tempValue;
+ asm volatile("0:\n"
+ "ll %[result], %[_q_value]\n"
+ "xor %[result], %[result], %[expectedValue]\n"
+ "bnez %[result], 0f\n"
+ "nop\n"
+ "move %[tempValue], %[newValue]\n"
+ "sc %[tempValue], %[_q_value]\n"
+ "beqz %[tempValue], 0b\n"
+ "nop\n"
+ "0:\n"
+ : [result] "=&r" (result),
+ [tempValue] "=&r" (tempValue),
+ [_q_value] "+m" (_q_value)
+ : [expectedValue] "r" (expectedValue),
+ [newValue] "r" (newValue)
+ : "cc", "memory");
+ return result == 0;
+}
+
+inline bool QBasicAtomicInt::testAndSetAcquire(int expectedValue, int newValue)
+{
+ register int result;
+ register int tempValue;
+ asm volatile("0:\n"
+ "ll %[result], %[_q_value]\n"
+ "xor %[result], %[result], %[expectedValue]\n"
+ "bnez %[result], 0f\n"
+ "nop\n"
+ "move %[tempValue], %[newValue]\n"
+ "sc %[tempValue], %[_q_value]\n"
+ "beqz %[tempValue], 0b\n"
+ "nop\n"
+ "sync\n"
+ "0:\n"
+ : [result] "=&r" (result),
+ [tempValue] "=&r" (tempValue),
+ [_q_value] "+m" (_q_value)
+ : [expectedValue] "r" (expectedValue),
+ [newValue] "r" (newValue)
+ : "cc", "memory");
+ return result == 0;
+}
+
+inline bool QBasicAtomicInt::testAndSetRelease(int expectedValue, int newValue)
+{
+ register int result;
+ register int tempValue;
+ asm volatile("sync\n"
+ "0:\n"
+ "ll %[result], %[_q_value]\n"
+ "xor %[result], %[result], %[expectedValue]\n"
+ "bnez %[result], 0f\n"
+ "nop\n"
+ "move %[tempValue], %[newValue]\n"
+ "sc %[tempValue], %[_q_value]\n"
+ "beqz %[tempValue], 0b\n"
+ "nop\n"
+ "0:\n"
+ : [result] "=&r" (result),
+ [tempValue] "=&r" (tempValue),
+ [_q_value] "+m" (_q_value)
+ : [expectedValue] "r" (expectedValue),
+ [newValue] "r" (newValue)
+ : "cc", "memory");
+ return result == 0;
+}
+
+inline bool QBasicAtomicInt::testAndSetOrdered(int expectedValue, int newValue)
+{
+ return testAndSetAcquire(expectedValue, newValue);
+}
+
+inline int QBasicAtomicInt::fetchAndStoreRelaxed(int newValue)
+{
+ register int originalValue;
+ register int tempValue;
+ asm volatile("0:\n"
+ "ll %[originalValue], %[_q_value]\n"
+ "move %[tempValue], %[newValue]\n"
+ "sc %[tempValue], %[_q_value]\n"
+ "beqz %[tempValue], 0b\n"
+ "nop\n"
+ : [originalValue] "=&r" (originalValue),
+ [tempValue] "=&r" (tempValue),
+ [_q_value] "+m" (_q_value)
+ : [newValue] "r" (newValue)
+ : "cc", "memory");
+ return originalValue;
+}
+
+inline int QBasicAtomicInt::fetchAndStoreAcquire(int newValue)
+{
+ register int originalValue;
+ register int tempValue;
+ asm volatile("0:\n"
+ "ll %[originalValue], %[_q_value]\n"
+ "move %[tempValue], %[newValue]\n"
+ "sc %[tempValue], %[_q_value]\n"
+ "beqz %[tempValue], 0b\n"
+ "nop\n"
+ "sync\n"
+ : [originalValue] "=&r" (originalValue),
+ [tempValue] "=&r" (tempValue),
+ [_q_value] "+m" (_q_value)
+ : [newValue] "r" (newValue)
+ : "cc", "memory");
+ return originalValue;
+}
+
+inline int QBasicAtomicInt::fetchAndStoreRelease(int newValue)
+{
+ register int originalValue;
+ register int tempValue;
+ asm volatile("sync\n"
+ "0:\n"
+ "ll %[originalValue], %[_q_value]\n"
+ "move %[tempValue], %[newValue]\n"
+ "sc %[tempValue], %[_q_value]\n"
+ "beqz %[tempValue], 0b\n"
+ "nop\n"
+ : [originalValue] "=&r" (originalValue),
+ [tempValue] "=&r" (tempValue),
+ [_q_value] "+m" (_q_value)
+ : [newValue] "r" (newValue)
+ : "cc", "memory");
+ return originalValue;
+}
+
+inline int QBasicAtomicInt::fetchAndStoreOrdered(int newValue)
+{
+ return fetchAndStoreAcquire(newValue);
+}
+
+inline int QBasicAtomicInt::fetchAndAddRelaxed(int valueToAdd)
+{
+ register int originalValue;
+ register int newValue;
+ asm volatile("0:\n"
+ "ll %[originalValue], %[_q_value]\n"
+ "addu %[newValue], %[originalValue], %[valueToAdd]\n"
+ "sc %[newValue], %[_q_value]\n"
+ "beqz %[newValue], 0b\n"
+ "nop\n"
+ : [originalValue] "=&r" (originalValue),
+ [_q_value] "+m" (_q_value),
+ [newValue] "=&r" (newValue)
+ : [valueToAdd] "r" (valueToAdd)
+ : "cc", "memory");
+ return originalValue;
+}
+
+inline int QBasicAtomicInt::fetchAndAddAcquire(int valueToAdd)
+{
+ register int originalValue;
+ register int newValue;
+ asm volatile("0:\n"
+ "ll %[originalValue], %[_q_value]\n"
+ "addu %[newValue], %[originalValue], %[valueToAdd]\n"
+ "sc %[newValue], %[_q_value]\n"
+ "beqz %[newValue], 0b\n"
+ "nop\n"
+ "sync\n"
+ : [originalValue] "=&r" (originalValue),
+ [_q_value] "+m" (_q_value),
+ [newValue] "=&r" (newValue)
+ : [valueToAdd] "r" (valueToAdd)
+ : "cc", "memory");
+ return originalValue;
+}
+
+inline int QBasicAtomicInt::fetchAndAddRelease(int valueToAdd)
+{
+ register int originalValue;
+ register int newValue;
+ asm volatile("sync\n"
+ "0:\n"
+ "ll %[originalValue], %[_q_value]\n"
+ "addu %[newValue], %[originalValue], %[valueToAdd]\n"
+ "sc %[newValue], %[_q_value]\n"
+ "beqz %[newValue], 0b\n"
+ "nop\n"
+ : [originalValue] "=&r" (originalValue),
+ [_q_value] "+m" (_q_value),
+ [newValue] "=&r" (newValue)
+ : [valueToAdd] "r" (valueToAdd)
+ : "cc", "memory");
+ return originalValue;
+}
+
+inline int QBasicAtomicInt::fetchAndAddOrdered(int valueToAdd)
+{
+ return fetchAndAddAcquire(valueToAdd);
+}
+
+#if defined(__LP64__)
+# define LLP "lld"
+# define SCP "scd"
+#else
+# define LLP "ll"
+# define SCP "sc"
+#endif
+
+template <typename T>
+Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::testAndSetRelaxed(T *expectedValue, T *newValue)
+{
+ register T *result;
+ register T *tempValue;
+ asm volatile("0:\n"
+ LLP" %[result], %[_q_value]\n"
+ "xor %[result], %[result], %[expectedValue]\n"
+ "bnez %[result], 0f\n"
+ "nop\n"
+ "move %[tempValue], %[newValue]\n"
+ SCP" %[tempValue], %[_q_value]\n"
+ "beqz %[tempValue], 0b\n"
+ "nop\n"
+ "0:\n"
+ : [result] "=&r" (result),
+ [tempValue] "=&r" (tempValue),
+ [_q_value] "+m" (_q_value)
+ : [expectedValue] "r" (expectedValue),
+ [newValue] "r" (newValue)
+ : "cc", "memory");
+ return result == 0;
+}
+
+template <typename T>
+Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::testAndSetAcquire(T *expectedValue, T *newValue)
+{
+ register T *result;
+ register T *tempValue;
+ asm volatile("0:\n"
+ LLP" %[result], %[_q_value]\n"
+ "xor %[result], %[result], %[expectedValue]\n"
+ "bnez %[result], 0f\n"
+ "nop\n"
+ "move %[tempValue], %[newValue]\n"
+ SCP" %[tempValue], %[_q_value]\n"
+ "beqz %[tempValue], 0b\n"
+ "nop\n"
+ "sync\n"
+ "0:\n"
+ : [result] "=&r" (result),
+ [tempValue] "=&r" (tempValue),
+ [_q_value] "+m" (_q_value)
+ : [expectedValue] "r" (expectedValue),
+ [newValue] "r" (newValue)
+ : "cc", "memory");
+ return result == 0;
+}
+
+template <typename T>
+Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::testAndSetRelease(T *expectedValue, T *newValue)
+{
+ register T *result;
+ register T *tempValue;
+ asm volatile("sync\n"
+ "0:\n"
+ LLP" %[result], %[_q_value]\n"
+ "xor %[result], %[result], %[expectedValue]\n"
+ "bnez %[result], 0f\n"
+ "nop\n"
+ "move %[tempValue], %[newValue]\n"
+ SCP" %[tempValue], %[_q_value]\n"
+ "beqz %[tempValue], 0b\n"
+ "nop\n"
+ "0:\n"
+ : [result] "=&r" (result),
+ [tempValue] "=&r" (tempValue),
+ [_q_value] "+m" (_q_value)
+ : [expectedValue] "r" (expectedValue),
+ [newValue] "r" (newValue)
+ : "cc", "memory");
+ return result == 0;
+}
+
+template <typename T>
+Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::testAndSetOrdered(T *expectedValue, T *newValue)
+{
+ return testAndSetAcquire(expectedValue, newValue);
+}
+
+template <typename T>
+Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndStoreRelaxed(T *newValue)
+{
+ register T *originalValue;
+ register T *tempValue;
+ asm volatile("0:\n"
+ LLP" %[originalValue], %[_q_value]\n"
+ "move %[tempValue], %[newValue]\n"
+ SCP" %[tempValue], %[_q_value]\n"
+ "beqz %[tempValue], 0b\n"
+ "nop\n"
+ : [originalValue] "=&r" (originalValue),
+ [tempValue] "=&r" (tempValue),
+ [_q_value] "+m" (_q_value)
+ : [newValue] "r" (newValue)
+ : "cc", "memory");
+ return originalValue;
+}
+
+template <typename T>
+Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndStoreAcquire(T *newValue)
+{
+ register T *originalValue;
+ register T *tempValue;
+ asm volatile("0:\n"
+ LLP" %[originalValue], %[_q_value]\n"
+ "move %[tempValue], %[newValue]\n"
+ SCP" %[tempValue], %[_q_value]\n"
+ "beqz %[tempValue], 0b\n"
+ "nop\n"
+ "sync\n"
+ : [originalValue] "=&r" (originalValue),
+ [tempValue] "=&r" (tempValue),
+ [_q_value] "+m" (_q_value)
+ : [newValue] "r" (newValue)
+ : "cc", "memory");
+ return originalValue;
+}
+
+template <typename T>
+Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndStoreRelease(T *newValue)
+{
+ register T *originalValue;
+ register T *tempValue;
+ asm volatile("sync\n"
+ "0:\n"
+ LLP" %[originalValue], %[_q_value]\n"
+ "move %[tempValue], %[newValue]\n"
+ SCP" %[tempValue], %[_q_value]\n"
+ "beqz %[tempValue], 0b\n"
+ "nop\n"
+ : [originalValue] "=&r" (originalValue),
+ [tempValue] "=&r" (tempValue),
+ [_q_value] "+m" (_q_value)
+ : [newValue] "r" (newValue)
+ : "cc", "memory");
+ return originalValue;
+}
+
+template <typename T>
+Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndStoreOrdered(T *newValue)
+{
+ return fetchAndStoreAcquire(newValue);
+}
+
+template <typename T>
+Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndAddRelaxed(qptrdiff valueToAdd)
+{
+ register T *originalValue;
+ register T *newValue;
+ asm volatile("0:\n"
+ LLP" %[originalValue], %[_q_value]\n"
+ "addu %[newValue], %[originalValue], %[valueToAdd]\n"
+ SCP" %[newValue], %[_q_value]\n"
+ "beqz %[newValue], 0b\n"
+ "nop\n"
+ : [originalValue] "=&r" (originalValue),
+ [_q_value] "+m" (_q_value),
+ [newValue] "=&r" (newValue)
+ : [valueToAdd] "r" (valueToAdd * sizeof(T))
+ : "cc", "memory");
+ return originalValue;
+}
+
+template <typename T>
+Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndAddAcquire(qptrdiff valueToAdd)
+{
+ register T *originalValue;
+ register T *newValue;
+ asm volatile("0:\n"
+ LLP" %[originalValue], %[_q_value]\n"
+ "addu %[newValue], %[originalValue], %[valueToAdd]\n"
+ SCP" %[newValue], %[_q_value]\n"
+ "beqz %[newValue], 0b\n"
+ "nop\n"
+ "sync\n"
+ : [originalValue] "=&r" (originalValue),
+ [_q_value] "+m" (_q_value),
+ [newValue] "=&r" (newValue)
+ : [valueToAdd] "r" (valueToAdd * sizeof(T))
+ : "cc", "memory");
+ return originalValue;
+}
+
+template <typename T>
+Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndAddRelease(qptrdiff valueToAdd)
+{
+ register T *originalValue;
+ register T *newValue;
+ asm volatile("sync\n"
+ "0:\n"
+ LLP" %[originalValue], %[_q_value]\n"
+ "addu %[newValue], %[originalValue], %[valueToAdd]\n"
+ SCP" %[newValue], %[_q_value]\n"
+ "beqz %[newValue], 0b\n"
+ "nop\n"
+ : [originalValue] "=&r" (originalValue),
+ [_q_value] "+m" (_q_value),
+ [newValue] "=&r" (newValue)
+ : [valueToAdd] "r" (valueToAdd * sizeof(T))
+ : "cc", "memory");
+ return originalValue;
+}
+
+template <typename T>
+Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndAddOrdered(qptrdiff valueToAdd)
+{
+ return fetchAndAddAcquire(valueToAdd);
+}
+
+#else // !Q_CC_GNU
+
+extern "C" {
+ Q_CORE_EXPORT int q_atomic_test_and_set_int(volatile int *ptr, int expected, int newval);
+ Q_CORE_EXPORT int q_atomic_test_and_set_acquire_int(volatile int *ptr, int expected, int newval);
+ Q_CORE_EXPORT int q_atomic_test_and_set_release_int(volatile int *ptr, int expected, int newval);
+ Q_CORE_EXPORT int q_atomic_test_and_set_ptr(volatile void *ptr, void *expected, void *newval);
+ Q_CORE_EXPORT int q_atomic_test_and_set_acquire_ptr(volatile void *ptr, void *expected, void *newval);
+ Q_CORE_EXPORT int q_atomic_test_and_set_release_ptr(volatile void *ptr, void *expected, void *newval);
+} // extern "C"
+
+inline bool QBasicAtomicInt::ref()
+{
+ register int expected;
+ for (;;) {
+ expected = _q_value;
+ if (q_atomic_test_and_set_int(&_q_value, expected, expected + 1))
+ break;
+ }
+ return expected != -1;
+}
+
+inline bool QBasicAtomicInt::deref()
+{
+ register int expected;
+ for (;;) {
+ expected = _q_value;
+ if (q_atomic_test_and_set_int(&_q_value, expected, expected - 1))
+ break;
+ }
+ return expected != 1;
+}
+
+inline bool QBasicAtomicInt::testAndSetRelaxed(int expectedValue, int newValue)
+{
+ return q_atomic_test_and_set_int(&_q_value, expectedValue, newValue) != 0;
+}
+
+inline bool QBasicAtomicInt::testAndSetAcquire(int expectedValue, int newValue)
+{
+ return q_atomic_test_and_set_acquire_int(&_q_value, expectedValue, newValue) != 0;
+}
+
+inline bool QBasicAtomicInt::testAndSetRelease(int expectedValue, int newValue)
+{
+ return q_atomic_test_and_set_release_int(&_q_value, expectedValue, newValue) != 0;
+}
+
+inline bool QBasicAtomicInt::testAndSetOrdered(int expectedValue, int newValue)
+{
+ return q_atomic_test_and_set_acquire_int(&_q_value, expectedValue, newValue) != 0;
+}
+
+inline int QBasicAtomicInt::fetchAndStoreRelaxed(int newValue)
+{
+ int returnValue;
+ for (;;) {
+ returnValue = _q_value;
+ if (testAndSetRelaxed(returnValue, newValue))
+ break;
+ }
+ return returnValue;
+}
+
+inline int QBasicAtomicInt::fetchAndStoreAcquire(int newValue)
+{
+ int returnValue;
+ for (;;) {
+ returnValue = _q_value;
+ if (testAndSetAcquire(returnValue, newValue))
+ break;
+ }
+ return returnValue;
+}
+
+inline int QBasicAtomicInt::fetchAndStoreRelease(int newValue)
+{
+ int returnValue;
+ for (;;) {
+ returnValue = _q_value;
+ if (testAndSetRelease(returnValue, newValue))
+ break;
+ }
+ return returnValue;
+}
+
+inline int QBasicAtomicInt::fetchAndStoreOrdered(int newValue)
+{
+ int returnValue;
+ for (;;) {
+ returnValue = _q_value;
+ if (testAndSetOrdered(returnValue, newValue))
+ break;
+ }
+ return returnValue;
+}
+
+inline int QBasicAtomicInt::fetchAndAddRelaxed(int valueToAdd)
+{
+ int returnValue;
+ for (;;) {
+ returnValue = _q_value;
+ if (testAndSetRelaxed(returnValue, returnValue + valueToAdd))
+ break;
+ }
+ return returnValue;
+}
+
+inline int QBasicAtomicInt::fetchAndAddAcquire(int valueToAdd)
+{
+ int returnValue;
+ for (;;) {
+ returnValue = _q_value;
+ if (testAndSetAcquire(returnValue, returnValue + valueToAdd))
+ break;
+ }
+ return returnValue;
+}
+
+inline int QBasicAtomicInt::fetchAndAddRelease(int valueToAdd)
+{
+ int returnValue;
+ for (;;) {
+ returnValue = _q_value;
+ if (testAndSetRelease(returnValue, returnValue + valueToAdd))
+ break;
+ }
+ return returnValue;
+}
+
+inline int QBasicAtomicInt::fetchAndAddOrdered(int valueToAdd)
+{
+ int returnValue;
+ for (;;) {
+ returnValue = _q_value;
+ if (testAndSetOrdered(returnValue, returnValue + valueToAdd))
+ break;
+ }
+ return returnValue;
+}
+
+template <typename T>
+Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::testAndSetRelaxed(T *expectedValue, T *newValue)
+{
+ return q_atomic_test_and_set_ptr(&_q_value, expectedValue, newValue) != 0;
+}
+
+template <typename T>
+Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::testAndSetAcquire(T *expectedValue, T *newValue)
+{
+ return q_atomic_test_and_set_acquire_ptr(&_q_value, expectedValue, newValue) != 0;
+}
+
+template <typename T>
+Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::testAndSetRelease(T *expectedValue, T *newValue)
+{
+ return q_atomic_test_and_set_release_ptr(&_q_value, expectedValue, newValue) != 0;
+}
+
+template <typename T>
+Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::testAndSetOrdered(T *expectedValue, T *newValue)
+{
+ return q_atomic_test_and_set_acquire_ptr(&_q_value, expectedValue, newValue) != 0;
+}
+
+template <typename T>
+Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndStoreRelaxed(T *newValue)
+{
+ T *returnValue;
+ for (;;) {
+ returnValue = (_q_value);
+ if (testAndSetRelaxed(returnValue, newValue))
+ break;
+ }
+ return returnValue;
+}
+
+template <typename T>
+Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndStoreAcquire(T *newValue)
+{
+ T *returnValue;
+ for (;;) {
+ returnValue = (_q_value);
+ if (testAndSetAcquire(returnValue, newValue))
+ break;
+ }
+ return returnValue;
+}
+
+template <typename T>
+Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndStoreRelease(T *newValue)
+{
+ T *returnValue;
+ for (;;) {
+ returnValue = (_q_value);
+ if (testAndSetRelease(returnValue, newValue))
+ break;
+ }
+ return returnValue;
+}
+
+template <typename T>
+Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndStoreOrdered(T *newValue)
+{
+ T *returnValue;
+ for (;;) {
+ returnValue = (_q_value);
+ if (testAndSetOrdered(returnValue, newValue))
+ break;
+ }
+ return returnValue;
+}
+
+template <typename T>
+Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndAddRelaxed(qptrdiff valueToAdd)
+{
+ T *returnValue;
+ for (;;) {
+ returnValue = (_q_value);
+ if (testAndSetRelaxed(returnValue, returnValue + valueToAdd))
+ break;
+ }
+ return returnValue;
+}
+
+template <typename T>
+Q_INLINE_TEMPLATE
+T *QBasicAtomicPointer<T>::fetchAndAddAcquire(qptrdiff valueToAdd)
+{
+ T *returnValue;
+ for (;;) {
+ returnValue = (_q_value);
+ if (testAndSetAcquire(returnValue, returnValue + valueToAdd))
+ break;
+ }
+ return returnValue;
+}
+
+template <typename T>
+Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndAddRelease(qptrdiff valueToAdd)
+{
+ T *returnValue;
+ for (;;) {
+ returnValue = (_q_value);
+ if (testAndSetRelease(returnValue, returnValue + valueToAdd))
+ break;
+ }
+ return returnValue;
+}
+
+template <typename T>
+Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndAddOrdered(qptrdiff valueToAdd)
+{
+ T *returnValue;
+ for (;;) {
+ returnValue = (_q_value);
+ if (testAndSetOrdered(returnValue, returnValue + valueToAdd))
+ break;
+ }
+ return returnValue;
+}
+
+#endif // Q_CC_GNU
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // QATOMIC_MIPS_H
diff --git a/src/corelib/arch/qatomic_parisc.h b/src/corelib/arch/qatomic_parisc.h
new file mode 100644
index 0000000000..134faf93af
--- /dev/null
+++ b/src/corelib/arch/qatomic_parisc.h
@@ -0,0 +1,305 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtCore module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QATOMIC_PARISC_H
+#define QATOMIC_PARISC_H
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+#define Q_ATOMIC_INT_REFERENCE_COUNTING_IS_NOT_NATIVE
+
+inline bool QBasicAtomicInt::isReferenceCountingNative()
+{ return false; }
+inline bool QBasicAtomicInt::isReferenceCountingWaitFree()
+{ return false; }
+
+#define Q_ATOMIC_INT_TEST_AND_SET_IS_NOT_NATIVE
+
+inline bool QBasicAtomicInt::isTestAndSetNative()
+{ return false; }
+inline bool QBasicAtomicInt::isTestAndSetWaitFree()
+{ return false; }
+
+#define Q_ATOMIC_INT_FETCH_AND_STORE_IS_NOT_NATIVE
+
+inline bool QBasicAtomicInt::isFetchAndStoreNative()
+{ return false; }
+inline bool QBasicAtomicInt::isFetchAndStoreWaitFree()
+{ return false; }
+
+#define Q_ATOMIC_INT_FETCH_AND_ADD_IS_NOT_NATIVE
+
+inline bool QBasicAtomicInt::isFetchAndAddNative()
+{ return false; }
+inline bool QBasicAtomicInt::isFetchAndAddWaitFree()
+{ return false; }
+
+#define Q_ATOMIC_POINTER_TEST_AND_SET_IS_NOT_NATIVE
+
+template <typename T>
+Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::isTestAndSetNative()
+{ return false; }
+template <typename T>
+Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::isTestAndSetWaitFree()
+{ return false; }
+
+#define Q_ATOMIC_POINTER_FETCH_AND_STORE_IS_NOT_NATIVE
+
+template <typename T>
+Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::isFetchAndStoreNative()
+{ return false; }
+template <typename T>
+Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::isFetchAndStoreWaitFree()
+{ return false; }
+
+#define Q_ATOMIC_POINTER_FETCH_AND_ADD_IS_NOT_NATIVE
+
+template <typename T>
+Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::isFetchAndAddNative()
+{ return false; }
+template <typename T>
+Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::isFetchAndAddWaitFree()
+{ return false; }
+
+extern "C" {
+ Q_CORE_EXPORT void q_atomic_lock(int *lock);
+ Q_CORE_EXPORT void q_atomic_unlock(int *lock);
+}
+
+// Reference counting
+
+inline bool QBasicAtomicInt::ref()
+{
+ q_atomic_lock(_q_lock);
+ bool ret = (++_q_value != 0);
+ q_atomic_unlock(_q_lock);
+ return ret;
+}
+
+inline bool QBasicAtomicInt::deref()
+{
+ q_atomic_lock(_q_lock);
+ bool ret = (--_q_value != 0);
+ q_atomic_unlock(_q_lock);
+ return ret;
+}
+
+// Test-and-set for integers
+
+inline bool QBasicAtomicInt::testAndSetOrdered(int expectedValue, int newValue)
+{
+ q_atomic_lock(_q_lock);
+ if (_q_value == expectedValue) {
+ _q_value = newValue;
+ q_atomic_unlock(_q_lock);
+ return true;
+ }
+ q_atomic_unlock(_q_lock);
+ return false;
+}
+
+inline bool QBasicAtomicInt::testAndSetRelaxed(int expectedValue, int newValue)
+{
+ return testAndSetOrdered(expectedValue, newValue);
+}
+
+inline bool QBasicAtomicInt::testAndSetAcquire(int expectedValue, int newValue)
+{
+ return testAndSetOrdered(expectedValue, newValue);
+}
+
+inline bool QBasicAtomicInt::testAndSetRelease(int expectedValue, int newValue)
+{
+ return testAndSetOrdered(expectedValue, newValue);
+}
+
+// Fetch-and-store for integers
+
+inline int QBasicAtomicInt::fetchAndStoreOrdered(int newValue)
+{
+ q_atomic_lock(_q_lock);
+ int returnValue = _q_value;
+ _q_value = newValue;
+ q_atomic_unlock(_q_lock);
+ return returnValue;
+}
+
+inline int QBasicAtomicInt::fetchAndStoreRelaxed(int newValue)
+{
+ return fetchAndStoreOrdered(newValue);
+}
+
+inline int QBasicAtomicInt::fetchAndStoreAcquire(int newValue)
+{
+ return fetchAndStoreOrdered(newValue);
+}
+
+inline int QBasicAtomicInt::fetchAndStoreRelease(int newValue)
+{
+ return fetchAndStoreOrdered(newValue);
+}
+
+// Fetch-and-add for integers
+
+inline int QBasicAtomicInt::fetchAndAddOrdered(int valueToAdd)
+{
+ q_atomic_lock(_q_lock);
+ int originalValue = _q_value;
+ _q_value += valueToAdd;
+ q_atomic_unlock(_q_lock);
+ return originalValue;
+}
+
+inline int QBasicAtomicInt::fetchAndAddRelaxed(int valueToAdd)
+{
+ return fetchAndAddOrdered(valueToAdd);
+}
+
+inline int QBasicAtomicInt::fetchAndAddAcquire(int valueToAdd)
+{
+ return fetchAndAddOrdered(valueToAdd);
+}
+
+inline int QBasicAtomicInt::fetchAndAddRelease(int valueToAdd)
+{
+ return fetchAndAddOrdered(valueToAdd);
+}
+
+// Test and set for pointers
+
+template <typename T>
+Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::testAndSetOrdered(T *expectedValue, T *newValue)
+{
+ q_atomic_lock(_q_lock);
+ if (_q_value == expectedValue) {
+ _q_value = newValue;
+ q_atomic_unlock(_q_lock);
+ return true;
+ }
+ q_atomic_unlock(_q_lock);
+ return false;
+}
+
+template <typename T>
+Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::testAndSetRelaxed(T *expectedValue, T *newValue)
+{
+ return testAndSetOrdered(expectedValue, newValue);
+}
+
+template <typename T>
+Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::testAndSetAcquire(T *expectedValue, T *newValue)
+{
+ return testAndSetOrdered(expectedValue, newValue);
+}
+
+template <typename T>
+Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::testAndSetRelease(T *expectedValue, T *newValue)
+{
+ return testAndSetOrdered(expectedValue, newValue);
+}
+
+// Fetch and store for pointers
+
+template <typename T>
+Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndStoreOrdered(T *newValue)
+{
+ q_atomic_lock(_q_lock);
+ T *returnValue = (_q_value);
+ _q_value = newValue;
+ q_atomic_unlock(_q_lock);
+ return returnValue;
+}
+
+template <typename T>
+Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndStoreRelaxed(T *newValue)
+{
+ return fetchAndStoreOrdered(newValue);
+}
+
+template <typename T>
+Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndStoreAcquire(T *newValue)
+{
+ return fetchAndStoreOrdered(newValue);
+}
+
+template <typename T>
+Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndStoreRelease(T *newValue)
+{
+ return fetchAndStoreOrdered(newValue);
+}
+
+// Fetch and add for pointers
+
+template <typename T>
+Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndAddOrdered(qptrdiff valueToAdd)
+{
+ q_atomic_lock(_q_lock);
+ T *returnValue = (_q_value);
+ _q_value += valueToAdd;
+ q_atomic_unlock(_q_lock);
+ return returnValue;
+}
+
+template <typename T>
+Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndAddRelaxed(qptrdiff valueToAdd)
+{
+ return fetchAndAddOrdered(valueToAdd);
+}
+
+template <typename T>
+Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndAddAcquire(qptrdiff valueToAdd)
+{
+ return fetchAndAddOrdered(valueToAdd);
+}
+
+template <typename T>
+Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndAddRelease(qptrdiff valueToAdd)
+{
+ return fetchAndAddOrdered(valueToAdd);
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // QATOMIC_PARISC_H
diff --git a/src/corelib/arch/qatomic_powerpc.h b/src/corelib/arch/qatomic_powerpc.h
new file mode 100644
index 0000000000..28a143e2a0
--- /dev/null
+++ b/src/corelib/arch/qatomic_powerpc.h
@@ -0,0 +1,650 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtCore module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QATOMIC_POWERPC_H
+#define QATOMIC_POWERPC_H
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+#define Q_ATOMIC_INT_REFERENCE_COUNTING_IS_ALWAYS_NATIVE
+
+inline bool QBasicAtomicInt::isReferenceCountingNative()
+{ return true; }
+inline bool QBasicAtomicInt::isReferenceCountingWaitFree()
+{ return false; }
+
+#define Q_ATOMIC_INT_TEST_AND_SET_IS_ALWAYS_NATIVE
+
+inline bool QBasicAtomicInt::isTestAndSetNative()
+{ return true; }
+inline bool QBasicAtomicInt::isTestAndSetWaitFree()
+{ return false; }
+
+#define Q_ATOMIC_INT_FETCH_AND_STORE_IS_ALWAYS_NATIVE
+
+inline bool QBasicAtomicInt::isFetchAndStoreNative()
+{ return true; }
+inline bool QBasicAtomicInt::isFetchAndStoreWaitFree()
+{ return false; }
+
+#define Q_ATOMIC_INT_FETCH_AND_ADD_IS_ALWAYS_NATIVE
+
+inline bool QBasicAtomicInt::isFetchAndAddNative()
+{ return true; }
+inline bool QBasicAtomicInt::isFetchAndAddWaitFree()
+{ return false; }
+
+#define Q_ATOMIC_POINTER_TEST_AND_SET_IS_ALWAYS_NATIVE
+
+template <typename T>
+Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::isTestAndSetNative()
+{ return true; }
+template <typename T>
+Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::isTestAndSetWaitFree()
+{ return false; }
+
+#define Q_ATOMIC_POINTER_FETCH_AND_STORE_IS_ALWAYS_NATIVE
+
+template <typename T>
+Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::isFetchAndStoreNative()
+{ return true; }
+template <typename T>
+Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::isFetchAndStoreWaitFree()
+{ return false; }
+
+#define Q_ATOMIC_POINTER_FETCH_AND_ADD_IS_ALWAYS_NATIVE
+
+template <typename T>
+Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::isFetchAndAddNative()
+{ return true; }
+template <typename T>
+Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::isFetchAndAddWaitFree()
+{ return false; }
+
+QT_BEGIN_NAMESPACE
+
+#if defined(Q_CC_GNU)
+
+#if __GNUC__ < 4 || (__GNUC__ == 4 && __GNUC_MINOR__ < 2) \
+ || (!defined(__64BIT__) && !defined(__powerpc64__) && !defined(__ppc64__))
+# define _Q_VALUE "0, %[_q_value]"
+# define _Q_VALUE_MEMORY_OPERAND "+m" (_q_value)
+# define _Q_VALUE_REGISTER_OPERAND [_q_value] "r" (&_q_value),
+#else
+// On 64-bit with gcc >= 4.2
+# define _Q_VALUE "%y[_q_value]"
+# define _Q_VALUE_MEMORY_OPERAND [_q_value] "+Z" (_q_value)
+# define _Q_VALUE_REGISTER_OPERAND
+#endif
+
+inline bool QBasicAtomicInt::ref()
+{
+ register int originalValue;
+ register int newValue;
+ asm volatile("lwarx %[originalValue]," _Q_VALUE "\n"
+ "addi %[newValue], %[originalValue], %[one]\n"
+ "stwcx. %[newValue]," _Q_VALUE "\n"
+ "bne- $-12\n"
+ : [originalValue] "=&b" (originalValue),
+ [newValue] "=&r" (newValue),
+ _Q_VALUE_MEMORY_OPERAND
+ : _Q_VALUE_REGISTER_OPERAND
+ [one] "i" (1)
+ : "cc", "memory");
+ return newValue != 0;
+}
+
+inline bool QBasicAtomicInt::deref()
+{
+ register int originalValue;
+ register int newValue;
+ asm volatile("lwarx %[originalValue]," _Q_VALUE "\n"
+ "addi %[newValue], %[originalValue], %[minusOne]\n"
+ "stwcx. %[newValue]," _Q_VALUE "\n"
+ "bne- $-12\n"
+ : [originalValue] "=&b" (originalValue),
+ [newValue] "=&r" (newValue),
+ _Q_VALUE_MEMORY_OPERAND
+ : _Q_VALUE_REGISTER_OPERAND
+ [minusOne] "i" (-1)
+ : "cc", "memory");
+ return newValue != 0;
+}
+
+inline bool QBasicAtomicInt::testAndSetRelaxed(int expectedValue, int newValue)
+{
+ register int result;
+ asm volatile("lwarx %[result]," _Q_VALUE "\n"
+ "xor. %[result], %[result], %[expectedValue]\n"
+ "bne $+12\n"
+ "stwcx. %[newValue]," _Q_VALUE "\n"
+ "bne- $-16\n"
+ : [result] "=&r" (result),
+ _Q_VALUE_MEMORY_OPERAND
+ : _Q_VALUE_REGISTER_OPERAND
+ [expectedValue] "r" (expectedValue),
+ [newValue] "r" (newValue)
+ : "cc", "memory");
+ return result == 0;
+}
+
+inline bool QBasicAtomicInt::testAndSetAcquire(int expectedValue, int newValue)
+{
+ register int result;
+ asm volatile("lwarx %[result]," _Q_VALUE "\n"
+ "xor. %[result], %[result], %[expectedValue]\n"
+ "bne $+16\n"
+ "stwcx. %[newValue]," _Q_VALUE "\n"
+ "bne- $-16\n"
+ "isync\n"
+ : [result] "=&r" (result),
+ _Q_VALUE_MEMORY_OPERAND
+ : _Q_VALUE_REGISTER_OPERAND
+ [expectedValue] "r" (expectedValue),
+ [newValue] "r" (newValue)
+ : "cc", "memory");
+ return result == 0;
+}
+
+inline bool QBasicAtomicInt::testAndSetRelease(int expectedValue, int newValue)
+{
+ register int result;
+ asm volatile("eieio\n"
+ "lwarx %[result]," _Q_VALUE "\n"
+ "xor. %[result], %[result], %[expectedValue]\n"
+ "bne $+12\n"
+ "stwcx. %[newValue]," _Q_VALUE "\n"
+ "bne- $-16\n"
+ : [result] "=&r" (result),
+ _Q_VALUE_MEMORY_OPERAND
+ : _Q_VALUE_REGISTER_OPERAND
+ [expectedValue] "r" (expectedValue),
+ [newValue] "r" (newValue)
+ : "cc", "memory");
+ return result == 0;
+}
+
+inline int QBasicAtomicInt::fetchAndStoreRelaxed(int newValue)
+{
+ register int originalValue;
+ asm volatile("lwarx %[originalValue]," _Q_VALUE "\n"
+ "stwcx. %[newValue]," _Q_VALUE "\n"
+ "bne- $-8\n"
+ : [originalValue] "=&r" (originalValue),
+ _Q_VALUE_MEMORY_OPERAND
+ : _Q_VALUE_REGISTER_OPERAND
+ [newValue] "r" (newValue)
+ : "cc", "memory");
+ return originalValue;
+}
+
+inline int QBasicAtomicInt::fetchAndStoreAcquire(int newValue)
+{
+ register int originalValue;
+ asm volatile("lwarx %[originalValue]," _Q_VALUE "\n"
+ "stwcx. %[newValue]," _Q_VALUE "\n"
+ "bne- $-8\n"
+ "isync\n"
+ : [originalValue] "=&r" (originalValue),
+ _Q_VALUE_MEMORY_OPERAND
+ : _Q_VALUE_REGISTER_OPERAND
+ [newValue] "r" (newValue)
+ : "cc", "memory");
+ return originalValue;
+}
+
+inline int QBasicAtomicInt::fetchAndStoreRelease(int newValue)
+{
+ register int originalValue;
+ asm volatile("eieio\n"
+ "lwarx %[originalValue]," _Q_VALUE "\n"
+ "stwcx. %[newValue]," _Q_VALUE "\n"
+ "bne- $-8\n"
+ : [originalValue] "=&r" (originalValue),
+ _Q_VALUE_MEMORY_OPERAND
+ : _Q_VALUE_REGISTER_OPERAND
+ [newValue] "r" (newValue)
+ : "cc", "memory");
+ return originalValue;
+}
+
+inline int QBasicAtomicInt::fetchAndAddRelaxed(int valueToAdd)
+{
+ register int originalValue;
+ register int newValue;
+ asm volatile("lwarx %[originalValue]," _Q_VALUE "\n"
+ "add %[newValue], %[originalValue], %[valueToAdd]\n"
+ "stwcx. %[newValue]," _Q_VALUE "\n"
+ "bne- $-12\n"
+ : [originalValue] "=&r" (originalValue),
+ [newValue] "=&r" (newValue),
+ _Q_VALUE_MEMORY_OPERAND
+ : _Q_VALUE_REGISTER_OPERAND
+ [valueToAdd] "r" (valueToAdd)
+ : "cc", "memory");
+ return originalValue;
+}
+
+inline int QBasicAtomicInt::fetchAndAddAcquire(int valueToAdd)
+{
+ register int originalValue;
+ register int newValue;
+ asm volatile("lwarx %[originalValue]," _Q_VALUE "\n"
+ "add %[newValue], %[originalValue], %[valueToAdd]\n"
+ "stwcx. %[newValue]," _Q_VALUE "\n"
+ "bne- $-12\n"
+ "isync\n"
+ : [originalValue] "=&r" (originalValue),
+ [newValue] "=&r" (newValue),
+ _Q_VALUE_MEMORY_OPERAND
+ : _Q_VALUE_REGISTER_OPERAND
+ [valueToAdd] "r" (valueToAdd)
+ : "cc", "memory");
+ return originalValue;
+}
+
+inline int QBasicAtomicInt::fetchAndAddRelease(int valueToAdd)
+{
+ register int originalValue;
+ register int newValue;
+ asm volatile("eieio\n"
+ "lwarx %[originalValue]," _Q_VALUE "\n"
+ "add %[newValue], %[originalValue], %[valueToAdd]\n"
+ "stwcx. %[newValue]," _Q_VALUE "\n"
+ "bne- $-12\n"
+ : [originalValue] "=&r" (originalValue),
+ [newValue] "=&r" (newValue),
+ _Q_VALUE_MEMORY_OPERAND
+ : _Q_VALUE_REGISTER_OPERAND
+ [valueToAdd] "r" (valueToAdd)
+ : "cc", "memory");
+ return originalValue;
+}
+
+#if defined(__64BIT__) || defined(__powerpc64__) || defined(__ppc64__)
+# define LPARX "ldarx"
+# define STPCX "stdcx."
+#else
+# define LPARX "lwarx"
+# define STPCX "stwcx."
+#endif
+
+template <typename T>
+Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::testAndSetRelaxed(T *expectedValue, T *newValue)
+{
+ register void *result;
+ asm volatile(LPARX" %[result]," _Q_VALUE "\n"
+ "xor. %[result], %[result], %[expectedValue]\n"
+ "bne $+12\n"
+ STPCX" %[newValue]," _Q_VALUE "\n"
+ "bne- $-16\n"
+ : [result] "=&r" (result),
+ _Q_VALUE_MEMORY_OPERAND
+ : _Q_VALUE_REGISTER_OPERAND
+ [expectedValue] "r" (expectedValue),
+ [newValue] "r" (newValue)
+ : "cc", "memory");
+ return result == 0;
+}
+
+template <typename T>
+Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::testAndSetAcquire(T *expectedValue, T *newValue)
+{
+ register void *result;
+ asm volatile(LPARX" %[result]," _Q_VALUE "\n"
+ "xor. %[result], %[result], %[expectedValue]\n"
+ "bne $+16\n"
+ STPCX" %[newValue]," _Q_VALUE "\n"
+ "bne- $-16\n"
+ "isync\n"
+ : [result] "=&r" (result),
+ _Q_VALUE_MEMORY_OPERAND
+ : _Q_VALUE_REGISTER_OPERAND
+ [expectedValue] "r" (expectedValue),
+ [newValue] "r" (newValue)
+ : "cc", "memory");
+ return result == 0;
+}
+
+template <typename T>
+Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::testAndSetRelease(T *expectedValue, T *newValue)
+{
+ register void *result;
+ asm volatile("eieio\n"
+ LPARX" %[result]," _Q_VALUE "\n"
+ "xor. %[result], %[result], %[expectedValue]\n"
+ "bne $+12\n"
+ STPCX" %[newValue]," _Q_VALUE "\n"
+ "bne- $-16\n"
+ : [result] "=&r" (result),
+ _Q_VALUE_MEMORY_OPERAND
+ : _Q_VALUE_REGISTER_OPERAND
+ [expectedValue] "r" (expectedValue),
+ [newValue] "r" (newValue)
+ : "cc", "memory");
+ return result == 0;
+}
+
+template <typename T>
+Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndStoreRelaxed(T *newValue)
+{
+ register T *originalValue;
+ asm volatile(LPARX" %[originalValue]," _Q_VALUE "\n"
+ STPCX" %[newValue]," _Q_VALUE "\n"
+ "bne- $-8\n"
+ : [originalValue] "=&r" (originalValue),
+ _Q_VALUE_MEMORY_OPERAND
+ : _Q_VALUE_REGISTER_OPERAND
+ [newValue] "r" (newValue)
+ : "cc", "memory");
+ return originalValue;
+}
+
+template <typename T>
+Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndStoreAcquire(T *newValue)
+{
+ register T *originalValue;
+ asm volatile(LPARX" %[originalValue]," _Q_VALUE "\n"
+ STPCX" %[newValue]," _Q_VALUE "\n"
+ "bne- $-8\n"
+ "isync\n"
+ : [originalValue] "=&r" (originalValue),
+ _Q_VALUE_MEMORY_OPERAND
+ : _Q_VALUE_REGISTER_OPERAND
+ [newValue] "r" (newValue)
+ : "cc", "memory");
+ return originalValue;
+}
+
+template <typename T>
+Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndStoreRelease(T *newValue)
+{
+ register T *originalValue;
+ asm volatile("eieio\n"
+ LPARX" %[originalValue]," _Q_VALUE "\n"
+ STPCX" %[newValue]," _Q_VALUE "\n"
+ "bne- $-8\n"
+ : [originalValue] "=&r" (originalValue),
+ _Q_VALUE_MEMORY_OPERAND
+ : _Q_VALUE_REGISTER_OPERAND
+ [newValue] "r" (newValue)
+ : "cc", "memory");
+ return originalValue;
+}
+
+template <typename T>
+Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndAddRelaxed(qptrdiff valueToAdd)
+{
+ register T *originalValue;
+ register T *newValue;
+ asm volatile(LPARX" %[originalValue]," _Q_VALUE "\n"
+ "add %[newValue], %[originalValue], %[valueToAdd]\n"
+ STPCX" %[newValue]," _Q_VALUE "\n"
+ "bne- $-12\n"
+ : [originalValue] "=&r" (originalValue),
+ [newValue] "=&r" (newValue),
+ _Q_VALUE_MEMORY_OPERAND
+ : _Q_VALUE_REGISTER_OPERAND
+ [valueToAdd] "r" (valueToAdd * sizeof(T))
+ : "cc", "memory");
+ return originalValue;
+}
+
+template <typename T>
+Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndAddAcquire(qptrdiff valueToAdd)
+{
+ register T *originalValue;
+ register T *newValue;
+ asm volatile(LPARX" %[originalValue]," _Q_VALUE "\n"
+ "add %[newValue], %[originalValue], %[valueToAdd]\n"
+ STPCX" %[newValue]," _Q_VALUE "\n"
+ "bne- $-12\n"
+ "isync\n"
+ : [originalValue] "=&r" (originalValue),
+ [newValue] "=&r" (newValue),
+ _Q_VALUE_MEMORY_OPERAND
+ : _Q_VALUE_REGISTER_OPERAND
+ [valueToAdd] "r" (valueToAdd * sizeof(T))
+ : "cc", "memory");
+ return originalValue;
+}
+
+template <typename T>
+Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndAddRelease(qptrdiff valueToAdd)
+{
+ register T *originalValue;
+ register T *newValue;
+ asm volatile("eieio\n"
+ LPARX" %[originalValue]," _Q_VALUE "\n"
+ "add %[newValue], %[originalValue], %[valueToAdd]\n"
+ STPCX" %[newValue]," _Q_VALUE "\n"
+ "bne- $-12\n"
+ : [originalValue] "=&r" (originalValue),
+ [newValue] "=&r" (newValue),
+ _Q_VALUE_MEMORY_OPERAND
+ : _Q_VALUE_REGISTER_OPERAND
+ [valueToAdd] "r" (valueToAdd * sizeof(T))
+ : "cc", "memory");
+ return originalValue;
+}
+
+#undef LPARX
+#undef STPCX
+#undef _Q_VALUE
+#undef _Q_VALUE_MEMORY_OPERAND
+#undef _Q_VALUE_REGISTER_OPERAND
+
+#else
+
+extern "C" {
+ int q_atomic_test_and_set_int(volatile int *ptr, int expectedValue, int newValue);
+ int q_atomic_test_and_set_acquire_int(volatile int *ptr, int expectedValue, int newValue);
+ int q_atomic_test_and_set_release_int(volatile int *ptr, int expectedValue, int newValue);
+ int q_atomic_test_and_set_ptr(volatile void *ptr, void *expectedValue, void *newValue);
+ int q_atomic_test_and_set_acquire_ptr(volatile void *ptr, void *expectedValue, void *newValue);
+ int q_atomic_test_and_set_release_ptr(volatile void *ptr, void *expectedValue, void *newValue);
+ int q_atomic_increment(volatile int *);
+ int q_atomic_decrement(volatile int *);
+ int q_atomic_set_int(volatile int *, int);
+ int q_atomic_fetch_and_store_acquire_int(volatile int *ptr, int newValue);
+ int q_atomic_fetch_and_store_release_int(volatile int *ptr, int newValue);
+ void *q_atomic_set_ptr(volatile void *, void *);
+ int q_atomic_fetch_and_store_acquire_ptr(volatile void *ptr, void *newValue);
+ int q_atomic_fetch_and_store_release_ptr(volatile void *ptr, void *newValue);
+ int q_atomic_fetch_and_add_int(volatile int *ptr, int valueToAdd);
+ int q_atomic_fetch_and_add_acquire_int(volatile int *ptr, int valueToAdd);
+ int q_atomic_fetch_and_add_release_int(volatile int *ptr, int valueToAdd);
+ void *q_atomic_fetch_and_add_ptr(volatile void *ptr, qptrdiff valueToAdd);
+ void *q_atomic_fetch_and_add_acquire_ptr(volatile void *ptr, qptrdiff valueToAdd);
+ void *q_atomic_fetch_and_add_release_ptr(volatile void *ptr, qptrdiff valueToAdd);
+} // extern "C"
+
+
+inline bool QBasicAtomicInt::ref()
+{
+ return q_atomic_increment(&_q_value) != 0;
+}
+
+inline bool QBasicAtomicInt::deref()
+{
+ return q_atomic_decrement(&_q_value) != 0;
+}
+
+inline bool QBasicAtomicInt::testAndSetRelaxed(int expectedValue, int newValue)
+{
+ return q_atomic_test_and_set_int(&_q_value, expectedValue, newValue) != 0;
+}
+
+inline bool QBasicAtomicInt::testAndSetAcquire(int expectedValue, int newValue)
+{
+ return q_atomic_test_and_set_acquire_int(&_q_value, expectedValue, newValue) != 0;
+}
+
+inline bool QBasicAtomicInt::testAndSetRelease(int expectedValue, int newValue)
+{
+ return q_atomic_test_and_set_release_int(&_q_value, expectedValue, newValue) != 0;
+}
+
+inline int QBasicAtomicInt::fetchAndStoreRelaxed(int newValue)
+{
+ return q_atomic_set_int(&_q_value, newValue);
+}
+
+inline int QBasicAtomicInt::fetchAndStoreAcquire(int newValue)
+{
+ return q_atomic_fetch_and_store_acquire_int(&_q_value, newValue);
+}
+
+inline int QBasicAtomicInt::fetchAndStoreRelease(int newValue)
+{
+ return q_atomic_fetch_and_store_release_int(&_q_value, newValue);
+}
+
+inline int QBasicAtomicInt::fetchAndAddRelaxed(int valueToAdd)
+{
+ return q_atomic_fetch_and_add_int(&_q_value, valueToAdd);
+}
+
+inline int QBasicAtomicInt::fetchAndAddAcquire(int valueToAdd)
+{
+ return q_atomic_fetch_and_add_acquire_int(&_q_value, valueToAdd);
+}
+
+inline int QBasicAtomicInt::fetchAndAddRelease(int valueToAdd)
+{
+ return q_atomic_fetch_and_add_release_int(&_q_value, valueToAdd);
+}
+
+template <typename T>
+Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::testAndSetRelaxed(T *expectedValue, T *newValue)
+{
+ return q_atomic_test_and_set_ptr(&_q_value, expectedValue, newValue) != 0;
+}
+
+template <typename T>
+Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::testAndSetAcquire(T *expectedValue, T *newValue)
+{
+ return q_atomic_test_and_set_acquire_ptr(&_q_value, expectedValue, newValue) != 0;
+}
+
+template <typename T>
+Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::testAndSetRelease(T *expectedValue, T *newValue)
+{
+ return q_atomic_test_and_set_release_ptr(&_q_value, expectedValue, newValue) != 0;
+}
+
+template <typename T>
+Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndStoreRelaxed(T *newValue)
+{
+ return reinterpret_cast<T *>(q_atomic_set_ptr(&_q_value, newValue));
+}
+
+template <typename T>
+Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndStoreAcquire(T *newValue)
+{
+ return reinterpret_cast<T *>(q_atomic_fetch_and_store_acquire_ptr(&_q_value, newValue));
+}
+
+template <typename T>
+Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndStoreRelease(T *newValue)
+{
+ return reinterpret_cast<T *>(q_atomic_fetch_and_store_release_ptr(&_q_value, newValue));
+}
+
+template <typename T>
+Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndAddRelaxed(qptrdiff valueToAdd)
+{
+ return reinterpret_cast<T *>(q_atomic_fetch_and_add_ptr(&_q_value, valueToAdd * sizeof(T)));
+}
+template <typename T>
+Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndAddAcquire(qptrdiff valueToAdd)
+{
+ return reinterpret_cast<T *>(q_atomic_fetch_and_add_acquire_ptr(&_q_value, valueToAdd * sizeof(T)));
+}
+
+template <typename T>
+Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndAddRelease(qptrdiff valueToAdd)
+{
+ return reinterpret_cast<T *>(q_atomic_fetch_and_add_release_ptr(&_q_value, valueToAdd * sizeof(T)));
+}
+
+#endif
+
+inline bool QBasicAtomicInt::testAndSetOrdered(int expectedValue, int newValue)
+{
+ return testAndSetAcquire(expectedValue, newValue);
+}
+
+inline int QBasicAtomicInt::fetchAndStoreOrdered(int newValue)
+{
+ return fetchAndStoreAcquire(newValue);
+}
+
+inline int QBasicAtomicInt::fetchAndAddOrdered(int valueToAdd)
+{
+ return fetchAndAddAcquire(valueToAdd);
+}
+
+template <typename T>
+Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::testAndSetOrdered(T *expectedValue, T *newValue)
+{
+ return testAndSetAcquire(expectedValue, newValue);
+}
+
+template <typename T>
+Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndStoreOrdered(T *newValue)
+{
+ return fetchAndStoreAcquire(newValue);
+}
+
+template <typename T>
+Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndAddOrdered(qptrdiff valueToAdd)
+{
+ return fetchAndAddAcquire(valueToAdd);
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // QATOMIC_POWERPC_H
diff --git a/src/corelib/arch/qatomic_s390.h b/src/corelib/arch/qatomic_s390.h
new file mode 100644
index 0000000000..434e12ae6b
--- /dev/null
+++ b/src/corelib/arch/qatomic_s390.h
@@ -0,0 +1,430 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtCore module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QATOMIC_S390_H
+#define QATOMIC_S390_H
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+#define Q_ATOMIC_INT_REFERENCE_COUNTING_IS_ALWAYS_NATIVE
+
+inline bool QBasicAtomicInt::isReferenceCountingNative()
+{ return true; }
+inline bool QBasicAtomicInt::isReferenceCountingWaitFree()
+{ return false; }
+
+#define Q_ATOMIC_INT_TEST_AND_SET_IS_ALWAYS_NATIVE
+
+inline bool QBasicAtomicInt::isTestAndSetNative()
+{ return true; }
+inline bool QBasicAtomicInt::isTestAndSetWaitFree()
+{ return false; }
+
+#define Q_ATOMIC_INT_FETCH_AND_STORE_IS_ALWAYS_NATIVE
+
+inline bool QBasicAtomicInt::isFetchAndStoreNative()
+{ return true; }
+inline bool QBasicAtomicInt::isFetchAndStoreWaitFree()
+{ return false; }
+
+#define Q_ATOMIC_INT_FETCH_AND_ADD_IS_ALWAYS_NATIVE
+
+inline bool QBasicAtomicInt::isFetchAndAddNative()
+{ return true; }
+inline bool QBasicAtomicInt::isFetchAndAddWaitFree()
+{ return false; }
+
+#define Q_ATOMIC_POINTER_TEST_AND_SET_IS_ALWAYS_NATIVE
+
+template <typename T>
+Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::isTestAndSetNative()
+{ return true; }
+template <typename T>
+Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::isTestAndSetWaitFree()
+{ return false; }
+
+#define Q_ATOMIC_POINTER_FETCH_AND_STORE_IS_ALWAYS_NATIVE
+
+template <typename T>
+Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::isFetchAndStoreNative()
+{ return true; }
+template <typename T>
+Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::isFetchAndStoreWaitFree()
+{ return false; }
+
+#define Q_ATOMIC_POINTER_FETCH_AND_ADD_IS_ALWAYS_NATIVE
+
+template <typename T>
+Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::isFetchAndAddNative()
+{ return true; }
+template <typename T>
+Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::isFetchAndAddWaitFree()
+{ return false; }
+
+#ifdef __GNUC__
+#define __GNU_EXTENSION __extension__
+#else
+#define __GNU_EXTENSION
+#endif
+
+#define __CS_LOOP(ptr, op_val, op_string, pre, post) __GNU_EXTENSION ({ \
+ volatile int old_val, new_val; \
+ __asm__ __volatile__(pre \
+ " l %0,0(%3)\n" \
+ "0: lr %1,%0\n" \
+ op_string " %1,%4\n" \
+ " cs %0,%1,0(%3)\n" \
+ " jl 0b\n" \
+ post \
+ : "=&d" (old_val), "=&d" (new_val), \
+ "=m" (*ptr) \
+ : "a" (ptr), "d" (op_val), \
+ "m" (*ptr) \
+ : "cc", "memory" ); \
+ new_val; \
+})
+
+#define __CS_OLD_LOOP(ptr, op_val, op_string, pre, post ) __GNU_EXTENSION ({ \
+ volatile int old_val, new_val; \
+ __asm__ __volatile__(pre \
+ " l %0,0(%3)\n" \
+ "0: lr %1,%0\n" \
+ op_string " %1,%4\n" \
+ " cs %0,%1,0(%3)\n" \
+ " jl 0b\n" \
+ post \
+ : "=&d" (old_val), "=&d" (new_val), \
+ "=m" (*ptr) \
+ : "a" (ptr), "d" (op_val), \
+ "m" (*ptr) \
+ : "cc", "memory" ); \
+ old_val; \
+})
+
+#ifdef __s390x__
+#define __CSG_OLD_LOOP(ptr, op_val, op_string, pre, post) __GNU_EXTENSION ({ \
+ long old_val, new_val; \
+ __asm__ __volatile__(pre \
+ " lg %0,0(%3)\n" \
+ "0: lgr %1,%0\n" \
+ op_string " %1,%4\n" \
+ " csg %0,%1,0(%3)\n" \
+ " jl 0b\n" \
+ post \
+ : "=&d" (old_val), "=&d" (new_val), \
+ "=m" (*ptr) \
+ : "a" (ptr), "d" (op_val), \
+ "m" (*ptr) \
+ : "cc", "memory" ); \
+ old_val; \
+})
+#endif
+
+inline bool QBasicAtomicInt::ref()
+{
+ return __CS_LOOP(&_q_value, 1, "ar", "", "") != 0;
+}
+
+inline bool QBasicAtomicInt::deref()
+{
+ return __CS_LOOP(&_q_value, 1, "sr", "", "") != 0;
+}
+
+inline bool QBasicAtomicInt::testAndSetRelaxed(int expectedValue, int newValue)
+{
+ int retval;
+ __asm__ __volatile__(
+ " lr %0,%3\n"
+ " cs %0,%4,0(%2)\n"
+ " ipm %0\n"
+ " srl %0,28\n"
+ "0:"
+ : "=&d" (retval), "=m" (_q_value)
+ : "a" (&_q_value), "d" (expectedValue) , "d" (newValue),
+ "m" (_q_value) : "cc", "memory" );
+ return retval == 0;
+}
+
+inline bool QBasicAtomicInt::testAndSetAcquire(int expectedValue, int newValue)
+{
+ int retval;
+ __asm__ __volatile__(
+ " lr %0,%3\n"
+ " cs %0,%4,0(%2)\n"
+ " ipm %0\n"
+ " srl %0,28\n"
+ "0:\n"
+ " bcr 15,0\n"
+ : "=&d" (retval), "=m" (_q_value)
+ : "a" (&_q_value), "d" (expectedValue) , "d" (newValue),
+ "m" (_q_value) : "cc", "memory" );
+ return retval == 0;
+}
+
+inline bool QBasicAtomicInt::testAndSetRelease(int expectedValue, int newValue)
+{
+ int retval;
+ __asm__ __volatile__(
+ " bcr 15,0\n"
+ " lr %0,%3\n"
+ " cs %0,%4,0(%2)\n"
+ " ipm %0\n"
+ " srl %0,28\n"
+ "0:"
+ : "=&d" (retval), "=m" (_q_value)
+ : "a" (&_q_value), "d" (expectedValue) , "d" (newValue),
+ "m" (_q_value) : "cc", "memory" );
+ return retval == 0;
+}
+
+inline bool QBasicAtomicInt::testAndSetOrdered(int expectedValue, int newValue)
+{
+ return testAndSetAcquire(expectedValue, newValue);
+}
+
+inline int QBasicAtomicInt::fetchAndStoreRelaxed(int newValue)
+{
+ return __CS_OLD_LOOP(&_q_value, newValue, "lr", "", "");
+}
+
+inline int QBasicAtomicInt::fetchAndStoreAcquire(int newValue)
+{
+ return __CS_OLD_LOOP(&_q_value, newValue, "lr", "", "bcr 15,0\n");
+}
+
+inline int QBasicAtomicInt::fetchAndStoreRelease(int newValue)
+{
+ return __CS_OLD_LOOP(&_q_value, newValue, "lr", "bcr 15,0\n", "");
+}
+
+inline int QBasicAtomicInt::fetchAndStoreOrdered(int newValue)
+{
+ return fetchAndStoreAcquire(newValue);
+}
+
+inline int QBasicAtomicInt::fetchAndAddRelaxed(int valueToAdd)
+{
+ return fetchAndAddOrdered(valueToAdd);
+}
+
+inline int QBasicAtomicInt::fetchAndAddAcquire(int valueToAdd)
+{
+ return fetchAndAddOrdered(valueToAdd);
+}
+
+inline int QBasicAtomicInt::fetchAndAddRelease(int valueToAdd)
+{
+ return fetchAndAddOrdered(valueToAdd);
+}
+
+inline int QBasicAtomicInt::fetchAndAddOrdered(int valueToAdd)
+{
+ return __CS_OLD_LOOP(&_q_value, valueToAdd, "ar", "", "bcr 15,0\n");
+}
+
+template <typename T>
+Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::testAndSetRelaxed(T *expectedValue, T *newValue)
+{
+ int retval;
+
+#ifndef __s390x__
+ __asm__ __volatile__(
+ " lr %0,%3\n"
+ " cs %0,%4,0(%2)\n"
+ " ipm %0\n"
+ " srl %0,28\n"
+ "0:"
+ : "=&d" (retval), "=m" (_q_value)
+ : "a" (&_q_value), "d" (expectedValue) , "d" (newValue),
+ "m" (_q_value) : "cc", "memory" );
+#else
+ __asm__ __volatile__(
+ " lgr %0,%3\n"
+ " csg %0,%4,0(%2)\n"
+ " ipm %0\n"
+ " srl %0,28\n"
+ "0:"
+ : "=&d" (retval), "=m" (_q_value)
+ : "a" (&_q_value), "d" (expectedValue) , "d" (newValue),
+ "m" (_q_value) : "cc", "memory" );
+#endif
+
+ return retval == 0;
+}
+
+template <typename T>
+Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::testAndSetAcquire(T *expectedValue, T *newValue)
+{
+ int retval;
+
+#ifndef __s390x__
+ __asm__ __volatile__(
+ " lr %0,%3\n"
+ " cs %0,%4,0(%2)\n"
+ " ipm %0\n"
+ " srl %0,28\n"
+ "0:\n"
+ " bcr 15,0\n"
+ : "=&d" (retval), "=m" (_q_value)
+ : "a" (&_q_value), "d" (expectedValue) , "d" (newValue),
+ "m" (_q_value) : "cc", "memory" );
+#else
+ __asm__ __volatile__(
+ " lgr %0,%3\n"
+ " csg %0,%4,0(%2)\n"
+ " ipm %0\n"
+ " srl %0,28\n"
+ "0:\n"
+ " bcr 15,0\n"
+ : "=&d" (retval), "=m" (_q_value)
+ : "a" (&_q_value), "d" (expectedValue) , "d" (newValue),
+ "m" (_q_value) : "cc", "memory" );
+#endif
+
+ return retval == 0;
+}
+
+template <typename T>
+Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::testAndSetRelease(T *expectedValue, T *newValue)
+{
+ int retval;
+
+#ifndef __s390x__
+ __asm__ __volatile__(
+ " bcr 15,0\n"
+ " lr %0,%3\n"
+ " cs %0,%4,0(%2)\n"
+ " ipm %0\n"
+ " srl %0,28\n"
+ "0:"
+ : "=&d" (retval), "=m" (_q_value)
+ : "a" (&_q_value), "d" (expectedValue) , "d" (newValue),
+ "m" (_q_value) : "cc", "memory" );
+#else
+ __asm__ __volatile__(
+ " bcr 15,0\n"
+ " lgr %0,%3\n"
+ " csg %0,%4,0(%2)\n"
+ " ipm %0\n"
+ " srl %0,28\n"
+ "0:"
+ : "=&d" (retval), "=m" (_q_value)
+ : "a" (&_q_value), "d" (expectedValue) , "d" (newValue),
+ "m" (_q_value) : "cc", "memory" );
+#endif
+
+ return retval == 0;
+}
+
+template <typename T>
+Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::testAndSetOrdered(T *expectedValue, T *newValue)
+{
+ return testAndSetAcquire(expectedValue, newValue);
+}
+
+template <typename T>
+Q_INLINE_TEMPLATE T* QBasicAtomicPointer<T>::fetchAndStoreRelaxed(T *newValue)
+{
+#ifndef __s390x__
+ return (T*)__CS_OLD_LOOP(reinterpret_cast<volatile long*>(_q_value), (int)newValue, "lr",
+ "", "bcr 15,0\n");
+#else
+ return (T*)__CSG_OLD_LOOP(reinterpret_cast<volatile long*>(_q_value), (long)newValue, "lgr",
+ "", "bcr 15,0\n");
+#endif
+}
+
+template <typename T>
+Q_INLINE_TEMPLATE T* QBasicAtomicPointer<T>::fetchAndStoreAcquire(T *newValue)
+{
+#ifndef __s390x__
+ return (T*)__CS_OLD_LOOP(reinterpret_cast<volatile long*>(_q_value), (int)newValue, "lr", "", "");
+#else
+ return (T*)__CSG_OLD_LOOP(reinterpret_cast<volatile long*>(_q_value), (long)newValue, "lgr", "", "");
+#endif
+}
+
+template <typename T>
+Q_INLINE_TEMPLATE T* QBasicAtomicPointer<T>::fetchAndStoreRelease(T *newValue)
+{
+#ifndef __s390x__
+ return (T*)__CS_OLD_LOOP(reinterpret_cast<volatile long*>(_q_value), (int)newValue, "lr",
+ "bcr 15,0 \n", "");
+#else
+ return (T*)__CSG_OLD_LOOP(reinterpret_cast<volatile long*>(_q_value), (long)newValue, "lgr",
+ "bcr 15,0\n", "");
+#endif
+}
+
+template <typename T>
+Q_INLINE_TEMPLATE T* QBasicAtomicPointer<T>::fetchAndStoreOrdered(T *newValue)
+{
+ return fetchAndStoreAcquire(newValue);
+}
+
+
+template <typename T>
+Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndAddRelaxed(qptrdiff valueToAdd)
+{
+ return fetchAndAddOrdered(valueToAdd);
+}
+
+template <typename T>
+Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndAddAcquire(qptrdiff valueToAdd)
+{
+ return fetchAndAddOrdered(valueToAdd);
+}
+
+template <typename T>
+Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndAddRelease(qptrdiff valueToAdd)
+{
+ return fetchAndAddOrdered(valueToAdd);
+}
+
+#undef __GNU_EXTENSION
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // QATOMIC_S390_H
diff --git a/src/corelib/arch/qatomic_sh.h b/src/corelib/arch/qatomic_sh.h
new file mode 100644
index 0000000000..b78ad45d36
--- /dev/null
+++ b/src/corelib/arch/qatomic_sh.h
@@ -0,0 +1,330 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtCore module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QATOMIC_SH_H
+#define QATOMIC_SH_H
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+#define Q_ATOMIC_INT_REFERENCE_COUNTING_IS_NOT_NATIVE
+
+inline bool QBasicAtomicInt::isReferenceCountingNative()
+{ return false; }
+inline bool QBasicAtomicInt::isReferenceCountingWaitFree()
+{ return false; }
+
+#define Q_ATOMIC_INT_TEST_AND_SET_IS_NOT_NATIVE
+
+inline bool QBasicAtomicInt::isTestAndSetNative()
+{ return false; }
+inline bool QBasicAtomicInt::isTestAndSetWaitFree()
+{ return false; }
+
+#define Q_ATOMIC_INT_FETCH_AND_STORE_IS_NOT_NATIVE
+
+inline bool QBasicAtomicInt::isFetchAndStoreNative()
+{ return false; }
+inline bool QBasicAtomicInt::isFetchAndStoreWaitFree()
+{ return false; }
+
+#define Q_ATOMIC_INT_FETCH_AND_ADD_IS_NOT_NATIVE
+
+inline bool QBasicAtomicInt::isFetchAndAddNative()
+{ return false; }
+inline bool QBasicAtomicInt::isFetchAndAddWaitFree()
+{ return false; }
+
+#define Q_ATOMIC_POINTER_TEST_AND_SET_IS_NOT_NATIVE
+
+template <typename T>
+Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::isTestAndSetNative()
+{ return false; }
+template <typename T>
+Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::isTestAndSetWaitFree()
+{ return false; }
+
+#define Q_ATOMIC_POINTER_FETCH_AND_STORE_IS_NOT_NATIVE
+
+template <typename T>
+Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::isFetchAndStoreNative()
+{ return false; }
+template <typename T>
+Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::isFetchAndStoreWaitFree()
+{ return false; }
+
+#define Q_ATOMIC_POINTER_FETCH_AND_ADD_IS_NOT_NATIVE
+
+template <typename T>
+Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::isFetchAndAddNative()
+{ return false; }
+template <typename T>
+Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::isFetchAndAddWaitFree()
+{ return false; }
+
+extern Q_CORE_EXPORT volatile char qt_atomic_lock;
+Q_CORE_EXPORT void qt_atomic_yield(int *count);
+
+inline int qt_atomic_tasb(volatile char *ptr)
+{
+ register int ret;
+ asm volatile("tas.b @%2\n"
+ "movt %0"
+ : "=&r"(ret), "=m"(*ptr)
+ : "r"(ptr)
+ : "cc", "memory");
+ return ret;
+}
+
+// Reference counting
+
+inline bool QBasicAtomicInt::ref()
+{
+ int count = 0;
+ while (qt_atomic_tasb(&qt_atomic_lock) == 0)
+ qt_atomic_yield(&count);
+ int originalValue = _q_value++;
+ qt_atomic_lock = 0;
+ return originalValue != -1;
+}
+
+inline bool QBasicAtomicInt::deref()
+{
+ int count = 0;
+ while (qt_atomic_tasb(&qt_atomic_lock) == 0)
+ qt_atomic_yield(&count);
+ int originalValue = _q_value--;
+ qt_atomic_lock = 0;
+ return originalValue != 1;
+}
+
+// Test and set for integers
+
+inline bool QBasicAtomicInt::testAndSetOrdered(int expectedValue, int newValue)
+{
+ bool returnValue = false;
+ int count = 0;
+ while (qt_atomic_tasb(&qt_atomic_lock) == 0)
+ qt_atomic_yield(&count);
+ if (_q_value == expectedValue) {
+ _q_value = newValue;
+ returnValue = true;
+ }
+ qt_atomic_lock = 0;
+ return returnValue;
+}
+
+inline bool QBasicAtomicInt::testAndSetRelaxed(int expectedValue, int newValue)
+{
+ return testAndSetOrdered(expectedValue, newValue);
+}
+
+inline bool QBasicAtomicInt::testAndSetAcquire(int expectedValue, int newValue)
+{
+ return testAndSetOrdered(expectedValue, newValue);
+}
+
+inline bool QBasicAtomicInt::testAndSetRelease(int expectedValue, int newValue)
+{
+ return testAndSetOrdered(expectedValue, newValue);
+}
+
+// Fetch and store for integers
+
+inline int QBasicAtomicInt::fetchAndStoreOrdered(int newValue)
+{
+ int count = 0;
+ while (qt_atomic_tasb(&qt_atomic_lock) == 0)
+ qt_atomic_yield(&count);
+ int originalValue = _q_value;
+ _q_value = newValue;
+ qt_atomic_lock = 0;
+ return originalValue;
+}
+
+inline int QBasicAtomicInt::fetchAndStoreRelaxed(int newValue)
+{
+ return fetchAndStoreOrdered(newValue);
+}
+
+inline int QBasicAtomicInt::fetchAndStoreAcquire(int newValue)
+{
+ return fetchAndStoreOrdered(newValue);
+}
+
+inline int QBasicAtomicInt::fetchAndStoreRelease(int newValue)
+{
+ return fetchAndStoreOrdered(newValue);
+}
+
+// Fetch and add for integers
+
+inline int QBasicAtomicInt::fetchAndAddOrdered(int valueToAdd)
+{
+ int count = 0;
+ while (qt_atomic_tasb(&qt_atomic_lock) == 0)
+ qt_atomic_yield(&count);
+ int originalValue = _q_value;
+ _q_value += valueToAdd;
+ qt_atomic_lock = 0;
+ return originalValue;
+}
+
+inline int QBasicAtomicInt::fetchAndAddRelaxed(int valueToAdd)
+{
+ return fetchAndAddOrdered(valueToAdd);
+}
+
+inline int QBasicAtomicInt::fetchAndAddAcquire(int valueToAdd)
+{
+ return fetchAndAddOrdered(valueToAdd);
+}
+
+inline int QBasicAtomicInt::fetchAndAddRelease(int valueToAdd)
+{
+ return fetchAndAddOrdered(valueToAdd);
+}
+
+// Test and set for pointers
+
+template <typename T>
+Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::testAndSetOrdered(T *expectedValue, T *newValue)
+{
+ bool returnValue = false;
+ int count = 0;
+ while (qt_atomic_tasb(&qt_atomic_lock) == 0)
+ qt_atomic_yield(&count);
+ if (_q_value == expectedValue) {
+ _q_value = newValue;
+ returnValue = true;
+ }
+ qt_atomic_lock = 0;
+ return returnValue;
+}
+
+template <typename T>
+Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::testAndSetRelaxed(T *expectedValue, T *newValue)
+{
+ return testAndSetOrdered(expectedValue, newValue);
+}
+
+template <typename T>
+Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::testAndSetAcquire(T *expectedValue, T *newValue)
+{
+ return testAndSetOrdered(expectedValue, newValue);
+}
+
+template <typename T>
+Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::testAndSetRelease(T *expectedValue, T *newValue)
+{
+ return testAndSetOrdered(expectedValue, newValue);
+}
+
+// Fetch and store for pointers
+
+template <typename T>
+Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndStoreOrdered(T *newValue)
+{
+ int count = 0;
+ while (qt_atomic_tasb(&qt_atomic_lock) == 0)
+ qt_atomic_yield(&count);
+ T *originalValue = _q_value;
+ _q_value = newValue;
+ qt_atomic_lock = 0;
+ return originalValue;
+}
+
+template <typename T>
+Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndStoreRelaxed(T *newValue)
+{
+ return fetchAndStoreOrdered(newValue);
+}
+
+template <typename T>
+Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndStoreAcquire(T *newValue)
+{
+ return fetchAndStoreOrdered(newValue);
+}
+
+template <typename T>
+Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndStoreRelease(T *newValue)
+{
+ return fetchAndStoreOrdered(newValue);
+}
+
+// Fetch and add for pointers
+
+template <typename T>
+Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndAddOrdered(qptrdiff valueToAdd)
+{
+ int count = 0;
+ while (qt_atomic_tasb(&qt_atomic_lock) == 0)
+ qt_atomic_yield(&count);
+ T *originalValue = (_q_value);
+ _q_value += valueToAdd;
+ qt_atomic_lock = 0;
+ return originalValue;
+}
+
+template <typename T>
+Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndAddRelaxed(qptrdiff valueToAdd)
+{
+ return fetchAndAddOrdered(valueToAdd);
+}
+
+template <typename T>
+Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndAddAcquire(qptrdiff valueToAdd)
+{
+ return fetchAndAddOrdered(valueToAdd);
+}
+
+template <typename T>
+Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndAddRelease(qptrdiff valueToAdd)
+{
+ return fetchAndAddOrdered(valueToAdd);
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // QATOMIC_SH_H
diff --git a/src/corelib/arch/qatomic_sh4a.h b/src/corelib/arch/qatomic_sh4a.h
new file mode 100644
index 0000000000..54371cd86b
--- /dev/null
+++ b/src/corelib/arch/qatomic_sh4a.h
@@ -0,0 +1,537 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtCore module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QATOMIC_SH4A_H
+#define QATOMIC_SH4A_H
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#define Q_ATOMIC_INT_REFERENCE_COUNTING_IS_ALWAYS_NATIVE
+
+inline bool QBasicAtomicInt::isReferenceCountingNative()
+{ return true; }
+inline bool QBasicAtomicInt::isReferenceCountingWaitFree()
+{ return false; }
+
+#define Q_ATOMIC_INT_TEST_AND_SET_IS_ALWAYS_NATIVE
+
+inline bool QBasicAtomicInt::isTestAndSetNative()
+{ return true; }
+inline bool QBasicAtomicInt::isTestAndSetWaitFree()
+{ return false; }
+
+#define Q_ATOMIC_INT_FETCH_AND_STORE_IS_ALWAYS_NATIVE
+
+inline bool QBasicAtomicInt::isFetchAndStoreNative()
+{ return true; }
+inline bool QBasicAtomicInt::isFetchAndStoreWaitFree()
+{ return false; }
+
+#define Q_ATOMIC_INT_FETCH_AND_ADD_IS_ALWAYS_NATIVE
+
+inline bool QBasicAtomicInt::isFetchAndAddNative()
+{ return true; }
+inline bool QBasicAtomicInt::isFetchAndAddWaitFree()
+{ return false; }
+
+#define Q_ATOMIC_POINTER_TEST_AND_SET_IS_ALWAYS_NATIVE
+
+template <typename T>
+Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::isTestAndSetNative()
+{ return true; }
+template <typename T>
+Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::isTestAndSetWaitFree()
+{ return false; }
+
+#define Q_ATOMIC_POINTER_FETCH_AND_STORE_IS_ALWAYS_NATIVE
+
+template <typename T>
+Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::isFetchAndStoreNative()
+{ return true; }
+template <typename T>
+Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::isFetchAndStoreWaitFree()
+{ return false; }
+
+#define Q_ATOMIC_POINTER_FETCH_AND_ADD_IS_ALWAYS_NATIVE
+
+template <typename T>
+Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::isFetchAndAddNative()
+{ return true; }
+template <typename T>
+Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::isFetchAndAddWaitFree()
+{ return false; }
+
+QT_BEGIN_NAMESPACE
+
+#if !defined(Q_CC_GNU)
+# error "SH-4A support has not been added for this compiler"
+#else
+
+inline bool QBasicAtomicInt::ref()
+{
+ register int newValue asm("r0");
+ asm volatile("0:\n"
+ "movli.l @%[_q_value], %[newValue]\n"
+ "add #1,%[newValue]\n"
+ "movco.l %[newValue], @%[_q_value]\n"
+ "bf 0b\n"
+ : [newValue] "=&r" (newValue),
+ "+m" (_q_value)
+ : [_q_value] "r" (&_q_value)
+ : "cc", "memory");
+ return newValue != 0;
+}
+
+inline bool QBasicAtomicInt::deref()
+{
+ register int newValue asm("r0");
+ asm volatile("0:\n"
+ "movli.l @%[_q_value], %[newValue]\n"
+ "add #-1,%[newValue]\n"
+ "movco.l %[newValue], @%[_q_value]\n"
+ "bf 0b\n"
+ : [newValue] "=&r" (newValue),
+ "+m" (_q_value)
+ : [_q_value] "r" (&_q_value)
+ : "cc", "memory");
+ return newValue != 0;
+}
+
+inline bool QBasicAtomicInt::testAndSetRelaxed(int expectedValue, int newValue)
+{
+ register int result;
+ asm volatile("0:\n"
+ "movli.l @%[_q_value], r0\n"
+ "xor %[expectedValue], r0\n"
+ "cmp/eq #0, r0\n"
+ "bf/s 0f\n"
+ "mov r0, %[result]\n"
+ "mov %[newValue], r0\n"
+ "movco.l r0, @%[_q_value]\n"
+ "bf 0b\n"
+ "0:\n"
+ : [result] "=&r" (result),
+ "+m" (_q_value)
+ : [_q_value] "r" (&_q_value),
+ [expectedValue] "r" (expectedValue),
+ [newValue] "r" (newValue)
+ : "r0", "cc", "memory");
+ return result == 0;
+}
+
+inline bool QBasicAtomicInt::testAndSetAcquire(int expectedValue, int newValue)
+{
+ register int result;
+ asm volatile("0:\n"
+ "movli.l @%[_q_value], r0\n"
+ "xor %[expectedValue], r0\n"
+ "cmp/eq #0, r0\n"
+ "bf/s 0f\n"
+ "mov r0, %[result]\n"
+ "mov %[newValue], r0\n"
+ "movco.l r0, @%[_q_value]\n"
+ "bf 0b\n"
+ "synco\n"
+ "0:\n"
+ : [result] "=&r" (result),
+ "+m" (_q_value)
+ : [_q_value] "r" (&_q_value),
+ [expectedValue] "r" (expectedValue),
+ [newValue] "r" (newValue)
+ : "r0", "cc", "memory");
+ return result == 0;
+}
+
+inline bool QBasicAtomicInt::testAndSetRelease(int expectedValue, int newValue)
+{
+ register int result;
+ asm volatile("synco\n"
+ "0:\n"
+ "movli.l @%[_q_value], r0\n"
+ "xor %[expectedValue], r0\n"
+ "cmp/eq #0, r0\n"
+ "bf/s 0f\n"
+ "mov r0, %[result]\n"
+ "mov %[newValue], r0\n"
+ "movco.l r0, @%[_q_value]\n"
+ "bf 0b\n"
+ "0:\n"
+ : [result] "=&r" (result),
+ "+m" (_q_value)
+ : [_q_value] "r" (&_q_value),
+ [expectedValue] "r" (expectedValue),
+ [newValue] "r" (newValue)
+ : "r0", "cc", "memory");
+ return result == 0;
+}
+
+inline bool QBasicAtomicInt::testAndSetOrdered(int expectedValue, int newValue)
+{
+ return testAndSetAcquire(expectedValue, newValue);
+}
+
+inline int QBasicAtomicInt::fetchAndStoreRelaxed(int newValue)
+{
+ register int originalValue;
+ asm volatile("0:\n"
+ "movli.l @%[_q_value], r0\n"
+ "mov r0, %[originalValue]\n"
+ "mov %[newValue], r0\n"
+ "movco.l r0, @%[_q_value]\n"
+ "bf 0b\n"
+ : [originalValue] "=&r" (originalValue),
+ "+m" (_q_value)
+ : [_q_value] "r" (&_q_value),
+ [newValue] "r" (newValue)
+ : "r0", "cc", "memory");
+ return originalValue;
+}
+
+inline int QBasicAtomicInt::fetchAndStoreAcquire(int newValue)
+{
+ register int originalValue;
+ asm volatile("0:\n"
+ "movli.l @%[_q_value], r0\n"
+ "mov r0, %[originalValue]\n"
+ "mov %[newValue], r0\n"
+ "movco.l r0, @%[_q_value]\n"
+ "bf 0b\n"
+ "synco\n"
+ : [originalValue] "=&r" (originalValue),
+ "+m" (_q_value)
+ : [_q_value] "r" (&_q_value),
+ [newValue] "r" (newValue)
+ : "r0", "cc", "memory");
+ return originalValue;
+}
+
+inline int QBasicAtomicInt::fetchAndStoreRelease(int newValue)
+{
+ register int originalValue;
+ asm volatile("synco\n"
+ "0:\n"
+ "movli.l @%[_q_value], r0\n"
+ "mov r0, %[originalValue]\n"
+ "mov %[newValue], r0\n"
+ "movco.l r0, @%[_q_value]\n"
+ "bf 0b\n"
+ : [originalValue] "=&r" (originalValue),
+ "+m" (_q_value)
+ : [_q_value] "r" (&_q_value),
+ [newValue] "r" (newValue)
+ : "r0", "cc", "memory");
+ return originalValue;
+}
+
+inline int QBasicAtomicInt::fetchAndStoreOrdered(int newValue)
+{
+ return fetchAndStoreAcquire(newValue);
+}
+
+inline int QBasicAtomicInt::fetchAndAddRelaxed(int valueToAdd)
+{
+ register int originalValue;
+ asm volatile("0:\n"
+ "movli.l @%[_q_value], r0\n"
+ "mov r0, %[originalValue]\n"
+ "add %[valueToAdd], r0\n"
+ "movco.l r0, @%[_q_value]\n"
+ "bf 0b\n"
+ : [originalValue] "=&r" (originalValue),
+ "+m" (_q_value)
+ : [_q_value] "r" (&_q_value),
+ [valueToAdd] "r" (valueToAdd)
+ : "r0", "cc", "memory");
+ return originalValue;
+}
+
+inline int QBasicAtomicInt::fetchAndAddAcquire(int valueToAdd)
+{
+ register int originalValue;
+ asm volatile("0:\n"
+ "movli.l @%[_q_value], r0\n"
+ "mov r0, %[originalValue]\n"
+ "add %[valueToAdd], r0\n"
+ "movco.l r0, @%[_q_value]\n"
+ "bf 0b\n"
+ "synco\n"
+ : [originalValue] "=&r" (originalValue),
+ "+m" (_q_value)
+ : [_q_value] "r" (&_q_value),
+ [valueToAdd] "r" (valueToAdd)
+ : "r0", "cc", "memory");
+ return originalValue;
+}
+
+inline int QBasicAtomicInt::fetchAndAddRelease(int valueToAdd)
+{
+ register int originalValue;
+ asm volatile("synco\n"
+ "0:\n"
+ "movli.l @%[_q_value], r0\n"
+ "mov r0, %[originalValue]\n"
+ "add %[valueToAdd], r0\n"
+ "movco.l r0, @%[_q_value]\n"
+ "bf 0b\n"
+ : [originalValue] "=&r" (originalValue),
+ "+m" (_q_value)
+ : [_q_value] "r" (&_q_value),
+ [valueToAdd] "r" (valueToAdd)
+ : "r0", "cc", "memory");
+ return originalValue;
+}
+
+inline int QBasicAtomicInt::fetchAndAddOrdered(int valueToAdd)
+{
+ return fetchAndAddAcquire(valueToAdd);
+}
+
+template <typename T>
+Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::testAndSetRelaxed(T *expectedValue, T *newValue)
+{
+ register T *result;
+ asm volatile("0:\n"
+ "movli.l @%[_q_value], r0\n"
+ "xor %[expectedValue], r0\n"
+ "cmp/eq #0, r0\n"
+ "bf/s 0f\n"
+ "mov r0, %[result]\n"
+ "mov %[newValue], r0\n"
+ "movco.l r0, @%[_q_value]\n"
+ "bf 0b\n"
+ "0:\n"
+ : [result] "=&r" (result),
+ "+m" (_q_value)
+ : [_q_value] "r" (&_q_value),
+ [expectedValue] "r" (expectedValue),
+ [newValue] "r" (newValue)
+ : "r0", "cc", "memory");
+ return result == 0;
+}
+
+template <typename T>
+Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::testAndSetAcquire(T *expectedValue, T *newValue)
+{
+ register T *result;
+ asm volatile("0:\n"
+ "movli.l @%[_q_value], r0\n"
+ "xor %[expectedValue], r0\n"
+ "cmp/eq #0, r0\n"
+ "bf/s 0f\n"
+ "mov r0, %[result]\n"
+ "mov %[newValue], r0\n"
+ "movco.l r0, @%[_q_value]\n"
+ "bf 0b\n"
+ "synco\n"
+ "0:\n"
+ : [result] "=&r" (result),
+ "+m" (_q_value)
+ : [_q_value] "r" (&_q_value),
+ [expectedValue] "r" (expectedValue),
+ [newValue] "r" (newValue)
+ : "r0", "cc", "memory");
+ return result == 0;
+}
+
+template <typename T>
+Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::testAndSetRelease(T *expectedValue, T *newValue)
+{
+ register T *result;
+ asm volatile("synco\n"
+ "0:\n"
+ "movli.l @%[_q_value], r0\n"
+ "xor %[expectedValue], r0\n"
+ "cmp/eq #0, r0\n"
+ "bf/s 0f\n"
+ "mov r0, %[result]\n"
+ "mov %[newValue], r0\n"
+ "movco.l r0, @%[_q_value]\n"
+ "bf 0b\n"
+ "0:\n"
+ : [result] "=&r" (result),
+ "+m" (_q_value)
+ : [_q_value] "r" (&_q_value),
+ [expectedValue] "r" (expectedValue),
+ [newValue] "r" (newValue)
+ : "r0", "cc", "memory");
+ return result == 0;
+}
+
+template <typename T>
+Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::testAndSetOrdered(T *expectedValue, T *newValue)
+{
+ return testAndSetAcquire(expectedValue, newValue);
+}
+
+template <typename T>
+Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndStoreRelaxed(T *newValue)
+{
+ register T *originalValue;
+ asm volatile("0:\n"
+ "movli.l @%[_q_value], r0\n"
+ "mov r0, %[originalValue]\n"
+ "mov %[newValue], r0\n"
+ "movco.l r0, @%[_q_value]\n"
+ "bf 0b\n"
+ : [originalValue] "=&r" (originalValue),
+ "+m" (_q_value)
+ : [_q_value] "r" (&_q_value),
+ [newValue] "r" (newValue)
+ : "r0", "cc", "memory");
+ return originalValue;
+}
+
+template <typename T>
+Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndStoreAcquire(T *newValue)
+{
+ register T *originalValue;
+ asm volatile("0:\n"
+ "movli.l @%[_q_value], r0\n"
+ "mov r0, %[originalValue]\n"
+ "mov %[newValue], r0\n"
+ "movco.l r0, @%[_q_value]\n"
+ "bf 0b\n"
+ "synco\n"
+ : [originalValue] "=&r" (originalValue),
+ "+m" (_q_value)
+ : [_q_value] "r" (&_q_value),
+ [newValue] "r" (newValue)
+ : "r0", "cc", "memory");
+ return originalValue;
+}
+
+template <typename T>
+Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndStoreRelease(T *newValue)
+{
+ register T *originalValue;
+ asm volatile("synco\n"
+ "0:\n"
+ "movli.l @%[_q_value], r0\n"
+ "mov r0, %[originalValue]\n"
+ "mov %[newValue], r0\n"
+ "movco.l r0, @%[_q_value]\n"
+ "bf 0b\n"
+ : [originalValue] "=&r" (originalValue),
+ "+m" (_q_value)
+ : [_q_value] "r" (&_q_value),
+ [newValue] "r" (newValue)
+ : "r0", "cc", "memory");
+ return originalValue;
+}
+
+template <typename T>
+Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndStoreOrdered(T *newValue)
+{
+ return fetchAndStoreAcquire(newValue);
+}
+
+template <typename T>
+Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndAddRelaxed(qptrdiff valueToAdd)
+{
+ register T *originalValue;
+ asm volatile("0:\n"
+ "movli.l @%[_q_value], r0\n"
+ "mov r0, %[originalValue]\n"
+ "add %[valueToAdd], r0\n"
+ "movco.l r0, @%[_q_value]\n"
+ "bf 0b\n"
+ : [originalValue] "=&r" (originalValue),
+ "+m" (_q_value)
+ : [_q_value] "r" (&_q_value),
+ [valueToAdd] "r" (valueToAdd * sizeof(T))
+ : "r0", "cc", "memory");
+ return originalValue;
+}
+
+template <typename T>
+Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndAddAcquire(qptrdiff valueToAdd)
+{
+ register T *originalValue;
+ asm volatile("0:\n"
+ "movli.l @%[_q_value], r0\n"
+ "mov r0, %[originalValue]\n"
+ "add %[valueToAdd], r0\n"
+ "movco.l r0, @%[_q_value]\n"
+ "bf 0b\n"
+ "synco\n"
+ : [originalValue] "=&r" (originalValue),
+ "+m" (_q_value)
+ : [_q_value] "r" (&_q_value),
+ [valueToAdd] "r" (valueToAdd * sizeof(T))
+ : "r0", "cc", "memory");
+ return originalValue;
+}
+
+template <typename T>
+Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndAddRelease(qptrdiff valueToAdd)
+{
+ register T *originalValue;
+ asm volatile("synco\n"
+ "0:\n"
+ "movli.l @%[_q_value], r0\n"
+ "mov r0, %[originalValue]\n"
+ "add %[valueToAdd], r0\n"
+ "movco.l r0, @%[_q_value]\n"
+ "bf 0b\n"
+ : [originalValue] "=&r" (originalValue),
+ "+m" (_q_value)
+ : [_q_value] "r" (&_q_value),
+ [valueToAdd] "r" (valueToAdd * sizeof(T))
+ : "r0", "cc", "memory");
+ return originalValue;
+}
+
+template <typename T>
+Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndAddOrdered(qptrdiff valueToAdd)
+{
+ return fetchAndAddAcquire(valueToAdd);
+}
+
+#endif // Q_CC_GNU
+
+#endif // QATOMIC_SH4A_H
diff --git a/src/corelib/arch/qatomic_sparc.h b/src/corelib/arch/qatomic_sparc.h
new file mode 100644
index 0000000000..4129f1478b
--- /dev/null
+++ b/src/corelib/arch/qatomic_sparc.h
@@ -0,0 +1,525 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtCore module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QATOMIC_SPARC_H
+#define QATOMIC_SPARC_H
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+#if defined(_LP64)
+
+#define Q_ATOMIC_INT_REFERENCE_COUNTING_IS_ALWAYS_NATIVE
+
+inline bool QBasicAtomicInt::isReferenceCountingNative()
+{ return true; }
+inline bool QBasicAtomicInt::isReferenceCountingWaitFree()
+{ return false; }
+
+#define Q_ATOMIC_INT_TEST_AND_SET_IS_ALWAYS_NATIVE
+#define Q_ATOMIC_INT_TEST_AND_SET_IS_WAIT_FREE
+
+inline bool QBasicAtomicInt::isTestAndSetNative()
+{ return true; }
+inline bool QBasicAtomicInt::isTestAndSetWaitFree()
+{ return true; }
+
+#define Q_ATOMIC_INT_FETCH_AND_STORE_IS_ALWAYS_NATIVE
+#define Q_ATOMIC_INT_FETCH_AND_STORE_IS_WAIT_FREE
+
+inline bool QBasicAtomicInt::isFetchAndStoreNative()
+{ return true; }
+inline bool QBasicAtomicInt::isFetchAndStoreWaitFree()
+{ return true; }
+
+#define Q_ATOMIC_INT_FETCH_AND_ADD_IS_ALWAYS_NATIVE
+
+inline bool QBasicAtomicInt::isFetchAndAddNative()
+{ return true; }
+inline bool QBasicAtomicInt::isFetchAndAddWaitFree()
+{ return false; }
+
+#define Q_ATOMIC_POINTER_TEST_AND_SET_IS_ALWAYS_NATIVE
+#define Q_ATOMIC_POINTER_TEST_AND_SET_IS_WAIT_FREE
+
+template <typename T>
+Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::isTestAndSetNative()
+{ return true; }
+template <typename T>
+Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::isTestAndSetWaitFree()
+{ return true; }
+
+#define Q_ATOMIC_POINTER_FETCH_AND_STORE_IS_ALWAYS_NATIVE
+#define Q_ATOMIC_POINTER_FETCH_AND_STORE_IS_WAIT_FREE
+
+template <typename T>
+Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::isFetchAndStoreNative()
+{ return true; }
+template <typename T>
+Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::isFetchAndStoreWaitFree()
+{ return true; }
+
+#define Q_ATOMIC_POINTER_FETCH_AND_ADD_IS_ALWAYS_NATIVE
+
+template <typename T>
+Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::isFetchAndAddNative()
+{ return true; }
+template <typename T>
+Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::isFetchAndAddWaitFree()
+{ return false; }
+
+extern "C" {
+ Q_CORE_EXPORT int q_atomic_increment(volatile int *ptr);
+ Q_CORE_EXPORT int q_atomic_decrement(volatile int *ptr);
+
+ Q_CORE_EXPORT int q_atomic_test_and_set_int(volatile int *ptr, int expected, int newval);
+ Q_CORE_EXPORT int q_atomic_test_and_set_acquire_int(volatile int *ptr,
+ int expected,
+ int newval);
+ Q_CORE_EXPORT int q_atomic_test_and_set_release_int(volatile int *ptr,
+ int expected,
+ int newval);
+
+ Q_CORE_EXPORT int q_atomic_set_int(volatile int *ptr, int newval);
+ Q_CORE_EXPORT int q_atomic_fetch_and_store_acquire_int(volatile int *ptr, int newval);
+ Q_CORE_EXPORT int q_atomic_fetch_and_store_release_int(volatile int *ptr, int newval);
+
+ Q_CORE_EXPORT int q_atomic_fetch_and_add_int(volatile int *ptr, int value);
+ Q_CORE_EXPORT int q_atomic_fetch_and_add_acquire_int(volatile int *ptr, int value);
+ Q_CORE_EXPORT int q_atomic_fetch_and_add_release_int(volatile int *ptr, int value);
+
+ Q_CORE_EXPORT int q_atomic_test_and_set_ptr(volatile void *ptr, void *expected, void *newval);
+ Q_CORE_EXPORT int q_atomic_test_and_set_acquire_ptr(volatile void *ptr,
+ void *expected,
+ void *newval);
+ Q_CORE_EXPORT int q_atomic_test_and_set_release_ptr(volatile void *ptr,
+ void *expected,
+ void *newval);
+
+ Q_CORE_EXPORT void *q_atomic_set_ptr(volatile void *ptr, void *newval);
+ Q_CORE_EXPORT void *q_atomic_fetch_and_store_acquire_ptr(volatile void *ptr, void *newval);
+ Q_CORE_EXPORT void *q_atomic_fetch_and_store_release_ptr(volatile void *ptr, void *newval);
+
+ Q_CORE_EXPORT void *q_atomic_fetch_and_add_ptr(volatile void *ptr, int value);
+ Q_CORE_EXPORT void *q_atomic_fetch_and_add_acquire_ptr(volatile void *ptr, int value);
+ Q_CORE_EXPORT void *q_atomic_fetch_and_add_release_ptr(volatile void *ptr, int value);
+}
+
+inline bool QBasicAtomicInt::ref()
+{
+ return fetchAndAddRelaxed(1) != -1;
+}
+
+inline bool QBasicAtomicInt::deref()
+{
+ return fetchAndAddRelaxed(-1) != 1;
+}
+
+inline bool QBasicAtomicInt::testAndSetRelaxed(int expectedValue, int newValue)
+{
+ return q_atomic_test_and_set_int(&_q_value, expectedValue, newValue) != 0;
+}
+
+inline bool QBasicAtomicInt::testAndSetAcquire(int expectedValue, int newValue)
+{
+ return q_atomic_test_and_set_acquire_int(&_q_value, expectedValue, newValue) != 0;
+}
+
+inline bool QBasicAtomicInt::testAndSetRelease(int expectedValue, int newValue)
+{
+ return q_atomic_test_and_set_release_int(&_q_value, expectedValue, newValue) != 0;
+}
+
+inline bool QBasicAtomicInt::testAndSetOrdered(int expectedValue, int newValue)
+{
+ return q_atomic_test_and_set_acquire_int(&_q_value, expectedValue, newValue) != 0;
+}
+
+inline int QBasicAtomicInt::fetchAndStoreRelaxed(int newValue)
+{
+ return q_atomic_set_int(&_q_value, newValue);
+}
+
+inline int QBasicAtomicInt::fetchAndStoreAcquire(int newValue)
+{
+ return q_atomic_fetch_and_store_acquire_int(&_q_value, newValue);
+}
+
+inline int QBasicAtomicInt::fetchAndStoreRelease(int newValue)
+{
+ return q_atomic_fetch_and_store_release_int(&_q_value, newValue);
+}
+
+inline int QBasicAtomicInt::fetchAndStoreOrdered(int newValue)
+{
+ return q_atomic_fetch_and_store_acquire_int(&_q_value, newValue);
+}
+
+inline int QBasicAtomicInt::fetchAndAddRelaxed(int newValue)
+{
+ return q_atomic_fetch_and_add_int(&_q_value, newValue);
+}
+
+inline int QBasicAtomicInt::fetchAndAddAcquire(int newValue)
+{
+ return q_atomic_fetch_and_add_acquire_int(&_q_value, newValue);
+}
+
+inline int QBasicAtomicInt::fetchAndAddRelease(int newValue)
+{
+ return q_atomic_fetch_and_add_release_int(&_q_value, newValue);
+}
+
+inline int QBasicAtomicInt::fetchAndAddOrdered(int newValue)
+{
+ return q_atomic_fetch_and_add_acquire_int(&_q_value, newValue);
+}
+
+template <typename T>
+Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::testAndSetRelaxed(T *expectedValue, T *newValue)
+{
+ return q_atomic_test_and_set_ptr(&_q_value, expectedValue, newValue) != 0;
+}
+
+template <typename T>
+Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::testAndSetAcquire(T *expectedValue, T *newValue)
+{
+ return q_atomic_test_and_set_acquire_ptr(&_q_value, expectedValue, newValue) != 0;
+}
+
+template <typename T>
+Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::testAndSetRelease(T *expectedValue, T *newValue)
+{
+ return q_atomic_test_and_set_release_ptr(&_q_value, expectedValue, newValue) != 0;
+}
+
+template <typename T>
+Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::testAndSetOrdered(T *expectedValue, T *newValue)
+{
+ return q_atomic_test_and_set_acquire_ptr(&_q_value, expectedValue, newValue) != 0;
+}
+
+template <typename T>
+Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndStoreRelaxed(T *newValue)
+{
+ return reinterpret_cast<T *>(q_atomic_set_ptr(&_q_value, newValue));
+}
+
+template <typename T>
+Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndStoreAcquire(T *newValue)
+{
+ return reinterpret_cast<T *>(q_atomic_fetch_and_store_acquire_ptr(&_q_value, newValue));
+}
+
+template <typename T>
+Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndStoreRelease(T *newValue)
+{
+ return reinterpret_cast<T *>(q_atomic_fetch_and_store_release_ptr(&_q_value, newValue));
+}
+
+template <typename T>
+Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndStoreOrdered(T *newValue)
+{
+ return reinterpret_cast<T *>(q_atomic_fetch_and_store_acquire_ptr(&_q_value, newValue));
+}
+
+template <typename T>
+Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndAddRelaxed(qptrdiff valueToAdd)
+{
+ return reinterpret_cast<T *>(q_atomic_fetch_and_add_ptr(&_q_value, valueToAdd * sizeof(T)));
+}
+
+template <typename T>
+Q_INLINE_TEMPLATE
+T *QBasicAtomicPointer<T>::fetchAndAddAcquire(qptrdiff valueToAdd)
+{
+ return reinterpret_cast<T *>(q_atomic_fetch_and_add_acquire_ptr(&_q_value, valueToAdd * sizeof(T)));
+}
+
+template <typename T>
+Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndAddRelease(qptrdiff valueToAdd)
+{
+ return reinterpret_cast<T *>(q_atomic_fetch_and_add_release_ptr(&_q_value, valueToAdd * sizeof(T)));
+}
+
+template <typename T>
+Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndAddOrdered(qptrdiff valueToAdd)
+{
+ return reinterpret_cast<T *>(q_atomic_fetch_and_add_acquire_ptr(&_q_value, valueToAdd * sizeof(T)));
+}
+
+#else
+
+#define Q_ATOMIC_INT_REFERENCE_COUNTING_IS_NOT_NATIVE
+
+inline bool QBasicAtomicInt::isReferenceCountingNative()
+{ return false; }
+inline bool QBasicAtomicInt::isReferenceCountingWaitFree()
+{ return false; }
+
+#define Q_ATOMIC_INT_TEST_AND_SET_IS_NOT_NATIVE
+
+inline bool QBasicAtomicInt::isTestAndSetNative()
+{ return false; }
+inline bool QBasicAtomicInt::isTestAndSetWaitFree()
+{ return false; }
+
+#define Q_ATOMIC_INT_FETCH_AND_STORE_IS_ALWAYS_NATIVE
+#define Q_ATOMIC_INT_FETCH_AND_STORE_IS_WAIT_FREE
+
+inline bool QBasicAtomicInt::isFetchAndStoreNative()
+{ return true; }
+inline bool QBasicAtomicInt::isFetchAndStoreWaitFree()
+{ return true; }
+
+#define Q_ATOMIC_INT_FETCH_AND_ADD_IS_NOT_NATIVE
+
+inline bool QBasicAtomicInt::isFetchAndAddNative()
+{ return false; }
+inline bool QBasicAtomicInt::isFetchAndAddWaitFree()
+{ return false; }
+
+#define Q_ATOMIC_POINTER_TEST_AND_SET_IS_NOT_NATIVE
+
+template <typename T>
+Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::isTestAndSetNative()
+{ return false; }
+template <typename T>
+Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::isTestAndSetWaitFree()
+{ return false; }
+
+#define Q_ATOMIC_POINTER_FETCH_AND_STORE_IS_ALWAYS_NATIVE
+#define Q_ATOMIC_POINTER_FETCH_AND_STORE_IS_WAIT_FREE
+
+template <typename T>
+Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::isFetchAndStoreNative()
+{ return true; }
+template <typename T>
+Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::isFetchAndStoreWaitFree()
+{ return true; }
+
+#define Q_ATOMIC_POINTER_FETCH_AND_ADD_IS_NOT_NATIVE
+
+template <typename T>
+Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::isFetchAndAddNative()
+{ return false; }
+template <typename T>
+Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::isFetchAndAddWaitFree()
+{ return false; }
+
+extern "C" {
+ Q_CORE_EXPORT int q_atomic_lock_int(volatile int *addr);
+ Q_CORE_EXPORT int q_atomic_lock_ptr(volatile void *addr);
+ Q_CORE_EXPORT void q_atomic_unlock(volatile void *addr, int value);
+ Q_CORE_EXPORT int q_atomic_set_int(volatile int *ptr, int newval);
+ Q_CORE_EXPORT void *q_atomic_set_ptr(volatile void *ptr, void *newval);
+} // extern "C"
+
+inline bool QBasicAtomicInt::ref()
+{
+ const int val = q_atomic_lock_int(&_q_value);
+ q_atomic_unlock(&_q_value, val + 1);
+ return val != -1;
+}
+
+inline bool QBasicAtomicInt::deref()
+{
+ const int val = q_atomic_lock_int(&_q_value);
+ q_atomic_unlock(&_q_value, val - 1);
+ return val != 1;
+}
+
+inline bool QBasicAtomicInt::testAndSetOrdered(int expectedValue, int newValue)
+{
+ int val = q_atomic_lock_int(&_q_value);
+ if (val == expectedValue) {
+ q_atomic_unlock(&_q_value, newValue);
+ return true;
+ }
+ q_atomic_unlock(&_q_value, val);
+ return false;
+}
+
+inline bool QBasicAtomicInt::testAndSetRelaxed(int expectedValue, int newValue)
+{
+ return testAndSetOrdered(expectedValue, newValue);
+}
+
+inline bool QBasicAtomicInt::testAndSetAcquire(int expectedValue, int newValue)
+{
+ return testAndSetOrdered(expectedValue, newValue);
+}
+
+inline bool QBasicAtomicInt::testAndSetRelease(int expectedValue, int newValue)
+{
+ return testAndSetOrdered(expectedValue, newValue);
+}
+
+inline int QBasicAtomicInt::fetchAndStoreOrdered(int newValue)
+{
+ return q_atomic_set_int(&_q_value, newValue);
+}
+
+inline int QBasicAtomicInt::fetchAndStoreRelaxed(int newValue)
+{
+ return fetchAndStoreOrdered(newValue);
+}
+
+inline int QBasicAtomicInt::fetchAndStoreAcquire(int newValue)
+{
+ return fetchAndStoreOrdered(newValue);
+}
+
+inline int QBasicAtomicInt::fetchAndStoreRelease(int newValue)
+{
+ return fetchAndStoreOrdered(newValue);
+}
+
+inline int QBasicAtomicInt::fetchAndAddOrdered(int valueToAdd)
+{
+ const int originalValue = q_atomic_lock_int(&_q_value);
+ q_atomic_unlock(&_q_value, originalValue + valueToAdd);
+ return originalValue;
+}
+
+inline int QBasicAtomicInt::fetchAndAddRelaxed(int valueToAdd)
+{
+ return fetchAndAddOrdered(valueToAdd);
+}
+
+inline int QBasicAtomicInt::fetchAndAddAcquire(int valueToAdd)
+{
+ return fetchAndAddOrdered(valueToAdd);
+}
+
+inline int QBasicAtomicInt::fetchAndAddRelease(int valueToAdd)
+{
+ return fetchAndAddOrdered(valueToAdd);
+}
+
+template <typename T>
+Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::testAndSetOrdered(T *expectedValue, T *newValue)
+{
+ T *val = reinterpret_cast<T *>(q_atomic_lock_ptr(&_q_value));
+ if (val == expectedValue) {
+ q_atomic_unlock(&_q_value, reinterpret_cast<int>(newValue));
+ return true;
+ }
+ q_atomic_unlock(&_q_value, reinterpret_cast<int>(val));
+ return false;
+}
+
+template <typename T>
+Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::testAndSetRelaxed(T *expectedValue, T *newValue)
+{
+ return testAndSetOrdered(expectedValue, newValue);
+}
+
+template <typename T>
+Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::testAndSetAcquire(T *expectedValue, T *newValue)
+{
+ return testAndSetOrdered(expectedValue, newValue);
+}
+
+template <typename T>
+Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::testAndSetRelease(T *expectedValue, T *newValue)
+{
+ return testAndSetOrdered(expectedValue, newValue);
+}
+
+template <typename T>
+Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndStoreOrdered(T *newValue)
+{
+ return reinterpret_cast<T *>(q_atomic_set_ptr(&_q_value, newValue));
+}
+
+template <typename T>
+Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndStoreRelaxed(T *newValue)
+{
+ return fetchAndStoreOrdered(newValue);
+}
+
+template <typename T>
+Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndStoreAcquire(T *newValue)
+{
+ return fetchAndStoreOrdered(newValue);
+}
+
+template <typename T>
+Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndStoreRelease(T *newValue)
+{
+ return fetchAndStoreOrdered(newValue);
+}
+
+template <typename T>
+Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndAddOrdered(qptrdiff valueToAdd)
+{
+ T *originalValue = reinterpret_cast<T *>(q_atomic_lock_ptr(&_q_value));
+ q_atomic_unlock(&_q_value, int(originalValue + valueToAdd));
+ return originalValue;
+}
+
+template <typename T>
+Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndAddRelaxed(qptrdiff valueToAdd)
+{
+ return fetchAndAddOrdered(valueToAdd);
+}
+
+template <typename T>
+Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndAddAcquire(qptrdiff valueToAdd)
+{
+ return fetchAndAddOrdered(valueToAdd);
+}
+
+template <typename T>
+Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndAddRelease(qptrdiff valueToAdd)
+{
+ return fetchAndAddOrdered(valueToAdd);
+}
+
+#endif // _LP64
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // QATOMIC_SPARC_H
diff --git a/src/corelib/arch/qatomic_windows.h b/src/corelib/arch/qatomic_windows.h
new file mode 100644
index 0000000000..ac26b4f6cb
--- /dev/null
+++ b/src/corelib/arch/qatomic_windows.h
@@ -0,0 +1,564 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtCore module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QATOMIC_WINDOWS_H
+#define QATOMIC_WINDOWS_H
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+#define Q_ATOMIC_INT_REFERENCE_COUNTING_IS_ALWAYS_NATIVE
+#define Q_ATOMIC_INT_REFERENCE_COUNTING_IS_WAIT_FREE
+
+inline bool QBasicAtomicInt::isReferenceCountingNative()
+{ return true; }
+inline bool QBasicAtomicInt::isReferenceCountingWaitFree()
+{ return true; }
+
+#define Q_ATOMIC_INT_TEST_AND_SET_IS_ALWAYS_NATIVE
+#define Q_ATOMIC_INT_TEST_AND_SET_IS_WAIT_FREE
+
+inline bool QBasicAtomicInt::isTestAndSetNative()
+{ return true; }
+inline bool QBasicAtomicInt::isTestAndSetWaitFree()
+{ return true; }
+
+#define Q_ATOMIC_INT_FETCH_AND_STORE_IS_ALWAYS_NATIVE
+#define Q_ATOMIC_INT_FETCH_AND_STORE_IS_WAIT_FREE
+
+inline bool QBasicAtomicInt::isFetchAndStoreNative()
+{ return true; }
+inline bool QBasicAtomicInt::isFetchAndStoreWaitFree()
+{ return true; }
+
+#define Q_ATOMIC_INT_FETCH_AND_ADD_IS_ALWAYS_NATIVE
+#define Q_ATOMIC_INT_FETCH_AND_ADD_IS_WAIT_FREE
+
+inline bool QBasicAtomicInt::isFetchAndAddNative()
+{ return true; }
+inline bool QBasicAtomicInt::isFetchAndAddWaitFree()
+{ return true; }
+
+#define Q_ATOMIC_POINTER_TEST_AND_SET_IS_ALWAYS_NATIVE
+#define Q_ATOMIC_POINTER_TEST_AND_SET_IS_WAIT_FREE
+
+template <typename T>
+Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::isTestAndSetNative()
+{ return true; }
+template <typename T>
+Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::isTestAndSetWaitFree()
+{ return true; }
+
+#define Q_ATOMIC_POINTER_FETCH_AND_STORE_IS_ALWAYS_NATIVE
+#define Q_ATOMIC_POINTER_FETCH_AND_STORE_IS_WAIT_FREE
+
+template <typename T>
+Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::isFetchAndStoreNative()
+{ return true; }
+template <typename T>
+Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::isFetchAndStoreWaitFree()
+{ return true; }
+
+#define Q_ATOMIC_POINTER_FETCH_AND_ADD_IS_ALWAYS_NATIVE
+#define Q_ATOMIC_POINTER_FETCH_AND_ADD_IS_WAIT_FREE
+template <typename T>
+Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::isFetchAndAddNative()
+{ return true; }
+template <typename T>
+Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::isFetchAndAddWaitFree()
+{ return true; }
+
+#if defined(Q_CC_MSVC)
+
+// MSVC++ 6.0 doesn't generate correct code when optimizations are turned on!
+#if _MSC_VER < 1300 && defined (_M_IX86)
+
+inline bool QBasicAtomicInt::ref()
+{
+ volatile int *pointer = &_q_value;
+ unsigned char retVal;
+ __asm {
+ mov ECX,pointer
+ lock inc DWORD ptr[ECX]
+ setne retVal
+ }
+ return retVal != 0;
+}
+
+inline bool QBasicAtomicInt::deref()
+{
+ volatile int *pointer = &_q_value;
+ unsigned char retVal;
+ __asm {
+ mov ECX,pointer
+ lock dec DWORD ptr[ECX]
+ setne retVal
+ }
+ return retVal != 0;
+}
+
+inline bool QBasicAtomicInt::testAndSetOrdered(int expectedValue, int newValue)
+{
+ volatile int *pointer = &_q_value;
+ __asm {
+ mov EDX,pointer
+ mov EAX,expectedValue
+ mov ECX,newValue
+ lock cmpxchg dword ptr[EDX],ECX
+ mov newValue,EAX
+ }
+ return newValue == expectedValue;
+}
+
+
+inline int QBasicAtomicInt::fetchAndStoreOrdered(int newValue)
+{
+ volatile int *pointer = &_q_value;
+ __asm {
+ mov EDX,pointer
+ mov ECX,newValue
+ lock xchg dword ptr[EDX],ECX
+ mov newValue,ECX
+ }
+ return newValue;
+}
+
+
+inline int QBasicAtomicInt::fetchAndAddOrdered(int valueToAdd)
+{
+ volatile int *pointer = &_q_value;
+ __asm {
+ mov EDX,pointer
+ mov ECX,valueToAdd
+ lock xadd dword ptr[EDX],ECX
+ mov valueToAdd,ECX
+ }
+ return valueToAdd;
+}
+
+template <typename T>
+Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::testAndSetOrdered(T *expectedValue, T *newValue)
+{
+ volatile void *pointer = &_q_value;
+ __asm {
+ mov EDX,pointer
+ mov EAX,expectedValue
+ mov ECX,newValue
+ lock cmpxchg dword ptr[EDX],ECX
+ mov newValue,EAX
+ }
+ return newValue == expectedValue;
+}
+
+template <typename T>
+Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndStoreOrdered(T *newValue)
+{
+ volatile void *pointer = &_q_value;
+ __asm {
+ mov EDX,pointer
+ mov ECX,newValue
+ lock xchg dword ptr[EDX],ECX
+ mov newValue,ECX
+ }
+ return reinterpret_cast<T *>(newValue);
+}
+
+template <typename T>
+Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndAddOrdered(qptrdiff valueToAdd)
+{
+ volatile void *pointer = &_q_value;
+ valueToAdd *= sizeof(T);
+ __asm {
+ mov EDX,pointer
+ mov ECX,valueToAdd
+ lock xadd dword ptr[EDX],ECX
+ mov pointer,ECX
+ }
+ return reinterpret_cast<T *>(const_cast<void *>(pointer));
+}
+
+#else
+
+#if !defined(Q_OS_WINCE)
+// use compiler intrinsics for all atomic functions
+extern "C" {
+ long __cdecl _InterlockedIncrement(volatile long *);
+ long __cdecl _InterlockedDecrement(volatile long *);
+ long __cdecl _InterlockedExchange(volatile long *, long);
+ long __cdecl _InterlockedCompareExchange(volatile long *, long, long);
+ long __cdecl _InterlockedExchangeAdd(volatile long *, long);
+}
+# pragma intrinsic (_InterlockedIncrement)
+# pragma intrinsic (_InterlockedDecrement)
+# pragma intrinsic (_InterlockedExchange)
+# pragma intrinsic (_InterlockedCompareExchange)
+# pragma intrinsic (_InterlockedExchangeAdd)
+
+# ifndef _M_IX86
+extern "C" {
+ void *_InterlockedCompareExchangePointer(void * volatile *, void *, void *);
+ void *_InterlockedExchangePointer(void * volatile *, void *);
+ __int64 _InterlockedExchangeAdd64(__int64 volatile * Addend, __int64 Value);
+}
+# pragma intrinsic (_InterlockedCompareExchangePointer)
+# pragma intrinsic (_InterlockedExchangePointer)
+# pragma intrinsic (_InterlockedExchangeAdd64)
+# define _InterlockedExchangeAddPointer(a,b) \
+ _InterlockedExchangeAdd64(reinterpret_cast<volatile __int64 *>(a), __int64(b))
+# else
+# define _InterlockedCompareExchangePointer(a,b,c) \
+ _InterlockedCompareExchange(reinterpret_cast<volatile long *>(a), long(b), long(c))
+# define _InterlockedExchangePointer(a, b) \
+ _InterlockedExchange(reinterpret_cast<volatile long *>(a), long(b))
+# define _InterlockedExchangeAddPointer(a,b) \
+ _InterlockedExchangeAdd(reinterpret_cast<volatile long *>(a), long(b))
+# endif
+inline bool QBasicAtomicInt::ref()
+{
+ return _InterlockedIncrement(reinterpret_cast<volatile long *>(&_q_value)) != 0;
+}
+
+inline bool QBasicAtomicInt::deref()
+{
+ return _InterlockedDecrement(reinterpret_cast<volatile long *>(&_q_value)) != 0;
+}
+
+inline bool QBasicAtomicInt::testAndSetOrdered(int expectedValue, int newValue)
+{
+ return _InterlockedCompareExchange(reinterpret_cast<volatile long *>(&_q_value), newValue, expectedValue) == expectedValue;
+}
+
+inline int QBasicAtomicInt::fetchAndStoreOrdered(int newValue)
+{
+ return _InterlockedExchange(reinterpret_cast<volatile long *>(&_q_value), newValue);
+}
+
+inline int QBasicAtomicInt::fetchAndAddOrdered(int valueToAdd)
+{
+ return _InterlockedExchangeAdd(reinterpret_cast<volatile long *>(&_q_value), valueToAdd);
+}
+
+#if defined(Q_CC_MSVC)
+#pragma warning( push )
+#pragma warning( disable : 4311 ) // ignoring the warning from /Wp64
+#endif
+
+template <typename T>
+Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::testAndSetOrdered(T *expectedValue, T *newValue)
+{
+ return (_InterlockedCompareExchangePointer(reinterpret_cast<void * volatile *>(&_q_value),
+ newValue, expectedValue) ==
+#ifndef _M_IX86
+ (void *)
+#else
+ (long)
+#endif
+ (expectedValue));
+}
+
+#if defined(Q_CC_MSVC)
+#pragma warning( pop )
+#endif
+
+template <typename T>
+Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndStoreOrdered(T *newValue)
+{
+ return reinterpret_cast<T *>(_InterlockedExchangePointer(reinterpret_cast<void * volatile *>(&_q_value), newValue));
+}
+
+template <typename T>
+Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndAddOrdered(qptrdiff valueToAdd)
+{
+ return reinterpret_cast<T *>(_InterlockedExchangeAddPointer(reinterpret_cast<void * volatile *>(&_q_value), valueToAdd * sizeof(T)));
+}
+
+#else // Q_OS_WINCE
+
+#if _WIN32_WCE < 0x600 && defined(_X86_)
+// For X86 Windows CE build we need to include winbase.h to be able
+// to catch the inline functions which overwrite the regular
+// definitions inside of coredll.dll. Though one could use the
+// original version of Increment/Decrement, the others are not
+// exported at all.
+#include <winbase.h>
+#else
+
+#if _WIN32_WCE >= 0x600
+#define Q_ARGUMENT_TYPE volatile
+# if defined(_X86_)
+# define InterlockedIncrement _InterlockedIncrement
+# define InterlockedDecrement _InterlockedDecrement
+# define InterlockedExchange _InterlockedExchange
+# define InterlockedCompareExchange _InterlockedCompareExchange
+# define InterlockedExchangeAdd _InterlockedExchangeAdd
+# endif
+#else
+#define Q_ARGUMENT_TYPE
+#endif
+
+extern "C" {
+long __cdecl InterlockedIncrement(long Q_ARGUMENT_TYPE * lpAddend);
+long __cdecl InterlockedDecrement(long Q_ARGUMENT_TYPE * lpAddend);
+long __cdecl InterlockedExchange(long Q_ARGUMENT_TYPE * Target, long Value);
+long __cdecl InterlockedCompareExchange(long Q_ARGUMENT_TYPE * Destination, long Exchange, long Comperand);
+long __cdecl InterlockedExchangeAdd(long Q_ARGUMENT_TYPE * Addend, long Value);
+}
+
+#if _WIN32_WCE >= 0x600 && defined(_X86_)
+# pragma intrinsic (_InterlockedIncrement)
+# pragma intrinsic (_InterlockedDecrement)
+# pragma intrinsic (_InterlockedExchange)
+# pragma intrinsic (_InterlockedCompareExchange)
+# pragma intrinsic (_InterlockedExchangeAdd)
+#endif
+
+#endif
+
+
+inline bool QBasicAtomicInt::ref()
+{
+ return InterlockedIncrement((long*)(&_q_value)) != 0;
+}
+
+inline bool QBasicAtomicInt::deref()
+{
+ return InterlockedDecrement((long*)(&_q_value)) != 0;
+}
+
+inline bool QBasicAtomicInt::testAndSetOrdered(int expectedValue, int newValue)
+{
+ return InterlockedCompareExchange((long*)(&_q_value), newValue, expectedValue) == expectedValue;
+}
+
+inline int QBasicAtomicInt::fetchAndStoreOrdered(int newValue)
+{
+ return InterlockedExchange((long*)(&_q_value), newValue);
+}
+
+inline int QBasicAtomicInt::fetchAndAddOrdered(int valueToAdd)
+{
+ return InterlockedExchangeAdd((long*)(&_q_value), valueToAdd);
+}
+
+template <typename T>
+Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::testAndSetOrdered(T *expectedValue, T *newValue)
+{
+ return (InterlockedCompareExchange((long*)(&_q_value),
+ (long)newValue, (long)expectedValue) ==
+ (long)(expectedValue));
+}
+
+template <typename T>
+Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndStoreOrdered(T *newValue)
+{
+ return reinterpret_cast<T *>(InterlockedExchange((long*)(&_q_value), (long)newValue));
+}
+
+template <typename T>
+Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndAddOrdered(qptrdiff valueToAdd)
+{
+ return reinterpret_cast<T *>(InterlockedExchangeAdd((long*)(&_q_value), valueToAdd * sizeof(T)));
+}
+
+#endif //Q_OS_WINCE
+
+#endif // _MSC_VER ...
+
+#else
+
+// __INTERLOCKED_DECLARED is defined in MinGW's winbase.h. Simply, preferrably we use
+// MinGW's definition, such that we pick up variations in the headers.
+#ifndef __INTERLOCKED_DECLARED
+#define __INTERLOCKED_DECLARED
+extern "C" {
+ __declspec(dllimport) long __stdcall InterlockedCompareExchange(long *, long, long);
+ __declspec(dllimport) long __stdcall InterlockedIncrement(long *);
+ __declspec(dllimport) long __stdcall InterlockedDecrement(long *);
+ __declspec(dllimport) long __stdcall InterlockedExchange(long *, long);
+ __declspec(dllimport) long __stdcall InterlockedExchangeAdd(long *, long);
+}
+#endif
+
+inline bool QBasicAtomicInt::ref()
+{
+ return InterlockedIncrement(reinterpret_cast<long *>(const_cast<int *>(&_q_value))) != 0;
+}
+
+inline bool QBasicAtomicInt::deref()
+{
+ return InterlockedDecrement(reinterpret_cast<long *>(const_cast<int *>(&_q_value))) != 0;
+}
+
+inline bool QBasicAtomicInt::testAndSetOrdered(int expectedValue, int newValue)
+{
+ return InterlockedCompareExchange(reinterpret_cast<long *>(const_cast<int *>(&_q_value)), newValue, expectedValue) == expectedValue;
+}
+
+inline int QBasicAtomicInt::fetchAndStoreOrdered(int newValue)
+{ return InterlockedExchange(reinterpret_cast<long *>(const_cast<int *>(&_q_value)), newValue); }
+
+inline int QBasicAtomicInt::fetchAndAddOrdered(int valueToAdd)
+{
+ return InterlockedExchangeAdd(reinterpret_cast<long *>(const_cast<int *>(&_q_value)), valueToAdd);
+}
+
+template <typename T>
+Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::testAndSetOrdered(T *expectedValue, T* newValue)
+{ return InterlockedCompareExchange(reinterpret_cast<long *>(const_cast<T **>(&_q_value)),
+ reinterpret_cast<long>(newValue),
+ reinterpret_cast<long>(expectedValue)) == reinterpret_cast<long>(expectedValue); }
+
+template <typename T>
+Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndStoreOrdered(T* newValue)
+{ return reinterpret_cast<T *>(InterlockedExchange(reinterpret_cast<long *>(const_cast<T **>(&_q_value)),
+ reinterpret_cast<long>(newValue))); }
+
+template <typename T>
+Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndAddOrdered(qptrdiff valueToAdd)
+{ return reinterpret_cast<T *>(InterlockedExchangeAdd(reinterpret_cast<long *>(const_cast<T **>(&_q_value)), valueToAdd * sizeof(T))); }
+
+#endif // Q_CC_GNU
+
+inline bool QBasicAtomicInt::testAndSetRelaxed(int expectedValue, int newValue)
+{
+ return testAndSetOrdered(expectedValue, newValue);
+}
+
+inline bool QBasicAtomicInt::testAndSetAcquire(int expectedValue, int newValue)
+{
+ return testAndSetOrdered(expectedValue, newValue);
+}
+
+inline bool QBasicAtomicInt::testAndSetRelease(int expectedValue, int newValue)
+{
+ return testAndSetOrdered(expectedValue, newValue);
+}
+
+inline int QBasicAtomicInt::fetchAndStoreRelaxed(int newValue)
+{
+ return fetchAndStoreOrdered(newValue);
+}
+
+inline int QBasicAtomicInt::fetchAndStoreAcquire(int newValue)
+{
+ return fetchAndStoreOrdered(newValue);
+}
+
+inline int QBasicAtomicInt::fetchAndStoreRelease(int newValue)
+{
+ return fetchAndStoreOrdered(newValue);
+}
+
+inline int QBasicAtomicInt::fetchAndAddRelaxed(int valueToAdd)
+{
+ return fetchAndAddOrdered(valueToAdd);
+}
+
+inline int QBasicAtomicInt::fetchAndAddAcquire(int valueToAdd)
+{
+ return fetchAndAddOrdered(valueToAdd);
+}
+
+inline int QBasicAtomicInt::fetchAndAddRelease(int valueToAdd)
+{
+ return fetchAndAddOrdered(valueToAdd);
+}
+
+template <typename T>
+Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::testAndSetRelaxed(T *expectedValue, T *newValue)
+{
+ return testAndSetOrdered(expectedValue, newValue);
+}
+
+template <typename T>
+Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::testAndSetAcquire(T *expectedValue, T *newValue)
+{
+ return testAndSetOrdered(expectedValue, newValue);
+}
+
+template <typename T>
+Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::testAndSetRelease(T *expectedValue, T *newValue)
+{
+ return testAndSetOrdered(expectedValue, newValue);
+}
+
+template <typename T>
+Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndStoreRelaxed(T *newValue)
+{
+ return fetchAndStoreOrdered(newValue);
+}
+
+template <typename T>
+Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndStoreAcquire(T *newValue)
+{
+ return fetchAndStoreOrdered(newValue);
+}
+
+template <typename T>
+Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndStoreRelease(T *newValue)
+{
+ return fetchAndStoreOrdered(newValue);
+}
+
+template <typename T>
+Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndAddRelaxed(qptrdiff valueToAdd)
+{
+ return fetchAndAddOrdered(valueToAdd);
+}
+
+template <typename T>
+Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndAddAcquire(qptrdiff valueToAdd)
+{
+ return fetchAndAddOrdered(valueToAdd);
+}
+
+template <typename T>
+Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndAddRelease(qptrdiff valueToAdd)
+{
+ return fetchAndAddOrdered(valueToAdd);
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // QATOMIC_WINDOWS_H
diff --git a/src/corelib/arch/qatomic_windowsce.h b/src/corelib/arch/qatomic_windowsce.h
new file mode 100644
index 0000000000..95ecba84f9
--- /dev/null
+++ b/src/corelib/arch/qatomic_windowsce.h
@@ -0,0 +1,56 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtCore module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef WINDOWSCE_QATOMIC_H
+#define WINDOWSCE_QATOMIC_H
+
+#include <QtCore/qglobal.h>
+QT_BEGIN_HEADER
+
+#if defined(QT_ARCH_WINDOWSCE)
+#include "QtCore/qatomic_windows.h"
+#endif
+
+QT_END_HEADER
+
+#endif // QATOMIC_ARCH_H
+
+
diff --git a/src/corelib/arch/qatomic_x86_64.h b/src/corelib/arch/qatomic_x86_64.h
new file mode 100644
index 0000000000..79d8a075e7
--- /dev/null
+++ b/src/corelib/arch/qatomic_x86_64.h
@@ -0,0 +1,363 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtCore module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QATOMIC_X86_64_H
+#define QATOMIC_X86_64_H
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+#define Q_ATOMIC_INT_REFERENCE_COUNTING_IS_ALWAYS_NATIVE
+#define Q_ATOMIC_INT_REFERENCE_COUNTING_IS_WAIT_FREE
+
+inline bool QBasicAtomicInt::isReferenceCountingNative()
+{ return true; }
+inline bool QBasicAtomicInt::isReferenceCountingWaitFree()
+{ return true; }
+
+#define Q_ATOMIC_INT_TEST_AND_SET_IS_ALWAYS_NATIVE
+#define Q_ATOMIC_INT_TEST_AND_SET_IS_WAIT_FREE
+
+inline bool QBasicAtomicInt::isTestAndSetNative()
+{ return true; }
+inline bool QBasicAtomicInt::isTestAndSetWaitFree()
+{ return true; }
+
+#define Q_ATOMIC_INT_FETCH_AND_STORE_IS_ALWAYS_NATIVE
+#define Q_ATOMIC_INT_FETCH_AND_STORE_IS_WAIT_FREE
+
+inline bool QBasicAtomicInt::isFetchAndStoreNative()
+{ return true; }
+inline bool QBasicAtomicInt::isFetchAndStoreWaitFree()
+{ return true; }
+
+#define Q_ATOMIC_INT_FETCH_AND_ADD_IS_ALWAYS_NATIVE
+#define Q_ATOMIC_INT_FETCH_AND_ADD_IS_WAIT_FREE
+
+inline bool QBasicAtomicInt::isFetchAndAddNative()
+{ return true; }
+inline bool QBasicAtomicInt::isFetchAndAddWaitFree()
+{ return true; }
+
+#define Q_ATOMIC_POINTER_TEST_AND_SET_IS_ALWAYS_NATIVE
+#define Q_ATOMIC_POINTER_TEST_AND_SET_IS_WAIT_FREE
+
+template <typename T>
+Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::isTestAndSetNative()
+{ return true; }
+template <typename T>
+Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::isTestAndSetWaitFree()
+{ return true; }
+
+#define Q_ATOMIC_POINTER_FETCH_AND_STORE_IS_ALWAYS_NATIVE
+#define Q_ATOMIC_POINTER_FETCH_AND_STORE_IS_WAIT_FREE
+
+template <typename T>
+Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::isFetchAndStoreNative()
+{ return true; }
+template <typename T>
+Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::isFetchAndStoreWaitFree()
+{ return true; }
+
+#define Q_ATOMIC_POINTER_FETCH_AND_ADD_IS_ALWAYS_NATIVE
+#define Q_ATOMIC_POINTER_FETCH_AND_ADD_IS_WAIT_FREE
+
+template <typename T>
+Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::isFetchAndAddNative()
+{ return true; }
+template <typename T>
+Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::isFetchAndAddWaitFree()
+{ return true; }
+
+#if defined(Q_CC_GNU) || defined(Q_CC_INTEL)
+
+inline bool QBasicAtomicInt::ref()
+{
+ unsigned char ret;
+ asm volatile("lock\n"
+ "incl %0\n"
+ "setne %1"
+ : "=m" (_q_value), "=qm" (ret)
+ : "m" (_q_value)
+ : "memory");
+ return ret != 0;
+}
+
+inline bool QBasicAtomicInt::deref()
+{
+ unsigned char ret;
+ asm volatile("lock\n"
+ "decl %0\n"
+ "setne %1"
+ : "=m" (_q_value), "=qm" (ret)
+ : "m" (_q_value)
+ : "memory");
+ return ret != 0;
+}
+
+inline bool QBasicAtomicInt::testAndSetOrdered(int expectedValue, int newValue)
+{
+ unsigned char ret;
+ asm volatile("lock\n"
+ "cmpxchgl %3,%2\n"
+ "sete %1\n"
+ : "=a" (newValue), "=qm" (ret), "+m" (_q_value)
+ : "r" (newValue), "0" (expectedValue)
+ : "memory");
+ return ret != 0;
+}
+
+inline int QBasicAtomicInt::fetchAndStoreOrdered(int newValue)
+{
+ asm volatile("xchgl %0,%1"
+ : "=r" (newValue), "+m" (_q_value)
+ : "0" (newValue)
+ : "memory");
+ return newValue;
+}
+
+inline int QBasicAtomicInt::fetchAndAddOrdered(int valueToAdd)
+{
+ asm volatile("lock\n"
+ "xaddl %0,%1"
+ : "=r" (valueToAdd), "+m" (_q_value)
+ : "0" (valueToAdd)
+ : "memory");
+ return valueToAdd;
+}
+
+template <typename T>
+Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::testAndSetOrdered(T *expectedValue, T *newValue)
+{
+ unsigned char ret;
+ asm volatile("lock\n"
+ "cmpxchgq %3,%2\n"
+ "sete %1\n"
+ : "=a" (newValue), "=qm" (ret), "+m" (_q_value)
+ : "r" (newValue), "0" (expectedValue)
+ : "memory");
+ return ret != 0;
+}
+
+template <typename T>
+Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndStoreOrdered(T *newValue)
+{
+ asm volatile("xchgq %0,%1"
+ : "=r" (newValue), "+m" (_q_value)
+ : "0" (newValue)
+ : "memory");
+ return newValue;
+}
+
+template <typename T>
+Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndAddOrdered(qptrdiff valueToAdd)
+{
+ asm volatile("lock\n"
+ "xaddq %0,%1"
+ : "=r" (valueToAdd), "+m" (_q_value)
+ : "0" (valueToAdd * sizeof(T))
+ : "memory");
+ return reinterpret_cast<T *>(valueToAdd);
+}
+
+#else // !Q_CC_INTEL && !Q_CC_GNU
+
+extern "C" {
+ Q_CORE_EXPORT int q_atomic_test_and_set_int(volatile int *ptr, int expected, int newval);
+ Q_CORE_EXPORT int q_atomic_test_and_set_ptr(volatile void *ptr, void *expected, void *newval);
+ Q_CORE_EXPORT int q_atomic_increment(volatile int *ptr);
+ Q_CORE_EXPORT int q_atomic_decrement(volatile int *ptr);
+ Q_CORE_EXPORT int q_atomic_set_int(volatile int *ptr, int newval);
+ Q_CORE_EXPORT void *q_atomic_set_ptr(volatile void *ptr, void *newval);
+ Q_CORE_EXPORT int q_atomic_fetch_and_add_int(volatile int *ptr, int value);
+ Q_CORE_EXPORT void *q_atomic_fetch_and_add_ptr(volatile void *ptr, qptrdiff value);
+} // extern "C"
+
+inline bool QBasicAtomicInt::ref()
+{
+ return q_atomic_increment(&_q_value) != 0;
+}
+
+inline bool QBasicAtomicInt::deref()
+{
+ return q_atomic_decrement(&_q_value) != 0;
+}
+
+inline bool QBasicAtomicInt::testAndSetOrdered(int expected, int newval)
+{
+ return q_atomic_test_and_set_int(&_q_value, expected, newval) != 0;
+}
+
+inline int QBasicAtomicInt::fetchAndStoreOrdered(int newval)
+{
+ return q_atomic_set_int(&_q_value, newval);
+}
+
+inline int QBasicAtomicInt::fetchAndAddOrdered(int aValue)
+{
+ return q_atomic_fetch_and_add_int(&_q_value, aValue);
+}
+
+template <typename T>
+Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::testAndSetOrdered(T *expectedValue, T *newValue)
+{
+ return q_atomic_test_and_set_ptr(&_q_value, expectedValue, newValue);
+}
+
+template <typename T>
+Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndStoreOrdered(T *newValue)
+{
+ return reinterpret_cast<T *>(q_atomic_set_ptr(&_q_value, newValue));
+}
+
+template <typename T>
+Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndAddOrdered(qptrdiff valueToAdd)
+{
+ return reinterpret_cast<T *>(q_atomic_fetch_and_add_ptr(&_q_value, valueToAdd * sizeof(T)));
+}
+
+#endif // Q_CC_GNU || Q_CC_INTEL
+
+inline bool QBasicAtomicInt::testAndSetRelaxed(int expectedValue, int newValue)
+{
+ return testAndSetOrdered(expectedValue, newValue);
+}
+
+inline bool QBasicAtomicInt::testAndSetAcquire(int expectedValue, int newValue)
+{
+ return testAndSetOrdered(expectedValue, newValue);
+}
+
+inline bool QBasicAtomicInt::testAndSetRelease(int expectedValue, int newValue)
+{
+ return testAndSetOrdered(expectedValue, newValue);
+}
+
+inline int QBasicAtomicInt::fetchAndStoreRelaxed(int newValue)
+{
+ return fetchAndStoreOrdered(newValue);
+}
+
+inline int QBasicAtomicInt::fetchAndStoreAcquire(int newValue)
+{
+ return fetchAndStoreOrdered(newValue);
+}
+
+inline int QBasicAtomicInt::fetchAndStoreRelease(int newValue)
+{
+ return fetchAndStoreOrdered(newValue);
+}
+
+inline int QBasicAtomicInt::fetchAndAddRelaxed(int valueToAdd)
+{
+ return fetchAndAddOrdered(valueToAdd);
+}
+
+inline int QBasicAtomicInt::fetchAndAddAcquire(int valueToAdd)
+{
+ return fetchAndAddOrdered(valueToAdd);
+}
+
+inline int QBasicAtomicInt::fetchAndAddRelease(int valueToAdd)
+{
+ return fetchAndAddOrdered(valueToAdd);
+}
+
+template <typename T>
+Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::testAndSetRelaxed(T *expectedValue, T *newValue)
+{
+ return testAndSetOrdered(expectedValue, newValue);
+}
+
+template <typename T>
+Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::testAndSetAcquire(T *expectedValue, T *newValue)
+{
+ return testAndSetOrdered(expectedValue, newValue);
+}
+
+template <typename T>
+Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::testAndSetRelease(T *expectedValue, T *newValue)
+{
+ return testAndSetOrdered(expectedValue, newValue);
+}
+
+template <typename T>
+Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndStoreRelaxed(T *newValue)
+{
+ return fetchAndStoreOrdered(newValue);
+}
+
+template <typename T>
+Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndStoreAcquire(T *newValue)
+{
+ return fetchAndStoreOrdered(newValue);
+}
+
+template <typename T>
+Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndStoreRelease(T *newValue)
+{
+ return fetchAndStoreOrdered(newValue);
+}
+
+template <typename T>
+Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndAddRelaxed(qptrdiff valueToAdd)
+{
+ return fetchAndAddOrdered(valueToAdd);
+}
+
+template <typename T>
+Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndAddAcquire(qptrdiff valueToAdd)
+{
+ return fetchAndAddOrdered(valueToAdd);
+}
+
+template <typename T>
+Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndAddRelease(qptrdiff valueToAdd)
+{
+ return fetchAndAddOrdered(valueToAdd);
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // QATOMIC_X86_64_H
diff --git a/src/corelib/arch/s390/arch.pri b/src/corelib/arch/s390/arch.pri
new file mode 100644
index 0000000000..45cc57824b
--- /dev/null
+++ b/src/corelib/arch/s390/arch.pri
@@ -0,0 +1,3 @@
+#
+# S390 architecture
+#
diff --git a/src/corelib/arch/sh/arch.pri b/src/corelib/arch/sh/arch.pri
new file mode 100644
index 0000000000..67fbb16c10
--- /dev/null
+++ b/src/corelib/arch/sh/arch.pri
@@ -0,0 +1,4 @@
+#
+# SH (Renesas SuperH) architecture
+#
+SOURCES += $$QT_ARCH_CPP/qatomic_sh.cpp
diff --git a/src/corelib/arch/sh/qatomic_sh.cpp b/src/corelib/arch/sh/qatomic_sh.cpp
new file mode 100644
index 0000000000..00a32eea16
--- /dev/null
+++ b/src/corelib/arch/sh/qatomic_sh.cpp
@@ -0,0 +1,72 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtCore module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QtCore/qglobal.h>
+
+#include <unistd.h>
+#ifdef _POSIX_PRIORITY_SCHEDULING
+# include <sched.h>
+#endif
+#include <time.h>
+
+QT_BEGIN_NAMESPACE
+
+QT_USE_NAMESPACE
+
+Q_CORE_EXPORT volatile char qt_atomic_lock = 0;
+
+Q_CORE_EXPORT void qt_atomic_yield(int *count)
+{
+#ifdef _POSIX_PRIORITY_SCHEDULING
+ if((*count)++ < 50) {
+ sched_yield();
+ } else
+#endif
+ {
+ struct timespec tm;
+ tm.tv_sec = 0;
+ tm.tv_nsec = 2000001;
+ nanosleep(&tm, NULL);
+ *count = 0;
+ }
+}
+
+QT_END_NAMESPACE
diff --git a/src/corelib/arch/sh4a/arch.pri b/src/corelib/arch/sh4a/arch.pri
new file mode 100644
index 0000000000..19d5e040a9
--- /dev/null
+++ b/src/corelib/arch/sh4a/arch.pri
@@ -0,0 +1,3 @@
+#
+# SH-4A (Renesas SuperH) architecture
+#
diff --git a/src/corelib/arch/sparc/arch.pri b/src/corelib/arch/sparc/arch.pri
new file mode 100644
index 0000000000..3113dd3d82
--- /dev/null
+++ b/src/corelib/arch/sparc/arch.pri
@@ -0,0 +1,10 @@
+#
+# SPARC architecture
+#
+*-64 {
+ SOURCES += $$QT_ARCH_CPP/qatomic64.s
+}
+else {
+ SOURCES += $$QT_ARCH_CPP/qatomic32.s \
+ $$QT_ARCH_CPP/qatomic_sparc.cpp
+}
diff --git a/src/corelib/arch/sparc/qatomic32.s b/src/corelib/arch/sparc/qatomic32.s
new file mode 100644
index 0000000000..f0ab0d1ee7
--- /dev/null
+++ b/src/corelib/arch/sparc/qatomic32.s
@@ -0,0 +1,63 @@
+ .section ".text"
+
+ .align 4
+ .type q_atomic_trylock_int,#function
+ .global q_atomic_trylock_int
+q_atomic_trylock_int:
+ sethi %hi(-2147483648),%o2
+ swap [%o0],%o2
+ retl
+ mov %o2,%o0
+ .size q_atomic_trylock_int,.-q_atomic_trylock_int
+
+
+
+
+ .align 4
+ .type q_atomic_trylock_ptr,#function
+ .global q_atomic_trylock_ptr
+q_atomic_trylock_ptr:
+ mov -1, %o2
+ swap [%o0], %o2
+ retl
+ mov %o2, %o0
+ .size q_atomic_trylock_ptr,.-q_atomic_trylock_ptr
+
+
+
+
+ .align 4
+ .type q_atomic_unlock,#function
+ .global q_atomic_unlock
+q_atomic_unlock:
+ stbar
+ retl
+ st %o1,[%o0]
+ .size q_atomic_unlock,.-q_atomic_unlock
+
+
+
+
+ .align 4
+ .type q_atomic_set_int,#function
+ .global q_atomic_set_int
+q_atomic_set_int:
+ swap [%o0],%o1
+ stbar
+ retl
+ mov %o1,%o0
+ .size q_atomic_set_int,.-q_atomic_set_int
+
+
+
+
+ .align 4
+ .type q_atomic_set_ptr,#function
+ .global q_atomic_set_ptr
+q_atomic_set_ptr:
+ swap [%o0],%o1
+ stbar
+ retl
+ mov %o1,%o0
+ .size q_atomic_set_ptr,.-q_atomic_set_ptr
+
diff --git a/src/corelib/arch/sparc/qatomic64.s b/src/corelib/arch/sparc/qatomic64.s
new file mode 100644
index 0000000000..edd17167ca
--- /dev/null
+++ b/src/corelib/arch/sparc/qatomic64.s
@@ -0,0 +1,287 @@
+ .section ".text"
+
+ .align 4
+ .type q_atomic_test_and_set_int,#function
+ .global q_atomic_test_and_set_int
+q_atomic_test_and_set_int:
+ cas [%o0],%o1,%o2
+ cmp %o1,%o2
+ clr %o0
+ retl
+ move %icc,1,%o0
+ .size q_atomic_test_and_set_int,.-q_atomic_test_and_set_int
+
+ .align 4
+ .type q_atomic_test_and_set_acquire_int,#function
+ .global q_atomic_test_and_set_acquire_int
+q_atomic_test_and_set_acquire_int:
+ cas [%o0],%o1,%o2
+ cmp %o1,%o2
+ clr %o0
+ membar #LoadLoad | #LoadStore
+ retl
+ move %icc,1,%o0
+ .size q_atomic_test_and_set_acquire_int,.-q_atomic_test_and_set_acquire_int
+
+ .align 4
+ .type q_atomic_test_and_set_release_int,#function
+ .global q_atomic_test_and_set_release_int
+q_atomic_test_and_set_release_int:
+ membar #LoadStore | #StoreStore
+ cas [%o0],%o1,%o2
+ cmp %o1,%o2
+ clr %o0
+ retl
+ move %icc,1,%o0
+ .size q_atomic_test_and_set_release_int,.-q_atomic_test_and_set_release_int
+
+ .align 4
+ .type q_atomic_test_and_set_ptr,#function
+ .global q_atomic_test_and_set_ptr
+q_atomic_test_and_set_ptr:
+ casx [%o0],%o1,%o2
+ cmp %o1,%o2
+ clr %o0
+ retl
+ move %icc,1,%o0
+ .size q_atomic_test_and_set_ptr,.-q_atomic_test_and_set_ptr
+
+ .align 4
+ .type q_atomic_increment,#function
+ .global q_atomic_increment
+q_atomic_increment:
+q_atomic_increment_retry:
+ ld [%o0],%o3
+ add %o3,1,%o4
+ cas [%o0],%o3,%o4
+ cmp %o3,%o4
+ bne q_atomic_increment_retry
+ nop
+ cmp %o4,-1
+ clr %o0
+ retl
+ movne %icc,1,%o0
+ .size q_atomic_increment,.-q_atomic_increment
+
+ .align 4
+ .type q_atomic_decrement,#function
+ .global q_atomic_decrement
+q_atomic_decrement:
+q_atomic_decrement_retry:
+ ld [%o0],%o3
+ add %o3,-1,%o4
+ cas [%o0],%o3,%o4
+ cmp %o3,%o4
+ bne q_atomic_decrement_retry
+ nop
+ cmp %o4,1
+ clr %o0
+ retl
+ movne %icc,1,%o0
+ .size q_atomic_decrement,.-q_atomic_decrement
+
+ .align 4
+ .type q_atomic_set_int,#function
+ .global q_atomic_set_int
+q_atomic_set_int:
+q_atomic_set_int_retry:
+ ld [%o0],%o2
+ cas [%o0],%o2,%o1
+ cmp %o2,%o1
+ bne q_atomic_set_int_retry
+ nop
+ retl
+ mov %o1,%o0
+ .size q_atomic_set_int,.-q_atomic_set_int
+
+ .align 4
+ .type q_atomic_set_ptr,#function
+ .global q_atomic_set_ptr
+q_atomic_set_ptr:
+q_atomic_set_ptr_retry:
+ ldx [%o0],%o2
+ casx [%o0],%o2,%o1
+ cmp %o2,%o1
+ bne q_atomic_set_ptr_retry
+ nop
+ retl
+ mov %o1,%o0
+ .size q_atomic_set_ptr,.-q_atomic_set_ptr
+
+ .align 4
+ .type q_atomic_fetch_and_add_int,#function
+ .global q_atomic_fetch_and_add_int
+q_atomic_fetch_and_add_int:
+q_atomic_fetch_and_add_int_retry:
+ ld [%o0],%o3
+ add %o3,%o1,%o4
+ cas [%o0],%o3,%o4
+ cmp %o3,%o4
+ bne q_atomic_fetch_and_add_int_retry
+ nop
+ retl
+ mov %o3,%o0
+ .size q_atomic_fetch_and_add_int,.-q_atomic_fetch_and_add_int
+
+ .align 4
+ .type q_atomic_fetch_and_add_acquire_int,#function
+ .global q_atomic_fetch_and_add_acquire_int
+q_atomic_fetch_and_add_acquire_int:
+q_atomic_fetch_and_add_acquire_int_retry:
+ ld [%o0],%o3
+ add %o3,%o1,%o4
+ cas [%o0],%o3,%o4
+ cmp %o3,%o4
+ bne q_atomic_fetch_and_add_acquire_int_retry
+ nop
+ membar #LoadLoad | #LoadStore
+ retl
+ mov %o3,%o0
+ .size q_atomic_fetch_and_add_acquire_int,.-q_atomic_fetch_and_add_acquire_int
+
+ .align 4
+ .type q_atomic_fetch_and_add_release_int,#function
+ .global q_atomic_fetch_and_add_release_int
+q_atomic_fetch_and_add_release_int:
+q_atomic_fetch_and_add_release_int_retry:
+ membar #LoadStore | #StoreStore
+ ld [%o0],%o3
+ add %o3,%o1,%o4
+ cas [%o0],%o3,%o4
+ cmp %o3,%o4
+ bne q_atomic_fetch_and_add_release_int_retry
+ nop
+ retl
+ mov %o3,%o0
+ .size q_atomic_fetch_and_add_release_int,.-q_atomic_fetch_and_add_release_int
+
+ .align 4
+ .type q_atomic_fetch_and_store_acquire_int,#function
+ .global q_atomic_fetch_and_store_acquire_int
+q_atomic_fetch_and_store_acquire_int:
+q_atomic_fetch_and_store_acquire_int_retry:
+ ld [%o0],%o2
+ cas [%o0],%o2,%o1
+ cmp %o2,%o1
+ bne q_atomic_fetch_and_store_acquire_int_retry
+ nop
+ membar #LoadLoad | #LoadStore
+ retl
+ mov %o1,%o0
+ .size q_atomic_fetch_and_store_acquire_int,.-q_atomic_fetch_and_store_acquire_int
+
+ .align 4
+ .type q_atomic_fetch_and_store_release_int,#function
+ .global q_atomic_fetch_and_store_release_int
+q_atomic_fetch_and_store_release_int:
+q_atomic_fetch_and_store_release_int_retry:
+ membar #LoadStore | #StoreStore
+ ld [%o0],%o2
+ cas [%o0],%o2,%o1
+ cmp %o2,%o1
+ bne q_atomic_fetch_and_store_release_int_retry
+ nop
+ retl
+ mov %o1,%o0
+ .size q_atomic_fetch_and_store_release_int,.-q_atomic_fetch_and_store_release_int
+
+ .align 4
+ .type q_atomic_test_and_set_acquire_ptr,#function
+ .global q_atomic_test_and_set_acquire_ptr
+q_atomic_test_and_set_acquire_ptr:
+ casx [%o0],%o1,%o2
+ cmp %o1,%o2
+ clr %o0
+ membar #LoadLoad | #LoadStore
+ retl
+ move %icc,1,%o0
+ .size q_atomic_test_and_set_acquire_ptr,.-q_atomic_test_and_set_acquire_ptr
+
+ .align 4
+ .type q_atomic_test_and_set_release_ptr,#function
+ .global q_atomic_test_and_set_release_ptr
+q_atomic_test_and_set_release_ptr:
+ membar #LoadStore | #StoreStore
+ casx [%o0],%o1,%o2
+ cmp %o1,%o2
+ clr %o0
+ retl
+ move %icc,1,%o0
+ .size q_atomic_test_and_set_release_ptr,.-q_atomic_test_and_set_release_ptr
+
+ .align 4
+ .type q_atomic_fetch_and_store_acquire_ptr,#function
+ .global q_atomic_fetch_and_store_acquire_ptr
+q_atomic_fetch_and_store_acquire_ptr:
+q_atomic_fetch_and_store_acquire_ptr_retry:
+ ldx [%o0],%o2
+ casx [%o0],%o2,%o1
+ cmp %o2,%o1
+ bne q_atomic_fetch_and_store_acquire_ptr_retry
+ nop
+ membar #LoadLoad | #LoadStore
+ retl
+ mov %o1,%o0
+ .size q_atomic_fetch_and_store_acquire_ptr,.-q_atomic_fetch_and_store_acquire_ptr
+
+ .align 4
+ .type q_atomic_fetch_and_store_release_ptr,#function
+ .global q_atomic_fetch_and_store_release_ptr
+q_atomic_fetch_and_store_release_ptr:
+q_atomic_fetch_and_store_release_ptr_retry:
+ membar #LoadStore | #StoreStore
+ ldx [%o0],%o2
+ casx [%o0],%o2,%o1
+ cmp %o2,%o1
+ bne q_atomic_fetch_and_store_release_ptr_retry
+ nop
+ retl
+ mov %o1,%o0
+ .size q_atomic_fetch_and_store_release_ptr,.-q_atomic_fetch_and_store_release_ptr
+
+ .align 4
+ .type q_atomic_fetch_and_add_ptr,#function
+ .global q_atomic_fetch_and_add_ptr
+q_atomic_fetch_and_add_ptr:
+q_atomic_fetch_and_add_ptr_retry:
+ ldx [%o0],%o3
+ add %o3,%o1,%o4
+ casx [%o0],%o3,%o4
+ cmp %o3,%o4
+ bne q_atomic_fetch_and_add_ptr_retry
+ nop
+ retl
+ mov %o3,%o0
+ .size q_atomic_fetch_and_add_ptr,.-q_atomic_fetch_and_add_ptr
+
+ .align 4
+ .type q_atomic_fetch_and_add_acquire_ptr,#function
+ .global q_atomic_fetch_and_add_acquire_ptr
+q_atomic_fetch_and_add_acquire_ptr:
+q_atomic_fetch_and_add_acquire_ptr_retry:
+ ldx [%o0],%o3
+ add %o3,%o1,%o4
+ casx [%o0],%o3,%o4
+ cmp %o3,%o4
+ bne q_atomic_fetch_and_add_acquire_ptr_retry
+ nop
+ membar #LoadLoad | #LoadStore
+ retl
+ mov %o3,%o0
+ .size q_atomic_fetch_and_add_acquire_ptr,.-q_atomic_fetch_and_add_acquire_ptr
+
+ .align 4
+ .type q_atomic_fetch_and_add_release_ptr,#function
+ .global q_atomic_fetch_and_add_release_ptr
+q_atomic_fetch_and_add_release_ptr:
+q_atomic_fetch_and_add_release_ptr_retry:
+ membar #LoadStore | #StoreStore
+ ldx [%o0],%o3
+ add %o3,%o1,%o4
+ casx [%o0],%o3,%o4
+ cmp %o3,%o4
+ bne q_atomic_fetch_and_add_release_ptr_retry
+ nop
+ retl
+ mov %o3,%o0
+ .size q_atomic_fetch_and_add_release_ptr,.-q_atomic_fetch_and_add_release_ptr
diff --git a/src/corelib/arch/sparc/qatomic_sparc.cpp b/src/corelib/arch/sparc/qatomic_sparc.cpp
new file mode 100644
index 0000000000..bb411cd1f1
--- /dev/null
+++ b/src/corelib/arch/sparc/qatomic_sparc.cpp
@@ -0,0 +1,92 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtCore module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QtCore/qatomic.h>
+
+#include <limits.h>
+#include <sched.h>
+
+extern "C" {
+
+int q_atomic_trylock_int(volatile int *addr);
+int q_atomic_trylock_ptr(volatile void *addr);
+
+Q_CORE_EXPORT int q_atomic_lock_int(volatile int *addr)
+{
+ int returnValue = q_atomic_trylock_int(addr);
+
+ if (returnValue == INT_MIN) {
+ do {
+ // spin until we think we can succeed
+ do {
+ sched_yield();
+ returnValue = *addr;
+ } while (returnValue == INT_MIN);
+
+ // try again
+ returnValue = q_atomic_trylock_int(addr);
+ } while (returnValue == INT_MIN);
+ }
+
+ return returnValue;
+}
+
+Q_CORE_EXPORT int q_atomic_lock_ptr(volatile void *addr)
+{
+ int returnValue = q_atomic_trylock_ptr(addr);
+
+ if (returnValue == -1) {
+ do {
+ // spin until we think we can succeed
+ do {
+ sched_yield();
+ returnValue = *reinterpret_cast<volatile int *>(addr);
+ } while (returnValue == -1);
+
+ // try again
+ returnValue = q_atomic_trylock_ptr(addr);
+ } while (returnValue == -1);
+ }
+
+ return returnValue;
+}
+
+} // extern "C"
diff --git a/src/corelib/arch/windows/arch.pri b/src/corelib/arch/windows/arch.pri
new file mode 100644
index 0000000000..d42374b98f
--- /dev/null
+++ b/src/corelib/arch/windows/arch.pri
@@ -0,0 +1,3 @@
+#
+# Windows architecture
+#
diff --git a/src/corelib/arch/x86_64/arch.pri b/src/corelib/arch/x86_64/arch.pri
new file mode 100644
index 0000000000..4145b7b133
--- /dev/null
+++ b/src/corelib/arch/x86_64/arch.pri
@@ -0,0 +1,4 @@
+#
+# AMD64 architecture
+#
+solaris-cc*:SOURCES += $$QT_ARCH_CPP/qatomic_sun.s
diff --git a/src/corelib/arch/x86_64/qatomic_sun.s b/src/corelib/arch/x86_64/qatomic_sun.s
new file mode 100644
index 0000000000..37969e61cb
--- /dev/null
+++ b/src/corelib/arch/x86_64/qatomic_sun.s
@@ -0,0 +1,91 @@
+ .code64
+
+ .globl q_atomic_increment
+ .type q_atomic_increment,@function
+ .section .text, "ax"
+ .align 16
+q_atomic_increment:
+ lock
+ incl (%rdi)
+ setne %al
+ ret
+ .size q_atomic_increment,.-q_atomic_increment
+
+ .globl q_atomic_decrement
+ .type q_atomic_decrement,@function
+ .section .text, "ax"
+ .align 16
+q_atomic_decrement:
+ lock
+ decl (%rdi)
+ setne %al
+ ret
+ .size q_atomic_decrement,.-q_atomic_decrement
+
+ .globl q_atomic_test_and_set_int
+ .type q_atomic_test_and_set_int, @function
+ .section .text, "ax"
+ .align 16
+q_atomic_test_and_set_int:
+ movl %esi,%eax
+ lock
+ cmpxchgl %edx,(%rdi)
+ movl $0,%eax
+ sete %al
+ ret
+ .size q_atomic_test_and_set_int, . - q_atomic_test_and_set_int
+
+ .globl q_atomic_set_int
+ .type q_atomic_set_int,@function
+ .section .text, "ax"
+ .align 16
+q_atomic_set_int:
+ xchgl %esi,(%rdi)
+ movl %esi,%eax
+ ret
+ .size q_atomic_set_int,.-q_atomic_set_int
+
+ .globl q_atomic_fetch_and_add_int
+ .type q_atomic_fetch_and_add_int,@function
+ .section .text, "ax"
+ .align 16
+q_atomic_fetch_and_add_int:
+ lock
+ xaddl %esi,(%rdi)
+ movl %esi, %eax
+ ret
+ .size q_atomic_fetch_and_add_int,.-q_atomic_fetch_and_add_int
+
+ .globl q_atomic_test_and_set_ptr
+ .type q_atomic_test_and_set_ptr, @function
+ .section .text, "ax"
+ .align 16
+q_atomic_test_and_set_ptr:
+ movq %rsi,%rax
+ lock
+ cmpxchgq %rdx,(%rdi)
+ movq $0, %rax
+ sete %al
+ ret
+ .size q_atomic_test_and_set_ptr, . - q_atomic_test_and_set_ptr
+
+ .globl q_atomic_set_ptr
+ .type q_atomic_set_ptr,@function
+ .section .text, "ax"
+ .align 16
+q_atomic_set_ptr:
+ xchgq %rsi,(%rdi)
+ movq %rsi,%rax
+ ret
+ .size q_atomic_set_ptr,.-q_atomic_set_ptr
+
+ .globl q_atomic_fetch_and_add_ptr
+ .type q_atomic_fetch_and_add_ptr,@function
+ .section .text, "ax"
+ .align 16
+q_atomic_fetch_and_add_ptr:
+ lock
+ xaddq %rsi,(%rdi)
+ movq %rsi,%rax
+ ret
+ .size q_atomic_fetch_and_add_ptr,.-q_atomic_fetch_and_add_ptr