From a0f69c0f6bc1cd90fe07ce6a3f85b6dfd6a25ed5 Mon Sep 17 00:00:00 2001 From: "Bradley T. Hughes" Date: Tue, 21 Sep 2010 12:37:43 +0200 Subject: Move symbian specific qatomic_generic_armv6.cpp Put it in src/corelib/arch/symbian/ instead of src/corelib/arch/armv6/ Reviewed-by: thiago --- src/corelib/arch/armv6/qatomic_generic_armv6.cpp | 472 --------------------- src/corelib/arch/symbian/arch.pri | 2 +- src/corelib/arch/symbian/qatomic_generic_armv6.cpp | 472 +++++++++++++++++++++ 3 files changed, 473 insertions(+), 473 deletions(-) delete mode 100644 src/corelib/arch/armv6/qatomic_generic_armv6.cpp create mode 100644 src/corelib/arch/symbian/qatomic_generic_armv6.cpp diff --git a/src/corelib/arch/armv6/qatomic_generic_armv6.cpp b/src/corelib/arch/armv6/qatomic_generic_armv6.cpp deleted file mode 100644 index 39d966a..0000000 --- a/src/corelib/arch/armv6/qatomic_generic_armv6.cpp +++ /dev/null @@ -1,472 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying -** this package. -** -** 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.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** If you have questions regarding the use of this file, please contact -** Nokia at qt-info@nokia.com. -** -** -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -** This file implements the generic atomics interface using ARMv6 assembly -** instructions. It is more efficent than the inline versions when Qt is -** built for the THUMB instruction set, as the required instructions are -** only available in ARM state. -****************************************************************************/ - -#include - -#ifdef QT_HAVE_ARMV6 -#ifndef SYMBIAN_E32_ATOMIC_API - -QT_BEGIN_NAMESPACE - -QT_USE_NAMESPACE - -#ifdef Q_CC_RVCT -#pragma push -#pragma arm -Q_CORE_EXPORT asm -bool QBasicAtomicInt_testAndSetRelaxed(volatile int *_q_value, int expectedValue, int newValue) -{ - CODE32 - //fall through -} -Q_CORE_EXPORT asm -bool QBasicAtomicInt_testAndSetAcquire(volatile int *_q_value, int expectedValue, int newValue) -{ - CODE32 - //fall through -} -Q_CORE_EXPORT asm -bool QBasicAtomicInt_testAndSetRelease(volatile int *_q_value, int expectedValue, int newValue) -{ - CODE32 - //fall through -} -Q_CORE_EXPORT asm -bool QBasicAtomicInt_testAndSetOrdered(volatile int *_q_value, int expectedValue, int newValue) -{ - CODE32 - //R0 = _q_value - //R1 = expectedValue - //R2 = newValue -retry_testAndSetOrdered - LDREX r3,[r0] //r3 = *_q_value - EORS r3,r3,r1 //if (r3 == expectedValue) { - STREXEQ r3,r2,[r0] //*_q_value = newvalue, r3 = error - TEQEQ r3,#1 //if error - BEQ retry_testAndSetOrdered //then goto retry } - RSBS r0,r3,#1 //return (r3 == 0) - MOVCC r0,#0 - BX r14 -} - -Q_CORE_EXPORT asm -int QBasicAtomicInt_fetchAndStoreRelaxed(volatile int *_q_value, int newValue) -{ - CODE32 - //fall through -} -Q_CORE_EXPORT asm -int QBasicAtomicInt_fetchAndStoreAcquire(volatile int *_q_value, int newValue) -{ - CODE32 - //fall through -} -Q_CORE_EXPORT asm -int QBasicAtomicInt_fetchAndStoreRelease(volatile int *_q_value, int newValue) -{ - CODE32 - //fall through -} -Q_CORE_EXPORT asm -int QBasicAtomicInt_fetchAndStoreOrdered(volatile int *_q_value, int newValue) -{ - CODE32 -//R0 = _q_value -//R1 = newValue -retry_fetchAndStoreOrdered - LDREX r3,[r0] //r3 = *_q_value - STREX r2,r1,[r0] //*_q_value = newValue, r2 = error - TEQ r2,#0 //if error - BNE retry_fetchAndStoreOrdered //then goto retry - MOV r0,r3 //return r3 - BX r14 -} - -Q_CORE_EXPORT asm -int QBasicAtomicInt_fetchAndAddRelaxed(volatile int *_q_value, int valueToAdd) -{ - CODE32 - //fall through -} -Q_CORE_EXPORT asm -int QBasicAtomicInt_fetchAndAddAcquire(volatile int *_q_value, int valueToAdd) -{ - CODE32 - //fall through -} -Q_CORE_EXPORT asm -int QBasicAtomicInt_fetchAndAddRelease(volatile int *_q_value, int valueToAdd) -{ - CODE32 - //fall through -} -Q_CORE_EXPORT asm -int QBasicAtomicInt_fetchAndAddOrdered(volatile int *_q_value, int valueToAdd) -{ - CODE32 - //R0 = _q_value - //R1 = valueToAdd - STMDB sp!,{r12,lr} -retry_fetchAndAddOrdered - LDREX r2,[r0] //r2 = *_q_value - ADD r3,r2,r1 //r3 = r2 + r1 - STREX r12,r3,[r0] //*_q_value = r3, r12 = error - TEQ r12,#0 //if error - BNE retry_fetchAndAddOrdered //then retry - MOV r0,r2 //return r2 - LDMIA sp!,{r12,pc} -} - -Q_CORE_EXPORT asm -bool QBasicAtomicPointer_testAndSetRelaxed(void * volatile *_q_value, - void *expectedValue, - void *newValue) -{ - CODE32 - //fall through -} -Q_CORE_EXPORT asm -bool QBasicAtomicPointer_testAndSetRelease(void * volatile *_q_value, - void *expectedValue, - void *newValue) -{ - CODE32 - //fall through -} -Q_CORE_EXPORT asm -bool QBasicAtomicPointer_testAndSetAcquire(void * volatile *_q_value, - void *expectedValue, - void *newValue) -{ - CODE32 - //fall through -} -Q_CORE_EXPORT asm -bool QBasicAtomicPointer_testAndSetOrdered(void * volatile *_q_value, - void *expectedValue, - void *newValue) -{ - CODE32 - //R0 = _q_value - //R1 = expectedValue - //R2 = newValue -retryPointer_testAndSetOrdered - LDREX r3,[r0] //r3 = *_q_value - EORS r3,r3,r1 //if (r3 == expectedValue) { - STREXEQ r3,r2,[r0] //*_q_value = newvalue, r3 = error - TEQEQ r3,#1 //if error - BEQ retryPointer_testAndSetOrdered //then goto retry } - RSBS r0,r3,#1 //return (r3 == 0) - MOVCC r0,#0 - BX r14 -} - -Q_CORE_EXPORT asm -void *QBasicAtomicPointer_fetchAndStoreRelaxed(void * volatile *_q_value, void *newValue) -{ - CODE32 - //fall through -} -Q_CORE_EXPORT asm -void *QBasicAtomicPointer_fetchAndStoreAcquire(void * volatile *_q_value, void *newValue) -{ - CODE32 - //fall through -} -Q_CORE_EXPORT asm -void *QBasicAtomicPointer_fetchAndStoreRelease(void * volatile *_q_value, void *newValue) -{ - CODE32 - //fall through -} -Q_CORE_EXPORT asm -void *QBasicAtomicPointer_fetchAndStoreOrdered(void * volatile *_q_value, void *newValue) -{ - CODE32 - //R0 = _q_value - //R1 = newValue -retryPointer_fetchAndStoreOrdered - LDREX r3,[r0] //r3 = *_q_value - STREX r2,r1,[r0] //*_q_value = newValue, r2 = error - TEQ r2,#0 //if error - BNE retryPointer_fetchAndStoreOrdered //then goto retry - MOV r0,r3 //return r3 - BX r14 -} - -Q_CORE_EXPORT asm -void *QBasicAtomicPointer_fetchAndAddRelaxed(void * volatile *_q_value, qptrdiff valueToAdd) -{ - CODE32 - //fall through -} -Q_CORE_EXPORT asm -void *QBasicAtomicPointer_fetchAndAddRelease(void * volatile *_q_value, qptrdiff valueToAdd) -{ - CODE32 - //fall through -} -Q_CORE_EXPORT asm -void *QBasicAtomicPointer_fetchAndAddAcquire(void * volatile *_q_value, qptrdiff valueToAdd) -{ - CODE32 - //fall through -} -Q_CORE_EXPORT asm -void *QBasicAtomicPointer_fetchAndAddOrdered(void * volatile *_q_value, qptrdiff valueToAdd) -{ - CODE32 - //R0 = _q_value - //R1 = valueToAdd - STMDB sp!,{r12,lr} -retryPointer_fetchAndAddOrdered - LDREX r2,[r0] //r2 = *_q_value - ADD r3,r2,r1 //r3 = r2 + r1 - STREX r12,r3,[r0] //*_q_value = r3, r12 = error - TEQ r12,#0 //if error - BNE retryPointer_fetchAndAddOrdered //then retry - MOV r0,r2 //return r2 - LDMIA sp!,{r12,pc} -} - -#pragma pop -#elif defined (Q_CC_GCCE) -Q_CORE_EXPORT __declspec( naked ) -bool QBasicAtomicInt_testAndSetRelaxed(volatile int *_q_value, int expectedValue, int newValue) -{ - //fall through -} -Q_CORE_EXPORT __declspec( naked ) -bool QBasicAtomicInt_testAndSetAcquire(volatile int *_q_value, int expectedValue, int newValue) -{ - //fall through -} -Q_CORE_EXPORT __declspec( naked ) -bool QBasicAtomicInt_testAndSetRelease(volatile int *_q_value, int expectedValue, int newValue) -{ - //fall through -} -Q_CORE_EXPORT __declspec( naked ) -bool QBasicAtomicInt_testAndSetOrdered(volatile int *_q_value, int expectedValue, int newValue) -{ - //R0 = _q_value - //R1 = expectedValue - //R2 = newValue - asm("retry_testAndSetOrdered:"); - asm(" LDREX r3,[r0]"); //r3 = *_q_value - asm(" EORS r3,r3,r1"); //if (r3 == expectedValue) { - asm(" STREXEQ r3,r2,[r0]"); //*_q_value = newvalue, r3 = error - asm(" TEQEQ r3,#1"); //if error - asm(" BEQ retry_testAndSetOrdered"); //then goto retry } - asm(" RSBS r0,r3,#1"); //return (r3 == 0) - asm(" MOVCC r0,#0"); - asm(" BX r14"); -} - -Q_CORE_EXPORT __declspec( naked ) -int QBasicAtomicInt_fetchAndStoreRelaxed(volatile int *_q_value, int newValue) -{ - //fall through -} -Q_CORE_EXPORT __declspec( naked ) -int QBasicAtomicInt_fetchAndStoreAcquire(volatile int *_q_value, int newValue) -{ - //fall through -} -Q_CORE_EXPORT __declspec( naked ) -int QBasicAtomicInt_fetchAndStoreRelease(volatile int *_q_value, int newValue) -{ - //fall through -} -Q_CORE_EXPORT __declspec( naked ) -int QBasicAtomicInt_fetchAndStoreOrdered(volatile int *_q_value, int newValue) -{ -//R0 = _q_value -//R1 = newValue - asm("retry_fetchAndStoreOrdered:"); - asm(" LDREX r3,[r0]"); //r3 = *_q_value - asm(" STREX r2,r1,[r0]"); //*_q_value = newValue, r2 = error - asm(" TEQ r2,#0"); //if error - asm(" BNE retry_fetchAndStoreOrdered"); //then goto retry - asm(" MOV r0,r3"); //return r3 - asm(" BX r14"); -} - -Q_CORE_EXPORT __declspec( naked ) -int QBasicAtomicInt_fetchAndAddRelaxed(volatile int *_q_value, int valueToAdd) -{ - //fall through -} -Q_CORE_EXPORT __declspec( naked ) -int QBasicAtomicInt_fetchAndAddAcquire(volatile int *_q_value, int valueToAdd) -{ - //fall through -} -Q_CORE_EXPORT __declspec( naked ) -int QBasicAtomicInt_fetchAndAddRelease(volatile int *_q_value, int valueToAdd) -{ - //fall through -} -Q_CORE_EXPORT __declspec( naked ) -int QBasicAtomicInt_fetchAndAddOrdered(volatile int *_q_value, int valueToAdd) -{ - //R0 = _q_value - //R1 = valueToAdd - asm(" STMDB sp!,{r12,lr}"); - asm("retry_fetchAndAddOrdered:"); - asm(" LDREX r2,[r0]"); //r2 = *_q_value - asm(" ADD r3,r2,r1 "); //r3 = r2 + r1 - asm(" STREX r12,r3,[r0]"); //*_q_value = r3, r12 = error - asm(" TEQ r12,#0"); //if error - asm(" BNE retry_fetchAndAddOrdered"); //then retry - asm(" MOV r0,r2"); //return r2 - asm(" LDMIA sp!,{r12,pc}"); -} - -Q_CORE_EXPORT __declspec( naked ) -bool QBasicAtomicPointer_testAndSetRelaxed(void * volatile *_q_value, - void *expectedValue, - void *newValue) -{ - //fall through -} -Q_CORE_EXPORT __declspec( naked ) -bool QBasicAtomicPointer_testAndSetRelease(void * volatile *_q_value, - void *expectedValue, - void *newValue) -{ - //fall through -} -Q_CORE_EXPORT __declspec( naked ) -bool QBasicAtomicPointer_testAndSetAcquire(void * volatile *_q_value, - void *expectedValue, - void *newValue) -{ - //fall through -} -Q_CORE_EXPORT __declspec( naked ) -bool QBasicAtomicPointer_testAndSetOrdered(void * volatile *_q_value, - void *expectedValue, - void *newValue) -{ - //R0 = _q_value - //R1 = expectedValue - //R2 = newValue - asm("retryPointer_testAndSetOrdered:"); - asm(" LDREX r3,[r0]"); //r3 = *_q_value - asm(" EORS r3,r3,r1"); //if (r3 == expectedValue) { - asm(" STREXEQ r3,r2,[r0]"); //*_q_value = newvalue, r3 = error - asm(" TEQEQ r3,#1"); //if error - asm(" BEQ retryPointer_testAndSetOrdered"); //then goto retry } - asm(" RSBS r0,r3,#1"); //return (r3 == 0) - asm(" MOVCC r0,#0"); - asm(" BX r14"); -} - -Q_CORE_EXPORT __declspec( naked ) -void *QBasicAtomicPointer_fetchAndStoreRelaxed(void * volatile *_q_value, void *newValue) -{ - //fall through -} -Q_CORE_EXPORT __declspec( naked ) -void *QBasicAtomicPointer_fetchAndStoreAcquire(void * volatile *_q_value, void *newValue) -{ - //fall through -} -Q_CORE_EXPORT __declspec( naked ) -void *QBasicAtomicPointer_fetchAndStoreRelease(void * volatile *_q_value, void *newValue) -{ - //fall through -} -Q_CORE_EXPORT __declspec( naked ) -void *QBasicAtomicPointer_fetchAndStoreOrdered(void * volatile *_q_value, void *newValue) -{ - //R0 = _q_value - //R1 = newValue - asm("retryPointer_fetchAndStoreOrdered:"); - asm(" LDREX r3,[r0]"); //r3 = *_q_value - asm(" STREX r2,r1,[r0]"); //*_q_value = newValue, r2 = error - asm(" TEQ r2,#0"); //if error - asm(" BNE retryPointer_fetchAndStoreOrdered"); //then goto retry - asm(" MOV r0,r3"); //return r3 - asm(" BX r14"); -} - -Q_CORE_EXPORT __declspec( naked ) -void *QBasicAtomicPointer_fetchAndAddRelaxed(void * volatile *_q_value, qptrdiff valueToAdd) -{ - //fall through -} -Q_CORE_EXPORT __declspec( naked ) -void *QBasicAtomicPointer_fetchAndAddRelease(void * volatile *_q_value, qptrdiff valueToAdd) -{ - //fall through -} -Q_CORE_EXPORT __declspec( naked ) -void *QBasicAtomicPointer_fetchAndAddAcquire(void * volatile *_q_value, qptrdiff valueToAdd) -{ - //fall through -} -Q_CORE_EXPORT __declspec( naked ) -void *QBasicAtomicPointer_fetchAndAddOrdered(void * volatile *_q_value, qptrdiff valueToAdd) -{ - //R0 = _q_value - //R1 = valueToAdd - asm(" STMDB sp!,{r12,lr}"); - asm("retryPointer_fetchAndAddOrdered:"); - asm(" LDREX r2,[r0]"); //r2 = *_q_value - asm(" ADD r3,r2,r1"); //r3 = r2 + r1 - asm(" STREX r12,r3,[r0]"); //*_q_value = r3, r12 = error - asm(" TEQ r12,#0"); //if error - asm(" BNE retryPointer_fetchAndAddOrdered"); //then retry - asm(" MOV r0,r2"); //return r2 - asm(" LDMIA sp!,{r12,pc}"); -} -#else -#error unknown arm compiler -#endif -QT_END_NAMESPACE -#endif -#endif diff --git a/src/corelib/arch/symbian/arch.pri b/src/corelib/arch/symbian/arch.pri index 3ef1c9e..84a4984 100644 --- a/src/corelib/arch/symbian/arch.pri +++ b/src/corelib/arch/symbian/arch.pri @@ -2,4 +2,4 @@ # Symbian architecture # SOURCES += $$QT_ARCH_CPP/qatomic_symbian.cpp \ - $$QT_ARCH_CPP/../armv6/qatomic_generic_armv6.cpp + $$QT_ARCH_CPP/qatomic_generic_armv6.cpp diff --git a/src/corelib/arch/symbian/qatomic_generic_armv6.cpp b/src/corelib/arch/symbian/qatomic_generic_armv6.cpp new file mode 100644 index 0000000..39d966a --- /dev/null +++ b/src/corelib/arch/symbian/qatomic_generic_armv6.cpp @@ -0,0 +1,472 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying +** this package. +** +** 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.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +** This file implements the generic atomics interface using ARMv6 assembly +** instructions. It is more efficent than the inline versions when Qt is +** built for the THUMB instruction set, as the required instructions are +** only available in ARM state. +****************************************************************************/ + +#include + +#ifdef QT_HAVE_ARMV6 +#ifndef SYMBIAN_E32_ATOMIC_API + +QT_BEGIN_NAMESPACE + +QT_USE_NAMESPACE + +#ifdef Q_CC_RVCT +#pragma push +#pragma arm +Q_CORE_EXPORT asm +bool QBasicAtomicInt_testAndSetRelaxed(volatile int *_q_value, int expectedValue, int newValue) +{ + CODE32 + //fall through +} +Q_CORE_EXPORT asm +bool QBasicAtomicInt_testAndSetAcquire(volatile int *_q_value, int expectedValue, int newValue) +{ + CODE32 + //fall through +} +Q_CORE_EXPORT asm +bool QBasicAtomicInt_testAndSetRelease(volatile int *_q_value, int expectedValue, int newValue) +{ + CODE32 + //fall through +} +Q_CORE_EXPORT asm +bool QBasicAtomicInt_testAndSetOrdered(volatile int *_q_value, int expectedValue, int newValue) +{ + CODE32 + //R0 = _q_value + //R1 = expectedValue + //R2 = newValue +retry_testAndSetOrdered + LDREX r3,[r0] //r3 = *_q_value + EORS r3,r3,r1 //if (r3 == expectedValue) { + STREXEQ r3,r2,[r0] //*_q_value = newvalue, r3 = error + TEQEQ r3,#1 //if error + BEQ retry_testAndSetOrdered //then goto retry } + RSBS r0,r3,#1 //return (r3 == 0) + MOVCC r0,#0 + BX r14 +} + +Q_CORE_EXPORT asm +int QBasicAtomicInt_fetchAndStoreRelaxed(volatile int *_q_value, int newValue) +{ + CODE32 + //fall through +} +Q_CORE_EXPORT asm +int QBasicAtomicInt_fetchAndStoreAcquire(volatile int *_q_value, int newValue) +{ + CODE32 + //fall through +} +Q_CORE_EXPORT asm +int QBasicAtomicInt_fetchAndStoreRelease(volatile int *_q_value, int newValue) +{ + CODE32 + //fall through +} +Q_CORE_EXPORT asm +int QBasicAtomicInt_fetchAndStoreOrdered(volatile int *_q_value, int newValue) +{ + CODE32 +//R0 = _q_value +//R1 = newValue +retry_fetchAndStoreOrdered + LDREX r3,[r0] //r3 = *_q_value + STREX r2,r1,[r0] //*_q_value = newValue, r2 = error + TEQ r2,#0 //if error + BNE retry_fetchAndStoreOrdered //then goto retry + MOV r0,r3 //return r3 + BX r14 +} + +Q_CORE_EXPORT asm +int QBasicAtomicInt_fetchAndAddRelaxed(volatile int *_q_value, int valueToAdd) +{ + CODE32 + //fall through +} +Q_CORE_EXPORT asm +int QBasicAtomicInt_fetchAndAddAcquire(volatile int *_q_value, int valueToAdd) +{ + CODE32 + //fall through +} +Q_CORE_EXPORT asm +int QBasicAtomicInt_fetchAndAddRelease(volatile int *_q_value, int valueToAdd) +{ + CODE32 + //fall through +} +Q_CORE_EXPORT asm +int QBasicAtomicInt_fetchAndAddOrdered(volatile int *_q_value, int valueToAdd) +{ + CODE32 + //R0 = _q_value + //R1 = valueToAdd + STMDB sp!,{r12,lr} +retry_fetchAndAddOrdered + LDREX r2,[r0] //r2 = *_q_value + ADD r3,r2,r1 //r3 = r2 + r1 + STREX r12,r3,[r0] //*_q_value = r3, r12 = error + TEQ r12,#0 //if error + BNE retry_fetchAndAddOrdered //then retry + MOV r0,r2 //return r2 + LDMIA sp!,{r12,pc} +} + +Q_CORE_EXPORT asm +bool QBasicAtomicPointer_testAndSetRelaxed(void * volatile *_q_value, + void *expectedValue, + void *newValue) +{ + CODE32 + //fall through +} +Q_CORE_EXPORT asm +bool QBasicAtomicPointer_testAndSetRelease(void * volatile *_q_value, + void *expectedValue, + void *newValue) +{ + CODE32 + //fall through +} +Q_CORE_EXPORT asm +bool QBasicAtomicPointer_testAndSetAcquire(void * volatile *_q_value, + void *expectedValue, + void *newValue) +{ + CODE32 + //fall through +} +Q_CORE_EXPORT asm +bool QBasicAtomicPointer_testAndSetOrdered(void * volatile *_q_value, + void *expectedValue, + void *newValue) +{ + CODE32 + //R0 = _q_value + //R1 = expectedValue + //R2 = newValue +retryPointer_testAndSetOrdered + LDREX r3,[r0] //r3 = *_q_value + EORS r3,r3,r1 //if (r3 == expectedValue) { + STREXEQ r3,r2,[r0] //*_q_value = newvalue, r3 = error + TEQEQ r3,#1 //if error + BEQ retryPointer_testAndSetOrdered //then goto retry } + RSBS r0,r3,#1 //return (r3 == 0) + MOVCC r0,#0 + BX r14 +} + +Q_CORE_EXPORT asm +void *QBasicAtomicPointer_fetchAndStoreRelaxed(void * volatile *_q_value, void *newValue) +{ + CODE32 + //fall through +} +Q_CORE_EXPORT asm +void *QBasicAtomicPointer_fetchAndStoreAcquire(void * volatile *_q_value, void *newValue) +{ + CODE32 + //fall through +} +Q_CORE_EXPORT asm +void *QBasicAtomicPointer_fetchAndStoreRelease(void * volatile *_q_value, void *newValue) +{ + CODE32 + //fall through +} +Q_CORE_EXPORT asm +void *QBasicAtomicPointer_fetchAndStoreOrdered(void * volatile *_q_value, void *newValue) +{ + CODE32 + //R0 = _q_value + //R1 = newValue +retryPointer_fetchAndStoreOrdered + LDREX r3,[r0] //r3 = *_q_value + STREX r2,r1,[r0] //*_q_value = newValue, r2 = error + TEQ r2,#0 //if error + BNE retryPointer_fetchAndStoreOrdered //then goto retry + MOV r0,r3 //return r3 + BX r14 +} + +Q_CORE_EXPORT asm +void *QBasicAtomicPointer_fetchAndAddRelaxed(void * volatile *_q_value, qptrdiff valueToAdd) +{ + CODE32 + //fall through +} +Q_CORE_EXPORT asm +void *QBasicAtomicPointer_fetchAndAddRelease(void * volatile *_q_value, qptrdiff valueToAdd) +{ + CODE32 + //fall through +} +Q_CORE_EXPORT asm +void *QBasicAtomicPointer_fetchAndAddAcquire(void * volatile *_q_value, qptrdiff valueToAdd) +{ + CODE32 + //fall through +} +Q_CORE_EXPORT asm +void *QBasicAtomicPointer_fetchAndAddOrdered(void * volatile *_q_value, qptrdiff valueToAdd) +{ + CODE32 + //R0 = _q_value + //R1 = valueToAdd + STMDB sp!,{r12,lr} +retryPointer_fetchAndAddOrdered + LDREX r2,[r0] //r2 = *_q_value + ADD r3,r2,r1 //r3 = r2 + r1 + STREX r12,r3,[r0] //*_q_value = r3, r12 = error + TEQ r12,#0 //if error + BNE retryPointer_fetchAndAddOrdered //then retry + MOV r0,r2 //return r2 + LDMIA sp!,{r12,pc} +} + +#pragma pop +#elif defined (Q_CC_GCCE) +Q_CORE_EXPORT __declspec( naked ) +bool QBasicAtomicInt_testAndSetRelaxed(volatile int *_q_value, int expectedValue, int newValue) +{ + //fall through +} +Q_CORE_EXPORT __declspec( naked ) +bool QBasicAtomicInt_testAndSetAcquire(volatile int *_q_value, int expectedValue, int newValue) +{ + //fall through +} +Q_CORE_EXPORT __declspec( naked ) +bool QBasicAtomicInt_testAndSetRelease(volatile int *_q_value, int expectedValue, int newValue) +{ + //fall through +} +Q_CORE_EXPORT __declspec( naked ) +bool QBasicAtomicInt_testAndSetOrdered(volatile int *_q_value, int expectedValue, int newValue) +{ + //R0 = _q_value + //R1 = expectedValue + //R2 = newValue + asm("retry_testAndSetOrdered:"); + asm(" LDREX r3,[r0]"); //r3 = *_q_value + asm(" EORS r3,r3,r1"); //if (r3 == expectedValue) { + asm(" STREXEQ r3,r2,[r0]"); //*_q_value = newvalue, r3 = error + asm(" TEQEQ r3,#1"); //if error + asm(" BEQ retry_testAndSetOrdered"); //then goto retry } + asm(" RSBS r0,r3,#1"); //return (r3 == 0) + asm(" MOVCC r0,#0"); + asm(" BX r14"); +} + +Q_CORE_EXPORT __declspec( naked ) +int QBasicAtomicInt_fetchAndStoreRelaxed(volatile int *_q_value, int newValue) +{ + //fall through +} +Q_CORE_EXPORT __declspec( naked ) +int QBasicAtomicInt_fetchAndStoreAcquire(volatile int *_q_value, int newValue) +{ + //fall through +} +Q_CORE_EXPORT __declspec( naked ) +int QBasicAtomicInt_fetchAndStoreRelease(volatile int *_q_value, int newValue) +{ + //fall through +} +Q_CORE_EXPORT __declspec( naked ) +int QBasicAtomicInt_fetchAndStoreOrdered(volatile int *_q_value, int newValue) +{ +//R0 = _q_value +//R1 = newValue + asm("retry_fetchAndStoreOrdered:"); + asm(" LDREX r3,[r0]"); //r3 = *_q_value + asm(" STREX r2,r1,[r0]"); //*_q_value = newValue, r2 = error + asm(" TEQ r2,#0"); //if error + asm(" BNE retry_fetchAndStoreOrdered"); //then goto retry + asm(" MOV r0,r3"); //return r3 + asm(" BX r14"); +} + +Q_CORE_EXPORT __declspec( naked ) +int QBasicAtomicInt_fetchAndAddRelaxed(volatile int *_q_value, int valueToAdd) +{ + //fall through +} +Q_CORE_EXPORT __declspec( naked ) +int QBasicAtomicInt_fetchAndAddAcquire(volatile int *_q_value, int valueToAdd) +{ + //fall through +} +Q_CORE_EXPORT __declspec( naked ) +int QBasicAtomicInt_fetchAndAddRelease(volatile int *_q_value, int valueToAdd) +{ + //fall through +} +Q_CORE_EXPORT __declspec( naked ) +int QBasicAtomicInt_fetchAndAddOrdered(volatile int *_q_value, int valueToAdd) +{ + //R0 = _q_value + //R1 = valueToAdd + asm(" STMDB sp!,{r12,lr}"); + asm("retry_fetchAndAddOrdered:"); + asm(" LDREX r2,[r0]"); //r2 = *_q_value + asm(" ADD r3,r2,r1 "); //r3 = r2 + r1 + asm(" STREX r12,r3,[r0]"); //*_q_value = r3, r12 = error + asm(" TEQ r12,#0"); //if error + asm(" BNE retry_fetchAndAddOrdered"); //then retry + asm(" MOV r0,r2"); //return r2 + asm(" LDMIA sp!,{r12,pc}"); +} + +Q_CORE_EXPORT __declspec( naked ) +bool QBasicAtomicPointer_testAndSetRelaxed(void * volatile *_q_value, + void *expectedValue, + void *newValue) +{ + //fall through +} +Q_CORE_EXPORT __declspec( naked ) +bool QBasicAtomicPointer_testAndSetRelease(void * volatile *_q_value, + void *expectedValue, + void *newValue) +{ + //fall through +} +Q_CORE_EXPORT __declspec( naked ) +bool QBasicAtomicPointer_testAndSetAcquire(void * volatile *_q_value, + void *expectedValue, + void *newValue) +{ + //fall through +} +Q_CORE_EXPORT __declspec( naked ) +bool QBasicAtomicPointer_testAndSetOrdered(void * volatile *_q_value, + void *expectedValue, + void *newValue) +{ + //R0 = _q_value + //R1 = expectedValue + //R2 = newValue + asm("retryPointer_testAndSetOrdered:"); + asm(" LDREX r3,[r0]"); //r3 = *_q_value + asm(" EORS r3,r3,r1"); //if (r3 == expectedValue) { + asm(" STREXEQ r3,r2,[r0]"); //*_q_value = newvalue, r3 = error + asm(" TEQEQ r3,#1"); //if error + asm(" BEQ retryPointer_testAndSetOrdered"); //then goto retry } + asm(" RSBS r0,r3,#1"); //return (r3 == 0) + asm(" MOVCC r0,#0"); + asm(" BX r14"); +} + +Q_CORE_EXPORT __declspec( naked ) +void *QBasicAtomicPointer_fetchAndStoreRelaxed(void * volatile *_q_value, void *newValue) +{ + //fall through +} +Q_CORE_EXPORT __declspec( naked ) +void *QBasicAtomicPointer_fetchAndStoreAcquire(void * volatile *_q_value, void *newValue) +{ + //fall through +} +Q_CORE_EXPORT __declspec( naked ) +void *QBasicAtomicPointer_fetchAndStoreRelease(void * volatile *_q_value, void *newValue) +{ + //fall through +} +Q_CORE_EXPORT __declspec( naked ) +void *QBasicAtomicPointer_fetchAndStoreOrdered(void * volatile *_q_value, void *newValue) +{ + //R0 = _q_value + //R1 = newValue + asm("retryPointer_fetchAndStoreOrdered:"); + asm(" LDREX r3,[r0]"); //r3 = *_q_value + asm(" STREX r2,r1,[r0]"); //*_q_value = newValue, r2 = error + asm(" TEQ r2,#0"); //if error + asm(" BNE retryPointer_fetchAndStoreOrdered"); //then goto retry + asm(" MOV r0,r3"); //return r3 + asm(" BX r14"); +} + +Q_CORE_EXPORT __declspec( naked ) +void *QBasicAtomicPointer_fetchAndAddRelaxed(void * volatile *_q_value, qptrdiff valueToAdd) +{ + //fall through +} +Q_CORE_EXPORT __declspec( naked ) +void *QBasicAtomicPointer_fetchAndAddRelease(void * volatile *_q_value, qptrdiff valueToAdd) +{ + //fall through +} +Q_CORE_EXPORT __declspec( naked ) +void *QBasicAtomicPointer_fetchAndAddAcquire(void * volatile *_q_value, qptrdiff valueToAdd) +{ + //fall through +} +Q_CORE_EXPORT __declspec( naked ) +void *QBasicAtomicPointer_fetchAndAddOrdered(void * volatile *_q_value, qptrdiff valueToAdd) +{ + //R0 = _q_value + //R1 = valueToAdd + asm(" STMDB sp!,{r12,lr}"); + asm("retryPointer_fetchAndAddOrdered:"); + asm(" LDREX r2,[r0]"); //r2 = *_q_value + asm(" ADD r3,r2,r1"); //r3 = r2 + r1 + asm(" STREX r12,r3,[r0]"); //*_q_value = r3, r12 = error + asm(" TEQ r12,#0"); //if error + asm(" BNE retryPointer_fetchAndAddOrdered"); //then retry + asm(" MOV r0,r2"); //return r2 + asm(" LDMIA sp!,{r12,pc}"); +} +#else +#error unknown arm compiler +#endif +QT_END_NAMESPACE +#endif +#endif -- cgit v0.12 From 1c0b32371f912c76ad6a943d6bdab6f024b7ee34 Mon Sep 17 00:00:00 2001 From: "Bradley T. Hughes" Date: Wed, 22 Sep 2010 16:18:27 +0200 Subject: Copy src/corelib/arch/qatomic_arm.h to src/corelib/arch/qatomic_armv5.h ... in preparation for the next commit Reviewed-by: thiago --- src/corelib/arch/qatomic_armv5.h | 431 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 431 insertions(+) create mode 100644 src/corelib/arch/qatomic_armv5.h diff --git a/src/corelib/arch/qatomic_armv5.h b/src/corelib/arch/qatomic_armv5.h new file mode 100644 index 0000000..9df02a2 --- /dev/null +++ b/src/corelib/arch/qatomic_armv5.h @@ -0,0 +1,431 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying +** this package. +** +** 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.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@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 +Q_INLINE_TEMPLATE bool QBasicAtomicPointer::isTestAndSetNative() +{ return false; } +template +Q_INLINE_TEMPLATE bool QBasicAtomicPointer::isTestAndSetWaitFree() +{ return false; } + +#define Q_ATOMIC_POINTER_FETCH_AND_STORE_IS_ALWAYS_NATIVE +#define Q_ATOMIC_POINTER_FETCH_AND_STORE_IS_WAIT_FREE + +template +Q_INLINE_TEMPLATE bool QBasicAtomicPointer::isFetchAndStoreNative() +{ return true; } +template +Q_INLINE_TEMPLATE bool QBasicAtomicPointer::isFetchAndStoreWaitFree() +{ return true; } + +#define Q_ATOMIC_POINTER_FETCH_AND_ADD_IS_NOT_NATIVE + +template +Q_INLINE_TEMPLATE bool QBasicAtomicPointer::isFetchAndAddNative() +{ return false; } +template +Q_INLINE_TEMPLATE bool QBasicAtomicPointer::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 (*reinterpret_cast(0xffff0fc0)) +#define qt_atomic_eabi_cmpxchg_ptr (*reinterpret_cast(0xffff0fc0)) + +#else + +extern Q_CORE_EXPORT char q_atomic_lock; +Q_CORE_EXPORT void qt_atomic_yield(int *); + +#ifdef Q_CC_RVCT + +Q_CORE_EXPORT __asm char q_atomic_swp(volatile char *ptr, char newval); + +#else + +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 // Q_CC_RVCT + +#endif // QT_NO_ARM_EABI + +// 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 + +#ifndef Q_CC_RVCT + +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; +} + +#endif + +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 +Q_INLINE_TEMPLATE bool QBasicAtomicPointer::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 +Q_INLINE_TEMPLATE bool QBasicAtomicPointer::testAndSetRelaxed(T *expectedValue, T *newValue) +{ + return testAndSetOrdered(expectedValue, newValue); +} + +template +Q_INLINE_TEMPLATE bool QBasicAtomicPointer::testAndSetAcquire(T *expectedValue, T *newValue) +{ + return testAndSetOrdered(expectedValue, newValue); +} + +template +Q_INLINE_TEMPLATE bool QBasicAtomicPointer::testAndSetRelease(T *expectedValue, T *newValue) +{ + return testAndSetOrdered(expectedValue, newValue); +} + +// Fetch and store for pointers + +#ifdef Q_CC_RVCT + +template +__asm T *QBasicAtomicPointer::fetchAndStoreOrdered(T *newValue) +{ + add r2, pc, #0 + bx r2 + arm + swp r2,r1,[r0] + mov r0, r2 + bx lr + thumb +} + +#else + +template +Q_INLINE_TEMPLATE T *QBasicAtomicPointer::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; +} + +#endif // Q_CC_RVCT + +template +Q_INLINE_TEMPLATE T *QBasicAtomicPointer::fetchAndStoreRelaxed(T *newValue) +{ + return fetchAndStoreOrdered(newValue); +} + +template +Q_INLINE_TEMPLATE T *QBasicAtomicPointer::fetchAndStoreAcquire(T *newValue) +{ + return fetchAndStoreOrdered(newValue); +} + +template +Q_INLINE_TEMPLATE T *QBasicAtomicPointer::fetchAndStoreRelease(T *newValue) +{ + return fetchAndStoreOrdered(newValue); +} + +// Fetch and add for pointers + +template +Q_INLINE_TEMPLATE T *QBasicAtomicPointer::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 +Q_INLINE_TEMPLATE T *QBasicAtomicPointer::fetchAndAddRelaxed(qptrdiff valueToAdd) +{ + return fetchAndAddOrdered(valueToAdd); +} + +template +Q_INLINE_TEMPLATE T *QBasicAtomicPointer::fetchAndAddAcquire(qptrdiff valueToAdd) +{ + return fetchAndAddOrdered(valueToAdd); +} + +template +Q_INLINE_TEMPLATE T *QBasicAtomicPointer::fetchAndAddRelease(qptrdiff valueToAdd) +{ + return fetchAndAddOrdered(valueToAdd); +} + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif // QATOMIC_ARM_H -- cgit v0.12 From 7be2c5824e0331bbeec87b482e71efe72fb026b0 Mon Sep 17 00:00:00 2001 From: "Bradley T. Hughes" Date: Wed, 22 Sep 2010 12:08:36 +0200 Subject: Merge the armv6 and arm architectures Instead of having multiple architectures, merge them and select the appropriate implementation based on what the compiler actually supports. The original qatomic_arm.h header has been renamed to qatomic_armv5.h, and qatomic_arm.h now does nothing more than including either qatomic_armv6.h or qatomic_armv5.h Since this changes the build-key for targets that previously used armv6, we need a 3rd compatibility build-key for the architecture. The configure script will always write out this build-key when building for arm (and silently converts -arch armv6 to -arch arm). Reviewed-by: thiago --- bin/syncqt | 2 +- configure | 36 +++- src/corelib/arch/arch.pri | 1 + src/corelib/arch/armv6/arch.pri | 3 - src/corelib/arch/qatomic_arm.h | 399 ++---------------------------------- src/corelib/arch/qatomic_armv5.h | 6 +- src/corelib/global/qlibraryinfo.cpp | 3 + src/corelib/plugin/qlibrary.cpp | 3 + 8 files changed, 63 insertions(+), 390 deletions(-) delete mode 100644 src/corelib/arch/armv6/arch.pri diff --git a/bin/syncqt b/bin/syncqt index 648b6d9..b2a2577 100755 --- a/bin/syncqt +++ b/bin/syncqt @@ -691,7 +691,7 @@ my $class_lib_map_contents = ""; my @ignore_for_master_contents = ( "qt.h", "qpaintdevicedefs.h" ); my @ignore_for_include_check = ( "qatomic.h" ); my @ignore_for_qt_begin_header_check = ( "qiconset.h", "qconfig.h", "qconfig-dist.h", "qconfig-large.h", "qconfig-medium.h", "qconfig-minimal.h", "qconfig-small.h", "qfeatures.h", "qt_windows.h" ); -my @ignore_for_qt_begin_namespace_check = ( "qconfig.h", "qconfig-dist.h", "qconfig-large.h", "qconfig-medium.h", "qconfig-minimal.h", "qconfig-small.h", "qfeatures.h", "qatomic_arch.h", "qatomic_windowsce.h", "qt_windows.h", "qatomic_macosx.h" ); +my @ignore_for_qt_begin_namespace_check = ( "qconfig.h", "qconfig-dist.h", "qconfig-large.h", "qconfig-medium.h", "qconfig-minimal.h", "qconfig-small.h", "qfeatures.h", "qatomic_arch.h", "qatomic_windowsce.h", "qt_windows.h", "qatomic_macosx.h", "qatomic_arm.h" ); my @ignore_for_qt_module_check = ( "$modules{QtCore}/arch", "$modules{QtCore}/global", "$modules{QtSql}/drivers", "$modules{QtTest}", "$modules{QtDesigner}", "$modules{QtUiTools}", "$modules{QtDBus}", "$modules{phonon}" ); my %colliding_headers = (); my %inject_headers; diff --git a/configure b/configure index 4316cc8..5b8d46e 100755 --- a/configure +++ b/configure @@ -3019,6 +3019,9 @@ if [ "$PLATFORM" != "$XPLATFORM" -a "$CFG_EMBEDDED" != "no" ]; then sh4al) CFG_ARCH=sh4a ;; + arm*) + CFG_ARCH=arm + ;; *) CFG_ARCH="$CFG_EMBEDDED" ;; @@ -3031,6 +3034,16 @@ elif [ "$PLATFORM_MAC" = "yes" ] || [ -z "$CFG_ARCH" ]; then CFG_ARCH=$CFG_HOST_ARCH fi +# for compatibility +COMPAT_ARCH= +case "$CFG_ARCH" in +arm*) + # previously, armv6 was a different arch + CFG_ARCH=arm + COMPAT_ARCH=armv6 + ;; +esac + if [ -d "$relpath/src/corelib/arch/$CFG_ARCH" ]; then if [ "$OPT_VERBOSE" = "yes" ]; then echo " '$CFG_ARCH' is supported" @@ -3055,9 +3068,9 @@ if [ "$CFG_HOST_ARCH" != "$CFG_ARCH" ]; then fi if [ "$OPT_VERBOSE" = "yes" ]; then - echo "System architecture: '$CFG_ARCH'" + echo "Target architecture: '$CFG_ARCH'" if [ "$PLATFORM_QWS" = "yes" ]; then - echo "Host architecture: '$CFG_HOST_ARCH'" + echo "Host architecture: '$CFG_HOST_ARCH'" fi fi @@ -4849,7 +4862,7 @@ if [ "$CFG_IWMMXT" = "yes" ]; then fi # detect neon support -if ( [ "$CFG_ARCH" = "arm" ] || [ "$CFG_ARCH" = "armv6" ] ) && [ "${CFG_NEON}" = "auto" ]; then +if [ "$CFG_ARCH" = "arm" ] && [ "${CFG_NEON}" = "auto" ]; then if "$unixtests/compile.test" "$XQMAKESPEC" "$QMAKE_CONFIG" $OPT_VERBOSE "$relpath" "$outpath" config.tests/unix/neon "neon" $L_FLAGS $I_FLAGS $l_FLAGS "-mfpu=neon"; then CFG_NEON=yes else @@ -6444,7 +6457,7 @@ elif [ "$XPLATFORM" = "symbian-sbsv2" ]; then fi if [ "$CFG_JAVASCRIPTCORE_JIT" = "yes" ] || [ "$CFG_JAVASCRIPTCORE_JIT" = "auto" ]; then - if [ "$CFG_ARCH" = "arm" ] || [ "$CFG_ARCH" = "armv6" ]; then + if [ "$CFG_ARCH" = "arm" ]; then "$unixtests/compile.test" "$XQMAKESPEC" "$QMAKE_CONFIG" $OPT_VERBOSE "$relpath" "$outpath" config.tests/unix/javascriptcore-jit "javascriptcore-jit" $L_FLAGS $I_FLAGS $l_FLAGS if [ $? != "0" ]; then CFG_JAVASCRIPTCORE_JIT=no @@ -7521,10 +7534,20 @@ if [ ! -z "$COMPAT_COMPILER" ]; then fi fi +# is this arch compatible with some other "standard" build key +QT_BUILD_KEY_COMPAT_ARCH= +if [ ! -z "$COMPAT_ARCH" ]; then + QT_BUILD_KEY_COMPAT_ARCH="$CFG_USER_BUILD_KEY $COMPAT_ARCH $TARGET_OPERATING_SYSTEM $COMPILER $BUILD_OPTIONS" + if [ -n "$QT_NAMESPACE" ]; then + QT_BUILD_KEY_COMPAT_COMPILER="$QT_BUILD_KEY_COMPAT_ARCH $QT_NAMESPACE" + fi +fi + # strip out leading/trailing/extra whitespace QT_BUILD_KEY=`echo $QT_BUILD_KEY | sed -e "s, *, ,g" -e "s,^ *,," -e "s, *$,,"` QT_BUILD_KEY_COMPAT=`echo $QT_BUILD_KEY_COMPAT | sed -e "s, *, ,g" -e "s,^ *,," -e "s, *$,,"` QT_BUILD_KEY_COMPAT_COMPILER=`echo $QT_BUILD_KEY_COMPAT_COMPILER | sed -e "s, *, ,g" -e "s,^ *,," -e "s, *$,,"` +QT_BUILD_KEY_COMPAT_ARCH=`echo $QT_BUILD_KEY_COMPAT_ARCH | sed -e "s, *, ,g" -e "s,^ *,," -e "s, *$,,"` #------------------------------------------------------------------------------- # part of configuration information goes into qconfig.h @@ -7577,6 +7600,11 @@ if [ -n "$QT_BUILD_KEY_COMPAT_COMPILER" ]; then echo "#define QT_BUILD_KEY_COMPAT2 \"$QT_BUILD_KEY_COMPAT_COMPILER\"" \ >> "$outpath/src/corelib/global/qconfig.h.new" fi +if [ -n "$QT_BUILD_KEY_COMPAT_ARCH" ]; then + echo "#define QT_BUILD_KEY_COMPAT3 \"$QT_BUILD_KEY_COMPAT_ARCH\"" \ + >> "$outpath/src/corelib/global/qconfig.h.new" +fi + echo "" >>"$outpath/src/corelib/global/qconfig.h.new" echo "#ifdef QT_BOOTSTRAPPED" >>"$outpath/src/corelib/global/qconfig.h.new" diff --git a/src/corelib/arch/arch.pri b/src/corelib/arch/arch.pri index 57bc80a..046ecdf 100644 --- a/src/corelib/arch/arch.pri +++ b/src/corelib/arch/arch.pri @@ -21,6 +21,7 @@ vxworks:HEADERS += arch/qatomic_vxworks.h arch/qatomic_generic.h \ arch/qatomic_powerpc.h \ arch/qatomic_arm.h \ + arch/qatomic_armv5.h \ arch/qatomic_armv6.h \ arch/qatomic_i386.h \ arch/qatomic_mips.h \ diff --git a/src/corelib/arch/armv6/arch.pri b/src/corelib/arch/armv6/arch.pri deleted file mode 100644 index fd0cce1..0000000 --- a/src/corelib/arch/armv6/arch.pri +++ /dev/null @@ -1,3 +0,0 @@ -# -# ARMv6 -# diff --git a/src/corelib/arch/qatomic_arm.h b/src/corelib/arch/qatomic_arm.h index 9df02a2..5db7082 100644 --- a/src/corelib/arch/qatomic_arm.h +++ b/src/corelib/arch/qatomic_arm.h @@ -44,387 +44,28 @@ 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 -Q_INLINE_TEMPLATE bool QBasicAtomicPointer::isTestAndSetNative() -{ return false; } -template -Q_INLINE_TEMPLATE bool QBasicAtomicPointer::isTestAndSetWaitFree() -{ return false; } - -#define Q_ATOMIC_POINTER_FETCH_AND_STORE_IS_ALWAYS_NATIVE -#define Q_ATOMIC_POINTER_FETCH_AND_STORE_IS_WAIT_FREE - -template -Q_INLINE_TEMPLATE bool QBasicAtomicPointer::isFetchAndStoreNative() -{ return true; } -template -Q_INLINE_TEMPLATE bool QBasicAtomicPointer::isFetchAndStoreWaitFree() -{ return true; } - -#define Q_ATOMIC_POINTER_FETCH_AND_ADD_IS_NOT_NATIVE - -template -Q_INLINE_TEMPLATE bool QBasicAtomicPointer::isFetchAndAddNative() -{ return false; } -template -Q_INLINE_TEMPLATE bool QBasicAtomicPointer::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 (*reinterpret_cast(0xffff0fc0)) -#define qt_atomic_eabi_cmpxchg_ptr (*reinterpret_cast(0xffff0fc0)) - -#else - -extern Q_CORE_EXPORT char q_atomic_lock; -Q_CORE_EXPORT void qt_atomic_yield(int *); - -#ifdef Q_CC_RVCT - -Q_CORE_EXPORT __asm char q_atomic_swp(volatile char *ptr, char newval); - -#else - -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 // Q_CC_RVCT - -#endif // QT_NO_ARM_EABI - -// 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 - -#ifndef Q_CC_RVCT - -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; -} - -#endif - -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 -Q_INLINE_TEMPLATE bool QBasicAtomicPointer::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; +#if defined(__ARM_ARCH_7__) \ + || defined(__ARM_ARCH_7A__) \ + || defined(__ARM_ARCH_7R__) \ + || defined(__ARM_ARCH_7M__) \ + || defined(__ARM_ARCH_6__) \ + || defined(__ARM_ARCH_6J__) \ + || defined(__ARM_ARCH_6T2__) \ + || defined(__ARM_ARCH_6Z__) \ + || defined(__ARM_ARCH_6K__) \ + || defined(__ARM_ARCH_6ZK__) \ + || defined(__ARM_ARCH_6M__) \ + || (__TARGET_ARCH_ARM-0 >= 6) +# define QT_ARCH_ARMV6 +QT_BEGIN_INCLUDE_HEADER +# include "QtCore/qatomic_armv6.h" +QT_END_INCLUDE_HEADER #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; +# define QT_ARCH_ARMV5 +QT_BEGIN_INCLUDE_HEADER +# include "QtCore/qatomic_armv5.h" +QT_END_INCLUDE_HEADERS #endif -} - -template -Q_INLINE_TEMPLATE bool QBasicAtomicPointer::testAndSetRelaxed(T *expectedValue, T *newValue) -{ - return testAndSetOrdered(expectedValue, newValue); -} - -template -Q_INLINE_TEMPLATE bool QBasicAtomicPointer::testAndSetAcquire(T *expectedValue, T *newValue) -{ - return testAndSetOrdered(expectedValue, newValue); -} - -template -Q_INLINE_TEMPLATE bool QBasicAtomicPointer::testAndSetRelease(T *expectedValue, T *newValue) -{ - return testAndSetOrdered(expectedValue, newValue); -} - -// Fetch and store for pointers - -#ifdef Q_CC_RVCT - -template -__asm T *QBasicAtomicPointer::fetchAndStoreOrdered(T *newValue) -{ - add r2, pc, #0 - bx r2 - arm - swp r2,r1,[r0] - mov r0, r2 - bx lr - thumb -} - -#else - -template -Q_INLINE_TEMPLATE T *QBasicAtomicPointer::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; -} - -#endif // Q_CC_RVCT - -template -Q_INLINE_TEMPLATE T *QBasicAtomicPointer::fetchAndStoreRelaxed(T *newValue) -{ - return fetchAndStoreOrdered(newValue); -} - -template -Q_INLINE_TEMPLATE T *QBasicAtomicPointer::fetchAndStoreAcquire(T *newValue) -{ - return fetchAndStoreOrdered(newValue); -} - -template -Q_INLINE_TEMPLATE T *QBasicAtomicPointer::fetchAndStoreRelease(T *newValue) -{ - return fetchAndStoreOrdered(newValue); -} - -// Fetch and add for pointers - -template -Q_INLINE_TEMPLATE T *QBasicAtomicPointer::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 -Q_INLINE_TEMPLATE T *QBasicAtomicPointer::fetchAndAddRelaxed(qptrdiff valueToAdd) -{ - return fetchAndAddOrdered(valueToAdd); -} - -template -Q_INLINE_TEMPLATE T *QBasicAtomicPointer::fetchAndAddAcquire(qptrdiff valueToAdd) -{ - return fetchAndAddOrdered(valueToAdd); -} - -template -Q_INLINE_TEMPLATE T *QBasicAtomicPointer::fetchAndAddRelease(qptrdiff valueToAdd) -{ - return fetchAndAddOrdered(valueToAdd); -} - -QT_END_NAMESPACE QT_END_HEADER diff --git a/src/corelib/arch/qatomic_armv5.h b/src/corelib/arch/qatomic_armv5.h index 9df02a2..ab48380 100644 --- a/src/corelib/arch/qatomic_armv5.h +++ b/src/corelib/arch/qatomic_armv5.h @@ -39,8 +39,8 @@ ** ****************************************************************************/ -#ifndef QATOMIC_ARM_H -#define QATOMIC_ARM_H +#ifndef QATOMIC_ARMV5_H +#define QATOMIC_ARMV5_H QT_BEGIN_HEADER @@ -428,4 +428,4 @@ QT_END_NAMESPACE QT_END_HEADER -#endif // QATOMIC_ARM_H +#endif // QATOMIC_ARMV5_H diff --git a/src/corelib/global/qlibraryinfo.cpp b/src/corelib/global/qlibraryinfo.cpp index 957abbf..d493390 100644 --- a/src/corelib/global/qlibraryinfo.cpp +++ b/src/corelib/global/qlibraryinfo.cpp @@ -517,6 +517,9 @@ void qt_core_boilerplate() #ifdef QT_BUILD_KEY_COMPAT2 "| " QT_BUILD_KEY_COMPAT2 " " #endif +#ifdef QT_BUILD_KEY_COMPAT3 + "| " QT_BUILD_KEY_COMPAT3 " " +#endif "|\n" "Build date: %s\n" "Installation prefix: %s\n" diff --git a/src/corelib/plugin/qlibrary.cpp b/src/corelib/plugin/qlibrary.cpp index 239509e..f812275 100644 --- a/src/corelib/plugin/qlibrary.cpp +++ b/src/corelib/plugin/qlibrary.cpp @@ -854,6 +854,9 @@ bool QLibraryPrivate::isPlugin(QSettings *settings) #ifdef QT_BUILD_KEY_COMPAT2 && key != QT_BUILD_KEY_COMPAT2 #endif +#ifdef QT_BUILD_KEY_COMPAT3 + && key != QT_BUILD_KEY_COMPAT3 +#endif ) { if (qt_debug_component()) { qWarning("In %s:\n" -- cgit v0.12 From 6d1fb317f53017aee99ec191cc8740e7e668ba0e Mon Sep 17 00:00:00 2001 From: "Bradley T. Hughes" Date: Wed, 22 Sep 2010 15:21:57 +0200 Subject: Fix usage of QT_ARCH_ARM* after a28ddf6 Remove unnecessary use of QT_ARCH_ARMV6 from qglobal.h (QT_ARCH_ARM is always defined when QT_ARCH_ARMV6 is defined), and fix the use of QT_ARCH_ARM to assume ARM < v6 in qblendfunctions.cpp (use QT_ARCH_ARMV5 instead). Reviewed-by: thiago --- src/corelib/global/qglobal.h | 2 +- src/gui/painting/qblendfunctions.cpp | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/corelib/global/qglobal.h b/src/corelib/global/qglobal.h index b0a24b0..986b5c5 100644 --- a/src/corelib/global/qglobal.h +++ b/src/corelib/global/qglobal.h @@ -1091,7 +1091,7 @@ redefine to built-in booleans to make autotests work properly */ typedef int QNoImplicitBoolCast; -#if defined(QT_ARCH_ARM) || defined(QT_ARCH_ARMV6) || defined(QT_ARCH_AVR32) || (defined(QT_ARCH_MIPS) && (defined(Q_WS_QWS) || defined(Q_OS_WINCE))) || defined(QT_ARCH_SH) || defined(QT_ARCH_SH4A) +#if defined(QT_ARCH_ARM) || defined(QT_ARCH_AVR32) || (defined(QT_ARCH_MIPS) && (defined(Q_WS_QWS) || defined(Q_OS_WINCE))) || defined(QT_ARCH_SH) || defined(QT_ARCH_SH4A) #define QT_NO_FPU #endif diff --git a/src/gui/painting/qblendfunctions.cpp b/src/gui/painting/qblendfunctions.cpp index 0edf256..e0c2d16 100644 --- a/src/gui/painting/qblendfunctions.cpp +++ b/src/gui/painting/qblendfunctions.cpp @@ -309,9 +309,9 @@ template void qt_blend_argb24_on_rgb16(uchar *destPixels, int dbpl, const uchar *src = srcPixels + y * sbpl; const uchar *srcEnd = src + srcOffset; while (src < srcEnd) { -#if defined(QT_ARCH_ARM) || defined(QT_ARCH_POWERPC) || defined(QT_ARCH_SH) || defined(QT_ARCH_AVR32) || (defined(QT_ARCH_WINDOWSCE) && !defined(_X86_)) || (defined(QT_ARCH_SPARC) && defined(Q_CC_GNU)) +#if defined(QT_ARCH_ARMV5) || defined(QT_ARCH_POWERPC) || defined(QT_ARCH_SH) || defined(QT_ARCH_AVR32) || (defined(QT_ARCH_WINDOWSCE) && !defined(_X86_)) || (defined(QT_ARCH_SPARC) && defined(Q_CC_GNU)) // non-16-bit aligned memory access is not possible on PowerPC, - // ARM Date: Wed, 22 Sep 2010 15:16:28 +0200 Subject: Add support for ARMv7 atomic operations ARMv7 adds the DMB (data memory barrier) instruction which we can use to enforce memory barriers in QAtomicInt and QAtomicPointer. Other than that, ARMv7 is identical to ARMv6. Adjust the ARMv6 code to relax the compiler memory barriers on the *Relaxed() operations, and use *Relaxed() functions together the appropriate compiler barriers in the *Acquire(), *Release(), and *Ordered() functions. For "pure" ARMv6 code, the barriers are only compiler barriers, but for ARMv7, we also emit the DMB instruction. Reviewed-by: thiago --- bin/syncqt | 2 +- src/corelib/arch/arch.pri | 1 + src/corelib/arch/qatomic_arm.h | 8 +- src/corelib/arch/qatomic_armv6.h | 161 ++++++++++++++++++++++++++------------- src/corelib/arch/qatomic_armv7.h | 61 +++++++++++++++ 5 files changed, 179 insertions(+), 54 deletions(-) create mode 100644 src/corelib/arch/qatomic_armv7.h diff --git a/bin/syncqt b/bin/syncqt index b2a2577..faa3575 100755 --- a/bin/syncqt +++ b/bin/syncqt @@ -691,7 +691,7 @@ my $class_lib_map_contents = ""; my @ignore_for_master_contents = ( "qt.h", "qpaintdevicedefs.h" ); my @ignore_for_include_check = ( "qatomic.h" ); my @ignore_for_qt_begin_header_check = ( "qiconset.h", "qconfig.h", "qconfig-dist.h", "qconfig-large.h", "qconfig-medium.h", "qconfig-minimal.h", "qconfig-small.h", "qfeatures.h", "qt_windows.h" ); -my @ignore_for_qt_begin_namespace_check = ( "qconfig.h", "qconfig-dist.h", "qconfig-large.h", "qconfig-medium.h", "qconfig-minimal.h", "qconfig-small.h", "qfeatures.h", "qatomic_arch.h", "qatomic_windowsce.h", "qt_windows.h", "qatomic_macosx.h", "qatomic_arm.h" ); +my @ignore_for_qt_begin_namespace_check = ( "qconfig.h", "qconfig-dist.h", "qconfig-large.h", "qconfig-medium.h", "qconfig-minimal.h", "qconfig-small.h", "qfeatures.h", "qatomic_arch.h", "qatomic_windowsce.h", "qt_windows.h", "qatomic_macosx.h", "qatomic_arm.h", "qatomic_armv7.h" ); my @ignore_for_qt_module_check = ( "$modules{QtCore}/arch", "$modules{QtCore}/global", "$modules{QtSql}/drivers", "$modules{QtTest}", "$modules{QtDesigner}", "$modules{QtUiTools}", "$modules{QtDBus}", "$modules{phonon}" ); my %colliding_headers = (); my %inject_headers; diff --git a/src/corelib/arch/arch.pri b/src/corelib/arch/arch.pri index 046ecdf..971069f 100644 --- a/src/corelib/arch/arch.pri +++ b/src/corelib/arch/arch.pri @@ -23,6 +23,7 @@ vxworks:HEADERS += arch/qatomic_vxworks.h arch/qatomic_arm.h \ arch/qatomic_armv5.h \ arch/qatomic_armv6.h \ + arch/qatomic_armv7.h \ arch/qatomic_i386.h \ arch/qatomic_mips.h \ arch/qatomic_s390.h \ diff --git a/src/corelib/arch/qatomic_arm.h b/src/corelib/arch/qatomic_arm.h index 5db7082..f9d71e9 100644 --- a/src/corelib/arch/qatomic_arm.h +++ b/src/corelib/arch/qatomic_arm.h @@ -47,8 +47,12 @@ QT_BEGIN_HEADER #if defined(__ARM_ARCH_7__) \ || defined(__ARM_ARCH_7A__) \ || defined(__ARM_ARCH_7R__) \ - || defined(__ARM_ARCH_7M__) \ - || defined(__ARM_ARCH_6__) \ + || defined(__ARM_ARCH_7M__) +# define QT_ARCH_ARMV7 +QT_BEGIN_INCLUDE_HEADER +# include "QtCore/qatomic_armv7.h" +QT_END_INCLUDE_HEADER +#elif defined(__ARM_ARCH_6__) \ || defined(__ARM_ARCH_6J__) \ || defined(__ARM_ARCH_6T2__) \ || defined(__ARM_ARCH_6Z__) \ diff --git a/src/corelib/arch/qatomic_armv6.h b/src/corelib/arch/qatomic_armv6.h index 38b7069..1aa3b88 100644 --- a/src/corelib/arch/qatomic_armv6.h +++ b/src/corelib/arch/qatomic_armv6.h @@ -45,6 +45,7 @@ QT_BEGIN_HEADER QT_BEGIN_NAMESPACE + #define Q_ATOMIC_INT_REFERENCE_COUNTING_IS_ALWAYS_NATIVE inline bool QBasicAtomicInt::isReferenceCountingNative() @@ -102,6 +103,13 @@ Q_INLINE_TEMPLATE bool QBasicAtomicPointer::isFetchAndAddWaitFree() #ifndef Q_CC_RVCT +#ifndef Q_DATA_MEMORY_BARRIER +# define Q_DATA_MEMORY_BARRIER asm volatile("":::"memory") +#endif +#ifndef Q_COMPILER_MEMORY_BARRIER +# define Q_COMPILER_MEMORY_BARRIER asm volatile("":::"memory") +#endif + inline bool QBasicAtomicInt::ref() { register int newValue; @@ -138,7 +146,7 @@ inline bool QBasicAtomicInt::deref() return newValue != 0; } -inline bool QBasicAtomicInt::testAndSetOrdered(int expectedValue, int newValue) +inline bool QBasicAtomicInt::testAndSetRelaxed(int expectedValue, int newValue) { register int result; asm volatile("0:\n" @@ -152,11 +160,11 @@ inline bool QBasicAtomicInt::testAndSetOrdered(int expectedValue, int newValue) : [expectedValue] "r" (expectedValue), [newValue] "r" (newValue), [_q_value] "r" (&_q_value) - : "cc", "memory"); + : "cc"); return result == 0; } -inline int QBasicAtomicInt::fetchAndStoreOrdered(int newValue) +inline int QBasicAtomicInt::fetchAndStoreRelaxed(int newValue) { register int originalValue; register int result; @@ -170,11 +178,11 @@ inline int QBasicAtomicInt::fetchAndStoreOrdered(int newValue) "+m" (_q_value) : [newValue] "r" (newValue), [_q_value] "r" (&_q_value) - : "cc", "memory"); + : "cc"); return originalValue; } -inline int QBasicAtomicInt::fetchAndAddOrdered(int valueToAdd) +inline int QBasicAtomicInt::fetchAndAddRelaxed(int valueToAdd) { register int originalValue; register int newValue; @@ -191,12 +199,12 @@ inline int QBasicAtomicInt::fetchAndAddOrdered(int valueToAdd) "+m" (_q_value) : [valueToAdd] "r" (valueToAdd), [_q_value] "r" (&_q_value) - : "cc", "memory"); + : "cc"); return originalValue; } template -Q_INLINE_TEMPLATE bool QBasicAtomicPointer::testAndSetOrdered(T *expectedValue, T *newValue) +Q_INLINE_TEMPLATE bool QBasicAtomicPointer::testAndSetRelaxed(T *expectedValue, T *newValue) { register T *result; asm volatile("0:\n" @@ -210,12 +218,12 @@ Q_INLINE_TEMPLATE bool QBasicAtomicPointer::testAndSetOrdered(T *expectedValu : [expectedValue] "r" (expectedValue), [newValue] "r" (newValue), [_q_value] "r" (&_q_value) - : "cc", "memory"); + : "cc"); return result == 0; } template -Q_INLINE_TEMPLATE T *QBasicAtomicPointer::fetchAndStoreOrdered(T *newValue) +Q_INLINE_TEMPLATE T *QBasicAtomicPointer::fetchAndStoreRelaxed(T *newValue) { register T *originalValue; register int result; @@ -229,12 +237,12 @@ Q_INLINE_TEMPLATE T *QBasicAtomicPointer::fetchAndStoreOrdered(T *newValue) "+m" (_q_value) : [newValue] "r" (newValue), [_q_value] "r" (&_q_value) - : "cc", "memory"); + : "cc"); return originalValue; } template -Q_INLINE_TEMPLATE T *QBasicAtomicPointer::fetchAndAddOrdered(qptrdiff valueToAdd) +Q_INLINE_TEMPLATE T *QBasicAtomicPointer::fetchAndAddRelaxed(qptrdiff valueToAdd) { register T *originalValue; register T *newValue; @@ -251,7 +259,7 @@ Q_INLINE_TEMPLATE T *QBasicAtomicPointer::fetchAndAddOrdered(qptrdiff valueTo "+m" (_q_value) : [valueToAdd] "r" (valueToAdd * sizeof(T)), [_q_value] "r" (&_q_value) - : "cc", "memory"); + : "cc"); return originalValue; } @@ -263,9 +271,18 @@ Q_INLINE_TEMPLATE T *QBasicAtomicPointer::fetchAndAddOrdered(qptrdiff valueTo // RVCT embedded assembly documentation: // http://www.keil.com/support/man/docs/armcc/armcc_chddbeib.htm -// save our pragma state and switch to ARM mode -#pragma push -#pragma arm +#if __TARGET_ARCH_THUMB-0 < 4 +// save our pragma state and switch to ARM mode (unless using Thumb2) +# pragma push +# pragma arm +#endif + +#ifndef Q_DATA_MEMORY_BARRIER +# define Q_DATA_MEMORY_BARRIER __schedule_barrier() +#endif +#ifndef Q_COMPILER_MEMORY_BARRIER +# define Q_COMPILER_MEMORY_BARRIER __schedule_barrier() +#endif inline bool QBasicAtomicInt::ref() { @@ -297,7 +314,7 @@ inline bool QBasicAtomicInt::deref() return newValue != 0; } -inline bool QBasicAtomicInt::testAndSetOrdered(int expectedValue, int newValue) +inline bool QBasicAtomicInt::testAndSetRelaxed(int expectedValue, int newValue) { register int result; retry: @@ -311,7 +328,7 @@ inline bool QBasicAtomicInt::testAndSetOrdered(int expectedValue, int newValue) return result == 0; } -inline int QBasicAtomicInt::fetchAndStoreOrdered(int newValue) +inline int QBasicAtomicInt::fetchAndStoreRelaxed(int newValue) { register int originalValue; register int result; @@ -325,7 +342,7 @@ inline int QBasicAtomicInt::fetchAndStoreOrdered(int newValue) return originalValue; } -inline int QBasicAtomicInt::fetchAndAddOrdered(int valueToAdd) +inline int QBasicAtomicInt::fetchAndAddRelaxed(int valueToAdd) { register int originalValue; register int newValue; @@ -342,7 +359,7 @@ inline int QBasicAtomicInt::fetchAndAddOrdered(int valueToAdd) } template -Q_INLINE_TEMPLATE bool QBasicAtomicPointer::testAndSetOrdered(T *expectedValue, T *newValue) +Q_INLINE_TEMPLATE bool QBasicAtomicPointer::testAndSetRelaxed(T *expectedValue, T *newValue) { register T *result; retry: @@ -357,7 +374,7 @@ Q_INLINE_TEMPLATE bool QBasicAtomicPointer::testAndSetOrdered(T *expectedValu } template -Q_INLINE_TEMPLATE T *QBasicAtomicPointer::fetchAndStoreOrdered(T *newValue) +Q_INLINE_TEMPLATE T *QBasicAtomicPointer::fetchAndStoreRelaxed(T *newValue) { register T *originalValue; register int result; @@ -372,7 +389,7 @@ Q_INLINE_TEMPLATE T *QBasicAtomicPointer::fetchAndStoreOrdered(T *newValue) } template -Q_INLINE_TEMPLATE T *QBasicAtomicPointer::fetchAndAddOrdered(qptrdiff valueToAdd) +Q_INLINE_TEMPLATE T *QBasicAtomicPointer::fetchAndAddRelaxed(qptrdiff valueToAdd) { register T *originalValue; register T *newValue; @@ -388,111 +405,153 @@ Q_INLINE_TEMPLATE T *QBasicAtomicPointer::fetchAndAddOrdered(qptrdiff valueTo return originalValue; } -// go back to the previous pragma state (probably Thumb mode) -#pragma pop +#if __TARGET_ARCH_THUMB-0 < 4 +# pragma pop #endif -// common code +#endif -inline bool QBasicAtomicInt::testAndSetRelaxed(int expectedValue, int newValue) -{ - return testAndSetOrdered(expectedValue, newValue); -} +// common code inline bool QBasicAtomicInt::testAndSetAcquire(int expectedValue, int newValue) { - return testAndSetOrdered(expectedValue, newValue); + bool returnValue = testAndSetRelaxed(expectedValue, newValue); + Q_DATA_MEMORY_BARRIER; + return returnValue; } inline bool QBasicAtomicInt::testAndSetRelease(int expectedValue, int newValue) { - return testAndSetOrdered(expectedValue, newValue); + Q_DATA_MEMORY_BARRIER; + return testAndSetRelaxed(expectedValue, newValue); } -inline int QBasicAtomicInt::fetchAndStoreRelaxed(int newValue) +inline bool QBasicAtomicInt::testAndSetOrdered(int expectedValue, int newValue) { - return fetchAndStoreOrdered(newValue); + Q_DATA_MEMORY_BARRIER; + bool returnValue = testAndSetRelaxed(expectedValue, newValue); + Q_COMPILER_MEMORY_BARRIER; + return returnValue; } inline int QBasicAtomicInt::fetchAndStoreAcquire(int newValue) { - return fetchAndStoreOrdered(newValue); + int returnValue = fetchAndStoreRelaxed(newValue); + Q_DATA_MEMORY_BARRIER; + return returnValue; } inline int QBasicAtomicInt::fetchAndStoreRelease(int newValue) { - return fetchAndStoreOrdered(newValue); + Q_DATA_MEMORY_BARRIER; + return fetchAndStoreRelaxed(newValue); } -inline int QBasicAtomicInt::fetchAndAddRelaxed(int valueToAdd) +inline int QBasicAtomicInt::fetchAndStoreOrdered(int newValue) { - return fetchAndAddOrdered(valueToAdd); + Q_DATA_MEMORY_BARRIER; + int returnValue = fetchAndStoreRelaxed(newValue); + Q_COMPILER_MEMORY_BARRIER; + return returnValue; } + inline int QBasicAtomicInt::fetchAndAddAcquire(int valueToAdd) { - return fetchAndAddOrdered(valueToAdd); + int returnValue = fetchAndAddRelaxed(valueToAdd); + Q_DATA_MEMORY_BARRIER; + return returnValue; } inline int QBasicAtomicInt::fetchAndAddRelease(int valueToAdd) { - return fetchAndAddOrdered(valueToAdd); + Q_DATA_MEMORY_BARRIER; + return fetchAndAddRelaxed(valueToAdd); } -template -Q_INLINE_TEMPLATE bool QBasicAtomicPointer::testAndSetRelaxed(T *expectedValue, T *newValue) +inline int QBasicAtomicInt::fetchAndAddOrdered(int valueToAdd) { - return testAndSetOrdered(expectedValue, newValue); + Q_DATA_MEMORY_BARRIER; + int returnValue = fetchAndAddRelaxed(valueToAdd); + Q_COMPILER_MEMORY_BARRIER; + return returnValue; } template Q_INLINE_TEMPLATE bool QBasicAtomicPointer::testAndSetAcquire(T *expectedValue, T *newValue) { - return testAndSetOrdered(expectedValue, newValue); + bool returnValue = testAndSetRelaxed(expectedValue, newValue); + Q_DATA_MEMORY_BARRIER; + return returnValue; } template Q_INLINE_TEMPLATE bool QBasicAtomicPointer::testAndSetRelease(T *expectedValue, T *newValue) { - return testAndSetOrdered(expectedValue, newValue); + Q_DATA_MEMORY_BARRIER; + return testAndSetRelaxed(expectedValue, newValue); } template -Q_INLINE_TEMPLATE T *QBasicAtomicPointer::fetchAndStoreRelaxed(T *newValue) +Q_INLINE_TEMPLATE bool QBasicAtomicPointer::testAndSetOrdered(T *expectedValue, T *newValue) { - return fetchAndStoreOrdered(newValue); + Q_DATA_MEMORY_BARRIER; + bool returnValue = testAndSetAcquire(expectedValue, newValue); + Q_COMPILER_MEMORY_BARRIER; + return returnValue; } template Q_INLINE_TEMPLATE T *QBasicAtomicPointer::fetchAndStoreAcquire(T *newValue) { - return fetchAndStoreOrdered(newValue); + T *returnValue = fetchAndStoreRelaxed(newValue); + Q_DATA_MEMORY_BARRIER; + return returnValue; } template Q_INLINE_TEMPLATE T *QBasicAtomicPointer::fetchAndStoreRelease(T *newValue) { - return fetchAndStoreOrdered(newValue); + Q_DATA_MEMORY_BARRIER; + return fetchAndStoreRelaxed(newValue); } template -Q_INLINE_TEMPLATE T *QBasicAtomicPointer::fetchAndAddRelaxed(qptrdiff valueToAdd) +Q_INLINE_TEMPLATE T *QBasicAtomicPointer::fetchAndStoreOrdered(T *newValue) { - return fetchAndAddOrdered(valueToAdd); + Q_DATA_MEMORY_BARRIER; + T *returnValue = fetchAndStoreRelaxed(newValue); + Q_COMPILER_MEMORY_BARRIER; + return returnValue; } template Q_INLINE_TEMPLATE T *QBasicAtomicPointer::fetchAndAddAcquire(qptrdiff valueToAdd) { - return fetchAndAddOrdered(valueToAdd); + T *returnValue = fetchAndAddRelaxed(valueToAdd); + Q_DATA_MEMORY_BARRIER; + return returnValue; } template Q_INLINE_TEMPLATE T *QBasicAtomicPointer::fetchAndAddRelease(qptrdiff valueToAdd) { - return fetchAndAddOrdered(valueToAdd); + Q_DATA_MEMORY_BARRIER; + return fetchAndAddRelaxed(valueToAdd); } +template +Q_INLINE_TEMPLATE T *QBasicAtomicPointer::fetchAndAddOrdered(qptrdiff valueToAdd) +{ + Q_DATA_MEMORY_BARRIER; + T *returnValue = fetchAndAddRelaxed(valueToAdd); + Q_COMPILER_MEMORY_BARRIER; + return returnValue; +} + +#undef Q_DATA_MEMORY_BARRIER +#undef Q_COMPILER_MEMORY_BARRIER + QT_END_NAMESPACE QT_END_HEADER diff --git a/src/corelib/arch/qatomic_armv7.h b/src/corelib/arch/qatomic_armv7.h new file mode 100644 index 0000000..a95c4ea --- /dev/null +++ b/src/corelib/arch/qatomic_armv7.h @@ -0,0 +1,61 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying +** this package. +** +** 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.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QATOMIC_ARMV7_H +#define QATOMIC_ARMV7_H + +QT_BEGIN_HEADER + +// use the DMB instruction when compiling for ARMv7, ... +#ifndef Q_CC_RCVT +# define Q_DATA_MEMORY_BARRIER asm volatile("dmb\n":::"memory") +#else +# define Q_DATA_MEMORY_BARRIER do{__asm { dmb } __schedule_barrier();}while(0) +#endif + +// ... but the implementation is otherwise identical to that for ARMv6 +QT_BEGIN_INCLUDE_HEADER +#include "QtCore/qatomic_armv6.h" +QT_END_INCLUDE_HEADER + +QT_END_HEADER + +#endif // QATOMIC_ARMV7_H -- cgit v0.12