sl@0: // Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). sl@0: // All rights reserved. sl@0: // This component and the accompanying materials are made available sl@0: // under the terms of the License "Eclipse Public License v1.0" sl@0: // which accompanies this distribution, and is available sl@0: // at the URL "http://www.eclipse.org/legal/epl-v10.html". sl@0: // sl@0: // Initial Contributors: sl@0: // Nokia Corporation - initial contribution. sl@0: // sl@0: // Contributors: sl@0: // sl@0: // Description: sl@0: // e32\common\arm\atomic_ops.h sl@0: // sl@0: // sl@0: sl@0: #ifdef __OPERATION__ sl@0: sl@0: #undef __OPERATION__ sl@0: #undef __OP_RMW1__ sl@0: #undef __OP_RMW2__ sl@0: #undef __OP_RMW3__ sl@0: #undef __OP_SIGNED__ sl@0: #undef __TYPE__ sl@0: #undef __SIZE_CODE__ sl@0: #undef __LDR_INST__ sl@0: #undef __LDRS_INST__ sl@0: #undef __STR_INST__ sl@0: #undef __LDREX_INST__ sl@0: #undef __STREX_INST__ sl@0: #undef __SIGN_EXTEND__ sl@0: #undef __LOG2_DATA_SIZE__ sl@0: sl@0: #undef __OP_LOAD__ sl@0: #undef __OP_STORE__ sl@0: #undef __OP_SWP__ sl@0: #undef __OP_CAS__ sl@0: #undef __OP_ADD__ sl@0: #undef __OP_AND__ sl@0: #undef __OP_IOR__ sl@0: #undef __OP_XOR__ sl@0: #undef __OP_AXO__ sl@0: #undef __OP_TAU__ sl@0: #undef __OP_TAS__ sl@0: sl@0: #undef ENSURE_8BYTE_ALIGNMENT sl@0: sl@0: #else // __OPERATION__ sl@0: sl@0: #if defined(__OP_LOAD__) sl@0: #define __OPERATION__ load sl@0: #elif defined(__OP_STORE__) sl@0: #define __OPERATION__ store sl@0: #elif defined(__OP_SWP__) sl@0: #define __OPERATION__ swp sl@0: #define __OP_RMW1__ sl@0: #elif defined(__OP_CAS__) sl@0: #define __OPERATION__ cas sl@0: #elif defined(__OP_ADD__) sl@0: #define __OPERATION__ add sl@0: #define __OP_RMW1__ sl@0: #elif defined(__OP_AND__) sl@0: #define __OPERATION__ and sl@0: #define __OP_RMW1__ sl@0: #elif defined(__OP_IOR__) sl@0: #define __OPERATION__ ior sl@0: #define __OP_RMW1__ sl@0: #elif defined(__OP_XOR__) sl@0: #define __OPERATION__ xor sl@0: #define __OP_RMW1__ sl@0: #elif defined(__OP_AXO__) sl@0: #define __OPERATION__ axo sl@0: #define __OP_RMW2__ sl@0: #elif defined(__OP_TAU__) sl@0: #define __OPERATION__ tau sl@0: #define __OP_RMW3__ sl@0: #elif defined(__OP_TAS__) sl@0: #define __OPERATION__ tas sl@0: #define __OP_RMW3__ sl@0: #define __OP_SIGNED__ sl@0: #else sl@0: #error Unknown atomic operation sl@0: #endif sl@0: sl@0: #if __DATA_SIZE__==8 sl@0: #define __LOG2_DATA_SIZE__ 3 sl@0: #define __SIZE_CODE__ "b" sl@0: #ifdef __CPU_ARM_HAS_LDREX_STREX_V6K sl@0: #define __LDREX_INST__(Rd,Rn) LDREXB(Rd,Rn) sl@0: #define __STREX_INST__(Rd,Rm,Rn) STREXB(Rd,Rm,Rn) sl@0: #endif sl@0: #define __SIGN_EXTEND__(reg) asm("mov "#reg ", "#reg ", lsl #24 "); asm("mov "#reg ", "#reg ", asr #24 "); sl@0: #define __LDR_INST__(cc,args) asm("ldr"#cc "b " args) sl@0: #define __LDRS_INST__(cc,args) asm("ldr"#cc "sb " args) sl@0: #define __STR_INST__(cc,args) asm("str"#cc "b " args) sl@0: #ifdef __OP_SIGNED__ sl@0: #define __TYPE__ TInt8 sl@0: #else sl@0: #define __TYPE__ TUint8 sl@0: #endif sl@0: #elif __DATA_SIZE__==16 sl@0: #define __LOG2_DATA_SIZE__ 4 sl@0: #define __SIZE_CODE__ "h" sl@0: #ifdef __CPU_ARM_HAS_LDREX_STREX_V6K sl@0: #define __LDREX_INST__(Rd,Rn) LDREXH(Rd,Rn) sl@0: #define __STREX_INST__(Rd,Rm,Rn) STREXH(Rd,Rm,Rn) sl@0: #endif sl@0: #define __SIGN_EXTEND__(reg) asm("mov "#reg ", "#reg ", lsl #16 "); asm("mov "#reg ", "#reg ", asr #16 "); sl@0: #define __LDR_INST__(cc,args) asm("ldr"#cc "h " args) sl@0: #define __LDRS_INST__(cc,args) asm("ldr"#cc "sh " args) sl@0: #define __STR_INST__(cc,args) asm("str"#cc "h " args) sl@0: #ifdef __OP_SIGNED__ sl@0: #define __TYPE__ TInt16 sl@0: #else sl@0: #define __TYPE__ TUint16 sl@0: #endif sl@0: #elif __DATA_SIZE__==32 sl@0: #define __LOG2_DATA_SIZE__ 5 sl@0: #define __SIZE_CODE__ "" sl@0: #ifdef __CPU_ARM_HAS_LDREX_STREX sl@0: #define __LDREX_INST__(Rd,Rn) LDREX(Rd,Rn) sl@0: #define __STREX_INST__(Rd,Rm,Rn) STREX(Rd,Rm,Rn) sl@0: #endif sl@0: #define __SIGN_EXTEND__(reg) sl@0: #define __LDR_INST__(cc,args) asm("ldr"#cc " " args) sl@0: #define __LDRS_INST__(cc,args) asm("ldr"#cc " " args) sl@0: #define __STR_INST__(cc,args) asm("str"#cc " " args) sl@0: #ifdef __OP_SIGNED__ sl@0: #define __TYPE__ TInt32 sl@0: #else sl@0: #define __TYPE__ TUint32 sl@0: #endif sl@0: #elif __DATA_SIZE__==64 sl@0: #define __LOG2_DATA_SIZE__ 6 sl@0: #define __SIZE_CODE__ "d" sl@0: #ifdef __CPU_ARM_HAS_LDREX_STREX_V6K sl@0: #define __LDREX_INST__(Rd,Rn) LDREXD(Rd,Rn) sl@0: #define __STREX_INST__(Rd,Rm,Rn) STREXD(Rd,Rm,Rn) sl@0: #endif sl@0: #ifdef __OP_SIGNED__ sl@0: #define __TYPE__ TInt64 sl@0: #else sl@0: #define __TYPE__ TUint64 sl@0: #endif sl@0: #else sl@0: #error Invalid data size sl@0: #endif sl@0: sl@0: #if (defined(__GNUC__) && (__GNUC__ >= 3)) || defined(__EABI__) sl@0: // Check 8 byte aligned and cause alignment fault if not. sl@0: // Doesn't work if alignment checking is disabled but gives consistent behaviour sl@0: // between processors with ldrexd etc and these hand coded versions. sl@0: #define ENSURE_8BYTE_ALIGNMENT(rAddr) \ sl@0: asm("tst r"#rAddr", #0x7 "); \ sl@0: asm("orrne r"#rAddr", r"#rAddr", #1 "); \ sl@0: asm("ldmne r"#rAddr", {r"#rAddr"} ") sl@0: #else sl@0: // Don't assert on old gcc (arm4) as it is not eabi compliant and this stops sl@0: // kernel booting. sl@0: #define ENSURE_8BYTE_ALIGNMENT(rAddr) sl@0: #endif sl@0: #endif // __OPERATION__