diff options
Diffstat (limited to 'src/corelib')
-rw-r--r-- | src/corelib/arch/armv6/qatomic_generic_armv6.cpp | 260 | ||||
-rw-r--r-- | src/corelib/arch/qatomic_armv6.h | 304 | ||||
-rw-r--r-- | src/corelib/arch/qatomic_symbian.h | 235 | ||||
-rw-r--r-- | src/corelib/arch/symbian/arch.pri | 2 | ||||
-rw-r--r-- | src/corelib/arch/symbian/qatomic_symbian.cpp | 167 | ||||
-rw-r--r-- | src/corelib/global/qglobal.h | 11 | ||||
-rw-r--r-- | src/corelib/global/qnumeric_p.h | 6 | ||||
-rw-r--r-- | src/corelib/kernel/qmath.h | 45 | ||||
-rw-r--r-- | src/corelib/tools/qdatetime.cpp | 2 | ||||
-rw-r--r-- | src/corelib/tools/qeasingcurve.cpp | 20 | ||||
-rw-r--r-- | src/corelib/tools/qline.cpp | 12 |
11 files changed, 921 insertions, 143 deletions
diff --git a/src/corelib/arch/armv6/qatomic_generic_armv6.cpp b/src/corelib/arch/armv6/qatomic_generic_armv6.cpp new file mode 100644 index 0000000..3078662 --- /dev/null +++ b/src/corelib/arch/armv6/qatomic_generic_armv6.cpp @@ -0,0 +1,260 @@ +/**************************************************************************** +** +** Copyright (C) 2009 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 <QtCore/qglobal.h> + +#ifdef QT_HAVE_ARMV6 + +QT_BEGIN_NAMESPACE + +QT_USE_NAMESPACE + +#ifdef Q_CC_RVCT +#pragma push +#pragma arm +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_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_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_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_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_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_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_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_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_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_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_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 diff --git a/src/corelib/arch/qatomic_armv6.h b/src/corelib/arch/qatomic_armv6.h index 6862638..1e9f0c4 100644 --- a/src/corelib/arch/qatomic_armv6.h +++ b/src/corelib/arch/qatomic_armv6.h @@ -45,7 +45,6 @@ QT_BEGIN_HEADER QT_BEGIN_NAMESPACE - #define Q_ATOMIC_INT_REFERENCE_COUNTING_IS_ALWAYS_NATIVE inline bool QBasicAtomicInt::isReferenceCountingNative() @@ -101,6 +100,8 @@ template <typename T> Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::isFetchAndAddWaitFree() { return false; } +#ifndef Q_CC_RVCT + inline bool QBasicAtomicInt::ref() { register int newValue; @@ -155,21 +156,6 @@ inline bool QBasicAtomicInt::testAndSetOrdered(int expectedValue, int newValue) 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; @@ -188,21 +174,6 @@ inline int QBasicAtomicInt::fetchAndStoreOrdered(int newValue) 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; @@ -224,21 +195,6 @@ inline int QBasicAtomicInt::fetchAndAddOrdered(int 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) { @@ -259,24 +215,6 @@ Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::testAndSetOrdered(T *expectedValu } 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; @@ -296,24 +234,6 @@ Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndStoreOrdered(T *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) { register T *originalValue; @@ -335,6 +255,226 @@ Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndAddOrdered(qptrdiff valueTo return originalValue; } +#else +// This is Q_CC_RVCT + +// RVCT inline assembly documentation: +// http://www.keil.com/support/man/docs/armcc/armcc_chdcffdb.htm +// 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 + +inline bool QBasicAtomicInt::ref() +{ + register int newValue; + register int result; + retry: + __asm { + ldrex newValue, [&_q_value] + add newValue, newValue, #1 + strex result, newValue, [&_q_value] + teq result, #0 + bne retry + } + return newValue != 0; +} + +inline bool QBasicAtomicInt::deref() +{ + register int newValue; + register int result; + retry: + __asm { + ldrex newValue, [&_q_value] + sub newValue, newValue, #1 + strex result, newValue, [&_q_value] + teq result, #0 + bne retry + } + return newValue != 0; +} + +inline bool QBasicAtomicInt::testAndSetOrdered(int expectedValue, int newValue) +{ + register int result; + retry: + __asm { + ldrex result, [&_q_value] + eors result, result, expectedValue + strexeq result, newValue, [&_q_value] + teqeq result, #1 + beq retry + } + return result == 0; +} + +inline int QBasicAtomicInt::fetchAndStoreOrdered(int newValue) +{ + register int originalValue; + register int result; + retry: + __asm { + ldrex originalValue, [&_q_value] + strex result, newValue, [&_q_value] + teq result, #0 + bne retry + } + return originalValue; +} + +inline int QBasicAtomicInt::fetchAndAddOrdered(int valueToAdd) +{ + register int originalValue; + register int newValue; + register int result; + retry: + __asm { + ldrex originalValue, [&_q_value] + add newValue, originalValue, valueToAdd + strex result, newValue, [&_q_value] + teq result, #0 + bne retry + } + return originalValue; +} + +template <typename T> +Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::testAndSetOrdered(T *expectedValue, T *newValue) +{ + register T *result; + retry: + __asm { + ldrex result, [&_q_value] + eors result, result, expectedValue + strexeq result, newValue, [&_q_value] + teqeq result, #1 + beq retry + } + return result == 0; +} + +template <typename T> +Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndStoreOrdered(T *newValue) +{ + register T *originalValue; + register int result; + retry: + __asm { + ldrex originalValue, [&_q_value] + strex result, newValue, [&_q_value] + teq result, #0 + bne retry + } + return originalValue; +} + +template <typename T> +Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndAddOrdered(qptrdiff valueToAdd) +{ + register T *originalValue; + register T *newValue; + register int result; + retry: + __asm { + ldrex originalValue, [&_q_value] + add newValue, originalValue, valueToAdd * sizeof(T) + strex result, newValue, [&_q_value] + teq result, #0 + bne retry + } + return originalValue; +} + +// go back to the previous pragma state (probably Thumb mode) +#pragma pop +#endif + +// common code + +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) { diff --git a/src/corelib/arch/qatomic_symbian.h b/src/corelib/arch/qatomic_symbian.h index 3721aca..92f6ef9 100644 --- a/src/corelib/arch/qatomic_symbian.h +++ b/src/corelib/arch/qatomic_symbian.h @@ -42,12 +42,8 @@ #ifndef QATOMIC_SYMBIAN_H #define QATOMIC_SYMBIAN_H -#if defined(Q_CC_RVCT) -# define QT_NO_ARM_EABI -# include <QtCore/qatomic_arm.h> -#elif defined(Q_CC_NOKIAX86) || defined(Q_CC_GCCE) -# include <QtCore/qatomic_generic.h> -#endif +#include <qglobal.h> +#include <e32std.h> QT_BEGIN_HEADER @@ -55,7 +51,232 @@ QT_BEGIN_NAMESPACE QT_MODULE(Core) -// Empty, but needed to avoid warnings +#define Q_ATOMIC_INT_REFERENCE_COUNTING_IS_SOMETIMES_NATIVE + +inline bool QBasicAtomicInt::isReferenceCountingWaitFree() +{ return false; } + +#define Q_ATOMIC_INT_TEST_AND_SET_IS_SOMETIMES_NATIVE + +inline bool QBasicAtomicInt::isTestAndSetWaitFree() +{ return false; } + +#define Q_ATOMIC_INT_FETCH_AND_STORE_IS_SOMETIMES_NATIVE + +inline bool QBasicAtomicInt::isFetchAndStoreWaitFree() +{ return false; } + +#define Q_ATOMIC_INT_FETCH_AND_ADD_IS_SOMETIMES_NATIVE + +inline bool QBasicAtomicInt::isFetchAndAddWaitFree() +{ return false; } + +#define Q_ATOMIC_POINTER_TEST_AND_SET_IS_SOMETIMES_NATIVE + +Q_CORE_EXPORT bool QBasicAtomicPointer_isTestAndSetNative(); +template <typename T> +Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::isTestAndSetNative() +{ return QBasicAtomicPointer_isTestAndSetNative(); } +template <typename T> +Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::isTestAndSetWaitFree() +{ return false; } + +#define Q_ATOMIC_POINTER_FETCH_AND_STORE_IS_SOMETIMES_NATIVE + +Q_CORE_EXPORT bool QBasicAtomicPointer_isFetchAndStoreNative(); +template <typename T> +Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::isFetchAndStoreNative() +{ return QBasicAtomicPointer_isFetchAndStoreNative(); } +template <typename T> +Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::isFetchAndStoreWaitFree() +{ return false; } + +#define Q_ATOMIC_POINTER_FETCH_AND_ADD_IS_SOMETIMES_NATIVE + +Q_CORE_EXPORT bool QBasicAtomicPointer_isFetchAndAddNative(); +template <typename T> +Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::isFetchAndAddNative() +{ return QBasicAtomicPointer_isFetchAndAddNative(); } +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 + +//LockedInc and LockedDec are machine coded for ARMv6 (and future proof) +inline bool QBasicAtomicInt::ref() +{ + int original = User::LockedInc((TInt&)_q_value); + return original != -1; +} + +inline bool QBasicAtomicInt::deref() +{ + int original = User::LockedDec((TInt&)_q_value); + return original != 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 diff --git a/src/corelib/arch/symbian/arch.pri b/src/corelib/arch/symbian/arch.pri index deb94b1..3ef1c9e 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/../generic/qatomic_generic_unix.cpp + $$QT_ARCH_CPP/../armv6/qatomic_generic_armv6.cpp diff --git a/src/corelib/arch/symbian/qatomic_symbian.cpp b/src/corelib/arch/symbian/qatomic_symbian.cpp index 8f02155..91b49c7 100644 --- a/src/corelib/arch/symbian/qatomic_symbian.cpp +++ b/src/corelib/arch/symbian/qatomic_symbian.cpp @@ -50,7 +50,7 @@ QT_BEGIN_NAMESPACE // This way we can report on heap cells and handles that are really not owned by anything which still exists. // This information can be used to detect whether memory leaks are happening, particularly if these numbers grow as the app is used more. // This code is placed here as it happens to make it the very last static to be destroyed in a Qt app. The -// reason assumed is that this file appears before any other file declaring static data in the generated +// reason assumed is that this file appears before any other file declaring static data in the generated // Symbian MMP file. This particular file was chosen as it is the earliest symbian specific file. struct QSymbianPrintExitInfo { @@ -77,37 +77,158 @@ struct QSymbianPrintExitInfo TInt initThreadHandleCount; } symbian_printExitInfo; -QT_END_NAMESPACE +Q_CORE_EXPORT bool QBasicAtomicInt::isReferenceCountingNative() +{ +#ifdef QT_HAVE_ARMV6 + return true; +#else + return false; +#endif +} +Q_CORE_EXPORT bool QBasicAtomicInt::isTestAndSetNative() +{ +#ifdef QT_HAVE_ARMV6 + return true; +#else + return false; +#endif +} -#if defined(Q_CC_RVCT) +Q_CORE_EXPORT bool QBasicAtomicInt::isFetchAndStoreNative() +{ +#ifdef QT_HAVE_ARMV6 + return true; +#else + return false; +#endif +} -#include "../arm/qatomic_arm.cpp" +Q_CORE_EXPORT bool QBasicAtomicInt::isFetchAndAddNative() +{ +#ifdef QT_HAVE_ARMV6 + return true; +#else + return false; +#endif +} -QT_BEGIN_NAMESPACE +Q_CORE_EXPORT bool QBasicAtomicPointer_isTestAndSetNative() +{ +#ifdef QT_HAVE_ARMV6 + return true; +#else + return false; +#endif +} -Q_CORE_EXPORT __asm char q_atomic_swp(volatile char *ptr, char newval) +Q_CORE_EXPORT bool QBasicAtomicPointer_isFetchAndStoreNative() { - add r2, pc, #0 - bx r2 - arm - swpb r2,r1,[r0] - mov r0, r2 - bx lr - thumb +#ifdef QT_HAVE_ARMV6 + return true; +#else + return false; +#endif } -Q_CORE_EXPORT __asm int QBasicAtomicInt::fetchAndStoreOrdered(int newValue) +Q_CORE_EXPORT bool QBasicAtomicPointer_isFetchAndAddNative() { - add r2, pc, #0 - bx r2 - arm - swp r2,r1,[r0] - mov r0, r2 - bx lr - thumb +#ifdef QT_HAVE_ARMV6 + return true; +#else + return false; +#endif } -QT_END_NAMESPACE +//For ARMv6, the generic atomics are machine coded +#ifndef QT_HAVE_ARMV6 + +class QCriticalSection +{ +public: + QCriticalSection() { fastlock.CreateLocal(); } + ~QCriticalSection() { fastlock.Close(); } + void lock() { fastlock.Wait(); } + void unlock() { fastlock.Signal(); } -#endif // Q_CC_RVCT +private: + RFastLock fastlock; +}; + +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; +} + +#endif // QT_HAVE_ARMV6 + +QT_END_NAMESPACE diff --git a/src/corelib/global/qglobal.h b/src/corelib/global/qglobal.h index d113e02..6befb33 100644 --- a/src/corelib/global/qglobal.h +++ b/src/corelib/global/qglobal.h @@ -437,13 +437,18 @@ namespace QT_NAMESPACE {} #elif defined(__GCCE__) # define Q_CC_GCCE # define QT_VISIBILITY_AVAILABLE +# if defined(__ARM_ARCH_6__) || defined(__ARM_ARCH_7__) || defined(__ARM_ARCH_7A__) +# define QT_HAVE_ARMV6 +# endif /* ARM Realview Compiler Suite RVCT compiler also defines __EDG__ and __GNUC__ (if --gnu flag is given), so check for it before that */ #elif defined(__ARMCC__) || defined(__CC_ARM) # define Q_CC_RVCT - +# if __TARGET_ARCH_ARM >= 6 +# define QT_HAVE_ARMV6 +# endif #elif defined(__GNUC__) # define Q_CC_GNU # define Q_C_CALLBACKS @@ -1076,14 +1081,14 @@ template <typename T> inline T qAbs(const T &t) { return t >= 0 ? t : -t; } inline int qRound(qreal d) -{ return d >= 0.0 ? int(d + 0.5) : int(d - int(d-1) + 0.5) + int(d-1); } +{ return d >= qreal(0.0) ? int(d + qreal(0.5)) : int(d - int(d-1) + qreal(0.5)) + int(d-1); } #if defined(QT_NO_FPU) || defined(QT_ARCH_ARM) || defined(QT_ARCH_WINDOWSCE) || defined(QT_ARCH_SYMBIAN) inline qint64 qRound64(double d) { return d >= 0.0 ? qint64(d + 0.5) : qint64(d - qreal(qint64(d-1)) + 0.5) + qint64(d-1); } #else inline qint64 qRound64(qreal d) -{ return d >= 0.0 ? qint64(d + 0.5) : qint64(d - qreal(qint64(d-1)) + 0.5) + qint64(d-1); } +{ return d >= 0.0 ? qint64(d + qreal(0.5)) : qint64(d - qreal(qint64(d-1)) + qreal(0.5)) + qint64(d-1); } #endif template <typename T> diff --git a/src/corelib/global/qnumeric_p.h b/src/corelib/global/qnumeric_p.h index c8b5735..3f7b5b5 100644 --- a/src/corelib/global/qnumeric_p.h +++ b/src/corelib/global/qnumeric_p.h @@ -57,6 +57,12 @@ QT_BEGIN_NAMESPACE +static const qreal Q_PI = qreal(3.14159265358979323846); // pi +static const qreal Q_2PI = qreal(6.28318530717958647693); // 2*pi +static const qreal Q_PI2 = qreal(1.57079632679489661923); // pi/2 +static const qreal Q_PI180 = qreal(0.01745329251994329577); // pi/180 +static const qreal Q_180PI = qreal(57.29577951308232087685); // 180/pi + #if !defined(Q_CC_MIPS) static const union { unsigned char c[8]; double d; } qt_be_inf_bytes = { { 0x7f, 0xf0, 0, 0, 0, 0, 0, 0 } }; diff --git a/src/corelib/kernel/qmath.h b/src/corelib/kernel/qmath.h index a9e4378..ef3a4b0 100644 --- a/src/corelib/kernel/qmath.h +++ b/src/corelib/kernel/qmath.h @@ -45,6 +45,7 @@ #include <math.h> #include <QtCore/qglobal.h> +#include <private/qnumeric_p.h> QT_BEGIN_HEADER @@ -106,6 +107,16 @@ inline qreal qAcos(qreal v) return acos(v); } +inline qreal qAsin(qreal v) +{ +#ifdef QT_USE_MATH_H_FLOATS + if (sizeof(qreal) == sizeof(float)) + return asinf(float(v)); + else +#endif + return asin(v); +} + inline qreal qSqrt(qreal v) { #ifdef QT_USE_MATH_H_FLOATS @@ -136,28 +147,42 @@ inline qreal qPow(qreal x, qreal y) return pow(x, y); } -#ifndef M_PI -#define M_PI (3.14159265358979323846) -#endif - inline qreal qFastSin(qreal x) { - int si = int(x * (0.5 * QT_SINE_TABLE_SIZE / M_PI)); // Would be more accurate with qRound, but slower. - qreal d = x - si * (2.0 * M_PI / QT_SINE_TABLE_SIZE); + int si = int(x * (qreal(0.5) * QT_SINE_TABLE_SIZE / Q_PI)); // Would be more accurate with qRound, but slower. + qreal d = x - si * (qreal(2.0) * Q_PI / QT_SINE_TABLE_SIZE); int ci = si + QT_SINE_TABLE_SIZE / 4; si &= QT_SINE_TABLE_SIZE - 1; ci &= QT_SINE_TABLE_SIZE - 1; - return qt_sine_table[si] + (qt_sine_table[ci] - 0.5 * qt_sine_table[si] * d) * d; + return qt_sine_table[si] + (qt_sine_table[ci] - qreal(0.5) * qt_sine_table[si] * d) * d; } inline qreal qFastCos(qreal x) { - int ci = int(x * (0.5 * QT_SINE_TABLE_SIZE / M_PI)); // Would be more accurate with qRound, but slower. - qreal d = x - ci * (2.0 * M_PI / QT_SINE_TABLE_SIZE); + int ci = int(x * (qreal(0.5) * QT_SINE_TABLE_SIZE / Q_PI)); // Would be more accurate with qRound, but slower. + qreal d = x - ci * (qreal(2.0) * Q_PI / QT_SINE_TABLE_SIZE); int si = ci + QT_SINE_TABLE_SIZE / 4; si &= QT_SINE_TABLE_SIZE - 1; ci &= QT_SINE_TABLE_SIZE - 1; - return qt_sine_table[si] - (qt_sine_table[ci] + 0.5 * qt_sine_table[si] * d) * d; + return qt_sine_table[si] - (qt_sine_table[ci] + qreal(0.5) * qt_sine_table[si] * d) * d; +} + +inline qreal qFabs(qreal x) +{ +#ifdef QT_USE_MATH_H_FLOATS + if(sizeof(qreal) == sizeof(float)) + return fabsf(x); +#endif + return fabs(x); +} + +inline qreal qAtan2(qreal x, qreal y) +{ +#ifdef QT_USE_MATH_H_FLOATS + if(sizeof(qreal) == sizeof(float)) + return atan2f(x, y); +#endif + return atan2(x, y); } QT_END_NAMESPACE diff --git a/src/corelib/tools/qdatetime.cpp b/src/corelib/tools/qdatetime.cpp index db6435e..5ae2dde 100644 --- a/src/corelib/tools/qdatetime.cpp +++ b/src/corelib/tools/qdatetime.cpp @@ -1915,7 +1915,7 @@ QTime QTime::fromString(const QString& s, Qt::DateFormat f) const float msec(msec_s.toFloat(&ok)); if (!ok) return QTime(); - return QTime(hour, minute, second, qMin(qRound(msec * 1000.0), 999)); + return QTime(hour, minute, second, qMin(qRound(msec * qreal(1000.0)), 999)); } } } diff --git a/src/corelib/tools/qeasingcurve.cpp b/src/corelib/tools/qeasingcurve.cpp index 3e1e1ee..a629ebc 100644 --- a/src/corelib/tools/qeasingcurve.cpp +++ b/src/corelib/tools/qeasingcurve.cpp @@ -317,7 +317,7 @@ class QEasingCurveFunction public: enum Type { In, Out, InOut, OutIn }; - QEasingCurveFunction(QEasingCurveFunction::Type type = In, qreal period = 0.3, qreal amplitude = 1.0, + QEasingCurveFunction(QEasingCurveFunction::Type type = In, qreal period = qreal(0.3), qreal amplitude = qreal(1.0), qreal overshoot = 1.70158f) : _t(type), _p(period), _a(amplitude), _o(overshoot) { } @@ -667,7 +667,7 @@ bool QEasingCurve::operator==(const QEasingCurve &other) const */ qreal QEasingCurve::amplitude() const { - return d_ptr->config ? d_ptr->config->_a : 1.0; + return d_ptr->config ? d_ptr->config->_a : qreal(1.0); } /*! @@ -691,7 +691,7 @@ void QEasingCurve::setAmplitude(qreal amplitude) */ qreal QEasingCurve::period() const { - return d_ptr->config ? d_ptr->config->_p : 0.3; + return d_ptr->config ? d_ptr->config->_p : qreal(0.3); } /*! @@ -742,9 +742,9 @@ QEasingCurve::Type QEasingCurve::type() const void QEasingCurvePrivate::setType_helper(QEasingCurve::Type newType) { - qreal amp = -1.0; - qreal period = -1.0; - qreal overshoot = -1.0; + qreal amp = qreal(-1.0); + qreal period = qreal(-1.0); + qreal overshoot = qreal(-1.0); if (config) { amp = config->_a; @@ -754,13 +754,13 @@ void QEasingCurvePrivate::setType_helper(QEasingCurve::Type newType) config = 0; } - if (isConfigFunction(newType) || (amp != -1.0) || (period != -1.0) || (overshoot != -1.0)) { + if (isConfigFunction(newType) || (amp != qreal(-1.0)) || (period != qreal(-1.0)) || (overshoot != qreal(-1.0))) { config = curveToFunctionObject(newType); - if (amp != -1.0) + if (amp != qreal(-1.0)) config->_a = amp; - if (period != -1.0) + if (period != qreal(-1.0)) config->_p = period; - if (overshoot != -1.0) + if (overshoot != qreal(-1.0)) config->_o = overshoot; func = 0; } else if (newType != QEasingCurve::Custom) { diff --git a/src/corelib/tools/qline.cpp b/src/corelib/tools/qline.cpp index d0afb7a..5b30c97 100644 --- a/src/corelib/tools/qline.cpp +++ b/src/corelib/tools/qline.cpp @@ -574,7 +574,7 @@ qreal QLineF::angle() const const qreal dx = pt2.x() - pt1.x(); const qreal dy = pt2.y() - pt1.y(); - const qreal theta = atan2(-dy, dx) * 360.0 / M_2PI; + const qreal theta = qAtan2(-dy, dx) * qreal(360.0) / Q_2PI; const qreal theta_normalized = theta < 0 ? theta + 360 : theta; @@ -598,7 +598,7 @@ qreal QLineF::angle() const */ void QLineF::setAngle(qreal angle) { - const qreal angleR = angle * M_2PI / 360.0; + const qreal angleR = angle * Q_2PI / qreal(360.0); const qreal l = length(); const qreal dx = qCos(angleR) * l; @@ -620,7 +620,7 @@ void QLineF::setAngle(qreal angle) */ QLineF QLineF::fromPolar(qreal length, qreal angle) { - const qreal angleR = angle * M_2PI / 360.0; + const qreal angleR = angle * Q_2PI / qreal(360.0); return QLineF(0, 0, qCos(angleR) * length, -qSin(angleR) * length); } @@ -639,7 +639,7 @@ QLineF QLineF::unitVector() const QLineF f(p1(), QPointF(pt1.x() + x/len, pt1.y() + y/len)); #ifndef QT_NO_DEBUG - if (qAbs(f.length() - 1) >= 0.001) + if (qAbs(f.length() - 1) >= qreal(0.001)) qWarning("QLine::unitVector: New line does not have unit length"); #endif @@ -814,8 +814,8 @@ qreal QLineF::angle(const QLineF &l) const qreal cos_line = (dx()*l.dx() + dy()*l.dy()) / (length()*l.length()); qreal rad = 0; // only accept cos_line in the range [-1,1], if it is outside, use 0 (we return 0 rather than PI for those cases) - if (cos_line >= -1.0 && cos_line <= 1.0) rad = acos( cos_line ); - return rad * 360 / M_2PI; + if (cos_line >= qreal(-1.0) && cos_line <= qreal(1.0)) rad = qAcos( cos_line ); + return rad * 360 / Q_2PI; } |