sl@0: // Copyright (c) 1995-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\include\cpudefs.h sl@0: // sl@0: // WARNING: This file contains some APIs which are internal and are subject sl@0: // to change without notice. Such APIs should therefore not be used sl@0: // outside the Kernel and Hardware Services package. sl@0: // sl@0: sl@0: /** sl@0: @file sl@0: @internalTechnology sl@0: */ sl@0: sl@0: #ifndef __CPUDEFS_H__ sl@0: #define __CPUDEFS_H__ sl@0: sl@0: #ifdef __ARMCC__ sl@0: #define __ARM_ASSEMBLER_ISA__ 4 // "Instruction not supported on targeted CPU :(" sl@0: #else sl@0: #define __ARM_ASSEMBLER_ISA__ 4 sl@0: #endif sl@0: sl@0: // Should really have been __CPU_CORTEX_A8__ instead of __CPU_CORTEX_A8N__ sl@0: #ifdef __CPU_CORTEX_A8N__ sl@0: #undef __CPU_CORTEX_A8__ sl@0: #define __CPU_CORTEX_A8__ sl@0: #endif sl@0: sl@0: // sl@0: // Supported CPUs sl@0: // sl@0: sl@0: #ifdef __MARM__ sl@0: sl@0: #undef __CPU_SPECIFIED sl@0: #if defined(__CPU_ARM710T__) sl@0: #define __CPU_SPECIFIED sl@0: #elif defined(__CPU_ARM720T__) sl@0: #define __CPU_SPECIFIED sl@0: #elif defined(__CPU_SA1__) sl@0: #define __CPU_SPECIFIED sl@0: #elif defined(__CPU_ARM920T__) sl@0: #define __CPU_SPECIFIED sl@0: #elif defined(__CPU_ARM925T__) sl@0: #define __CPU_SPECIFIED sl@0: #elif defined(__CPU_XSCALE__) sl@0: #define __CPU_SPECIFIED sl@0: #elif defined(__CPU_ARM926J__) sl@0: #define __CPU_SPECIFIED sl@0: #elif defined(__CPU_ARM1136__) sl@0: #define __CPU_SPECIFIED sl@0: #elif defined(__CPU_ARM1176__) sl@0: #define __CPU_SPECIFIED sl@0: #elif defined(__CPU_ARM11MP__) sl@0: #define __CPU_SPECIFIED sl@0: #elif defined(__CPU_CORTEX_A8__) sl@0: #define __CPU_SPECIFIED sl@0: #elif defined(__CPU_CORTEX_A9__) sl@0: #define __CPU_SPECIFIED sl@0: #elif defined(__CPU_GENERIC_ARM4__) sl@0: #define __CPU_SPECIFIED sl@0: #endif sl@0: sl@0: #if defined(__SMP__) sl@0: #if defined(__CPU_SPECIFIED) sl@0: #if !defined(__CPU_ARM11MP__) && !defined(__CPU_CORTEX_A9__) sl@0: #error Specified CPU does not support SMP sl@0: #endif sl@0: #else sl@0: // If no CPU specified, assume lowest common denominator SMP sl@0: #define __CPU_ARM11MP__ sl@0: #endif sl@0: #endif sl@0: sl@0: #if defined(__CPU_ARM710T__) sl@0: #define __CPU_ARMV4T sl@0: sl@0: #elif defined(__CPU_ARM720T__) sl@0: #define __CPU_ARMV4T sl@0: sl@0: #elif defined(__CPU_SA1__) sl@0: #define __CPU_ARMV4 sl@0: sl@0: #elif defined(__CPU_ARM920T__) sl@0: #define __CPU_ARMV4T sl@0: sl@0: #elif defined(__CPU_ARM925T__) sl@0: #define __CPU_ARMV4T sl@0: sl@0: #elif defined(__CPU_XSCALE__) sl@0: #define __CPU_ARMV5T sl@0: #define __ENHANCED_DSP_INSTRUCTIONS sl@0: sl@0: #elif defined(__CPU_ARM926J__) sl@0: #define __CPU_ARMV5T sl@0: #define __ENHANCED_DSP_INSTRUCTIONS sl@0: #define __CPU_HAS_JAZELLE sl@0: sl@0: #elif defined(__CPU_ARM1136__) sl@0: #define __CPU_ARMV6 sl@0: sl@0: #elif defined(__CPU_ARM1176__) sl@0: #define __CPU_ARMV6 sl@0: sl@0: #elif defined(__CPU_ARM11MP__) sl@0: #define __CPU_ARMV6 sl@0: #define __CPU_ARM_HAS_WFI sl@0: #define __CPU_ARM_HAS_WFE_SEV sl@0: sl@0: #elif defined(__CPU_CORTEX_A8__) sl@0: #define __CPU_ARMV7 sl@0: sl@0: #elif defined(__CPU_CORTEX_A9__) sl@0: #define __CPU_ARMV7 sl@0: sl@0: #elif defined(__CPU_GENERIC_ARM4__) sl@0: #define __CPU_ARMV4 sl@0: sl@0: #else sl@0: // #error Unsupported CPU sl@0: #define __CPU_UNKNOWN sl@0: #endif sl@0: sl@0: #endif // __MARM__ sl@0: sl@0: sl@0: sl@0: // Macros for emitting single bytes of machine code sl@0: #ifdef __CW32__ sl@0: # define BYTE(x) _asm byte x sl@0: #elif __GCC32__ sl@0: # define BYTE(x) asm(".byte "#x); sl@0: #else sl@0: # define BYTE(x) _asm _emit x sl@0: #endif sl@0: sl@0: sl@0: // thiscall is different on GCC sl@0: #ifdef __GCC32__ sl@0: #define THISCALL_PROLOG0() asm("mov ecx,[esp+4]"); sl@0: #define THISCALL_PROLOG1() asm("mov ecx,[esp+4] \n mov eax,[esp+8] \n mov [esp+4],eax"); sl@0: #define THISCALL_PROLOG2() asm("mov ecx,[esp+4] \n mov eax,[esp+8] \n mov [esp+4],eax \n mov eax,[esp+12] \n mov [esp+8],eax"); sl@0: #define THISCALL_PROLOG3() asm("mov ecx,[esp+4] \n mov eax,[esp+8] \n mov [esp+4],eax \n mov eax,[esp+12] \n mov [esp+8],eax \n mov eax,[esp+16] \n mov [esp+12],eax"); sl@0: #define THISCALL_PROLOG0_BIGRETVAL() asm("mov ecx,[esp+8]"); sl@0: #define THISCALL_PROLOG1_BIGRETVAL() asm("mov ecx,[esp+8] \n mov eax,[esp+12] \n mov [esp+8],eax"); sl@0: #define THISCALL_EPILOG0() asm("ret"); sl@0: #define THISCALL_EPILOG1() asm("ret"); sl@0: #define THISCALL_EPILOG2() asm("ret"); sl@0: #define THISCALL_EPILOG3() asm("ret"); sl@0: #define THISCALL_EPILOG0_BIGRETVAL() asm("ret 4"); sl@0: #define THISCALL_EPILOG1_BIGRETVAL() asm("ret 4"); sl@0: #else sl@0: #define THISCALL_PROLOG0() sl@0: #define THISCALL_PROLOG1() sl@0: #define THISCALL_PROLOG2() sl@0: #define THISCALL_PROLOG3() sl@0: #define THISCALL_PROLOG0_BIGRETVAL() sl@0: #define THISCALL_PROLOG1_BIGRETVAL() sl@0: #define THISCALL_EPILOG0() __asm ret sl@0: #define THISCALL_EPILOG1() __asm ret 4 sl@0: #define THISCALL_EPILOG2() __asm ret 8 sl@0: #define THISCALL_EPILOG3() __asm ret 12 sl@0: #define THISCALL_EPILOG0_BIGRETVAL() __asm ret 4 sl@0: #define THISCALL_EPILOG1_BIGRETVAL() __asm ret 8 sl@0: #endif sl@0: sl@0: sl@0: // Workaround for MSVC++ 5.0 bug; MSVC incorrectly fixes up conditional jumps sl@0: // when the destination is a C++ function. sl@0: #if defined(__VC32__) && (_MSC_VER==1100) // untested on MSVC++ > 5.0 sl@0: # define _ASM_j(cond,dest) _asm jn##cond short $+11 _asm jmp dest sl@0: # define _ASM_jn(cond,dest) _asm j##cond short $+11 _asm jmp dest sl@0: #else sl@0: # if defined __GCC32__ sl@0: # define _ASM_j(cond,dest) asm("j"#cond " %a0": : "i"(dest)); sl@0: # define _ASM_jn(cond,dest) asm("jn"#cond " %a0": :"i"(dest)); sl@0: # else sl@0: # define _ASM_j(cond,dest) _asm j##cond dest sl@0: # define _ASM_jn(cond,dest) _asm jn##cond dest sl@0: # endif sl@0: #endif sl@0: sl@0: sl@0: sl@0: //#define __MINIMUM_MACHINE_CODE__ sl@0: sl@0: #if defined(__WINS__) sl@0: #define __NAKED__ __declspec( naked ) sl@0: #ifndef __MINIMUM_MACHINE_CODE__ sl@0: //#define __MEM_MACHINE_CODED__ sl@0: #endif sl@0: #define __CPU_X86 sl@0: #endif sl@0: sl@0: #if defined(__X86__) sl@0: # ifdef __GCC32__ sl@0: # define __NAKED__ // GCC does not support naked functions on X86 sl@0: # else sl@0: # define __NAKED__ __declspec( naked ) sl@0: # endif sl@0: # ifndef __MINIMUM_MACHINE_CODE__ sl@0: # define __MEM_MACHINE_CODED__ sl@0: # endif sl@0: # define __CPU_X86 sl@0: #endif sl@0: sl@0: sl@0: #if defined(__MARM__) sl@0: #ifndef __NAKED__ // should be defined in prefix file sl@0: #ifndef __GCCXML__ sl@0: #define __NAKED__ __declspec( naked ) sl@0: #else sl@0: #define __NAKED__ sl@0: #endif sl@0: #endif sl@0: #ifndef __CIA__ sl@0: #undef __NAKED__ sl@0: #define __NAKED__ ____ONLY_USE_NAKED_IN_CIA____ sl@0: #endif sl@0: #define __CPU_ARM sl@0: sl@0: #if defined(__MARM_ARMV5__) && !defined(__CPU_ARMV5T) sl@0: #define __CPU_ARMV5T sl@0: #endif sl@0: sl@0: #ifndef __MINIMUM_MACHINE_CODE__ sl@0: #if !defined(__BIG_ENDIAN__) sl@0: #define __MEM_MACHINE_CODED__ sl@0: #define __DES_MACHINE_CODED__ sl@0: #define __REGIONS_MACHINE_CODED__ sl@0: #define __DES8_MACHINE_CODED__ sl@0: #define __DES16_MACHINE_CODED__ sl@0: #define __HEAP_MACHINE_CODED__ sl@0: #define __REALS_MACHINE_CODED__ sl@0: #define __COBJECT_MACHINE_CODED__ sl@0: #define __CACTIVESCHEDULER_MACHINE_CODED__ sl@0: #define __CSERVER_MACHINE_CODED__ sl@0: #define __ARRAY_MACHINE_CODED__ sl@0: #define __HUFFMAN_MACHINE_CODED__ sl@0: #if defined(__MARM_ARM4__) || defined(__MARM_ARMI__) || defined(__MARM_THUMB__) || defined(__MARM_ARMV4__) || defined(__MARM_ARMV5__) sl@0: #define __DES16_MACHINE_CODED_HWORD__ sl@0: #endif sl@0: #endif sl@0: #endif sl@0: #endif sl@0: sl@0: #ifdef __CPU_ARMV4 sl@0: #define __CPU_64BIT_MULTIPLY sl@0: #endif sl@0: #ifdef __CPU_ARMV4T sl@0: #define __CPU_THUMB sl@0: #define __CPU_ARM_SUPPORTS_BX sl@0: #define __CPU_64BIT_MULTIPLY sl@0: #endif sl@0: #ifdef __CPU_ARMV5T sl@0: #define __CPU_THUMB sl@0: #define __CPU_ARM_SUPPORTS_BX sl@0: #define __CPU_ARM_SUPPORTS_BLX sl@0: #define __CPU_64BIT_MULTIPLY sl@0: #define __CPU_ARM_LDR_PC_SETS_TBIT sl@0: #define __CPU_ARM_HAS_CLZ sl@0: #define __CPU_ARM_HAS_PLD sl@0: #endif sl@0: #ifdef __ENHANCED_DSP_INSTRUCTIONS sl@0: #define __CPU_ARM_HAS_MCRR sl@0: #define __CPU_ARM_HAS_LDRD_STRD sl@0: #endif sl@0: #if defined(__CPU_ARMV6) || defined(__CPU_ARMV7) sl@0: #define __CPU_THUMB sl@0: #define __CPU_ARM_SUPPORTS_BX sl@0: #define __CPU_ARM_SUPPORTS_BLX sl@0: #define __CPU_64BIT_MULTIPLY sl@0: #define __CPU_ARM_LDR_PC_SETS_TBIT sl@0: #define __CPU_ARM_HAS_CLZ sl@0: #define __CPU_ARM_HAS_MCRR sl@0: #define __CPU_ARM_HAS_LDREX_STREX sl@0: #define __CPU_ARM_HAS_LDRD_STRD sl@0: #define __CPU_ARM_HAS_PLD sl@0: #define __CPU_ARM_HAS_CPS sl@0: #define __CPU_ARM_HAS_SPLIT_FSR sl@0: #if !defined(__CPU_ARM1136__) && !defined(__CPU_ARM11MP__) sl@0: #define __CPU_ARM_HAS_CP15_IFAR sl@0: #endif sl@0: #define __CPU_ARM_SUPPORTS_USER_MODE_BARRIERS sl@0: #endif sl@0: #if defined(__CPU_ARMV7) || (defined(__CPU_ARM1136__) && defined(__CPU_ARM1136_IS_R1__)) || defined(__CPU_ARM1176__) || defined(__CPU_ARM11MP__) sl@0: #define __CPU_ARM_HAS_LDREX_STREX_V6K sl@0: #define __CPU_HAS_CP15_THREAD_ID_REG sl@0: #endif sl@0: #if defined(__MARM_ARM4T__) || defined(__MARM_INTERWORK__) sl@0: #define __SUPPORT_THUMB_INTERWORKING sl@0: #endif sl@0: #if defined(__CPU_ARMV7) sl@0: #define __CPU_ARM_HAS_WFI sl@0: #define __CPU_ARM_HAS_WFE_SEV sl@0: #define __CPU_THUMB2 sl@0: #define __CPU_SUPPORT_THUMB2EE sl@0: #endif sl@0: sl@0: sl@0: // ARM CPU macros to allow Thumb/Non-thumb builds sl@0: #ifdef __CPU_ARM sl@0: sl@0: #define EXC_TRAP_CTX_SZ 10 // Nonvolatile registers + sp + pc sl@0: sl@0: #ifdef __SUPPORT_THUMB_INTERWORKING sl@0: #define __JUMP(cc,r) asm("bx"#cc " "#r ) sl@0: #ifdef __CPU_ARM_LDR_PC_SETS_TBIT sl@0: #define __POPRET(rlist) asm("ldmfd sp!, {"rlist"pc} ") sl@0: #define __CPOPRET(cc,rlist) asm("ldm"#cc "fd sp!, {"rlist"pc} ") sl@0: #else sl@0: #define __POPRET(rlist) asm("ldmfd sp!, {"rlist"lr} ");\ sl@0: asm("bx lr ") sl@0: #define __CPOPRET(cc,rlist) asm("ldm"#cc "fd sp!, {"rlist"lr} ");\ sl@0: asm("bx"#cc " lr ") sl@0: #endif sl@0: #else sl@0: #define __JUMP(cc,r) asm("mov"#cc " pc, "#r ) sl@0: #define __POPRET(rlist) asm("ldmfd sp!, {"rlist"pc} ") sl@0: #define __CPOPRET(cc,rlist) asm("ldm"#cc "fd sp!, {"rlist"pc} ") sl@0: #endif sl@0: sl@0: #ifdef __CPU_ARM_SUPPORTS_BLX sl@0: #if __ARM_ASSEMBLER_ISA__ >= 5 sl@0: #define BLX(Rm) asm("blx r" #Rm) sl@0: #else sl@0: #define BLX(Rm) asm(".word %a0" : : "i" ((TInt)( 0xe12fff30 | (Rm) ))) sl@0: #endif sl@0: #define __JUMPL(Rm) BLX(Rm) sl@0: #else sl@0: #ifdef __SUPPORT_THUMB_INTERWORKING sl@0: #define __JUMPL(Rm) asm("mov lr, pc "); \ sl@0: asm("bx r"#Rm ) sl@0: #else sl@0: #define __JUMPL(Rm) asm("mov lr, pc "); \ sl@0: asm("mov pc, r"#Rm ) sl@0: #endif sl@0: #endif sl@0: sl@0: #ifdef __MARM_THUMB__ sl@0: #ifndef __ARMCC__ sl@0: #define __SWITCH_TO_ARM asm("push {r0} ");\ sl@0: asm("add r0, pc, #4 ");\ sl@0: asm("bx r0 ");\ sl@0: asm("nop ");\ sl@0: asm(".align 2 ");\ sl@0: asm(".code 32 ");\ sl@0: asm("ldr r0, [sp], #4 ") sl@0: #define __END_ARM asm(".code 16 ") sl@0: #else sl@0: #define __SWITCH_TO_ARM asm(".code 32 "); sl@0: #define __END_ARM sl@0: #endif sl@0: #else sl@0: #define __SWITCH_TO_ARM sl@0: #define __END_ARM sl@0: #endif sl@0: sl@0: #define CC_EQ 0 sl@0: #define CC_NE 1 sl@0: #define CC_CS 2 sl@0: #define CC_CC 3 sl@0: #define CC_MI 4 sl@0: #define CC_PL 5 sl@0: #define CC_VS 6 sl@0: #define CC_VC 7 sl@0: #define CC_HI 8 sl@0: #define CC_LS 9 sl@0: #define CC_GE 10 sl@0: #define CC_LT 11 sl@0: #define CC_GT 12 sl@0: #define CC_LE 13 sl@0: #define CC_AL 14 sl@0: sl@0: #ifdef __CPU_ARM_HAS_CLZ sl@0: #if __ARM_ASSEMBLER_ISA__ >= 5 sl@0: #define CLZ(Rd,Rm) asm("clz r" #Rd ", r" #Rm) sl@0: #else sl@0: #define CLZ(Rd,Rm) asm(".word %a0" : : "i" ((TInt)0xe16f0f10|((Rd)<<12)|(Rm))); sl@0: #endif sl@0: #define CLZcc(cc,Rd,Rm) asm(".word %a0" : : "i" ((TInt)0x016f0f10|((cc)<<28)|((Rd)<<12)|(Rm))); sl@0: #endif sl@0: #ifdef __CPU_ARM_HAS_MCRR sl@0: #define MCRR(cop,opc,Rd,Rn,CRm) asm(".word %a0" : : "i" ((TInt)0xec400000|((Rn)<<16)|((Rd)<<12)|((cop)<<8)|((opc)<<4)|(CRm))); sl@0: #define MCRRcc(cc,cop,opc,Rd,Rn,CRm) asm(".word %a0" : : "i" ((TInt)0x0c400000|((cc)<<28)|((Rn)<<16)|((Rd)<<12)|((cop)<<8)|((opc)<<4)|(CRm))); sl@0: #define MRRC(cop,opc,Rd,Rn,CRm) asm(".word %a0" : : "i" ((TInt)0xec500000|((Rn)<<16)|((Rd)<<12)|((cop)<<8)|((opc)<<4)|(CRm))); sl@0: #define MRRCcc(cc,cop,opc,Rd,Rn,CRm) asm(".word %a0" : : "i" ((TInt)0x0c500000|((cc)<<28)|((Rn)<<16)|((Rd)<<12)|((cop)<<8)|((opc)<<4)|(CRm))); sl@0: #endif sl@0: #ifdef __CPU_ARM_HAS_LDREX_STREX sl@0: // LDREX Rd, [Rn] - load from [Rn] into Rd exclusive sl@0: // STREX Rd, Rm, [Rn] - store Rm into [Rn] with exclusive access; success/fail indicator into Rd sl@0: #define LDREXcc(cc,Rd,Rn) asm(".word %a0" : : "i" ((TInt)(0x01900f9f|((cc)<<28)|((Rd)<<12)|((Rn)<<16)))); sl@0: #define STREXcc(cc,Rd,Rm,Rn) asm(".word %a0" : : "i" ((TInt)(0x01800f90|((cc)<<28)|((Rd)<<12)|(Rm)|((Rn)<<16)))); sl@0: #if __ARM_ASSEMBLER_ISA__ >= 6 sl@0: #define LDREX(Rd,Rn) asm("ldrex r" #Rd ", [r" #Rn "] ") sl@0: #define STREX(Rd,Rm,Rn) asm("strex r" #Rd ", r" #Rm ", [r" #Rn "] ") sl@0: #else sl@0: #define LDREX(Rd,Rn) asm(".word %a0" : : "i" ((TInt)(0x01900f9f|((CC_AL)<<28)|((Rd)<<12)|((Rn)<<16)))); sl@0: #define STREX(Rd,Rm,Rn) asm(".word %a0" : : "i" ((TInt)(0x01800f90|((CC_AL)<<28)|((Rd)<<12)|(Rm)|((Rn)<<16)))); sl@0: #endif sl@0: #endif sl@0: #ifdef __CPU_ARM_HAS_LDREX_STREX_V6K sl@0: // Byte, halfword, doubleword STREX/LDREX & unconditional CLREX sl@0: #if __ARM_ASSEMBLER_ISA__ >= 6 sl@0: #define LDREXB(Rd,Rn) asm("ldrexb r" #Rd ", [r" #Rn "] ") sl@0: #define STREXB(Rd,Rm,Rn) asm("strexb r" #Rd ", r" #Rm ", [r" #Rn "] ") sl@0: #define LDREXH(Rd,Rn) asm("ldrexh r" #Rd ", [r" #Rn "] ") sl@0: #define STREXH(Rd,Rm,Rn) asm("strexh r" #Rd ", r" #Rm ", [r" #Rn "] ") sl@0: #define LDREXD(Rd,Rn) asm("ldrexd r" #Rd ", [r" #Rn "] ") sl@0: #define STREXD(Rd,Rm,Rn) asm("strexd r" #Rd ", r" #Rm ", [r" #Rn "] ") sl@0: #else sl@0: #define LDREXB(Rd,Rn) asm(".word %a0" : : "i" ((TInt)(0x01D00f9f|((CC_AL)<<28)|((Rd)<<12)|((Rn)<<16)))); sl@0: #define STREXB(Rd,Rm,Rn) asm(".word %a0" : : "i" ((TInt)(0x01C00f90|((CC_AL)<<28)|((Rd)<<12)|(Rm)|((Rn)<<16)))); sl@0: #define LDREXH(Rd,Rn) asm(".word %a0" : : "i" ((TInt)(0x01f00f9f|((CC_AL)<<28)|((Rd)<<12)|((Rn)<<16)))); sl@0: #define STREXH(Rd,Rm,Rn) asm(".word %a0" : : "i" ((TInt)(0x01e00f90|((CC_AL)<<28)|((Rd)<<12)|(Rm)|((Rn)<<16)))); sl@0: #define LDREXD(Rd,Rn) asm(".word %a0" : : "i" ((TInt)(0x01b00f9f|((CC_AL)<<28)|((Rd)<<12)|((Rn)<<16)))); sl@0: #define STREXD(Rd,Rm,Rn) asm(".word %a0" : : "i" ((TInt)(0x01a00f90|((CC_AL)<<28)|((Rd)<<12)|(Rm)|((Rn)<<16)))); sl@0: #endif sl@0: #if !defined(__CPU_ARM1136__) || defined(__CPU_ARM1136_ERRATUM_406973_FIXED) sl@0: #define __CPU_ARM_HAS_WORKING_CLREX sl@0: #if __ARM_ASSEMBLER_ISA__ >= 6 sl@0: #define CLREX asm("clrex ") sl@0: #else sl@0: #define CLREX asm(".word %a0" : : "i" ((TInt)(0xf57ff01f))); sl@0: #endif sl@0: #endif sl@0: #endif sl@0: #ifdef __CPU_ARM_HAS_LDRD_STRD sl@0: #if __ARM_ASSEMBLER_ISA__ >= 5 sl@0: #define LDRD(Rd,Rn) asm("ldrd r" #Rd ", [r" #Rn "] ") sl@0: #define STRD(Rd,Rn) asm("strd r" #Rd ", [r" #Rn "] ") sl@0: #else sl@0: #define LDRD(Rd,Rn) asm(".word %a0" : : "i" ((TInt)( 0xe1c000d0 | ((Rn)<<16) | ((Rd)<<12) ))) sl@0: #define STRD(Rd,Rn) asm(".word %a0" : : "i" ((TInt)( 0xe1c000f0 | ((Rn)<<16) | ((Rd)<<12) ))) sl@0: #endif sl@0: #define LDRD_ioff(Rd,Rn,off) asm(".word %a0" : : "i" ((TInt)( 0xe1c000d0 | ((Rn)<<16) | ((Rd)<<12) | (((off)&0xf0)<<4) | ((off)&0x0f) ))) sl@0: #define STRD_ioff(Rd,Rn,off) asm(".word %a0" : : "i" ((TInt)( 0xe1c000f0 | ((Rn)<<16) | ((Rd)<<12) | (((off)&0xf0)<<4) | ((off)&0x0f) ))) sl@0: #endif sl@0: #if defined(__CPU_ARM_HAS_PLD) && !defined(__CPU_ARM926J__) && !defined(__CPU_UNKNOWN) // PLD is a no-op on ARM926 sl@0: #if __ARM_ASSEMBLER_ISA__ >= 5 sl@0: #define PLD(Rn) asm("pld [r" #Rn "] ") sl@0: #else sl@0: #define PLD(Rn) asm(".word %a0" : : "i" ((TInt)( 0xf5d0f000 | ((Rn)<<16) ))) sl@0: #endif sl@0: #define PLD_ioff(Rn, off) asm(".word %a0" : : "i" ((TInt)( 0xf5d0f000 | ((Rn)<<16) | (off) ))) // preload with immediate offset sl@0: #define PLD_noff(Rn, off) asm(".word %a0" : : "i" ((TInt)( 0xf550f000 | ((Rn)<<16) | (off) ))) // preload with negative offset sl@0: #else sl@0: #define PLD(Rn) sl@0: #define PLD_ioff(Rn, off) sl@0: #define PLD_noff(Rn, off) sl@0: #endif sl@0: #ifdef __CPU_HAS_CP15_THREAD_ID_REG sl@0: #define GET_RWRW_TID(cc,r) asm("mrc"#cc" p15, 0, "#r", c13, c0, 2 "); sl@0: #define GET_RWRO_TID(cc,r) asm("mrc"#cc" p15, 0, "#r", c13, c0, 3 "); sl@0: #define GET_RWNO_TID(cc,r) asm("mrc"#cc" p15, 0, "#r", c13, c0, 4 "); sl@0: #define SET_RWRW_TID(cc,r) asm("mcr"#cc" p15, 0, "#r", c13, c0, 2 "); sl@0: #define SET_RWRO_TID(cc,r) asm("mcr"#cc" p15, 0, "#r", c13, c0, 3 "); sl@0: #define SET_RWNO_TID(cc,r) asm("mcr"#cc" p15, 0, "#r", c13, c0, 4 "); sl@0: #endif sl@0: sl@0: #ifdef __CPU_SUPPORT_THUMB2EE sl@0: #define GET_THUMB2EE_HNDLR_BASE(cc,r) asm("mrc"#cc" p14, 6, "#r", c1, c0, 0 ") sl@0: #define SET_THUMB2EE_HNDLR_BASE(cc,r) asm("mcr"#cc" p14, 6, "#r", c1, c0, 0 ") sl@0: #endif sl@0: sl@0: #if defined(__CPU_ARMV7) sl@0: #define ARM_DMB_gen(opt) asm(".word %a0" : : "i" ((TInt)(0xf57ff050 | (opt) )) ) sl@0: #define ARM_DSB_gen(opt) asm(".word %a0" : : "i" ((TInt)(0xf57ff040 | (opt) )) ) sl@0: #define ARM_ISB_gen(opt) asm(".word %a0" : : "i" ((TInt)(0xf57ff060 | (opt) )) ) sl@0: sl@0: #define ARM_DMBSY ARM_DMB_gen(0xf) // full system DMB sl@0: #define ARM_DSBSY ARM_DSB_gen(0xf) // full system DSB sl@0: #define ARM_DMBST ARM_DMB_gen(0xe) // full system DMB, orders writes only sl@0: #define ARM_DSBST ARM_DSB_gen(0xe) // full system DSB, orders writes only sl@0: #define ARM_DMBSH ARM_DMB_gen(0xb) // DMB encompassing inner-shareable domain sl@0: #define ARM_DSBSH ARM_DSB_gen(0xb) // DMB encompassing inner-shareable domain sl@0: #define ARM_DMBSHST ARM_DMB_gen(0xa) // DMB encompassing inner-shareable domain, orders writes only sl@0: #define ARM_DSBSHST ARM_DSB_gen(0xa) // DMB encompassing inner-shareable domain, orders writes only sl@0: sl@0: #define ARM_ISBSY ARM_ISB_gen(0xf) // full system ISB sl@0: sl@0: #define ARM_NOP asm(".word 0xe320f000 ") sl@0: #define ARM_YIELD asm(".word 0xe320f001 ") sl@0: sl@0: #define __DATA_MEMORY_BARRIER__(reg) ARM_DMBSH sl@0: #define __DATA_MEMORY_BARRIER_Z__(reg) asm("mov "#reg", #0"); ARM_DMBSH sl@0: #define __DATA_SYNC_BARRIER__(reg) ARM_DSBSH sl@0: #define __DATA_SYNC_BARRIER_Z__(reg) asm("mov "#reg", #0"); ARM_DSBSH sl@0: #define __INST_SYNC_BARRIER__(reg) ARM_ISBSY sl@0: #define __INST_SYNC_BARRIER_Z__(reg) asm("mov "#reg", #0"); ARM_ISBSY sl@0: sl@0: #elif defined(__CPU_ARM11MP__) sl@0: sl@0: #define ARM_DMB(reg) asm("mcr p15, 0, "#reg", c7, c10, 5 ") sl@0: #define ARM_DSB(reg) asm("mcr p15, 0, "#reg", c7, c10, 4 ") sl@0: #define ARM_ISB(reg) asm("mcr p15, 0, "#reg", c7, c5, 4 ") sl@0: sl@0: #define ARM_NOP asm(".word 0xe320f000 ") sl@0: #define ARM_YIELD asm(".word 0xe320f001 ") sl@0: sl@0: #define __DATA_MEMORY_BARRIER__(reg) ARM_DMB(reg) sl@0: #define __DATA_MEMORY_BARRIER_Z__(reg) asm("mov "#reg", #0"); ARM_DMB(reg) sl@0: #define __DATA_SYNC_BARRIER__(reg) ARM_DSB(reg) sl@0: #define __DATA_SYNC_BARRIER_Z__(reg) asm("mov "#reg", #0"); ARM_DSB(reg) sl@0: #define __INST_SYNC_BARRIER__(reg) ARM_ISB(reg) sl@0: #define __INST_SYNC_BARRIER_Z__(reg) asm("mov "#reg", #0"); ARM_ISB(reg) sl@0: sl@0: #elif defined(__CPU_ARMV6__) sl@0: sl@0: #define ARM_DMB(reg) asm("mcr p15, 0, "#reg", c7, c10, 5 ") sl@0: #define ARM_DSB(reg) asm("mcr p15, 0, "#reg", c7, c10, 4 ") sl@0: #define ARM_ISB(reg) asm("mcr p15, 0, "#reg", c7, c5, 4 ") sl@0: sl@0: #define __DATA_MEMORY_BARRIER__(reg) ARM_DMB(reg) sl@0: #define __DATA_MEMORY_BARRIER_Z__(reg) asm("mov "#reg", #0"); ARM_DMB(reg) sl@0: #define __DATA_SYNC_BARRIER__(reg) ARM_DSB(reg) sl@0: #define __DATA_SYNC_BARRIER_Z__(reg) asm("mov "#reg", #0"); ARM_DSB(reg) sl@0: #define __INST_SYNC_BARRIER__(reg) ARM_ISB(reg) sl@0: #define __INST_SYNC_BARRIER_Z__(reg) asm("mov "#reg", #0"); ARM_ISB(reg) sl@0: sl@0: #else sl@0: sl@0: #define __DATA_MEMORY_BARRIER__(reg) sl@0: #define __DATA_MEMORY_BARRIER_Z__(reg) asm("mov "#reg", #0") sl@0: #define __DATA_SYNC_BARRIER__(reg) asm("mcr p15, 0, "#reg", c7, c10, 4 ") sl@0: #define __DATA_SYNC_BARRIER_Z__(reg) asm("mov "#reg", #0"); asm("mcr p15, 0, "#reg", c7, c10, 4 ") sl@0: #define __INST_SYNC_BARRIER__(reg) sl@0: #define __INST_SYNC_BARRIER_Z__(reg) asm("mov "#reg", #0") sl@0: sl@0: #endif sl@0: sl@0: #ifdef __SMP__ sl@0: #define __SMP_DATA_MEMORY_BARRIER__(reg) __DATA_MEMORY_BARRIER__(reg) sl@0: #define __SMP_DATA_MEMORY_BARRIER_Z__(reg) __DATA_MEMORY_BARRIER_Z__(reg) sl@0: #define __SMP_DATA_SYNC_BARRIER__(reg) __DATA_SYNC_BARRIER__(reg) sl@0: #define __SMP_DATA_SYNC_BARRIER_Z__(reg) __DATA_SYNC_BARRIER_Z__(reg) sl@0: #define __SMP_INST_SYNC_BARRIER__(reg) __INST_SYNC_BARRIER__(reg) sl@0: #define __SMP_INST_SYNC_BARRIER_Z__(reg) __INST_SYNC_BARRIER_Z__(reg) sl@0: #else sl@0: #define __SMP_DATA_MEMORY_BARRIER__(reg) sl@0: #define __SMP_DATA_MEMORY_BARRIER_Z__(reg) asm("mov "#reg", #0") sl@0: #define __SMP_DATA_SYNC_BARRIER__(reg) sl@0: #define __SMP_DATA_SYNC_BARRIER_Z__(reg) asm("mov "#reg", #0") sl@0: #define __SMP_INST_SYNC_BARRIER__(reg) sl@0: #define __SMP_INST_SYNC_BARRIER_Z__(reg) asm("mov "#reg", #0") sl@0: #endif sl@0: sl@0: #ifdef __CPU_ARM_HAS_WFI sl@0: #define ARM_WFIcc(cc) __DATA_SYNC_BARRIER__(r0); \ sl@0: asm(".word %a0" : : "i" ((TInt)(0x0320f003 | ((cc)<<28) )) ) sl@0: #define ARM_WFI ARM_WFIcc(CC_AL) sl@0: #endif sl@0: sl@0: #ifdef __CPU_ARM_HAS_WFE_SEV sl@0: #define ARM_WFEcc(cc) __DATA_SYNC_BARRIER__(r0); \ sl@0: asm(".word %a0" : : "i" ((TInt)(0x0320f002 | ((cc)<<28) )) ) sl@0: #if __ARM_ASSEMBLER_ISA__ >= 6 sl@0: #define ARM_WFE __DATA_SYNC_BARRIER__(r0); \ sl@0: asm("wfe ") sl@0: #else sl@0: #define ARM_WFE ARM_WFEcc(CC_AL) sl@0: #endif sl@0: #define ARM_SEVcc(cc) asm(".word %a0" : : "i" ((TInt)(0x0320f004 | ((cc)<<28) )) ) sl@0: #if __ARM_ASSEMBLER_ISA__ >= 6 sl@0: #define ARM_SEV asm("sev ") sl@0: #else sl@0: #define ARM_SEV ARM_SEVcc(CC_AL) sl@0: #endif sl@0: #endif sl@0: sl@0: #ifndef ARM_NOP sl@0: #define ARM_NOP asm("nop ") sl@0: #define ARM_YIELD asm("nop ") sl@0: #endif sl@0: sl@0: // Support for throwing exceptions through ARM embedded assembler sl@0: // Should only be needed user side sl@0: #ifndef __EH_FRAME_ADDRESS sl@0: #define __EH_FRAME_ADDRESS(reg,offset) sl@0: #define __EH_FRAME_PUSH2(reg1,reg2) sl@0: #define __EH_FRAME_SAVE1(reg,offset) sl@0: #endif sl@0: sl@0: // StrongARM msr bug workaround: sl@0: // (conditional msr might cause,that the next instruction is executed twice by these processors) sl@0: #ifdef __CPU_SA1__ sl@0: #define __MSR_CPSR_C(cc,r) \ sl@0: asm("msr"#cc" cpsr_c," #r); \ sl@0: ARM_NOP; sl@0: #else // !__CPU_SA1__ sl@0: #define __MSR_CPSR_C(cc,r) asm("msr"#cc" cpsr_c,"#r); sl@0: #endif sl@0: sl@0: // Causes undefined instruction exception on both ARM and THUMB sl@0: #define __ASM_CRASH() asm(".word 0xe7ffdeff ") sl@0: #if defined(__GNUC__) sl@0: #define __crash() asm(".word 0xe7ffdeff " : : : "memory") sl@0: #elif defined(__ARMCC__) sl@0: // RVCT doesn't let us inline an undefined instruction sl@0: // use a CDP to CP15 instead - doesn't work on THUMB but never mind sl@0: #if __ARMCC_VERSION < 310000 sl@0: #define __crash() asm("cdp p15, 0, c0, c0, c0, 0 ") sl@0: #else sl@0: // Inline assembler is deprecated in RVCT 3.1 so we use an intrinsic. sl@0: #define __crash() __cdp(15, 0x00, 0x000) sl@0: #endif sl@0: #endif sl@0: sl@0: // Macro used to get the caller of the function containing a CHECK_PRECONDITIONS() sl@0: #if defined(__ARMCC_VERSION) && __ARMCC_VERSION >= 200000 sl@0: #define PRECOND_FUNCTION_CALLER __return_address() sl@0: #endif sl@0: sl@0: #if !defined(__CPU_ARM_HAS_LDREX_STREX_V6K) sl@0: #if defined(__CPU_ARM_HAS_LDREX_STREX) sl@0: #define __ATOMIC64_USE_SLOW_EXEC__ sl@0: #else sl@0: #define __ATOMIC64_USE_FAST_EXEC__ sl@0: #define __ATOMIC_USE_FAST_EXEC__ sl@0: #endif sl@0: #endif sl@0: sl@0: #endif // __CPU_ARM sl@0: sl@0: #ifdef __CPU_X86 sl@0: #define EXC_TRAP_CTX_SZ 10 // ebx, esp, ebp, esi, edi, ds, es, fs, gs, eip sl@0: sl@0: // Causes exception sl@0: #if defined(__VC32__) || defined(__CW32__) sl@0: #define __crash() do { _asm int 0ffh } while(0) sl@0: #else sl@0: #define __crash() asm("int 0xff " : : : "memory") sl@0: #endif sl@0: sl@0: #ifdef __VC32__ sl@0: // Not available in the version of MSVC normally used sl@0: // #define PRECOND_FUNCTION_CALLER ((TLinAddr)_ReturnAddress()) sl@0: #endif sl@0: sl@0: #endif // __CPU_X86 sl@0: sl@0: #ifdef __GCC32__ sl@0: #define PRECOND_FUNCTION_CALLER ((TLinAddr)__builtin_return_address(0)) sl@0: #endif sl@0: sl@0: #endif