|
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 |