0
|
1 |
// Copyright (c) 1995-2009 Nokia Corporation and/or its subsidiary(-ies).
|
|
2 |
// All rights reserved.
|
|
3 |
// This component and the accompanying materials are made available
|
|
4 |
// under the terms of the License "Eclipse Public License v1.0"
|
|
5 |
// which accompanies this distribution, and is available
|
|
6 |
// at the URL "http://www.eclipse.org/legal/epl-v10.html".
|
|
7 |
//
|
|
8 |
// Initial Contributors:
|
|
9 |
// Nokia Corporation - initial contribution.
|
|
10 |
//
|
|
11 |
// Contributors:
|
|
12 |
//
|
|
13 |
// Description:
|
|
14 |
// e32\include\cpudefs.h
|
|
15 |
//
|
|
16 |
// WARNING: This file contains some APIs which are internal and are subject
|
|
17 |
// to change without notice. Such APIs should therefore not be used
|
|
18 |
// outside the Kernel and Hardware Services package.
|
|
19 |
//
|
|
20 |
|
|
21 |
/**
|
|
22 |
@file
|
|
23 |
@internalTechnology
|
|
24 |
*/
|
|
25 |
|
|
26 |
#ifndef __CPUDEFS_H__
|
|
27 |
#define __CPUDEFS_H__
|
|
28 |
|
|
29 |
#ifdef __ARMCC__
|
|
30 |
#define __ARM_ASSEMBLER_ISA__ 4 // "Instruction not supported on targeted CPU :("
|
|
31 |
#else
|
|
32 |
#define __ARM_ASSEMBLER_ISA__ 4
|
|
33 |
#endif
|
|
34 |
|
|
35 |
// Should really have been __CPU_CORTEX_A8__ instead of __CPU_CORTEX_A8N__
|
|
36 |
#ifdef __CPU_CORTEX_A8N__
|
|
37 |
#undef __CPU_CORTEX_A8__
|
|
38 |
#define __CPU_CORTEX_A8__
|
|
39 |
#endif
|
|
40 |
|
|
41 |
//
|
|
42 |
// Supported CPUs
|
|
43 |
//
|
|
44 |
|
|
45 |
#ifdef __MARM__
|
|
46 |
|
|
47 |
#undef __CPU_SPECIFIED
|
|
48 |
#if defined(__CPU_ARM710T__)
|
|
49 |
#define __CPU_SPECIFIED
|
|
50 |
#elif defined(__CPU_ARM720T__)
|
|
51 |
#define __CPU_SPECIFIED
|
|
52 |
#elif defined(__CPU_SA1__)
|
|
53 |
#define __CPU_SPECIFIED
|
|
54 |
#elif defined(__CPU_ARM920T__)
|
|
55 |
#define __CPU_SPECIFIED
|
|
56 |
#elif defined(__CPU_ARM925T__)
|
|
57 |
#define __CPU_SPECIFIED
|
|
58 |
#elif defined(__CPU_XSCALE__)
|
|
59 |
#define __CPU_SPECIFIED
|
|
60 |
#elif defined(__CPU_ARM926J__)
|
|
61 |
#define __CPU_SPECIFIED
|
|
62 |
#elif defined(__CPU_ARM1136__)
|
|
63 |
#define __CPU_SPECIFIED
|
|
64 |
#elif defined(__CPU_ARM1176__)
|
|
65 |
#define __CPU_SPECIFIED
|
|
66 |
#elif defined(__CPU_ARM11MP__)
|
|
67 |
#define __CPU_SPECIFIED
|
|
68 |
#elif defined(__CPU_CORTEX_A8__)
|
|
69 |
#define __CPU_SPECIFIED
|
|
70 |
#elif defined(__CPU_CORTEX_A9__)
|
|
71 |
#define __CPU_SPECIFIED
|
|
72 |
#elif defined(__CPU_GENERIC_ARM4__)
|
|
73 |
#define __CPU_SPECIFIED
|
|
74 |
#endif
|
|
75 |
|
|
76 |
#if defined(__SMP__)
|
|
77 |
#if defined(__CPU_SPECIFIED)
|
|
78 |
#if !defined(__CPU_ARM11MP__) && !defined(__CPU_CORTEX_A9__)
|
|
79 |
#error Specified CPU does not support SMP
|
|
80 |
#endif
|
|
81 |
#else
|
|
82 |
// If no CPU specified, assume lowest common denominator SMP
|
|
83 |
#define __CPU_ARM11MP__
|
|
84 |
#endif
|
|
85 |
#endif
|
|
86 |
|
|
87 |
#if defined(__CPU_ARM710T__)
|
|
88 |
#define __CPU_ARMV4T
|
|
89 |
|
|
90 |
#elif defined(__CPU_ARM720T__)
|
|
91 |
#define __CPU_ARMV4T
|
|
92 |
|
|
93 |
#elif defined(__CPU_SA1__)
|
|
94 |
#define __CPU_ARMV4
|
|
95 |
|
|
96 |
#elif defined(__CPU_ARM920T__)
|
|
97 |
#define __CPU_ARMV4T
|
|
98 |
|
|
99 |
#elif defined(__CPU_ARM925T__)
|
|
100 |
#define __CPU_ARMV4T
|
|
101 |
|
|
102 |
#elif defined(__CPU_XSCALE__)
|
|
103 |
#define __CPU_ARMV5T
|
|
104 |
#define __ENHANCED_DSP_INSTRUCTIONS
|
|
105 |
|
|
106 |
#elif defined(__CPU_ARM926J__)
|
|
107 |
#define __CPU_ARMV5T
|
|
108 |
#define __ENHANCED_DSP_INSTRUCTIONS
|
|
109 |
#define __CPU_HAS_JAZELLE
|
|
110 |
|
|
111 |
#elif defined(__CPU_ARM1136__)
|
|
112 |
#define __CPU_ARMV6
|
|
113 |
|
|
114 |
#elif defined(__CPU_ARM1176__)
|
|
115 |
#define __CPU_ARMV6
|
|
116 |
|
|
117 |
#elif defined(__CPU_ARM11MP__)
|
|
118 |
#define __CPU_ARMV6
|
|
119 |
#define __CPU_ARM_HAS_WFI
|
|
120 |
#define __CPU_ARM_HAS_WFE_SEV
|
|
121 |
|
|
122 |
#elif defined(__CPU_CORTEX_A8__)
|
|
123 |
#define __CPU_ARMV7
|
|
124 |
|
|
125 |
#elif defined(__CPU_CORTEX_A9__)
|
|
126 |
#define __CPU_ARMV7
|
|
127 |
|
|
128 |
#elif defined(__CPU_GENERIC_ARM4__)
|
|
129 |
#define __CPU_ARMV4
|
|
130 |
|
|
131 |
#else
|
|
132 |
// #error Unsupported CPU
|
|
133 |
#define __CPU_UNKNOWN
|
|
134 |
#endif
|
|
135 |
|
|
136 |
#endif // __MARM__
|
|
137 |
|
|
138 |
|
|
139 |
|
|
140 |
// Macros for emitting single bytes of machine code
|
|
141 |
#ifdef __CW32__
|
|
142 |
# define BYTE(x) _asm byte x
|
|
143 |
#elif __GCC32__
|
|
144 |
# define BYTE(x) asm(".byte "#x);
|
|
145 |
#else
|
|
146 |
# define BYTE(x) _asm _emit x
|
|
147 |
#endif
|
|
148 |
|
|
149 |
|
|
150 |
// thiscall is different on GCC
|
|
151 |
#ifdef __GCC32__
|
|
152 |
#define THISCALL_PROLOG0() asm("mov ecx,[esp+4]");
|
|
153 |
#define THISCALL_PROLOG1() asm("mov ecx,[esp+4] \n mov eax,[esp+8] \n mov [esp+4],eax");
|
|
154 |
#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");
|
|
155 |
#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");
|
|
156 |
#define THISCALL_PROLOG0_BIGRETVAL() asm("mov ecx,[esp+8]");
|
|
157 |
#define THISCALL_PROLOG1_BIGRETVAL() asm("mov ecx,[esp+8] \n mov eax,[esp+12] \n mov [esp+8],eax");
|
|
158 |
#define THISCALL_EPILOG0() asm("ret");
|
|
159 |
#define THISCALL_EPILOG1() asm("ret");
|
|
160 |
#define THISCALL_EPILOG2() asm("ret");
|
|
161 |
#define THISCALL_EPILOG3() asm("ret");
|
|
162 |
#define THISCALL_EPILOG0_BIGRETVAL() asm("ret 4");
|
|
163 |
#define THISCALL_EPILOG1_BIGRETVAL() asm("ret 4");
|
|
164 |
#else
|
|
165 |
#define THISCALL_PROLOG0()
|
|
166 |
#define THISCALL_PROLOG1()
|
|
167 |
#define THISCALL_PROLOG2()
|
|
168 |
#define THISCALL_PROLOG3()
|
|
169 |
#define THISCALL_PROLOG0_BIGRETVAL()
|
|
170 |
#define THISCALL_PROLOG1_BIGRETVAL()
|
|
171 |
#define THISCALL_EPILOG0() __asm ret
|
|
172 |
#define THISCALL_EPILOG1() __asm ret 4
|
|
173 |
#define THISCALL_EPILOG2() __asm ret 8
|
|
174 |
#define THISCALL_EPILOG3() __asm ret 12
|
|
175 |
#define THISCALL_EPILOG0_BIGRETVAL() __asm ret 4
|
|
176 |
#define THISCALL_EPILOG1_BIGRETVAL() __asm ret 8
|
|
177 |
#endif
|
|
178 |
|
|
179 |
|
|
180 |
// Workaround for MSVC++ 5.0 bug; MSVC incorrectly fixes up conditional jumps
|
|
181 |
// when the destination is a C++ function.
|
|
182 |
#if defined(__VC32__) && (_MSC_VER==1100) // untested on MSVC++ > 5.0
|
|
183 |
# define _ASM_j(cond,dest) _asm jn##cond short $+11 _asm jmp dest
|
|
184 |
# define _ASM_jn(cond,dest) _asm j##cond short $+11 _asm jmp dest
|
|
185 |
#else
|
|
186 |
# if defined __GCC32__
|
|
187 |
# define _ASM_j(cond,dest) asm("j"#cond " %a0": : "i"(dest));
|
|
188 |
# define _ASM_jn(cond,dest) asm("jn"#cond " %a0": :"i"(dest));
|
|
189 |
# else
|
|
190 |
# define _ASM_j(cond,dest) _asm j##cond dest
|
|
191 |
# define _ASM_jn(cond,dest) _asm jn##cond dest
|
|
192 |
# endif
|
|
193 |
#endif
|
|
194 |
|
|
195 |
|
|
196 |
|
|
197 |
//#define __MINIMUM_MACHINE_CODE__
|
|
198 |
|
|
199 |
#if defined(__WINS__)
|
|
200 |
#define __NAKED__ __declspec( naked )
|
|
201 |
#ifndef __MINIMUM_MACHINE_CODE__
|
|
202 |
//#define __MEM_MACHINE_CODED__
|
|
203 |
#endif
|
|
204 |
#define __CPU_X86
|
|
205 |
#endif
|
|
206 |
|
|
207 |
#if defined(__X86__)
|
|
208 |
# ifdef __GCC32__
|
|
209 |
# define __NAKED__ // GCC does not support naked functions on X86
|
|
210 |
# else
|
|
211 |
# define __NAKED__ __declspec( naked )
|
|
212 |
# endif
|
|
213 |
# ifndef __MINIMUM_MACHINE_CODE__
|
|
214 |
# define __MEM_MACHINE_CODED__
|
|
215 |
# endif
|
|
216 |
# define __CPU_X86
|
|
217 |
#endif
|
|
218 |
|
|
219 |
|
|
220 |
#if defined(__MARM__)
|
|
221 |
#ifndef __NAKED__ // should be defined in prefix file
|
|
222 |
#ifndef __GCCXML__
|
|
223 |
#define __NAKED__ __declspec( naked )
|
|
224 |
#else
|
|
225 |
#define __NAKED__
|
|
226 |
#endif
|
|
227 |
#endif
|
|
228 |
#ifndef __CIA__
|
|
229 |
#undef __NAKED__
|
|
230 |
#define __NAKED__ ____ONLY_USE_NAKED_IN_CIA____
|
|
231 |
#endif
|
|
232 |
#define __CPU_ARM
|
|
233 |
|
|
234 |
#if defined(__MARM_ARMV5__) && !defined(__CPU_ARMV5T)
|
|
235 |
#define __CPU_ARMV5T
|
|
236 |
#endif
|
|
237 |
|
|
238 |
#ifndef __MINIMUM_MACHINE_CODE__
|
|
239 |
#if !defined(__BIG_ENDIAN__)
|
|
240 |
#define __MEM_MACHINE_CODED__
|
|
241 |
#define __DES_MACHINE_CODED__
|
|
242 |
#define __REGIONS_MACHINE_CODED__
|
|
243 |
#define __DES8_MACHINE_CODED__
|
|
244 |
#define __DES16_MACHINE_CODED__
|
|
245 |
#define __HEAP_MACHINE_CODED__
|
|
246 |
#define __REALS_MACHINE_CODED__
|
|
247 |
#define __COBJECT_MACHINE_CODED__
|
|
248 |
#define __CACTIVESCHEDULER_MACHINE_CODED__
|
|
249 |
#define __CSERVER_MACHINE_CODED__
|
|
250 |
#define __ARRAY_MACHINE_CODED__
|
|
251 |
#define __HUFFMAN_MACHINE_CODED__
|
|
252 |
#if defined(__MARM_ARM4__) || defined(__MARM_ARMI__) || defined(__MARM_THUMB__) || defined(__MARM_ARMV4__) || defined(__MARM_ARMV5__)
|
|
253 |
#define __DES16_MACHINE_CODED_HWORD__
|
|
254 |
#endif
|
|
255 |
#endif
|
|
256 |
#endif
|
|
257 |
#endif
|
|
258 |
|
|
259 |
#ifdef __CPU_ARMV4
|
|
260 |
#define __CPU_64BIT_MULTIPLY
|
|
261 |
#endif
|
|
262 |
#ifdef __CPU_ARMV4T
|
|
263 |
#define __CPU_THUMB
|
|
264 |
#define __CPU_ARM_SUPPORTS_BX
|
|
265 |
#define __CPU_64BIT_MULTIPLY
|
|
266 |
#endif
|
|
267 |
#ifdef __CPU_ARMV5T
|
|
268 |
#define __CPU_THUMB
|
|
269 |
#define __CPU_ARM_SUPPORTS_BX
|
|
270 |
#define __CPU_ARM_SUPPORTS_BLX
|
|
271 |
#define __CPU_64BIT_MULTIPLY
|
|
272 |
#define __CPU_ARM_LDR_PC_SETS_TBIT
|
|
273 |
#define __CPU_ARM_HAS_CLZ
|
|
274 |
#define __CPU_ARM_HAS_PLD
|
|
275 |
#endif
|
|
276 |
#ifdef __ENHANCED_DSP_INSTRUCTIONS
|
|
277 |
#define __CPU_ARM_HAS_MCRR
|
|
278 |
#define __CPU_ARM_HAS_LDRD_STRD
|
|
279 |
#endif
|
|
280 |
#if defined(__CPU_ARMV6) || defined(__CPU_ARMV7)
|
|
281 |
#define __CPU_THUMB
|
|
282 |
#define __CPU_ARM_SUPPORTS_BX
|
|
283 |
#define __CPU_ARM_SUPPORTS_BLX
|
|
284 |
#define __CPU_64BIT_MULTIPLY
|
|
285 |
#define __CPU_ARM_LDR_PC_SETS_TBIT
|
|
286 |
#define __CPU_ARM_HAS_CLZ
|
|
287 |
#define __CPU_ARM_HAS_MCRR
|
|
288 |
#define __CPU_ARM_HAS_LDREX_STREX
|
|
289 |
#define __CPU_ARM_HAS_LDRD_STRD
|
|
290 |
#define __CPU_ARM_HAS_PLD
|
|
291 |
#define __CPU_ARM_HAS_CPS
|
|
292 |
#define __CPU_ARM_HAS_SPLIT_FSR
|
|
293 |
#if !defined(__CPU_ARM1136__) && !defined(__CPU_ARM11MP__)
|
|
294 |
#define __CPU_ARM_HAS_CP15_IFAR
|
|
295 |
#endif
|
|
296 |
#define __CPU_ARM_SUPPORTS_USER_MODE_BARRIERS
|
|
297 |
#endif
|
|
298 |
#if defined(__CPU_ARMV7) || (defined(__CPU_ARM1136__) && defined(__CPU_ARM1136_IS_R1__)) || defined(__CPU_ARM1176__) || defined(__CPU_ARM11MP__)
|
|
299 |
#define __CPU_ARM_HAS_LDREX_STREX_V6K
|
|
300 |
#define __CPU_HAS_CP15_THREAD_ID_REG
|
|
301 |
#endif
|
|
302 |
#if defined(__MARM_ARM4T__) || defined(__MARM_INTERWORK__)
|
|
303 |
#define __SUPPORT_THUMB_INTERWORKING
|
|
304 |
#endif
|
|
305 |
#if defined(__CPU_ARMV7)
|
|
306 |
#define __CPU_ARM_HAS_WFI
|
|
307 |
#define __CPU_ARM_HAS_WFE_SEV
|
|
308 |
#define __CPU_THUMB2
|
|
309 |
#define __CPU_SUPPORT_THUMB2EE
|
|
310 |
#endif
|
|
311 |
|
|
312 |
|
|
313 |
// ARM CPU macros to allow Thumb/Non-thumb builds
|
|
314 |
#ifdef __CPU_ARM
|
|
315 |
|
|
316 |
#define EXC_TRAP_CTX_SZ 10 // Nonvolatile registers + sp + pc
|
|
317 |
|
|
318 |
#ifdef __SUPPORT_THUMB_INTERWORKING
|
|
319 |
#define __JUMP(cc,r) asm("bx"#cc " "#r )
|
|
320 |
#ifdef __CPU_ARM_LDR_PC_SETS_TBIT
|
|
321 |
#define __POPRET(rlist) asm("ldmfd sp!, {"rlist"pc} ")
|
|
322 |
#define __CPOPRET(cc,rlist) asm("ldm"#cc "fd sp!, {"rlist"pc} ")
|
|
323 |
#else
|
|
324 |
#define __POPRET(rlist) asm("ldmfd sp!, {"rlist"lr} ");\
|
|
325 |
asm("bx lr ")
|
|
326 |
#define __CPOPRET(cc,rlist) asm("ldm"#cc "fd sp!, {"rlist"lr} ");\
|
|
327 |
asm("bx"#cc " lr ")
|
|
328 |
#endif
|
|
329 |
#else
|
|
330 |
#define __JUMP(cc,r) asm("mov"#cc " pc, "#r )
|
|
331 |
#define __POPRET(rlist) asm("ldmfd sp!, {"rlist"pc} ")
|
|
332 |
#define __CPOPRET(cc,rlist) asm("ldm"#cc "fd sp!, {"rlist"pc} ")
|
|
333 |
#endif
|
|
334 |
|
|
335 |
#ifdef __CPU_ARM_SUPPORTS_BLX
|
|
336 |
#if __ARM_ASSEMBLER_ISA__ >= 5
|
|
337 |
#define BLX(Rm) asm("blx r" #Rm)
|
|
338 |
#else
|
|
339 |
#define BLX(Rm) asm(".word %a0" : : "i" ((TInt)( 0xe12fff30 | (Rm) )))
|
|
340 |
#endif
|
|
341 |
#define __JUMPL(Rm) BLX(Rm)
|
|
342 |
#else
|
|
343 |
#ifdef __SUPPORT_THUMB_INTERWORKING
|
|
344 |
#define __JUMPL(Rm) asm("mov lr, pc "); \
|
|
345 |
asm("bx r"#Rm )
|
|
346 |
#else
|
|
347 |
#define __JUMPL(Rm) asm("mov lr, pc "); \
|
|
348 |
asm("mov pc, r"#Rm )
|
|
349 |
#endif
|
|
350 |
#endif
|
|
351 |
|
|
352 |
#ifdef __MARM_THUMB__
|
|
353 |
#ifndef __ARMCC__
|
|
354 |
#define __SWITCH_TO_ARM asm("push {r0} ");\
|
|
355 |
asm("add r0, pc, #4 ");\
|
|
356 |
asm("bx r0 ");\
|
|
357 |
asm("nop ");\
|
|
358 |
asm(".align 2 ");\
|
|
359 |
asm(".code 32 ");\
|
|
360 |
asm("ldr r0, [sp], #4 ")
|
|
361 |
#define __END_ARM asm(".code 16 ")
|
|
362 |
#else
|
|
363 |
#define __SWITCH_TO_ARM asm(".code 32 ");
|
|
364 |
#define __END_ARM
|
|
365 |
#endif
|
|
366 |
#else
|
|
367 |
#define __SWITCH_TO_ARM
|
|
368 |
#define __END_ARM
|
|
369 |
#endif
|
|
370 |
|
|
371 |
#define CC_EQ 0
|
|
372 |
#define CC_NE 1
|
|
373 |
#define CC_CS 2
|
|
374 |
#define CC_CC 3
|
|
375 |
#define CC_MI 4
|
|
376 |
#define CC_PL 5
|
|
377 |
#define CC_VS 6
|
|
378 |
#define CC_VC 7
|
|
379 |
#define CC_HI 8
|
|
380 |
#define CC_LS 9
|
|
381 |
#define CC_GE 10
|
|
382 |
#define CC_LT 11
|
|
383 |
#define CC_GT 12
|
|
384 |
#define CC_LE 13
|
|
385 |
#define CC_AL 14
|
|
386 |
|
|
387 |
#ifdef __CPU_ARM_HAS_CLZ
|
|
388 |
#if __ARM_ASSEMBLER_ISA__ >= 5
|
|
389 |
#define CLZ(Rd,Rm) asm("clz r" #Rd ", r" #Rm)
|
|
390 |
#else
|
|
391 |
#define CLZ(Rd,Rm) asm(".word %a0" : : "i" ((TInt)0xe16f0f10|((Rd)<<12)|(Rm)));
|
|
392 |
#endif
|
|
393 |
#define CLZcc(cc,Rd,Rm) asm(".word %a0" : : "i" ((TInt)0x016f0f10|((cc)<<28)|((Rd)<<12)|(Rm)));
|
|
394 |
#endif
|
|
395 |
#ifdef __CPU_ARM_HAS_MCRR
|
|
396 |
#define MCRR(cop,opc,Rd,Rn,CRm) asm(".word %a0" : : "i" ((TInt)0xec400000|((Rn)<<16)|((Rd)<<12)|((cop)<<8)|((opc)<<4)|(CRm)));
|
|
397 |
#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)));
|
|
398 |
#define MRRC(cop,opc,Rd,Rn,CRm) asm(".word %a0" : : "i" ((TInt)0xec500000|((Rn)<<16)|((Rd)<<12)|((cop)<<8)|((opc)<<4)|(CRm)));
|
|
399 |
#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)));
|
|
400 |
#endif
|
|
401 |
#ifdef __CPU_ARM_HAS_LDREX_STREX
|
|
402 |
// LDREX Rd, [Rn] - load from [Rn] into Rd exclusive
|
|
403 |
// STREX Rd, Rm, [Rn] - store Rm into [Rn] with exclusive access; success/fail indicator into Rd
|
|
404 |
#define LDREXcc(cc,Rd,Rn) asm(".word %a0" : : "i" ((TInt)(0x01900f9f|((cc)<<28)|((Rd)<<12)|((Rn)<<16))));
|
|
405 |
#define STREXcc(cc,Rd,Rm,Rn) asm(".word %a0" : : "i" ((TInt)(0x01800f90|((cc)<<28)|((Rd)<<12)|(Rm)|((Rn)<<16))));
|
|
406 |
#if __ARM_ASSEMBLER_ISA__ >= 6
|
|
407 |
#define LDREX(Rd,Rn) asm("ldrex r" #Rd ", [r" #Rn "] ")
|
|
408 |
#define STREX(Rd,Rm,Rn) asm("strex r" #Rd ", r" #Rm ", [r" #Rn "] ")
|
|
409 |
#else
|
|
410 |
#define LDREX(Rd,Rn) asm(".word %a0" : : "i" ((TInt)(0x01900f9f|((CC_AL)<<28)|((Rd)<<12)|((Rn)<<16))));
|
|
411 |
#define STREX(Rd,Rm,Rn) asm(".word %a0" : : "i" ((TInt)(0x01800f90|((CC_AL)<<28)|((Rd)<<12)|(Rm)|((Rn)<<16))));
|
|
412 |
#endif
|
|
413 |
#endif
|
|
414 |
#ifdef __CPU_ARM_HAS_LDREX_STREX_V6K
|
|
415 |
// Byte, halfword, doubleword STREX/LDREX & unconditional CLREX
|
|
416 |
#if __ARM_ASSEMBLER_ISA__ >= 6
|
|
417 |
#define LDREXB(Rd,Rn) asm("ldrexb r" #Rd ", [r" #Rn "] ")
|
|
418 |
#define STREXB(Rd,Rm,Rn) asm("strexb r" #Rd ", r" #Rm ", [r" #Rn "] ")
|
|
419 |
#define LDREXH(Rd,Rn) asm("ldrexh r" #Rd ", [r" #Rn "] ")
|
|
420 |
#define STREXH(Rd,Rm,Rn) asm("strexh r" #Rd ", r" #Rm ", [r" #Rn "] ")
|
|
421 |
#define LDREXD(Rd,Rn) asm("ldrexd r" #Rd ", [r" #Rn "] ")
|
|
422 |
#define STREXD(Rd,Rm,Rn) asm("strexd r" #Rd ", r" #Rm ", [r" #Rn "] ")
|
|
423 |
#else
|
|
424 |
#define LDREXB(Rd,Rn) asm(".word %a0" : : "i" ((TInt)(0x01D00f9f|((CC_AL)<<28)|((Rd)<<12)|((Rn)<<16))));
|
|
425 |
#define STREXB(Rd,Rm,Rn) asm(".word %a0" : : "i" ((TInt)(0x01C00f90|((CC_AL)<<28)|((Rd)<<12)|(Rm)|((Rn)<<16))));
|
|
426 |
#define LDREXH(Rd,Rn) asm(".word %a0" : : "i" ((TInt)(0x01f00f9f|((CC_AL)<<28)|((Rd)<<12)|((Rn)<<16))));
|
|
427 |
#define STREXH(Rd,Rm,Rn) asm(".word %a0" : : "i" ((TInt)(0x01e00f90|((CC_AL)<<28)|((Rd)<<12)|(Rm)|((Rn)<<16))));
|
|
428 |
#define LDREXD(Rd,Rn) asm(".word %a0" : : "i" ((TInt)(0x01b00f9f|((CC_AL)<<28)|((Rd)<<12)|((Rn)<<16))));
|
|
429 |
#define STREXD(Rd,Rm,Rn) asm(".word %a0" : : "i" ((TInt)(0x01a00f90|((CC_AL)<<28)|((Rd)<<12)|(Rm)|((Rn)<<16))));
|
|
430 |
#endif
|
|
431 |
#if !defined(__CPU_ARM1136__) || defined(__CPU_ARM1136_ERRATUM_406973_FIXED)
|
|
432 |
#define __CPU_ARM_HAS_WORKING_CLREX
|
|
433 |
#if __ARM_ASSEMBLER_ISA__ >= 6
|
|
434 |
#define CLREX asm("clrex ")
|
|
435 |
#else
|
|
436 |
#define CLREX asm(".word %a0" : : "i" ((TInt)(0xf57ff01f)));
|
|
437 |
#endif
|
|
438 |
#endif
|
|
439 |
#endif
|
|
440 |
#ifdef __CPU_ARM_HAS_LDRD_STRD
|
|
441 |
#if __ARM_ASSEMBLER_ISA__ >= 5
|
|
442 |
#define LDRD(Rd,Rn) asm("ldrd r" #Rd ", [r" #Rn "] ")
|
|
443 |
#define STRD(Rd,Rn) asm("strd r" #Rd ", [r" #Rn "] ")
|
|
444 |
#else
|
|
445 |
#define LDRD(Rd,Rn) asm(".word %a0" : : "i" ((TInt)( 0xe1c000d0 | ((Rn)<<16) | ((Rd)<<12) )))
|
|
446 |
#define STRD(Rd,Rn) asm(".word %a0" : : "i" ((TInt)( 0xe1c000f0 | ((Rn)<<16) | ((Rd)<<12) )))
|
|
447 |
#endif
|
|
448 |
#define LDRD_ioff(Rd,Rn,off) asm(".word %a0" : : "i" ((TInt)( 0xe1c000d0 | ((Rn)<<16) | ((Rd)<<12) | (((off)&0xf0)<<4) | ((off)&0x0f) )))
|
|
449 |
#define STRD_ioff(Rd,Rn,off) asm(".word %a0" : : "i" ((TInt)( 0xe1c000f0 | ((Rn)<<16) | ((Rd)<<12) | (((off)&0xf0)<<4) | ((off)&0x0f) )))
|
|
450 |
#endif
|
|
451 |
#if defined(__CPU_ARM_HAS_PLD) && !defined(__CPU_ARM926J__) && !defined(__CPU_UNKNOWN) // PLD is a no-op on ARM926
|
|
452 |
#if __ARM_ASSEMBLER_ISA__ >= 5
|
|
453 |
#define PLD(Rn) asm("pld [r" #Rn "] ")
|
|
454 |
#else
|
|
455 |
#define PLD(Rn) asm(".word %a0" : : "i" ((TInt)( 0xf5d0f000 | ((Rn)<<16) )))
|
|
456 |
#endif
|
|
457 |
#define PLD_ioff(Rn, off) asm(".word %a0" : : "i" ((TInt)( 0xf5d0f000 | ((Rn)<<16) | (off) ))) // preload with immediate offset
|
|
458 |
#define PLD_noff(Rn, off) asm(".word %a0" : : "i" ((TInt)( 0xf550f000 | ((Rn)<<16) | (off) ))) // preload with negative offset
|
|
459 |
#else
|
|
460 |
#define PLD(Rn)
|
|
461 |
#define PLD_ioff(Rn, off)
|
|
462 |
#define PLD_noff(Rn, off)
|
|
463 |
#endif
|
|
464 |
#ifdef __CPU_HAS_CP15_THREAD_ID_REG
|
|
465 |
#define GET_RWRW_TID(cc,r) asm("mrc"#cc" p15, 0, "#r", c13, c0, 2 ");
|
|
466 |
#define GET_RWRO_TID(cc,r) asm("mrc"#cc" p15, 0, "#r", c13, c0, 3 ");
|
|
467 |
#define GET_RWNO_TID(cc,r) asm("mrc"#cc" p15, 0, "#r", c13, c0, 4 ");
|
|
468 |
#define SET_RWRW_TID(cc,r) asm("mcr"#cc" p15, 0, "#r", c13, c0, 2 ");
|
|
469 |
#define SET_RWRO_TID(cc,r) asm("mcr"#cc" p15, 0, "#r", c13, c0, 3 ");
|
|
470 |
#define SET_RWNO_TID(cc,r) asm("mcr"#cc" p15, 0, "#r", c13, c0, 4 ");
|
|
471 |
#endif
|
|
472 |
|
|
473 |
#ifdef __CPU_SUPPORT_THUMB2EE
|
|
474 |
#define GET_THUMB2EE_HNDLR_BASE(cc,r) asm("mrc"#cc" p14, 6, "#r", c1, c0, 0 ")
|
|
475 |
#define SET_THUMB2EE_HNDLR_BASE(cc,r) asm("mcr"#cc" p14, 6, "#r", c1, c0, 0 ")
|
|
476 |
#endif
|
|
477 |
|
|
478 |
#if defined(__CPU_ARMV7)
|
|
479 |
#define ARM_DMB_gen(opt) asm(".word %a0" : : "i" ((TInt)(0xf57ff050 | (opt) )) )
|
|
480 |
#define ARM_DSB_gen(opt) asm(".word %a0" : : "i" ((TInt)(0xf57ff040 | (opt) )) )
|
|
481 |
#define ARM_ISB_gen(opt) asm(".word %a0" : : "i" ((TInt)(0xf57ff060 | (opt) )) )
|
|
482 |
|
|
483 |
#define ARM_DMBSY ARM_DMB_gen(0xf) // full system DMB
|
|
484 |
#define ARM_DSBSY ARM_DSB_gen(0xf) // full system DSB
|
|
485 |
#define ARM_DMBST ARM_DMB_gen(0xe) // full system DMB, orders writes only
|
|
486 |
#define ARM_DSBST ARM_DSB_gen(0xe) // full system DSB, orders writes only
|
|
487 |
#define ARM_DMBSH ARM_DMB_gen(0xb) // DMB encompassing inner-shareable domain
|
|
488 |
#define ARM_DSBSH ARM_DSB_gen(0xb) // DMB encompassing inner-shareable domain
|
|
489 |
#define ARM_DMBSHST ARM_DMB_gen(0xa) // DMB encompassing inner-shareable domain, orders writes only
|
|
490 |
#define ARM_DSBSHST ARM_DSB_gen(0xa) // DMB encompassing inner-shareable domain, orders writes only
|
|
491 |
|
|
492 |
#define ARM_ISBSY ARM_ISB_gen(0xf) // full system ISB
|
|
493 |
|
|
494 |
#define ARM_NOP asm(".word 0xe320f000 ")
|
|
495 |
#define ARM_YIELD asm(".word 0xe320f001 ")
|
|
496 |
|
|
497 |
#define __DATA_MEMORY_BARRIER__(reg) ARM_DMBSH
|
|
498 |
#define __DATA_MEMORY_BARRIER_Z__(reg) asm("mov "#reg", #0"); ARM_DMBSH
|
|
499 |
#define __DATA_SYNC_BARRIER__(reg) ARM_DSBSH
|
|
500 |
#define __DATA_SYNC_BARRIER_Z__(reg) asm("mov "#reg", #0"); ARM_DSBSH
|
|
501 |
#define __INST_SYNC_BARRIER__(reg) ARM_ISBSY
|
|
502 |
#define __INST_SYNC_BARRIER_Z__(reg) asm("mov "#reg", #0"); ARM_ISBSY
|
|
503 |
|
|
504 |
#elif defined(__CPU_ARM11MP__)
|
|
505 |
|
|
506 |
#define ARM_DMB(reg) asm("mcr p15, 0, "#reg", c7, c10, 5 ")
|
|
507 |
#define ARM_DSB(reg) asm("mcr p15, 0, "#reg", c7, c10, 4 ")
|
|
508 |
#define ARM_ISB(reg) asm("mcr p15, 0, "#reg", c7, c5, 4 ")
|
|
509 |
|
|
510 |
#define ARM_NOP asm(".word 0xe320f000 ")
|
|
511 |
#define ARM_YIELD asm(".word 0xe320f001 ")
|
|
512 |
|
|
513 |
#define __DATA_MEMORY_BARRIER__(reg) ARM_DMB(reg)
|
|
514 |
#define __DATA_MEMORY_BARRIER_Z__(reg) asm("mov "#reg", #0"); ARM_DMB(reg)
|
|
515 |
#define __DATA_SYNC_BARRIER__(reg) ARM_DSB(reg)
|
|
516 |
#define __DATA_SYNC_BARRIER_Z__(reg) asm("mov "#reg", #0"); ARM_DSB(reg)
|
|
517 |
#define __INST_SYNC_BARRIER__(reg) ARM_ISB(reg)
|
|
518 |
#define __INST_SYNC_BARRIER_Z__(reg) asm("mov "#reg", #0"); ARM_ISB(reg)
|
|
519 |
|
|
520 |
#elif defined(__CPU_ARMV6__)
|
|
521 |
|
|
522 |
#define ARM_DMB(reg) asm("mcr p15, 0, "#reg", c7, c10, 5 ")
|
|
523 |
#define ARM_DSB(reg) asm("mcr p15, 0, "#reg", c7, c10, 4 ")
|
|
524 |
#define ARM_ISB(reg) asm("mcr p15, 0, "#reg", c7, c5, 4 ")
|
|
525 |
|
|
526 |
#define __DATA_MEMORY_BARRIER__(reg) ARM_DMB(reg)
|
|
527 |
#define __DATA_MEMORY_BARRIER_Z__(reg) asm("mov "#reg", #0"); ARM_DMB(reg)
|
|
528 |
#define __DATA_SYNC_BARRIER__(reg) ARM_DSB(reg)
|
|
529 |
#define __DATA_SYNC_BARRIER_Z__(reg) asm("mov "#reg", #0"); ARM_DSB(reg)
|
|
530 |
#define __INST_SYNC_BARRIER__(reg) ARM_ISB(reg)
|
|
531 |
#define __INST_SYNC_BARRIER_Z__(reg) asm("mov "#reg", #0"); ARM_ISB(reg)
|
|
532 |
|
|
533 |
#else
|
|
534 |
|
|
535 |
#define __DATA_MEMORY_BARRIER__(reg)
|
|
536 |
#define __DATA_MEMORY_BARRIER_Z__(reg) asm("mov "#reg", #0")
|
|
537 |
#define __DATA_SYNC_BARRIER__(reg) asm("mcr p15, 0, "#reg", c7, c10, 4 ")
|
|
538 |
#define __DATA_SYNC_BARRIER_Z__(reg) asm("mov "#reg", #0"); asm("mcr p15, 0, "#reg", c7, c10, 4 ")
|
|
539 |
#define __INST_SYNC_BARRIER__(reg)
|
|
540 |
#define __INST_SYNC_BARRIER_Z__(reg) asm("mov "#reg", #0")
|
|
541 |
|
|
542 |
#endif
|
|
543 |
|
|
544 |
#ifdef __SMP__
|
|
545 |
#define __SMP_DATA_MEMORY_BARRIER__(reg) __DATA_MEMORY_BARRIER__(reg)
|
|
546 |
#define __SMP_DATA_MEMORY_BARRIER_Z__(reg) __DATA_MEMORY_BARRIER_Z__(reg)
|
|
547 |
#define __SMP_DATA_SYNC_BARRIER__(reg) __DATA_SYNC_BARRIER__(reg)
|
|
548 |
#define __SMP_DATA_SYNC_BARRIER_Z__(reg) __DATA_SYNC_BARRIER_Z__(reg)
|
|
549 |
#define __SMP_INST_SYNC_BARRIER__(reg) __INST_SYNC_BARRIER__(reg)
|
|
550 |
#define __SMP_INST_SYNC_BARRIER_Z__(reg) __INST_SYNC_BARRIER_Z__(reg)
|
|
551 |
#else
|
|
552 |
#define __SMP_DATA_MEMORY_BARRIER__(reg)
|
|
553 |
#define __SMP_DATA_MEMORY_BARRIER_Z__(reg) asm("mov "#reg", #0")
|
|
554 |
#define __SMP_DATA_SYNC_BARRIER__(reg)
|
|
555 |
#define __SMP_DATA_SYNC_BARRIER_Z__(reg) asm("mov "#reg", #0")
|
|
556 |
#define __SMP_INST_SYNC_BARRIER__(reg)
|
|
557 |
#define __SMP_INST_SYNC_BARRIER_Z__(reg) asm("mov "#reg", #0")
|
|
558 |
#endif
|
|
559 |
|
|
560 |
#ifdef __CPU_ARM_HAS_WFI
|
|
561 |
#define ARM_WFIcc(cc) __DATA_SYNC_BARRIER__(r0); \
|
|
562 |
asm(".word %a0" : : "i" ((TInt)(0x0320f003 | ((cc)<<28) )) )
|
|
563 |
#define ARM_WFI ARM_WFIcc(CC_AL)
|
|
564 |
#endif
|
|
565 |
|
|
566 |
#ifdef __CPU_ARM_HAS_WFE_SEV
|
|
567 |
#define ARM_WFEcc(cc) __DATA_SYNC_BARRIER__(r0); \
|
|
568 |
asm(".word %a0" : : "i" ((TInt)(0x0320f002 | ((cc)<<28) )) )
|
|
569 |
#if __ARM_ASSEMBLER_ISA__ >= 6
|
|
570 |
#define ARM_WFE __DATA_SYNC_BARRIER__(r0); \
|
|
571 |
asm("wfe ")
|
|
572 |
#else
|
|
573 |
#define ARM_WFE ARM_WFEcc(CC_AL)
|
|
574 |
#endif
|
|
575 |
#define ARM_SEVcc(cc) asm(".word %a0" : : "i" ((TInt)(0x0320f004 | ((cc)<<28) )) )
|
|
576 |
#if __ARM_ASSEMBLER_ISA__ >= 6
|
|
577 |
#define ARM_SEV asm("sev ")
|
|
578 |
#else
|
|
579 |
#define ARM_SEV ARM_SEVcc(CC_AL)
|
|
580 |
#endif
|
|
581 |
#endif
|
|
582 |
|
|
583 |
#ifndef ARM_NOP
|
|
584 |
#define ARM_NOP asm("nop ")
|
|
585 |
#define ARM_YIELD asm("nop ")
|
|
586 |
#endif
|
|
587 |
|
|
588 |
// Support for throwing exceptions through ARM embedded assembler
|
|
589 |
// Should only be needed user side
|
|
590 |
#ifndef __EH_FRAME_ADDRESS
|
|
591 |
#define __EH_FRAME_ADDRESS(reg,offset)
|
|
592 |
#define __EH_FRAME_PUSH2(reg1,reg2)
|
|
593 |
#define __EH_FRAME_SAVE1(reg,offset)
|
|
594 |
#endif
|
|
595 |
|
|
596 |
// StrongARM msr bug workaround:
|
|
597 |
// (conditional msr might cause,that the next instruction is executed twice by these processors)
|
|
598 |
#ifdef __CPU_SA1__
|
|
599 |
#define __MSR_CPSR_C(cc,r) \
|
|
600 |
asm("msr"#cc" cpsr_c," #r); \
|
|
601 |
ARM_NOP;
|
|
602 |
#else // !__CPU_SA1__
|
|
603 |
#define __MSR_CPSR_C(cc,r) asm("msr"#cc" cpsr_c,"#r);
|
|
604 |
#endif
|
|
605 |
|
|
606 |
// Causes undefined instruction exception on both ARM and THUMB
|
|
607 |
#define __ASM_CRASH() asm(".word 0xe7ffdeff ")
|
|
608 |
#if defined(__GNUC__)
|
|
609 |
#define __crash() asm(".word 0xe7ffdeff " : : : "memory")
|
|
610 |
#elif defined(__ARMCC__)
|
|
611 |
// RVCT doesn't let us inline an undefined instruction
|
|
612 |
// use a CDP to CP15 instead - doesn't work on THUMB but never mind
|
|
613 |
#if __ARMCC_VERSION < 310000
|
|
614 |
#define __crash() asm("cdp p15, 0, c0, c0, c0, 0 ")
|
|
615 |
#else
|
|
616 |
// Inline assembler is deprecated in RVCT 3.1 so we use an intrinsic.
|
|
617 |
#define __crash() __cdp(15, 0x00, 0x000)
|
|
618 |
#endif
|
|
619 |
#endif
|
|
620 |
|
|
621 |
#if !defined(__CPU_ARM_HAS_LDREX_STREX_V6K)
|
|
622 |
#if defined(__CPU_ARM_HAS_LDREX_STREX)
|
|
623 |
#define __ATOMIC64_USE_SLOW_EXEC__
|
|
624 |
#else
|
|
625 |
#define __ATOMIC64_USE_FAST_EXEC__
|
|
626 |
#define __ATOMIC_USE_FAST_EXEC__
|
|
627 |
#endif
|
|
628 |
#endif
|
|
629 |
|
|
630 |
#endif // __CPU_ARM
|
|
631 |
|
|
632 |
#ifdef __CPU_X86
|
|
633 |
#define EXC_TRAP_CTX_SZ 10 // ebx, esp, ebp, esi, edi, ds, es, fs, gs, eip
|
|
634 |
|
|
635 |
// Causes exception
|
|
636 |
#if defined(__VC32__) || defined(__CW32__)
|
|
637 |
#define __crash() do { _asm int 0ffh } while(0)
|
|
638 |
#else
|
|
639 |
#define __crash() asm("int 0xff " : : : "memory")
|
|
640 |
#endif
|
|
641 |
|
|
642 |
#endif // __CPU_X86
|
|
643 |
|
|
644 |
#endif
|