Go to most recent revision | Details | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
2 | mjames | 1 | /**************************************************************************//** |
2 | * @file cmsis_armcc.h |
||
3 | * @brief CMSIS compiler ARMCC (Arm Compiler 5) header file |
||
4 | * @version V5.0.4 |
||
5 | * @date 10. January 2018 |
||
6 | ******************************************************************************/ |
||
7 | /* |
||
8 | * Copyright (c) 2009-2018 Arm Limited. All rights reserved. |
||
9 | * |
||
10 | * SPDX-License-Identifier: Apache-2.0 |
||
11 | * |
||
12 | * Licensed under the Apache License, Version 2.0 (the License); you may |
||
13 | * not use this file except in compliance with the License. |
||
14 | * You may obtain a copy of the License at |
||
15 | * |
||
16 | * www.apache.org/licenses/LICENSE-2.0 |
||
17 | * |
||
18 | * Unless required by applicable law or agreed to in writing, software |
||
19 | * distributed under the License is distributed on an AS IS BASIS, WITHOUT |
||
20 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||
21 | * See the License for the specific language governing permissions and |
||
22 | * limitations under the License. |
||
23 | */ |
||
24 | |||
25 | #ifndef __CMSIS_ARMCC_H |
||
26 | #define __CMSIS_ARMCC_H |
||
27 | |||
28 | |||
29 | #if defined(__ARMCC_VERSION) && (__ARMCC_VERSION < 400677) |
||
30 | #error "Please use Arm Compiler Toolchain V4.0.677 or later!" |
||
31 | #endif |
||
32 | |||
33 | /* CMSIS compiler control architecture macros */ |
||
34 | #if ((defined (__TARGET_ARCH_6_M ) && (__TARGET_ARCH_6_M == 1)) || \ |
||
35 | (defined (__TARGET_ARCH_6S_M ) && (__TARGET_ARCH_6S_M == 1)) ) |
||
36 | #define __ARM_ARCH_6M__ 1 |
||
37 | #endif |
||
38 | |||
39 | #if (defined (__TARGET_ARCH_7_M ) && (__TARGET_ARCH_7_M == 1)) |
||
40 | #define __ARM_ARCH_7M__ 1 |
||
41 | #endif |
||
42 | |||
43 | #if (defined (__TARGET_ARCH_7E_M) && (__TARGET_ARCH_7E_M == 1)) |
||
44 | #define __ARM_ARCH_7EM__ 1 |
||
45 | #endif |
||
46 | |||
47 | /* __ARM_ARCH_8M_BASE__ not applicable */ |
||
48 | /* __ARM_ARCH_8M_MAIN__ not applicable */ |
||
49 | |||
50 | |||
51 | /* CMSIS compiler specific defines */ |
||
52 | #ifndef __ASM |
||
53 | #define __ASM __asm |
||
54 | #endif |
||
55 | #ifndef __INLINE |
||
56 | #define __INLINE __inline |
||
57 | #endif |
||
58 | #ifndef __STATIC_INLINE |
||
59 | #define __STATIC_INLINE static __inline |
||
60 | #endif |
||
61 | #ifndef __STATIC_FORCEINLINE |
||
62 | #define __STATIC_FORCEINLINE static __forceinline |
||
63 | #endif |
||
64 | #ifndef __NO_RETURN |
||
65 | #define __NO_RETURN __declspec(noreturn) |
||
66 | #endif |
||
67 | #ifndef __USED |
||
68 | #define __USED __attribute__((used)) |
||
69 | #endif |
||
70 | #ifndef __WEAK |
||
71 | #define __WEAK __attribute__((weak)) |
||
72 | #endif |
||
73 | #ifndef __PACKED |
||
74 | #define __PACKED __attribute__((packed)) |
||
75 | #endif |
||
76 | #ifndef __PACKED_STRUCT |
||
77 | #define __PACKED_STRUCT __packed struct |
||
78 | #endif |
||
79 | #ifndef __PACKED_UNION |
||
80 | #define __PACKED_UNION __packed union |
||
81 | #endif |
||
82 | #ifndef __UNALIGNED_UINT32 /* deprecated */ |
||
83 | #define __UNALIGNED_UINT32(x) (*((__packed uint32_t *)(x))) |
||
84 | #endif |
||
85 | #ifndef __UNALIGNED_UINT16_WRITE |
||
86 | #define __UNALIGNED_UINT16_WRITE(addr, val) ((*((__packed uint16_t *)(addr))) = (val)) |
||
87 | #endif |
||
88 | #ifndef __UNALIGNED_UINT16_READ |
||
89 | #define __UNALIGNED_UINT16_READ(addr) (*((const __packed uint16_t *)(addr))) |
||
90 | #endif |
||
91 | #ifndef __UNALIGNED_UINT32_WRITE |
||
92 | #define __UNALIGNED_UINT32_WRITE(addr, val) ((*((__packed uint32_t *)(addr))) = (val)) |
||
93 | #endif |
||
94 | #ifndef __UNALIGNED_UINT32_READ |
||
95 | #define __UNALIGNED_UINT32_READ(addr) (*((const __packed uint32_t *)(addr))) |
||
96 | #endif |
||
97 | #ifndef __ALIGNED |
||
98 | #define __ALIGNED(x) __attribute__((aligned(x))) |
||
99 | #endif |
||
100 | #ifndef __RESTRICT |
||
101 | #define __RESTRICT __restrict |
||
102 | #endif |
||
103 | |||
104 | /* ########################### Core Function Access ########################### */ |
||
105 | /** \ingroup CMSIS_Core_FunctionInterface |
||
106 | \defgroup CMSIS_Core_RegAccFunctions CMSIS Core Register Access Functions |
||
107 | @{ |
||
108 | */ |
||
109 | |||
110 | /** |
||
111 | \brief Enable IRQ Interrupts |
||
112 | \details Enables IRQ interrupts by clearing the I-bit in the CPSR. |
||
113 | Can only be executed in Privileged modes. |
||
114 | */ |
||
115 | /* intrinsic void __enable_irq(); */ |
||
116 | |||
117 | |||
118 | /** |
||
119 | \brief Disable IRQ Interrupts |
||
120 | \details Disables IRQ interrupts by setting the I-bit in the CPSR. |
||
121 | Can only be executed in Privileged modes. |
||
122 | */ |
||
123 | /* intrinsic void __disable_irq(); */ |
||
124 | |||
125 | /** |
||
126 | \brief Get Control Register |
||
127 | \details Returns the content of the Control Register. |
||
128 | \return Control Register value |
||
129 | */ |
||
130 | __STATIC_INLINE uint32_t __get_CONTROL(void) |
||
131 | { |
||
132 | register uint32_t __regControl __ASM("control"); |
||
133 | return(__regControl); |
||
134 | } |
||
135 | |||
136 | |||
137 | /** |
||
138 | \brief Set Control Register |
||
139 | \details Writes the given value to the Control Register. |
||
140 | \param [in] control Control Register value to set |
||
141 | */ |
||
142 | __STATIC_INLINE void __set_CONTROL(uint32_t control) |
||
143 | { |
||
144 | register uint32_t __regControl __ASM("control"); |
||
145 | __regControl = control; |
||
146 | } |
||
147 | |||
148 | |||
149 | /** |
||
150 | \brief Get IPSR Register |
||
151 | \details Returns the content of the IPSR Register. |
||
152 | \return IPSR Register value |
||
153 | */ |
||
154 | __STATIC_INLINE uint32_t __get_IPSR(void) |
||
155 | { |
||
156 | register uint32_t __regIPSR __ASM("ipsr"); |
||
157 | return(__regIPSR); |
||
158 | } |
||
159 | |||
160 | |||
161 | /** |
||
162 | \brief Get APSR Register |
||
163 | \details Returns the content of the APSR Register. |
||
164 | \return APSR Register value |
||
165 | */ |
||
166 | __STATIC_INLINE uint32_t __get_APSR(void) |
||
167 | { |
||
168 | register uint32_t __regAPSR __ASM("apsr"); |
||
169 | return(__regAPSR); |
||
170 | } |
||
171 | |||
172 | |||
173 | /** |
||
174 | \brief Get xPSR Register |
||
175 | \details Returns the content of the xPSR Register. |
||
176 | \return xPSR Register value |
||
177 | */ |
||
178 | __STATIC_INLINE uint32_t __get_xPSR(void) |
||
179 | { |
||
180 | register uint32_t __regXPSR __ASM("xpsr"); |
||
181 | return(__regXPSR); |
||
182 | } |
||
183 | |||
184 | |||
185 | /** |
||
186 | \brief Get Process Stack Pointer |
||
187 | \details Returns the current value of the Process Stack Pointer (PSP). |
||
188 | \return PSP Register value |
||
189 | */ |
||
190 | __STATIC_INLINE uint32_t __get_PSP(void) |
||
191 | { |
||
192 | register uint32_t __regProcessStackPointer __ASM("psp"); |
||
193 | return(__regProcessStackPointer); |
||
194 | } |
||
195 | |||
196 | |||
197 | /** |
||
198 | \brief Set Process Stack Pointer |
||
199 | \details Assigns the given value to the Process Stack Pointer (PSP). |
||
200 | \param [in] topOfProcStack Process Stack Pointer value to set |
||
201 | */ |
||
202 | __STATIC_INLINE void __set_PSP(uint32_t topOfProcStack) |
||
203 | { |
||
204 | register uint32_t __regProcessStackPointer __ASM("psp"); |
||
205 | __regProcessStackPointer = topOfProcStack; |
||
206 | } |
||
207 | |||
208 | |||
209 | /** |
||
210 | \brief Get Main Stack Pointer |
||
211 | \details Returns the current value of the Main Stack Pointer (MSP). |
||
212 | \return MSP Register value |
||
213 | */ |
||
214 | __STATIC_INLINE uint32_t __get_MSP(void) |
||
215 | { |
||
216 | register uint32_t __regMainStackPointer __ASM("msp"); |
||
217 | return(__regMainStackPointer); |
||
218 | } |
||
219 | |||
220 | |||
221 | /** |
||
222 | \brief Set Main Stack Pointer |
||
223 | \details Assigns the given value to the Main Stack Pointer (MSP). |
||
224 | \param [in] topOfMainStack Main Stack Pointer value to set |
||
225 | */ |
||
226 | __STATIC_INLINE void __set_MSP(uint32_t topOfMainStack) |
||
227 | { |
||
228 | register uint32_t __regMainStackPointer __ASM("msp"); |
||
229 | __regMainStackPointer = topOfMainStack; |
||
230 | } |
||
231 | |||
232 | |||
233 | /** |
||
234 | \brief Get Priority Mask |
||
235 | \details Returns the current state of the priority mask bit from the Priority Mask Register. |
||
236 | \return Priority Mask value |
||
237 | */ |
||
238 | __STATIC_INLINE uint32_t __get_PRIMASK(void) |
||
239 | { |
||
240 | register uint32_t __regPriMask __ASM("primask"); |
||
241 | return(__regPriMask); |
||
242 | } |
||
243 | |||
244 | |||
245 | /** |
||
246 | \brief Set Priority Mask |
||
247 | \details Assigns the given value to the Priority Mask Register. |
||
248 | \param [in] priMask Priority Mask |
||
249 | */ |
||
250 | __STATIC_INLINE void __set_PRIMASK(uint32_t priMask) |
||
251 | { |
||
252 | register uint32_t __regPriMask __ASM("primask"); |
||
253 | __regPriMask = (priMask); |
||
254 | } |
||
255 | |||
256 | |||
257 | #if ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ |
||
258 | (defined (__ARM_ARCH_7EM__) && (__ARM_ARCH_7EM__ == 1)) ) |
||
259 | |||
260 | /** |
||
261 | \brief Enable FIQ |
||
262 | \details Enables FIQ interrupts by clearing the F-bit in the CPSR. |
||
263 | Can only be executed in Privileged modes. |
||
264 | */ |
||
265 | #define __enable_fault_irq __enable_fiq |
||
266 | |||
267 | |||
268 | /** |
||
269 | \brief Disable FIQ |
||
270 | \details Disables FIQ interrupts by setting the F-bit in the CPSR. |
||
271 | Can only be executed in Privileged modes. |
||
272 | */ |
||
273 | #define __disable_fault_irq __disable_fiq |
||
274 | |||
275 | |||
276 | /** |
||
277 | \brief Get Base Priority |
||
278 | \details Returns the current value of the Base Priority register. |
||
279 | \return Base Priority register value |
||
280 | */ |
||
281 | __STATIC_INLINE uint32_t __get_BASEPRI(void) |
||
282 | { |
||
283 | register uint32_t __regBasePri __ASM("basepri"); |
||
284 | return(__regBasePri); |
||
285 | } |
||
286 | |||
287 | |||
288 | /** |
||
289 | \brief Set Base Priority |
||
290 | \details Assigns the given value to the Base Priority register. |
||
291 | \param [in] basePri Base Priority value to set |
||
292 | */ |
||
293 | __STATIC_INLINE void __set_BASEPRI(uint32_t basePri) |
||
294 | { |
||
295 | register uint32_t __regBasePri __ASM("basepri"); |
||
296 | __regBasePri = (basePri & 0xFFU); |
||
297 | } |
||
298 | |||
299 | |||
300 | /** |
||
301 | \brief Set Base Priority with condition |
||
302 | \details Assigns the given value to the Base Priority register only if BASEPRI masking is disabled, |
||
303 | or the new value increases the BASEPRI priority level. |
||
304 | \param [in] basePri Base Priority value to set |
||
305 | */ |
||
306 | __STATIC_INLINE void __set_BASEPRI_MAX(uint32_t basePri) |
||
307 | { |
||
308 | register uint32_t __regBasePriMax __ASM("basepri_max"); |
||
309 | __regBasePriMax = (basePri & 0xFFU); |
||
310 | } |
||
311 | |||
312 | |||
313 | /** |
||
314 | \brief Get Fault Mask |
||
315 | \details Returns the current value of the Fault Mask register. |
||
316 | \return Fault Mask register value |
||
317 | */ |
||
318 | __STATIC_INLINE uint32_t __get_FAULTMASK(void) |
||
319 | { |
||
320 | register uint32_t __regFaultMask __ASM("faultmask"); |
||
321 | return(__regFaultMask); |
||
322 | } |
||
323 | |||
324 | |||
325 | /** |
||
326 | \brief Set Fault Mask |
||
327 | \details Assigns the given value to the Fault Mask register. |
||
328 | \param [in] faultMask Fault Mask value to set |
||
329 | */ |
||
330 | __STATIC_INLINE void __set_FAULTMASK(uint32_t faultMask) |
||
331 | { |
||
332 | register uint32_t __regFaultMask __ASM("faultmask"); |
||
333 | __regFaultMask = (faultMask & (uint32_t)1U); |
||
334 | } |
||
335 | |||
336 | #endif /* ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ |
||
337 | (defined (__ARM_ARCH_7EM__) && (__ARM_ARCH_7EM__ == 1)) ) */ |
||
338 | |||
339 | |||
340 | /** |
||
341 | \brief Get FPSCR |
||
342 | \details Returns the current value of the Floating Point Status/Control register. |
||
343 | \return Floating Point Status/Control register value |
||
344 | */ |
||
345 | __STATIC_INLINE uint32_t __get_FPSCR(void) |
||
346 | { |
||
347 | #if ((defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U)) && \ |
||
348 | (defined (__FPU_USED ) && (__FPU_USED == 1U)) ) |
||
349 | register uint32_t __regfpscr __ASM("fpscr"); |
||
350 | return(__regfpscr); |
||
351 | #else |
||
352 | return(0U); |
||
353 | #endif |
||
354 | } |
||
355 | |||
356 | |||
357 | /** |
||
358 | \brief Set FPSCR |
||
359 | \details Assigns the given value to the Floating Point Status/Control register. |
||
360 | \param [in] fpscr Floating Point Status/Control value to set |
||
361 | */ |
||
362 | __STATIC_INLINE void __set_FPSCR(uint32_t fpscr) |
||
363 | { |
||
364 | #if ((defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U)) && \ |
||
365 | (defined (__FPU_USED ) && (__FPU_USED == 1U)) ) |
||
366 | register uint32_t __regfpscr __ASM("fpscr"); |
||
367 | __regfpscr = (fpscr); |
||
368 | #else |
||
369 | (void)fpscr; |
||
370 | #endif |
||
371 | } |
||
372 | |||
373 | |||
374 | /*@} end of CMSIS_Core_RegAccFunctions */ |
||
375 | |||
376 | |||
377 | /* ########################## Core Instruction Access ######################### */ |
||
378 | /** \defgroup CMSIS_Core_InstructionInterface CMSIS Core Instruction Interface |
||
379 | Access to dedicated instructions |
||
380 | @{ |
||
381 | */ |
||
382 | |||
383 | /** |
||
384 | \brief No Operation |
||
385 | \details No Operation does nothing. This instruction can be used for code alignment purposes. |
||
386 | */ |
||
387 | #define __NOP __nop |
||
388 | |||
389 | |||
390 | /** |
||
391 | \brief Wait For Interrupt |
||
392 | \details Wait For Interrupt is a hint instruction that suspends execution until one of a number of events occurs. |
||
393 | */ |
||
394 | #define __WFI __wfi |
||
395 | |||
396 | |||
397 | /** |
||
398 | \brief Wait For Event |
||
399 | \details Wait For Event is a hint instruction that permits the processor to enter |
||
400 | a low-power state until one of a number of events occurs. |
||
401 | */ |
||
402 | #define __WFE __wfe |
||
403 | |||
404 | |||
405 | /** |
||
406 | \brief Send Event |
||
407 | \details Send Event is a hint instruction. It causes an event to be signaled to the CPU. |
||
408 | */ |
||
409 | #define __SEV __sev |
||
410 | |||
411 | |||
412 | /** |
||
413 | \brief Instruction Synchronization Barrier |
||
414 | \details Instruction Synchronization Barrier flushes the pipeline in the processor, |
||
415 | so that all instructions following the ISB are fetched from cache or memory, |
||
416 | after the instruction has been completed. |
||
417 | */ |
||
418 | #define __ISB() do {\ |
||
419 | __schedule_barrier();\ |
||
420 | __isb(0xF);\ |
||
421 | __schedule_barrier();\ |
||
422 | } while (0U) |
||
423 | |||
424 | /** |
||
425 | \brief Data Synchronization Barrier |
||
426 | \details Acts as a special kind of Data Memory Barrier. |
||
427 | It completes when all explicit memory accesses before this instruction complete. |
||
428 | */ |
||
429 | #define __DSB() do {\ |
||
430 | __schedule_barrier();\ |
||
431 | __dsb(0xF);\ |
||
432 | __schedule_barrier();\ |
||
433 | } while (0U) |
||
434 | |||
435 | /** |
||
436 | \brief Data Memory Barrier |
||
437 | \details Ensures the apparent order of the explicit memory operations before |
||
438 | and after the instruction, without ensuring their completion. |
||
439 | */ |
||
440 | #define __DMB() do {\ |
||
441 | __schedule_barrier();\ |
||
442 | __dmb(0xF);\ |
||
443 | __schedule_barrier();\ |
||
444 | } while (0U) |
||
445 | |||
446 | |||
447 | /** |
||
448 | \brief Reverse byte order (32 bit) |
||
449 | \details Reverses the byte order in unsigned integer value. For example, 0x12345678 becomes 0x78563412. |
||
450 | \param [in] value Value to reverse |
||
451 | \return Reversed value |
||
452 | */ |
||
453 | #define __REV __rev |
||
454 | |||
455 | |||
456 | /** |
||
457 | \brief Reverse byte order (16 bit) |
||
458 | \details Reverses the byte order within each halfword of a word. For example, 0x12345678 becomes 0x34127856. |
||
459 | \param [in] value Value to reverse |
||
460 | \return Reversed value |
||
461 | */ |
||
462 | #ifndef __NO_EMBEDDED_ASM |
||
463 | __attribute__((section(".rev16_text"))) __STATIC_INLINE __ASM uint32_t __REV16(uint32_t value) |
||
464 | { |
||
465 | rev16 r0, r0 |
||
466 | bx lr |
||
467 | } |
||
468 | #endif |
||
469 | |||
470 | |||
471 | /** |
||
472 | \brief Reverse byte order (16 bit) |
||
473 | \details Reverses the byte order in a 16-bit value and returns the signed 16-bit result. For example, 0x0080 becomes 0x8000. |
||
474 | \param [in] value Value to reverse |
||
475 | \return Reversed value |
||
476 | */ |
||
477 | #ifndef __NO_EMBEDDED_ASM |
||
478 | __attribute__((section(".revsh_text"))) __STATIC_INLINE __ASM int16_t __REVSH(int16_t value) |
||
479 | { |
||
480 | revsh r0, r0 |
||
481 | bx lr |
||
482 | } |
||
483 | #endif |
||
484 | |||
485 | |||
486 | /** |
||
487 | \brief Rotate Right in unsigned value (32 bit) |
||
488 | \details Rotate Right (immediate) provides the value of the contents of a register rotated by a variable number of bits. |
||
489 | \param [in] op1 Value to rotate |
||
490 | \param [in] op2 Number of Bits to rotate |
||
491 | \return Rotated value |
||
492 | */ |
||
493 | #define __ROR __ror |
||
494 | |||
495 | |||
496 | /** |
||
497 | \brief Breakpoint |
||
498 | \details Causes the processor to enter Debug state. |
||
499 | Debug tools can use this to investigate system state when the instruction at a particular address is reached. |
||
500 | \param [in] value is ignored by the processor. |
||
501 | If required, a debugger can use it to store additional information about the breakpoint. |
||
502 | */ |
||
503 | #define __BKPT(value) __breakpoint(value) |
||
504 | |||
505 | |||
506 | /** |
||
507 | \brief Reverse bit order of value |
||
508 | \details Reverses the bit order of the given value. |
||
509 | \param [in] value Value to reverse |
||
510 | \return Reversed value |
||
511 | */ |
||
512 | #if ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ |
||
513 | (defined (__ARM_ARCH_7EM__) && (__ARM_ARCH_7EM__ == 1)) ) |
||
514 | #define __RBIT __rbit |
||
515 | #else |
||
516 | __attribute__((always_inline)) __STATIC_INLINE uint32_t __RBIT(uint32_t value) |
||
517 | { |
||
518 | uint32_t result; |
||
519 | uint32_t s = (4U /*sizeof(v)*/ * 8U) - 1U; /* extra shift needed at end */ |
||
520 | |||
521 | result = value; /* r will be reversed bits of v; first get LSB of v */ |
||
522 | for (value >>= 1U; value != 0U; value >>= 1U) |
||
523 | { |
||
524 | result <<= 1U; |
||
525 | result |= value & 1U; |
||
526 | s--; |
||
527 | } |
||
528 | result <<= s; /* shift when v's highest bits are zero */ |
||
529 | return result; |
||
530 | } |
||
531 | #endif |
||
532 | |||
533 | |||
534 | /** |
||
535 | \brief Count leading zeros |
||
536 | \details Counts the number of leading zeros of a data value. |
||
537 | \param [in] value Value to count the leading zeros |
||
538 | \return number of leading zeros in value |
||
539 | */ |
||
540 | #define __CLZ __clz |
||
541 | |||
542 | |||
543 | #if ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ |
||
544 | (defined (__ARM_ARCH_7EM__) && (__ARM_ARCH_7EM__ == 1)) ) |
||
545 | |||
546 | /** |
||
547 | \brief LDR Exclusive (8 bit) |
||
548 | \details Executes a exclusive LDR instruction for 8 bit value. |
||
549 | \param [in] ptr Pointer to data |
||
550 | \return value of type uint8_t at (*ptr) |
||
551 | */ |
||
552 | #if defined(__ARMCC_VERSION) && (__ARMCC_VERSION < 5060020) |
||
553 | #define __LDREXB(ptr) ((uint8_t ) __ldrex(ptr)) |
||
554 | #else |
||
555 | #define __LDREXB(ptr) _Pragma("push") _Pragma("diag_suppress 3731") ((uint8_t ) __ldrex(ptr)) _Pragma("pop") |
||
556 | #endif |
||
557 | |||
558 | |||
559 | /** |
||
560 | \brief LDR Exclusive (16 bit) |
||
561 | \details Executes a exclusive LDR instruction for 16 bit values. |
||
562 | \param [in] ptr Pointer to data |
||
563 | \return value of type uint16_t at (*ptr) |
||
564 | */ |
||
565 | #if defined(__ARMCC_VERSION) && (__ARMCC_VERSION < 5060020) |
||
566 | #define __LDREXH(ptr) ((uint16_t) __ldrex(ptr)) |
||
567 | #else |
||
568 | #define __LDREXH(ptr) _Pragma("push") _Pragma("diag_suppress 3731") ((uint16_t) __ldrex(ptr)) _Pragma("pop") |
||
569 | #endif |
||
570 | |||
571 | |||
572 | /** |
||
573 | \brief LDR Exclusive (32 bit) |
||
574 | \details Executes a exclusive LDR instruction for 32 bit values. |
||
575 | \param [in] ptr Pointer to data |
||
576 | \return value of type uint32_t at (*ptr) |
||
577 | */ |
||
578 | #if defined(__ARMCC_VERSION) && (__ARMCC_VERSION < 5060020) |
||
579 | #define __LDREXW(ptr) ((uint32_t ) __ldrex(ptr)) |
||
580 | #else |
||
581 | #define __LDREXW(ptr) _Pragma("push") _Pragma("diag_suppress 3731") ((uint32_t ) __ldrex(ptr)) _Pragma("pop") |
||
582 | #endif |
||
583 | |||
584 | |||
585 | /** |
||
586 | \brief STR Exclusive (8 bit) |
||
587 | \details Executes a exclusive STR instruction for 8 bit values. |
||
588 | \param [in] value Value to store |
||
589 | \param [in] ptr Pointer to location |
||
590 | \return 0 Function succeeded |
||
591 | \return 1 Function failed |
||
592 | */ |
||
593 | #if defined(__ARMCC_VERSION) && (__ARMCC_VERSION < 5060020) |
||
594 | #define __STREXB(value, ptr) __strex(value, ptr) |
||
595 | #else |
||
596 | #define __STREXB(value, ptr) _Pragma("push") _Pragma("diag_suppress 3731") __strex(value, ptr) _Pragma("pop") |
||
597 | #endif |
||
598 | |||
599 | |||
600 | /** |
||
601 | \brief STR Exclusive (16 bit) |
||
602 | \details Executes a exclusive STR instruction for 16 bit values. |
||
603 | \param [in] value Value to store |
||
604 | \param [in] ptr Pointer to location |
||
605 | \return 0 Function succeeded |
||
606 | \return 1 Function failed |
||
607 | */ |
||
608 | #if defined(__ARMCC_VERSION) && (__ARMCC_VERSION < 5060020) |
||
609 | #define __STREXH(value, ptr) __strex(value, ptr) |
||
610 | #else |
||
611 | #define __STREXH(value, ptr) _Pragma("push") _Pragma("diag_suppress 3731") __strex(value, ptr) _Pragma("pop") |
||
612 | #endif |
||
613 | |||
614 | |||
615 | /** |
||
616 | \brief STR Exclusive (32 bit) |
||
617 | \details Executes a exclusive STR instruction for 32 bit values. |
||
618 | \param [in] value Value to store |
||
619 | \param [in] ptr Pointer to location |
||
620 | \return 0 Function succeeded |
||
621 | \return 1 Function failed |
||
622 | */ |
||
623 | #if defined(__ARMCC_VERSION) && (__ARMCC_VERSION < 5060020) |
||
624 | #define __STREXW(value, ptr) __strex(value, ptr) |
||
625 | #else |
||
626 | #define __STREXW(value, ptr) _Pragma("push") _Pragma("diag_suppress 3731") __strex(value, ptr) _Pragma("pop") |
||
627 | #endif |
||
628 | |||
629 | |||
630 | /** |
||
631 | \brief Remove the exclusive lock |
||
632 | \details Removes the exclusive lock which is created by LDREX. |
||
633 | */ |
||
634 | #define __CLREX __clrex |
||
635 | |||
636 | |||
637 | /** |
||
638 | \brief Signed Saturate |
||
639 | \details Saturates a signed value. |
||
640 | \param [in] value Value to be saturated |
||
641 | \param [in] sat Bit position to saturate to (1..32) |
||
642 | \return Saturated value |
||
643 | */ |
||
644 | #define __SSAT __ssat |
||
645 | |||
646 | |||
647 | /** |
||
648 | \brief Unsigned Saturate |
||
649 | \details Saturates an unsigned value. |
||
650 | \param [in] value Value to be saturated |
||
651 | \param [in] sat Bit position to saturate to (0..31) |
||
652 | \return Saturated value |
||
653 | */ |
||
654 | #define __USAT __usat |
||
655 | |||
656 | |||
657 | /** |
||
658 | \brief Rotate Right with Extend (32 bit) |
||
659 | \details Moves each bit of a bitstring right by one bit. |
||
660 | The carry input is shifted in at the left end of the bitstring. |
||
661 | \param [in] value Value to rotate |
||
662 | \return Rotated value |
||
663 | */ |
||
664 | #ifndef __NO_EMBEDDED_ASM |
||
665 | __attribute__((section(".rrx_text"))) __STATIC_INLINE __ASM uint32_t __RRX(uint32_t value) |
||
666 | { |
||
667 | rrx r0, r0 |
||
668 | bx lr |
||
669 | } |
||
670 | #endif |
||
671 | |||
672 | |||
673 | /** |
||
674 | \brief LDRT Unprivileged (8 bit) |
||
675 | \details Executes a Unprivileged LDRT instruction for 8 bit value. |
||
676 | \param [in] ptr Pointer to data |
||
677 | \return value of type uint8_t at (*ptr) |
||
678 | */ |
||
679 | #define __LDRBT(ptr) ((uint8_t ) __ldrt(ptr)) |
||
680 | |||
681 | |||
682 | /** |
||
683 | \brief LDRT Unprivileged (16 bit) |
||
684 | \details Executes a Unprivileged LDRT instruction for 16 bit values. |
||
685 | \param [in] ptr Pointer to data |
||
686 | \return value of type uint16_t at (*ptr) |
||
687 | */ |
||
688 | #define __LDRHT(ptr) ((uint16_t) __ldrt(ptr)) |
||
689 | |||
690 | |||
691 | /** |
||
692 | \brief LDRT Unprivileged (32 bit) |
||
693 | \details Executes a Unprivileged LDRT instruction for 32 bit values. |
||
694 | \param [in] ptr Pointer to data |
||
695 | \return value of type uint32_t at (*ptr) |
||
696 | */ |
||
697 | #define __LDRT(ptr) ((uint32_t ) __ldrt(ptr)) |
||
698 | |||
699 | |||
700 | /** |
||
701 | \brief STRT Unprivileged (8 bit) |
||
702 | \details Executes a Unprivileged STRT instruction for 8 bit values. |
||
703 | \param [in] value Value to store |
||
704 | \param [in] ptr Pointer to location |
||
705 | */ |
||
706 | #define __STRBT(value, ptr) __strt(value, ptr) |
||
707 | |||
708 | |||
709 | /** |
||
710 | \brief STRT Unprivileged (16 bit) |
||
711 | \details Executes a Unprivileged STRT instruction for 16 bit values. |
||
712 | \param [in] value Value to store |
||
713 | \param [in] ptr Pointer to location |
||
714 | */ |
||
715 | #define __STRHT(value, ptr) __strt(value, ptr) |
||
716 | |||
717 | |||
718 | /** |
||
719 | \brief STRT Unprivileged (32 bit) |
||
720 | \details Executes a Unprivileged STRT instruction for 32 bit values. |
||
721 | \param [in] value Value to store |
||
722 | \param [in] ptr Pointer to location |
||
723 | */ |
||
724 | #define __STRT(value, ptr) __strt(value, ptr) |
||
725 | |||
726 | #else /* ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ |
||
727 | (defined (__ARM_ARCH_7EM__) && (__ARM_ARCH_7EM__ == 1)) ) */ |
||
728 | |||
729 | /** |
||
730 | \brief Signed Saturate |
||
731 | \details Saturates a signed value. |
||
732 | \param [in] value Value to be saturated |
||
733 | \param [in] sat Bit position to saturate to (1..32) |
||
734 | \return Saturated value |
||
735 | */ |
||
736 | __attribute__((always_inline)) __STATIC_INLINE int32_t __SSAT(int32_t val, uint32_t sat) |
||
737 | { |
||
738 | if ((sat >= 1U) && (sat <= 32U)) |
||
739 | { |
||
740 | const int32_t max = (int32_t)((1U << (sat - 1U)) - 1U); |
||
741 | const int32_t min = -1 - max ; |
||
742 | if (val > max) |
||
743 | { |
||
744 | return max; |
||
745 | } |
||
746 | else if (val < min) |
||
747 | { |
||
748 | return min; |
||
749 | } |
||
750 | } |
||
751 | return val; |
||
752 | } |
||
753 | |||
754 | /** |
||
755 | \brief Unsigned Saturate |
||
756 | \details Saturates an unsigned value. |
||
757 | \param [in] value Value to be saturated |
||
758 | \param [in] sat Bit position to saturate to (0..31) |
||
759 | \return Saturated value |
||
760 | */ |
||
761 | __attribute__((always_inline)) __STATIC_INLINE uint32_t __USAT(int32_t val, uint32_t sat) |
||
762 | { |
||
763 | if (sat <= 31U) |
||
764 | { |
||
765 | const uint32_t max = ((1U << sat) - 1U); |
||
766 | if (val > (int32_t)max) |
||
767 | { |
||
768 | return max; |
||
769 | } |
||
770 | else if (val < 0) |
||
771 | { |
||
772 | return 0U; |
||
773 | } |
||
774 | } |
||
775 | return (uint32_t)val; |
||
776 | } |
||
777 | |||
778 | #endif /* ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ |
||
779 | (defined (__ARM_ARCH_7EM__) && (__ARM_ARCH_7EM__ == 1)) ) */ |
||
780 | |||
781 | /*@}*/ /* end of group CMSIS_Core_InstructionInterface */ |
||
782 | |||
783 | |||
784 | /* ################### Compiler specific Intrinsics ########################### */ |
||
785 | /** \defgroup CMSIS_SIMD_intrinsics CMSIS SIMD Intrinsics |
||
786 | Access to dedicated SIMD instructions |
||
787 | @{ |
||
788 | */ |
||
789 | |||
790 | #if ((defined (__ARM_ARCH_7EM__) && (__ARM_ARCH_7EM__ == 1)) ) |
||
791 | |||
792 | #define __SADD8 __sadd8 |
||
793 | #define __QADD8 __qadd8 |
||
794 | #define __SHADD8 __shadd8 |
||
795 | #define __UADD8 __uadd8 |
||
796 | #define __UQADD8 __uqadd8 |
||
797 | #define __UHADD8 __uhadd8 |
||
798 | #define __SSUB8 __ssub8 |
||
799 | #define __QSUB8 __qsub8 |
||
800 | #define __SHSUB8 __shsub8 |
||
801 | #define __USUB8 __usub8 |
||
802 | #define __UQSUB8 __uqsub8 |
||
803 | #define __UHSUB8 __uhsub8 |
||
804 | #define __SADD16 __sadd16 |
||
805 | #define __QADD16 __qadd16 |
||
806 | #define __SHADD16 __shadd16 |
||
807 | #define __UADD16 __uadd16 |
||
808 | #define __UQADD16 __uqadd16 |
||
809 | #define __UHADD16 __uhadd16 |
||
810 | #define __SSUB16 __ssub16 |
||
811 | #define __QSUB16 __qsub16 |
||
812 | #define __SHSUB16 __shsub16 |
||
813 | #define __USUB16 __usub16 |
||
814 | #define __UQSUB16 __uqsub16 |
||
815 | #define __UHSUB16 __uhsub16 |
||
816 | #define __SASX __sasx |
||
817 | #define __QASX __qasx |
||
818 | #define __SHASX __shasx |
||
819 | #define __UASX __uasx |
||
820 | #define __UQASX __uqasx |
||
821 | #define __UHASX __uhasx |
||
822 | #define __SSAX __ssax |
||
823 | #define __QSAX __qsax |
||
824 | #define __SHSAX __shsax |
||
825 | #define __USAX __usax |
||
826 | #define __UQSAX __uqsax |
||
827 | #define __UHSAX __uhsax |
||
828 | #define __USAD8 __usad8 |
||
829 | #define __USADA8 __usada8 |
||
830 | #define __SSAT16 __ssat16 |
||
831 | #define __USAT16 __usat16 |
||
832 | #define __UXTB16 __uxtb16 |
||
833 | #define __UXTAB16 __uxtab16 |
||
834 | #define __SXTB16 __sxtb16 |
||
835 | #define __SXTAB16 __sxtab16 |
||
836 | #define __SMUAD __smuad |
||
837 | #define __SMUADX __smuadx |
||
838 | #define __SMLAD __smlad |
||
839 | #define __SMLADX __smladx |
||
840 | #define __SMLALD __smlald |
||
841 | #define __SMLALDX __smlaldx |
||
842 | #define __SMUSD __smusd |
||
843 | #define __SMUSDX __smusdx |
||
844 | #define __SMLSD __smlsd |
||
845 | #define __SMLSDX __smlsdx |
||
846 | #define __SMLSLD __smlsld |
||
847 | #define __SMLSLDX __smlsldx |
||
848 | #define __SEL __sel |
||
849 | #define __QADD __qadd |
||
850 | #define __QSUB __qsub |
||
851 | |||
852 | #define __PKHBT(ARG1,ARG2,ARG3) ( ((((uint32_t)(ARG1)) ) & 0x0000FFFFUL) | \ |
||
853 | ((((uint32_t)(ARG2)) << (ARG3)) & 0xFFFF0000UL) ) |
||
854 | |||
855 | #define __PKHTB(ARG1,ARG2,ARG3) ( ((((uint32_t)(ARG1)) ) & 0xFFFF0000UL) | \ |
||
856 | ((((uint32_t)(ARG2)) >> (ARG3)) & 0x0000FFFFUL) ) |
||
857 | |||
858 | #define __SMMLA(ARG1,ARG2,ARG3) ( (int32_t)((((int64_t)(ARG1) * (ARG2)) + \ |
||
859 | ((int64_t)(ARG3) << 32U) ) >> 32U)) |
||
860 | |||
861 | #endif /* ((defined (__ARM_ARCH_7EM__) && (__ARM_ARCH_7EM__ == 1)) ) */ |
||
862 | /*@} end of group CMSIS_SIMD_intrinsics */ |
||
863 | |||
864 | |||
865 | #endif /* __CMSIS_ARMCC_H */ |