Branch data Line data Source code
1 : : /**************************************************************************//**
2 : : * @file cmsis_gcc.h
3 : : * @brief CMSIS compiler GCC header file
4 : : * @version V5.4.1
5 : : * @date 27. May 2021
6 : : ******************************************************************************/
7 : : /*
8 : : * Copyright (c) 2009-2021 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_GCC_H
26 : : #define __CMSIS_GCC_H
27 : :
28 : : /* ignore some GCC warnings */
29 : : #pragma GCC diagnostic push
30 : : #pragma GCC diagnostic ignored "-Wsign-conversion"
31 : : #pragma GCC diagnostic ignored "-Wconversion"
32 : : #pragma GCC diagnostic ignored "-Wunused-parameter"
33 : :
34 : : /* Fallback for __has_builtin */
35 : : #ifndef __has_builtin
36 : : #define __has_builtin(x) (0)
37 : : #endif
38 : :
39 : : /* CMSIS compiler specific defines */
40 : : #ifndef __ASM
41 : : #define __ASM __asm
42 : : #endif
43 : : #ifndef __INLINE
44 : : #define __INLINE inline
45 : : #endif
46 : : #ifndef __STATIC_INLINE
47 : : #define __STATIC_INLINE static inline
48 : : #endif
49 : : #ifndef __STATIC_FORCEINLINE
50 : : #define __STATIC_FORCEINLINE __attribute__((always_inline)) static inline
51 : : #endif
52 : : #ifndef __NO_RETURN
53 : : #define __NO_RETURN __attribute__((__noreturn__))
54 : : #endif
55 : : #ifndef __USED
56 : : #define __USED __attribute__((used))
57 : : #endif
58 : : #ifndef __WEAK
59 : : #define __WEAK __attribute__((weak))
60 : : #endif
61 : : #ifndef __PACKED
62 : : #define __PACKED __attribute__((packed, aligned(1)))
63 : : #endif
64 : : #ifndef __PACKED_STRUCT
65 : : #define __PACKED_STRUCT struct __attribute__((packed, aligned(1)))
66 : : #endif
67 : : #ifndef __PACKED_UNION
68 : : #define __PACKED_UNION union __attribute__((packed, aligned(1)))
69 : : #endif
70 : : #ifndef __UNALIGNED_UINT32 /* deprecated */
71 : : #pragma GCC diagnostic push
72 : : #pragma GCC diagnostic ignored "-Wpacked"
73 : : #pragma GCC diagnostic ignored "-Wattributes"
74 : : struct __attribute__((packed)) T_UINT32 { uint32_t v; };
75 : : #pragma GCC diagnostic pop
76 : : #define __UNALIGNED_UINT32(x) (((struct T_UINT32 *)(x))->v)
77 : : #endif
78 : : #ifndef __UNALIGNED_UINT16_WRITE
79 : : #pragma GCC diagnostic push
80 : : #pragma GCC diagnostic ignored "-Wpacked"
81 : : #pragma GCC diagnostic ignored "-Wattributes"
82 : : __PACKED_STRUCT T_UINT16_WRITE { uint16_t v; };
83 : : #pragma GCC diagnostic pop
84 : : #define __UNALIGNED_UINT16_WRITE(addr, val) (void)((((struct T_UINT16_WRITE *)(void *)(addr))->v) = (val))
85 : : #endif
86 : : #ifndef __UNALIGNED_UINT16_READ
87 : : #pragma GCC diagnostic push
88 : : #pragma GCC diagnostic ignored "-Wpacked"
89 : : #pragma GCC diagnostic ignored "-Wattributes"
90 : : __PACKED_STRUCT T_UINT16_READ { uint16_t v; };
91 : : #pragma GCC diagnostic pop
92 : : #define __UNALIGNED_UINT16_READ(addr) (((const struct T_UINT16_READ *)(const void *)(addr))->v)
93 : : #endif
94 : : #ifndef __UNALIGNED_UINT32_WRITE
95 : : #pragma GCC diagnostic push
96 : : #pragma GCC diagnostic ignored "-Wpacked"
97 : : #pragma GCC diagnostic ignored "-Wattributes"
98 : : __PACKED_STRUCT T_UINT32_WRITE { uint32_t v; };
99 : : #pragma GCC diagnostic pop
100 : : #define __UNALIGNED_UINT32_WRITE(addr, val) (void)((((struct T_UINT32_WRITE *)(void *)(addr))->v) = (val))
101 : : #endif
102 : : #ifndef __UNALIGNED_UINT32_READ
103 : : #pragma GCC diagnostic push
104 : : #pragma GCC diagnostic ignored "-Wpacked"
105 : : #pragma GCC diagnostic ignored "-Wattributes"
106 : : __PACKED_STRUCT T_UINT32_READ { uint32_t v; };
107 : : #pragma GCC diagnostic pop
108 : : #define __UNALIGNED_UINT32_READ(addr) (((const struct T_UINT32_READ *)(const void *)(addr))->v)
109 : : #endif
110 : : #ifndef __ALIGNED
111 : : #define __ALIGNED(x) __attribute__((aligned(x)))
112 : : #endif
113 : : #ifndef __RESTRICT
114 : : #define __RESTRICT __restrict
115 : : #endif
116 : : #ifndef __COMPILER_BARRIER
117 : : #define __COMPILER_BARRIER() __ASM volatile("":::"memory")
118 : : #endif
119 : :
120 : : /* ######################### Startup and Lowlevel Init ######################## */
121 : :
122 : : #ifndef __PROGRAM_START
123 : :
124 : : /**
125 : : \brief Initializes data and bss sections
126 : : \details This default implementations initialized all data and additional bss
127 : : sections relying on .copy.table and .zero.table specified properly
128 : : in the used linker script.
129 : :
130 : : */
131 : : __STATIC_FORCEINLINE __NO_RETURN void __cmsis_start(void)
132 : : {
133 : : extern void _start(void) __NO_RETURN;
134 : :
135 : : typedef struct {
136 : : uint32_t const* src;
137 : : uint32_t* dest;
138 : : uint32_t wlen;
139 : : } __copy_table_t;
140 : :
141 : : typedef struct {
142 : : uint32_t* dest;
143 : : uint32_t wlen;
144 : : } __zero_table_t;
145 : :
146 : : extern const __copy_table_t __copy_table_start__;
147 : : extern const __copy_table_t __copy_table_end__;
148 : : extern const __zero_table_t __zero_table_start__;
149 : : extern const __zero_table_t __zero_table_end__;
150 : :
151 : : for (__copy_table_t const* pTable = &__copy_table_start__; pTable < &__copy_table_end__; ++pTable) {
152 : : for(uint32_t i=0u; i<pTable->wlen; ++i) {
153 : : pTable->dest[i] = pTable->src[i];
154 : : }
155 : : }
156 : :
157 : : for (__zero_table_t const* pTable = &__zero_table_start__; pTable < &__zero_table_end__; ++pTable) {
158 : : for(uint32_t i=0u; i<pTable->wlen; ++i) {
159 : : pTable->dest[i] = 0u;
160 : : }
161 : : }
162 : :
163 : : _start();
164 : : }
165 : :
166 : : #define __PROGRAM_START __cmsis_start
167 : : #endif
168 : :
169 : : #ifndef __INITIAL_SP
170 : : #define __INITIAL_SP __StackTop
171 : : #endif
172 : :
173 : : #ifndef __STACK_LIMIT
174 : : #define __STACK_LIMIT __StackLimit
175 : : #endif
176 : :
177 : : #ifndef __VECTOR_TABLE
178 : : #define __VECTOR_TABLE __Vectors
179 : : #endif
180 : :
181 : : #ifndef __VECTOR_TABLE_ATTRIBUTE
182 : : #define __VECTOR_TABLE_ATTRIBUTE __attribute__((used, section(".vectors")))
183 : : #endif
184 : :
185 : : #if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)
186 : : #ifndef __STACK_SEAL
187 : : #define __STACK_SEAL __StackSeal
188 : : #endif
189 : :
190 : : #ifndef __TZ_STACK_SEAL_SIZE
191 : : #define __TZ_STACK_SEAL_SIZE 8U
192 : : #endif
193 : :
194 : : #ifndef __TZ_STACK_SEAL_VALUE
195 : : #define __TZ_STACK_SEAL_VALUE 0xFEF5EDA5FEF5EDA5ULL
196 : : #endif
197 : :
198 : :
199 : : __STATIC_FORCEINLINE void __TZ_set_STACKSEAL_S (uint32_t* stackTop) {
200 : : *((uint64_t *)stackTop) = __TZ_STACK_SEAL_VALUE;
201 : : }
202 : : #endif
203 : :
204 : :
205 : : /* ########################## Core Instruction Access ######################### */
206 : : /** \defgroup CMSIS_Core_InstructionInterface CMSIS Core Instruction Interface
207 : : Access to dedicated instructions
208 : : @{
209 : : */
210 : :
211 : : /* Define macros for porting to both thumb1 and thumb2.
212 : : * For thumb1, use low register (r0-r7), specified by constraint "l"
213 : : * Otherwise, use general registers, specified by constraint "r" */
214 : : #if defined (__thumb__) && !defined (__thumb2__)
215 : : #define __CMSIS_GCC_OUT_REG(r) "=l" (r)
216 : : #define __CMSIS_GCC_RW_REG(r) "+l" (r)
217 : : #define __CMSIS_GCC_USE_REG(r) "l" (r)
218 : : #else
219 : : #define __CMSIS_GCC_OUT_REG(r) "=r" (r)
220 : : #define __CMSIS_GCC_RW_REG(r) "+r" (r)
221 : : #define __CMSIS_GCC_USE_REG(r) "r" (r)
222 : : #endif
223 : :
224 : : /**
225 : : \brief No Operation
226 : : \details No Operation does nothing. This instruction can be used for code alignment purposes.
227 : : */
228 : : #define __NOP() __ASM volatile ("nop")
229 : :
230 : : /**
231 : : \brief Wait For Interrupt
232 : : \details Wait For Interrupt is a hint instruction that suspends execution until one of a number of events occurs.
233 : : */
234 : : #define __WFI() __ASM volatile ("wfi":::"memory")
235 : :
236 : :
237 : : /**
238 : : \brief Wait For Event
239 : : \details Wait For Event is a hint instruction that permits the processor to enter
240 : : a low-power state until one of a number of events occurs.
241 : : */
242 : : #define __WFE() __ASM volatile ("wfe":::"memory")
243 : :
244 : :
245 : : /**
246 : : \brief Send Event
247 : : \details Send Event is a hint instruction. It causes an event to be signaled to the CPU.
248 : : */
249 : : #define __SEV() __ASM volatile ("sev")
250 : :
251 : :
252 : : /**
253 : : \brief Instruction Synchronization Barrier
254 : : \details Instruction Synchronization Barrier flushes the pipeline in the processor,
255 : : so that all instructions following the ISB are fetched from cache or memory,
256 : : after the instruction has been completed.
257 : : */
258 : : __STATIC_FORCEINLINE void __ISB(void)
259 : : {
260 : 2 : __ASM volatile ("isb 0xF":::"memory");
261 : 2 : }
262 : :
263 : :
264 : : /**
265 : : \brief Data Synchronization Barrier
266 : : \details Acts as a special kind of Data Memory Barrier.
267 : : It completes when all explicit memory accesses before this instruction complete.
268 : : */
269 : : __STATIC_FORCEINLINE void __DSB(void)
270 : : {
271 : 1 : __ASM volatile ("dsb 0xF":::"memory");
272 : 1 : }
273 : :
274 : :
275 : : /**
276 : : \brief Data Memory Barrier
277 : : \details Ensures the apparent order of the explicit memory operations before
278 : : and after the instruction, without ensuring their completion.
279 : : */
280 : : __STATIC_FORCEINLINE void __DMB(void)
281 : : {
282 : 53 : __ASM volatile ("dmb 0xF":::"memory");
283 : 53 : }
284 : :
285 : :
286 : : /**
287 : : \brief Reverse byte order (32 bit)
288 : : \details Reverses the byte order in unsigned integer value. For example, 0x12345678 becomes 0x78563412.
289 : : \param [in] value Value to reverse
290 : : \return Reversed value
291 : : */
292 : : __STATIC_FORCEINLINE uint32_t __REV(uint32_t value)
293 : : {
294 : : #if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 5)
295 : : return __builtin_bswap32(value);
296 : : #else
297 : : uint32_t result;
298 : :
299 : : __ASM ("rev %0, %1" : __CMSIS_GCC_OUT_REG (result) : __CMSIS_GCC_USE_REG (value) );
300 : : return result;
301 : : #endif
302 : : }
303 : :
304 : :
305 : : /**
306 : : \brief Reverse byte order (16 bit)
307 : : \details Reverses the byte order within each halfword of a word. For example, 0x12345678 becomes 0x34127856.
308 : : \param [in] value Value to reverse
309 : : \return Reversed value
310 : : */
311 : : __STATIC_FORCEINLINE uint32_t __REV16(uint32_t value)
312 : : {
313 : : uint32_t result;
314 : :
315 : : __ASM ("rev16 %0, %1" : __CMSIS_GCC_OUT_REG (result) : __CMSIS_GCC_USE_REG (value) );
316 : : return result;
317 : : }
318 : :
319 : :
320 : : /**
321 : : \brief Reverse byte order (16 bit)
322 : : \details Reverses the byte order in a 16-bit value and returns the signed 16-bit result. For example, 0x0080 becomes 0x8000.
323 : : \param [in] value Value to reverse
324 : : \return Reversed value
325 : : */
326 : : __STATIC_FORCEINLINE int16_t __REVSH(int16_t value)
327 : : {
328 : : #if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8)
329 : : return (int16_t)__builtin_bswap16(value);
330 : : #else
331 : : int16_t result;
332 : :
333 : : __ASM ("revsh %0, %1" : __CMSIS_GCC_OUT_REG (result) : __CMSIS_GCC_USE_REG (value) );
334 : : return result;
335 : : #endif
336 : : }
337 : :
338 : :
339 : : /**
340 : : \brief Rotate Right in unsigned value (32 bit)
341 : : \details Rotate Right (immediate) provides the value of the contents of a register rotated by a variable number of bits.
342 : : \param [in] op1 Value to rotate
343 : : \param [in] op2 Number of Bits to rotate
344 : : \return Rotated value
345 : : */
346 : : __STATIC_FORCEINLINE uint32_t __ROR(uint32_t op1, uint32_t op2)
347 : : {
348 : : op2 %= 32U;
349 : : if (op2 == 0U)
350 : : {
351 : : return op1;
352 : : }
353 : : return (op1 >> op2) | (op1 << (32U - op2));
354 : : }
355 : :
356 : :
357 : : /**
358 : : \brief Breakpoint
359 : : \details Causes the processor to enter Debug state.
360 : : Debug tools can use this to investigate system state when the instruction at a particular address is reached.
361 : : \param [in] value is ignored by the processor.
362 : : If required, a debugger can use it to store additional information about the breakpoint.
363 : : */
364 : : #define __BKPT(value) __ASM volatile ("bkpt "#value)
365 : :
366 : :
367 : : /**
368 : : \brief Reverse bit order of value
369 : : \details Reverses the bit order of the given value.
370 : : \param [in] value Value to reverse
371 : : \return Reversed value
372 : : */
373 : : __STATIC_FORCEINLINE uint32_t __RBIT(uint32_t value)
374 : : {
375 : : uint32_t result;
376 : :
377 : : #if ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \
378 : : (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \
379 : : (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) )
380 : : __ASM ("rbit %0, %1" : "=r" (result) : "r" (value) );
381 : : #else
382 : : uint32_t s = (4U /*sizeof(v)*/ * 8U) - 1U; /* extra shift needed at end */
383 : :
384 : : result = value; /* r will be reversed bits of v; first get LSB of v */
385 : : for (value >>= 1U; value != 0U; value >>= 1U)
386 : : {
387 : : result <<= 1U;
388 : : result |= value & 1U;
389 : : s--;
390 : : }
391 : : result <<= s; /* shift when v's highest bits are zero */
392 : : #endif
393 : : return result;
394 : : }
395 : :
396 : :
397 : : /**
398 : : \brief Count leading zeros
399 : : \details Counts the number of leading zeros of a data value.
400 : : \param [in] value Value to count the leading zeros
401 : : \return number of leading zeros in value
402 : : */
403 : : __STATIC_FORCEINLINE uint8_t __CLZ(uint32_t value)
404 : : {
405 : : /* Even though __builtin_clz produces a CLZ instruction on ARM, formally
406 : : __builtin_clz(0) is undefined behaviour, so handle this case specially.
407 : : This guarantees ARM-compatible results if happening to compile on a non-ARM
408 : : target, and ensures the compiler doesn't decide to activate any
409 : : optimisations using the logic "value was passed to __builtin_clz, so it
410 : : is non-zero".
411 : : ARM GCC 7.3 and possibly earlier will optimise this test away, leaving a
412 : : single CLZ instruction.
413 : : */
414 : : if (value == 0U)
415 : : {
416 : : return 32U;
417 : : }
418 : : return __builtin_clz(value);
419 : : }
420 : :
421 : :
422 : : #if ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \
423 : : (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \
424 : : (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \
425 : : (defined (__ARM_ARCH_8M_BASE__ ) && (__ARM_ARCH_8M_BASE__ == 1)) )
426 : : /**
427 : : \brief LDR Exclusive (8 bit)
428 : : \details Executes a exclusive LDR instruction for 8 bit value.
429 : : \param [in] ptr Pointer to data
430 : : \return value of type uint8_t at (*ptr)
431 : : */
432 : : __STATIC_FORCEINLINE uint8_t __LDREXB(volatile uint8_t *addr)
433 : : {
434 : : uint32_t result;
435 : :
436 : : #if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8)
437 : : __ASM volatile ("ldrexb %0, %1" : "=r" (result) : "Q" (*addr) );
438 : : #else
439 : : /* Prior to GCC 4.8, "Q" will be expanded to [rx, #0] which is not
440 : : accepted by assembler. So has to use following less efficient pattern.
441 : : */
442 : : __ASM volatile ("ldrexb %0, [%1]" : "=r" (result) : "r" (addr) : "memory" );
443 : : #endif
444 : : return ((uint8_t) result); /* Add explicit type cast here */
445 : : }
446 : :
447 : :
448 : : /**
449 : : \brief LDR Exclusive (16 bit)
450 : : \details Executes a exclusive LDR instruction for 16 bit values.
451 : : \param [in] ptr Pointer to data
452 : : \return value of type uint16_t at (*ptr)
453 : : */
454 : : __STATIC_FORCEINLINE uint16_t __LDREXH(volatile uint16_t *addr)
455 : : {
456 : : uint32_t result;
457 : :
458 : : #if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8)
459 : : __ASM volatile ("ldrexh %0, %1" : "=r" (result) : "Q" (*addr) );
460 : : #else
461 : : /* Prior to GCC 4.8, "Q" will be expanded to [rx, #0] which is not
462 : : accepted by assembler. So has to use following less efficient pattern.
463 : : */
464 : : __ASM volatile ("ldrexh %0, [%1]" : "=r" (result) : "r" (addr) : "memory" );
465 : : #endif
466 : : return ((uint16_t) result); /* Add explicit type cast here */
467 : : }
468 : :
469 : :
470 : : /**
471 : : \brief LDR Exclusive (32 bit)
472 : : \details Executes a exclusive LDR instruction for 32 bit values.
473 : : \param [in] ptr Pointer to data
474 : : \return value of type uint32_t at (*ptr)
475 : : */
476 : : __STATIC_FORCEINLINE uint32_t __LDREXW(volatile uint32_t *addr)
477 : : {
478 : : uint32_t result;
479 : :
480 : : __ASM volatile ("ldrex %0, %1" : "=r" (result) : "Q" (*addr) );
481 : : return(result);
482 : : }
483 : :
484 : :
485 : : /**
486 : : \brief STR Exclusive (8 bit)
487 : : \details Executes a exclusive STR instruction for 8 bit values.
488 : : \param [in] value Value to store
489 : : \param [in] ptr Pointer to location
490 : : \return 0 Function succeeded
491 : : \return 1 Function failed
492 : : */
493 : : __STATIC_FORCEINLINE uint32_t __STREXB(uint8_t value, volatile uint8_t *addr)
494 : : {
495 : : uint32_t result;
496 : :
497 : : __ASM volatile ("strexb %0, %2, %1" : "=&r" (result), "=Q" (*addr) : "r" ((uint32_t)value) );
498 : : return(result);
499 : : }
500 : :
501 : :
502 : : /**
503 : : \brief STR Exclusive (16 bit)
504 : : \details Executes a exclusive STR instruction for 16 bit values.
505 : : \param [in] value Value to store
506 : : \param [in] ptr Pointer to location
507 : : \return 0 Function succeeded
508 : : \return 1 Function failed
509 : : */
510 : : __STATIC_FORCEINLINE uint32_t __STREXH(uint16_t value, volatile uint16_t *addr)
511 : : {
512 : : uint32_t result;
513 : :
514 : : __ASM volatile ("strexh %0, %2, %1" : "=&r" (result), "=Q" (*addr) : "r" ((uint32_t)value) );
515 : : return(result);
516 : : }
517 : :
518 : :
519 : : /**
520 : : \brief STR Exclusive (32 bit)
521 : : \details Executes a exclusive STR instruction for 32 bit values.
522 : : \param [in] value Value to store
523 : : \param [in] ptr Pointer to location
524 : : \return 0 Function succeeded
525 : : \return 1 Function failed
526 : : */
527 : : __STATIC_FORCEINLINE uint32_t __STREXW(uint32_t value, volatile uint32_t *addr)
528 : : {
529 : : uint32_t result;
530 : :
531 : : __ASM volatile ("strex %0, %2, %1" : "=&r" (result), "=Q" (*addr) : "r" (value) );
532 : : return(result);
533 : : }
534 : :
535 : :
536 : : /**
537 : : \brief Remove the exclusive lock
538 : : \details Removes the exclusive lock which is created by LDREX.
539 : : */
540 : : __STATIC_FORCEINLINE void __CLREX(void)
541 : : {
542 : : __ASM volatile ("clrex" ::: "memory");
543 : : }
544 : :
545 : : #endif /* ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \
546 : : (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \
547 : : (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \
548 : : (defined (__ARM_ARCH_8M_BASE__ ) && (__ARM_ARCH_8M_BASE__ == 1)) ) */
549 : :
550 : :
551 : : #if ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \
552 : : (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \
553 : : (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) )
554 : : /**
555 : : \brief Signed Saturate
556 : : \details Saturates a signed value.
557 : : \param [in] ARG1 Value to be saturated
558 : : \param [in] ARG2 Bit position to saturate to (1..32)
559 : : \return Saturated value
560 : : */
561 : : #define __SSAT(ARG1, ARG2) \
562 : : __extension__ \
563 : : ({ \
564 : : int32_t __RES, __ARG1 = (ARG1); \
565 : : __ASM volatile ("ssat %0, %1, %2" : "=r" (__RES) : "I" (ARG2), "r" (__ARG1) : "cc" ); \
566 : : __RES; \
567 : : })
568 : :
569 : :
570 : : /**
571 : : \brief Unsigned Saturate
572 : : \details Saturates an unsigned value.
573 : : \param [in] ARG1 Value to be saturated
574 : : \param [in] ARG2 Bit position to saturate to (0..31)
575 : : \return Saturated value
576 : : */
577 : : #define __USAT(ARG1, ARG2) \
578 : : __extension__ \
579 : : ({ \
580 : : uint32_t __RES, __ARG1 = (ARG1); \
581 : : __ASM volatile ("usat %0, %1, %2" : "=r" (__RES) : "I" (ARG2), "r" (__ARG1) : "cc" ); \
582 : : __RES; \
583 : : })
584 : :
585 : :
586 : : /**
587 : : \brief Rotate Right with Extend (32 bit)
588 : : \details Moves each bit of a bitstring right by one bit.
589 : : The carry input is shifted in at the left end of the bitstring.
590 : : \param [in] value Value to rotate
591 : : \return Rotated value
592 : : */
593 : : __STATIC_FORCEINLINE uint32_t __RRX(uint32_t value)
594 : : {
595 : : uint32_t result;
596 : :
597 : : __ASM volatile ("rrx %0, %1" : __CMSIS_GCC_OUT_REG (result) : __CMSIS_GCC_USE_REG (value) );
598 : : return(result);
599 : : }
600 : :
601 : :
602 : : /**
603 : : \brief LDRT Unprivileged (8 bit)
604 : : \details Executes a Unprivileged LDRT instruction for 8 bit value.
605 : : \param [in] ptr Pointer to data
606 : : \return value of type uint8_t at (*ptr)
607 : : */
608 : : __STATIC_FORCEINLINE uint8_t __LDRBT(volatile uint8_t *ptr)
609 : : {
610 : : uint32_t result;
611 : :
612 : : #if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8)
613 : : __ASM volatile ("ldrbt %0, %1" : "=r" (result) : "Q" (*ptr) );
614 : : #else
615 : : /* Prior to GCC 4.8, "Q" will be expanded to [rx, #0] which is not
616 : : accepted by assembler. So has to use following less efficient pattern.
617 : : */
618 : : __ASM volatile ("ldrbt %0, [%1]" : "=r" (result) : "r" (ptr) : "memory" );
619 : : #endif
620 : : return ((uint8_t) result); /* Add explicit type cast here */
621 : : }
622 : :
623 : :
624 : : /**
625 : : \brief LDRT Unprivileged (16 bit)
626 : : \details Executes a Unprivileged LDRT instruction for 16 bit values.
627 : : \param [in] ptr Pointer to data
628 : : \return value of type uint16_t at (*ptr)
629 : : */
630 : : __STATIC_FORCEINLINE uint16_t __LDRHT(volatile uint16_t *ptr)
631 : : {
632 : : uint32_t result;
633 : :
634 : : #if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8)
635 : : __ASM volatile ("ldrht %0, %1" : "=r" (result) : "Q" (*ptr) );
636 : : #else
637 : : /* Prior to GCC 4.8, "Q" will be expanded to [rx, #0] which is not
638 : : accepted by assembler. So has to use following less efficient pattern.
639 : : */
640 : : __ASM volatile ("ldrht %0, [%1]" : "=r" (result) : "r" (ptr) : "memory" );
641 : : #endif
642 : : return ((uint16_t) result); /* Add explicit type cast here */
643 : : }
644 : :
645 : :
646 : : /**
647 : : \brief LDRT Unprivileged (32 bit)
648 : : \details Executes a Unprivileged LDRT instruction for 32 bit values.
649 : : \param [in] ptr Pointer to data
650 : : \return value of type uint32_t at (*ptr)
651 : : */
652 : : __STATIC_FORCEINLINE uint32_t __LDRT(volatile uint32_t *ptr)
653 : : {
654 : : uint32_t result;
655 : :
656 : : __ASM volatile ("ldrt %0, %1" : "=r" (result) : "Q" (*ptr) );
657 : : return(result);
658 : : }
659 : :
660 : :
661 : : /**
662 : : \brief STRT Unprivileged (8 bit)
663 : : \details Executes a Unprivileged STRT instruction for 8 bit values.
664 : : \param [in] value Value to store
665 : : \param [in] ptr Pointer to location
666 : : */
667 : : __STATIC_FORCEINLINE void __STRBT(uint8_t value, volatile uint8_t *ptr)
668 : : {
669 : : __ASM volatile ("strbt %1, %0" : "=Q" (*ptr) : "r" ((uint32_t)value) );
670 : : }
671 : :
672 : :
673 : : /**
674 : : \brief STRT Unprivileged (16 bit)
675 : : \details Executes a Unprivileged STRT instruction for 16 bit values.
676 : : \param [in] value Value to store
677 : : \param [in] ptr Pointer to location
678 : : */
679 : : __STATIC_FORCEINLINE void __STRHT(uint16_t value, volatile uint16_t *ptr)
680 : : {
681 : : __ASM volatile ("strht %1, %0" : "=Q" (*ptr) : "r" ((uint32_t)value) );
682 : : }
683 : :
684 : :
685 : : /**
686 : : \brief STRT Unprivileged (32 bit)
687 : : \details Executes a Unprivileged STRT instruction for 32 bit values.
688 : : \param [in] value Value to store
689 : : \param [in] ptr Pointer to location
690 : : */
691 : : __STATIC_FORCEINLINE void __STRT(uint32_t value, volatile uint32_t *ptr)
692 : : {
693 : : __ASM volatile ("strt %1, %0" : "=Q" (*ptr) : "r" (value) );
694 : : }
695 : :
696 : : #else /* ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \
697 : : (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \
698 : : (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) ) */
699 : :
700 : : /**
701 : : \brief Signed Saturate
702 : : \details Saturates a signed value.
703 : : \param [in] value Value to be saturated
704 : : \param [in] sat Bit position to saturate to (1..32)
705 : : \return Saturated value
706 : : */
707 : : __STATIC_FORCEINLINE int32_t __SSAT(int32_t val, uint32_t sat)
708 : : {
709 : : if ((sat >= 1U) && (sat <= 32U))
710 : : {
711 : : const int32_t max = (int32_t)((1U << (sat - 1U)) - 1U);
712 : : const int32_t min = -1 - max ;
713 : : if (val > max)
714 : : {
715 : : return max;
716 : : }
717 : : else if (val < min)
718 : : {
719 : : return min;
720 : : }
721 : : }
722 : : return val;
723 : : }
724 : :
725 : : /**
726 : : \brief Unsigned Saturate
727 : : \details Saturates an unsigned value.
728 : : \param [in] value Value to be saturated
729 : : \param [in] sat Bit position to saturate to (0..31)
730 : : \return Saturated value
731 : : */
732 : : __STATIC_FORCEINLINE uint32_t __USAT(int32_t val, uint32_t sat)
733 : : {
734 : : if (sat <= 31U)
735 : : {
736 : : const uint32_t max = ((1U << sat) - 1U);
737 : : if (val > (int32_t)max)
738 : : {
739 : : return max;
740 : : }
741 : : else if (val < 0)
742 : : {
743 : : return 0U;
744 : : }
745 : : }
746 : : return (uint32_t)val;
747 : : }
748 : :
749 : : #endif /* ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \
750 : : (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \
751 : : (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) ) */
752 : :
753 : :
754 : : #if ((defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \
755 : : (defined (__ARM_ARCH_8M_BASE__ ) && (__ARM_ARCH_8M_BASE__ == 1)) )
756 : : /**
757 : : \brief Load-Acquire (8 bit)
758 : : \details Executes a LDAB instruction for 8 bit value.
759 : : \param [in] ptr Pointer to data
760 : : \return value of type uint8_t at (*ptr)
761 : : */
762 : : __STATIC_FORCEINLINE uint8_t __LDAB(volatile uint8_t *ptr)
763 : : {
764 : : uint32_t result;
765 : :
766 : : __ASM volatile ("ldab %0, %1" : "=r" (result) : "Q" (*ptr) : "memory" );
767 : : return ((uint8_t) result);
768 : : }
769 : :
770 : :
771 : : /**
772 : : \brief Load-Acquire (16 bit)
773 : : \details Executes a LDAH instruction for 16 bit values.
774 : : \param [in] ptr Pointer to data
775 : : \return value of type uint16_t at (*ptr)
776 : : */
777 : : __STATIC_FORCEINLINE uint16_t __LDAH(volatile uint16_t *ptr)
778 : : {
779 : : uint32_t result;
780 : :
781 : : __ASM volatile ("ldah %0, %1" : "=r" (result) : "Q" (*ptr) : "memory" );
782 : : return ((uint16_t) result);
783 : : }
784 : :
785 : :
786 : : /**
787 : : \brief Load-Acquire (32 bit)
788 : : \details Executes a LDA instruction for 32 bit values.
789 : : \param [in] ptr Pointer to data
790 : : \return value of type uint32_t at (*ptr)
791 : : */
792 : : __STATIC_FORCEINLINE uint32_t __LDA(volatile uint32_t *ptr)
793 : : {
794 : : uint32_t result;
795 : :
796 : : __ASM volatile ("lda %0, %1" : "=r" (result) : "Q" (*ptr) : "memory" );
797 : : return(result);
798 : : }
799 : :
800 : :
801 : : /**
802 : : \brief Store-Release (8 bit)
803 : : \details Executes a STLB instruction for 8 bit values.
804 : : \param [in] value Value to store
805 : : \param [in] ptr Pointer to location
806 : : */
807 : : __STATIC_FORCEINLINE void __STLB(uint8_t value, volatile uint8_t *ptr)
808 : : {
809 : : __ASM volatile ("stlb %1, %0" : "=Q" (*ptr) : "r" ((uint32_t)value) : "memory" );
810 : : }
811 : :
812 : :
813 : : /**
814 : : \brief Store-Release (16 bit)
815 : : \details Executes a STLH instruction for 16 bit values.
816 : : \param [in] value Value to store
817 : : \param [in] ptr Pointer to location
818 : : */
819 : : __STATIC_FORCEINLINE void __STLH(uint16_t value, volatile uint16_t *ptr)
820 : : {
821 : : __ASM volatile ("stlh %1, %0" : "=Q" (*ptr) : "r" ((uint32_t)value) : "memory" );
822 : : }
823 : :
824 : :
825 : : /**
826 : : \brief Store-Release (32 bit)
827 : : \details Executes a STL instruction for 32 bit values.
828 : : \param [in] value Value to store
829 : : \param [in] ptr Pointer to location
830 : : */
831 : : __STATIC_FORCEINLINE void __STL(uint32_t value, volatile uint32_t *ptr)
832 : : {
833 : : __ASM volatile ("stl %1, %0" : "=Q" (*ptr) : "r" ((uint32_t)value) : "memory" );
834 : : }
835 : :
836 : :
837 : : /**
838 : : \brief Load-Acquire Exclusive (8 bit)
839 : : \details Executes a LDAB exclusive instruction for 8 bit value.
840 : : \param [in] ptr Pointer to data
841 : : \return value of type uint8_t at (*ptr)
842 : : */
843 : : __STATIC_FORCEINLINE uint8_t __LDAEXB(volatile uint8_t *ptr)
844 : : {
845 : : uint32_t result;
846 : :
847 : : __ASM volatile ("ldaexb %0, %1" : "=r" (result) : "Q" (*ptr) : "memory" );
848 : : return ((uint8_t) result);
849 : : }
850 : :
851 : :
852 : : /**
853 : : \brief Load-Acquire Exclusive (16 bit)
854 : : \details Executes a LDAH exclusive instruction for 16 bit values.
855 : : \param [in] ptr Pointer to data
856 : : \return value of type uint16_t at (*ptr)
857 : : */
858 : : __STATIC_FORCEINLINE uint16_t __LDAEXH(volatile uint16_t *ptr)
859 : : {
860 : : uint32_t result;
861 : :
862 : : __ASM volatile ("ldaexh %0, %1" : "=r" (result) : "Q" (*ptr) : "memory" );
863 : : return ((uint16_t) result);
864 : : }
865 : :
866 : :
867 : : /**
868 : : \brief Load-Acquire Exclusive (32 bit)
869 : : \details Executes a LDA exclusive instruction for 32 bit values.
870 : : \param [in] ptr Pointer to data
871 : : \return value of type uint32_t at (*ptr)
872 : : */
873 : : __STATIC_FORCEINLINE uint32_t __LDAEX(volatile uint32_t *ptr)
874 : : {
875 : : uint32_t result;
876 : :
877 : : __ASM volatile ("ldaex %0, %1" : "=r" (result) : "Q" (*ptr) : "memory" );
878 : : return(result);
879 : : }
880 : :
881 : :
882 : : /**
883 : : \brief Store-Release Exclusive (8 bit)
884 : : \details Executes a STLB exclusive instruction for 8 bit values.
885 : : \param [in] value Value to store
886 : : \param [in] ptr Pointer to location
887 : : \return 0 Function succeeded
888 : : \return 1 Function failed
889 : : */
890 : : __STATIC_FORCEINLINE uint32_t __STLEXB(uint8_t value, volatile uint8_t *ptr)
891 : : {
892 : : uint32_t result;
893 : :
894 : : __ASM volatile ("stlexb %0, %2, %1" : "=&r" (result), "=Q" (*ptr) : "r" ((uint32_t)value) : "memory" );
895 : : return(result);
896 : : }
897 : :
898 : :
899 : : /**
900 : : \brief Store-Release Exclusive (16 bit)
901 : : \details Executes a STLH exclusive instruction for 16 bit values.
902 : : \param [in] value Value to store
903 : : \param [in] ptr Pointer to location
904 : : \return 0 Function succeeded
905 : : \return 1 Function failed
906 : : */
907 : : __STATIC_FORCEINLINE uint32_t __STLEXH(uint16_t value, volatile uint16_t *ptr)
908 : : {
909 : : uint32_t result;
910 : :
911 : : __ASM volatile ("stlexh %0, %2, %1" : "=&r" (result), "=Q" (*ptr) : "r" ((uint32_t)value) : "memory" );
912 : : return(result);
913 : : }
914 : :
915 : :
916 : : /**
917 : : \brief Store-Release Exclusive (32 bit)
918 : : \details Executes a STL exclusive instruction for 32 bit values.
919 : : \param [in] value Value to store
920 : : \param [in] ptr Pointer to location
921 : : \return 0 Function succeeded
922 : : \return 1 Function failed
923 : : */
924 : : __STATIC_FORCEINLINE uint32_t __STLEX(uint32_t value, volatile uint32_t *ptr)
925 : : {
926 : : uint32_t result;
927 : :
928 : : __ASM volatile ("stlex %0, %2, %1" : "=&r" (result), "=Q" (*ptr) : "r" ((uint32_t)value) : "memory" );
929 : : return(result);
930 : : }
931 : :
932 : : #endif /* ((defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \
933 : : (defined (__ARM_ARCH_8M_BASE__ ) && (__ARM_ARCH_8M_BASE__ == 1)) ) */
934 : :
935 : : /*@}*/ /* end of group CMSIS_Core_InstructionInterface */
936 : :
937 : :
938 : : /* ########################### Core Function Access ########################### */
939 : : /** \ingroup CMSIS_Core_FunctionInterface
940 : : \defgroup CMSIS_Core_RegAccFunctions CMSIS Core Register Access Functions
941 : : @{
942 : : */
943 : :
944 : : /**
945 : : \brief Enable IRQ Interrupts
946 : : \details Enables IRQ interrupts by clearing special-purpose register PRIMASK.
947 : : Can only be executed in Privileged modes.
948 : : */
949 : : __STATIC_FORCEINLINE void __enable_irq(void)
950 : : {
951 : 0 : __ASM volatile ("cpsie i" : : : "memory");
952 : 0 : }
953 : :
954 : :
955 : : /**
956 : : \brief Disable IRQ Interrupts
957 : : \details Disables IRQ interrupts by setting special-purpose register PRIMASK.
958 : : Can only be executed in Privileged modes.
959 : : */
960 : : __STATIC_FORCEINLINE void __disable_irq(void)
961 : : {
962 : 0 : __ASM volatile ("cpsid i" : : : "memory");
963 : 0 : }
964 : :
965 : :
966 : : /**
967 : : \brief Get Control Register
968 : : \details Returns the content of the Control Register.
969 : : \return Control Register value
970 : : */
971 : : __STATIC_FORCEINLINE uint32_t __get_CONTROL(void)
972 : : {
973 : : uint32_t result;
974 : :
975 : : __ASM volatile ("MRS %0, control" : "=r" (result) );
976 : : return(result);
977 : : }
978 : :
979 : :
980 : : #if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3))
981 : : /**
982 : : \brief Get Control Register (non-secure)
983 : : \details Returns the content of the non-secure Control Register when in secure mode.
984 : : \return non-secure Control Register value
985 : : */
986 : : __STATIC_FORCEINLINE uint32_t __TZ_get_CONTROL_NS(void)
987 : : {
988 : : uint32_t result;
989 : :
990 : : __ASM volatile ("MRS %0, control_ns" : "=r" (result) );
991 : : return(result);
992 : : }
993 : : #endif
994 : :
995 : :
996 : : /**
997 : : \brief Set Control Register
998 : : \details Writes the given value to the Control Register.
999 : : \param [in] control Control Register value to set
1000 : : */
1001 : : __STATIC_FORCEINLINE void __set_CONTROL(uint32_t control)
1002 : : {
1003 : : __ASM volatile ("MSR control, %0" : : "r" (control) : "memory");
1004 : : __ISB();
1005 : : }
1006 : :
1007 : :
1008 : : #if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3))
1009 : : /**
1010 : : \brief Set Control Register (non-secure)
1011 : : \details Writes the given value to the non-secure Control Register when in secure state.
1012 : : \param [in] control Control Register value to set
1013 : : */
1014 : : __STATIC_FORCEINLINE void __TZ_set_CONTROL_NS(uint32_t control)
1015 : : {
1016 : : __ASM volatile ("MSR control_ns, %0" : : "r" (control) : "memory");
1017 : : __ISB();
1018 : : }
1019 : : #endif
1020 : :
1021 : :
1022 : : /**
1023 : : \brief Get IPSR Register
1024 : : \details Returns the content of the IPSR Register.
1025 : : \return IPSR Register value
1026 : : */
1027 : : __STATIC_FORCEINLINE uint32_t __get_IPSR(void)
1028 : : {
1029 : : uint32_t result;
1030 : :
1031 : 44336 : __ASM volatile ("MRS %0, ipsr" : "=r" (result) );
1032 : 44336 : return(result);
1033 : : }
1034 : :
1035 : :
1036 : : /**
1037 : : \brief Get APSR Register
1038 : : \details Returns the content of the APSR Register.
1039 : : \return APSR Register value
1040 : : */
1041 : : __STATIC_FORCEINLINE uint32_t __get_APSR(void)
1042 : : {
1043 : : uint32_t result;
1044 : :
1045 : : __ASM volatile ("MRS %0, apsr" : "=r" (result) );
1046 : : return(result);
1047 : : }
1048 : :
1049 : :
1050 : : /**
1051 : : \brief Get xPSR Register
1052 : : \details Returns the content of the xPSR Register.
1053 : : \return xPSR Register value
1054 : : */
1055 : : __STATIC_FORCEINLINE uint32_t __get_xPSR(void)
1056 : : {
1057 : : uint32_t result;
1058 : :
1059 : : __ASM volatile ("MRS %0, xpsr" : "=r" (result) );
1060 : : return(result);
1061 : : }
1062 : :
1063 : :
1064 : : /**
1065 : : \brief Get Process Stack Pointer
1066 : : \details Returns the current value of the Process Stack Pointer (PSP).
1067 : : \return PSP Register value
1068 : : */
1069 : : __STATIC_FORCEINLINE uint32_t __get_PSP(void)
1070 : : {
1071 : : uint32_t result;
1072 : :
1073 : : __ASM volatile ("MRS %0, psp" : "=r" (result) );
1074 : : return(result);
1075 : : }
1076 : :
1077 : :
1078 : : #if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3))
1079 : : /**
1080 : : \brief Get Process Stack Pointer (non-secure)
1081 : : \details Returns the current value of the non-secure Process Stack Pointer (PSP) when in secure state.
1082 : : \return PSP Register value
1083 : : */
1084 : : __STATIC_FORCEINLINE uint32_t __TZ_get_PSP_NS(void)
1085 : : {
1086 : : uint32_t result;
1087 : :
1088 : : __ASM volatile ("MRS %0, psp_ns" : "=r" (result) );
1089 : : return(result);
1090 : : }
1091 : : #endif
1092 : :
1093 : :
1094 : : /**
1095 : : \brief Set Process Stack Pointer
1096 : : \details Assigns the given value to the Process Stack Pointer (PSP).
1097 : : \param [in] topOfProcStack Process Stack Pointer value to set
1098 : : */
1099 : : __STATIC_FORCEINLINE void __set_PSP(uint32_t topOfProcStack)
1100 : : {
1101 : : __ASM volatile ("MSR psp, %0" : : "r" (topOfProcStack) : );
1102 : : }
1103 : :
1104 : :
1105 : : #if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3))
1106 : : /**
1107 : : \brief Set Process Stack Pointer (non-secure)
1108 : : \details Assigns the given value to the non-secure Process Stack Pointer (PSP) when in secure state.
1109 : : \param [in] topOfProcStack Process Stack Pointer value to set
1110 : : */
1111 : : __STATIC_FORCEINLINE void __TZ_set_PSP_NS(uint32_t topOfProcStack)
1112 : : {
1113 : : __ASM volatile ("MSR psp_ns, %0" : : "r" (topOfProcStack) : );
1114 : : }
1115 : : #endif
1116 : :
1117 : :
1118 : : /**
1119 : : \brief Get Main Stack Pointer
1120 : : \details Returns the current value of the Main Stack Pointer (MSP).
1121 : : \return MSP Register value
1122 : : */
1123 : : __STATIC_FORCEINLINE uint32_t __get_MSP(void)
1124 : : {
1125 : : uint32_t result;
1126 : :
1127 : : __ASM volatile ("MRS %0, msp" : "=r" (result) );
1128 : : return(result);
1129 : : }
1130 : :
1131 : :
1132 : : #if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3))
1133 : : /**
1134 : : \brief Get Main Stack Pointer (non-secure)
1135 : : \details Returns the current value of the non-secure Main Stack Pointer (MSP) when in secure state.
1136 : : \return MSP Register value
1137 : : */
1138 : : __STATIC_FORCEINLINE uint32_t __TZ_get_MSP_NS(void)
1139 : : {
1140 : : uint32_t result;
1141 : :
1142 : : __ASM volatile ("MRS %0, msp_ns" : "=r" (result) );
1143 : : return(result);
1144 : : }
1145 : : #endif
1146 : :
1147 : :
1148 : : /**
1149 : : \brief Set Main Stack Pointer
1150 : : \details Assigns the given value to the Main Stack Pointer (MSP).
1151 : : \param [in] topOfMainStack Main Stack Pointer value to set
1152 : : */
1153 : : __STATIC_FORCEINLINE void __set_MSP(uint32_t topOfMainStack)
1154 : : {
1155 : 1 : __ASM volatile ("MSR msp, %0" : : "r" (topOfMainStack) : );
1156 : 1 : }
1157 : :
1158 : :
1159 : : #if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3))
1160 : : /**
1161 : : \brief Set Main Stack Pointer (non-secure)
1162 : : \details Assigns the given value to the non-secure Main Stack Pointer (MSP) when in secure state.
1163 : : \param [in] topOfMainStack Main Stack Pointer value to set
1164 : : */
1165 : : __STATIC_FORCEINLINE void __TZ_set_MSP_NS(uint32_t topOfMainStack)
1166 : : {
1167 : : __ASM volatile ("MSR msp_ns, %0" : : "r" (topOfMainStack) : );
1168 : : }
1169 : : #endif
1170 : :
1171 : :
1172 : : #if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3))
1173 : : /**
1174 : : \brief Get Stack Pointer (non-secure)
1175 : : \details Returns the current value of the non-secure Stack Pointer (SP) when in secure state.
1176 : : \return SP Register value
1177 : : */
1178 : : __STATIC_FORCEINLINE uint32_t __TZ_get_SP_NS(void)
1179 : : {
1180 : : uint32_t result;
1181 : :
1182 : : __ASM volatile ("MRS %0, sp_ns" : "=r" (result) );
1183 : : return(result);
1184 : : }
1185 : :
1186 : :
1187 : : /**
1188 : : \brief Set Stack Pointer (non-secure)
1189 : : \details Assigns the given value to the non-secure Stack Pointer (SP) when in secure state.
1190 : : \param [in] topOfStack Stack Pointer value to set
1191 : : */
1192 : : __STATIC_FORCEINLINE void __TZ_set_SP_NS(uint32_t topOfStack)
1193 : : {
1194 : : __ASM volatile ("MSR sp_ns, %0" : : "r" (topOfStack) : );
1195 : : }
1196 : : #endif
1197 : :
1198 : :
1199 : : /**
1200 : : \brief Get Priority Mask
1201 : : \details Returns the current state of the priority mask bit from the Priority Mask Register.
1202 : : \return Priority Mask value
1203 : : */
1204 : : __STATIC_FORCEINLINE uint32_t __get_PRIMASK(void)
1205 : : {
1206 : : uint32_t result;
1207 : :
1208 : : __ASM volatile ("MRS %0, primask" : "=r" (result) );
1209 : : return(result);
1210 : : }
1211 : :
1212 : :
1213 : : #if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3))
1214 : : /**
1215 : : \brief Get Priority Mask (non-secure)
1216 : : \details Returns the current state of the non-secure priority mask bit from the Priority Mask Register when in secure state.
1217 : : \return Priority Mask value
1218 : : */
1219 : : __STATIC_FORCEINLINE uint32_t __TZ_get_PRIMASK_NS(void)
1220 : : {
1221 : : uint32_t result;
1222 : :
1223 : : __ASM volatile ("MRS %0, primask_ns" : "=r" (result) );
1224 : : return(result);
1225 : : }
1226 : : #endif
1227 : :
1228 : :
1229 : : /**
1230 : : \brief Set Priority Mask
1231 : : \details Assigns the given value to the Priority Mask Register.
1232 : : \param [in] priMask Priority Mask
1233 : : */
1234 : : __STATIC_FORCEINLINE void __set_PRIMASK(uint32_t priMask)
1235 : : {
1236 : : __ASM volatile ("MSR primask, %0" : : "r" (priMask) : "memory");
1237 : : }
1238 : :
1239 : :
1240 : : #if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3))
1241 : : /**
1242 : : \brief Set Priority Mask (non-secure)
1243 : : \details Assigns the given value to the non-secure Priority Mask Register when in secure state.
1244 : : \param [in] priMask Priority Mask
1245 : : */
1246 : : __STATIC_FORCEINLINE void __TZ_set_PRIMASK_NS(uint32_t priMask)
1247 : : {
1248 : : __ASM volatile ("MSR primask_ns, %0" : : "r" (priMask) : "memory");
1249 : : }
1250 : : #endif
1251 : :
1252 : :
1253 : : #if ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \
1254 : : (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \
1255 : : (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) )
1256 : : /**
1257 : : \brief Enable FIQ
1258 : : \details Enables FIQ interrupts by clearing special-purpose register FAULTMASK.
1259 : : Can only be executed in Privileged modes.
1260 : : */
1261 : : __STATIC_FORCEINLINE void __enable_fault_irq(void)
1262 : : {
1263 : : __ASM volatile ("cpsie f" : : : "memory");
1264 : : }
1265 : :
1266 : :
1267 : : /**
1268 : : \brief Disable FIQ
1269 : : \details Disables FIQ interrupts by setting special-purpose register FAULTMASK.
1270 : : Can only be executed in Privileged modes.
1271 : : */
1272 : : __STATIC_FORCEINLINE void __disable_fault_irq(void)
1273 : : {
1274 : : __ASM volatile ("cpsid f" : : : "memory");
1275 : : }
1276 : :
1277 : :
1278 : : /**
1279 : : \brief Get Base Priority
1280 : : \details Returns the current value of the Base Priority register.
1281 : : \return Base Priority register value
1282 : : */
1283 : : __STATIC_FORCEINLINE uint32_t __get_BASEPRI(void)
1284 : : {
1285 : : uint32_t result;
1286 : :
1287 : : __ASM volatile ("MRS %0, basepri" : "=r" (result) );
1288 : : return(result);
1289 : : }
1290 : :
1291 : :
1292 : : #if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3))
1293 : : /**
1294 : : \brief Get Base Priority (non-secure)
1295 : : \details Returns the current value of the non-secure Base Priority register when in secure state.
1296 : : \return Base Priority register value
1297 : : */
1298 : : __STATIC_FORCEINLINE uint32_t __TZ_get_BASEPRI_NS(void)
1299 : : {
1300 : : uint32_t result;
1301 : :
1302 : : __ASM volatile ("MRS %0, basepri_ns" : "=r" (result) );
1303 : : return(result);
1304 : : }
1305 : : #endif
1306 : :
1307 : :
1308 : : /**
1309 : : \brief Set Base Priority
1310 : : \details Assigns the given value to the Base Priority register.
1311 : : \param [in] basePri Base Priority value to set
1312 : : */
1313 : : __STATIC_FORCEINLINE void __set_BASEPRI(uint32_t basePri)
1314 : : {
1315 : : __ASM volatile ("MSR basepri, %0" : : "r" (basePri) : "memory");
1316 : : }
1317 : :
1318 : :
1319 : : #if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3))
1320 : : /**
1321 : : \brief Set Base Priority (non-secure)
1322 : : \details Assigns the given value to the non-secure Base Priority register when in secure state.
1323 : : \param [in] basePri Base Priority value to set
1324 : : */
1325 : : __STATIC_FORCEINLINE void __TZ_set_BASEPRI_NS(uint32_t basePri)
1326 : : {
1327 : : __ASM volatile ("MSR basepri_ns, %0" : : "r" (basePri) : "memory");
1328 : : }
1329 : : #endif
1330 : :
1331 : :
1332 : : /**
1333 : : \brief Set Base Priority with condition
1334 : : \details Assigns the given value to the Base Priority register only if BASEPRI masking is disabled,
1335 : : or the new value increases the BASEPRI priority level.
1336 : : \param [in] basePri Base Priority value to set
1337 : : */
1338 : : __STATIC_FORCEINLINE void __set_BASEPRI_MAX(uint32_t basePri)
1339 : : {
1340 : : __ASM volatile ("MSR basepri_max, %0" : : "r" (basePri) : "memory");
1341 : : }
1342 : :
1343 : :
1344 : : /**
1345 : : \brief Get Fault Mask
1346 : : \details Returns the current value of the Fault Mask register.
1347 : : \return Fault Mask register value
1348 : : */
1349 : : __STATIC_FORCEINLINE uint32_t __get_FAULTMASK(void)
1350 : : {
1351 : : uint32_t result;
1352 : :
1353 : : __ASM volatile ("MRS %0, faultmask" : "=r" (result) );
1354 : : return(result);
1355 : : }
1356 : :
1357 : :
1358 : : #if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3))
1359 : : /**
1360 : : \brief Get Fault Mask (non-secure)
1361 : : \details Returns the current value of the non-secure Fault Mask register when in secure state.
1362 : : \return Fault Mask register value
1363 : : */
1364 : : __STATIC_FORCEINLINE uint32_t __TZ_get_FAULTMASK_NS(void)
1365 : : {
1366 : : uint32_t result;
1367 : :
1368 : : __ASM volatile ("MRS %0, faultmask_ns" : "=r" (result) );
1369 : : return(result);
1370 : : }
1371 : : #endif
1372 : :
1373 : :
1374 : : /**
1375 : : \brief Set Fault Mask
1376 : : \details Assigns the given value to the Fault Mask register.
1377 : : \param [in] faultMask Fault Mask value to set
1378 : : */
1379 : : __STATIC_FORCEINLINE void __set_FAULTMASK(uint32_t faultMask)
1380 : : {
1381 : 0 : __ASM volatile ("MSR faultmask, %0" : : "r" (faultMask) : "memory");
1382 : 0 : }
1383 : :
1384 : :
1385 : : #if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3))
1386 : : /**
1387 : : \brief Set Fault Mask (non-secure)
1388 : : \details Assigns the given value to the non-secure Fault Mask register when in secure state.
1389 : : \param [in] faultMask Fault Mask value to set
1390 : : */
1391 : : __STATIC_FORCEINLINE void __TZ_set_FAULTMASK_NS(uint32_t faultMask)
1392 : : {
1393 : : __ASM volatile ("MSR faultmask_ns, %0" : : "r" (faultMask) : "memory");
1394 : : }
1395 : : #endif
1396 : :
1397 : : #endif /* ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \
1398 : : (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \
1399 : : (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) ) */
1400 : :
1401 : :
1402 : : #if ((defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \
1403 : : (defined (__ARM_ARCH_8M_BASE__ ) && (__ARM_ARCH_8M_BASE__ == 1)) )
1404 : :
1405 : : /**
1406 : : \brief Get Process Stack Pointer Limit
1407 : : Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure
1408 : : Stack Pointer Limit register hence zero is returned always in non-secure
1409 : : mode.
1410 : :
1411 : : \details Returns the current value of the Process Stack Pointer Limit (PSPLIM).
1412 : : \return PSPLIM Register value
1413 : : */
1414 : : __STATIC_FORCEINLINE uint32_t __get_PSPLIM(void)
1415 : : {
1416 : : #if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \
1417 : : (!defined (__ARM_FEATURE_CMSE) || (__ARM_FEATURE_CMSE < 3)))
1418 : : // without main extensions, the non-secure PSPLIM is RAZ/WI
1419 : : return 0U;
1420 : : #else
1421 : : uint32_t result;
1422 : : __ASM volatile ("MRS %0, psplim" : "=r" (result) );
1423 : : return result;
1424 : : #endif
1425 : : }
1426 : :
1427 : : #if (defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3))
1428 : : /**
1429 : : \brief Get Process Stack Pointer Limit (non-secure)
1430 : : Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure
1431 : : Stack Pointer Limit register hence zero is returned always.
1432 : :
1433 : : \details Returns the current value of the non-secure Process Stack Pointer Limit (PSPLIM) when in secure state.
1434 : : \return PSPLIM Register value
1435 : : */
1436 : : __STATIC_FORCEINLINE uint32_t __TZ_get_PSPLIM_NS(void)
1437 : : {
1438 : : #if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)))
1439 : : // without main extensions, the non-secure PSPLIM is RAZ/WI
1440 : : return 0U;
1441 : : #else
1442 : : uint32_t result;
1443 : : __ASM volatile ("MRS %0, psplim_ns" : "=r" (result) );
1444 : : return result;
1445 : : #endif
1446 : : }
1447 : : #endif
1448 : :
1449 : :
1450 : : /**
1451 : : \brief Set Process Stack Pointer Limit
1452 : : Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure
1453 : : Stack Pointer Limit register hence the write is silently ignored in non-secure
1454 : : mode.
1455 : :
1456 : : \details Assigns the given value to the Process Stack Pointer Limit (PSPLIM).
1457 : : \param [in] ProcStackPtrLimit Process Stack Pointer Limit value to set
1458 : : */
1459 : : __STATIC_FORCEINLINE void __set_PSPLIM(uint32_t ProcStackPtrLimit)
1460 : : {
1461 : : #if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \
1462 : : (!defined (__ARM_FEATURE_CMSE) || (__ARM_FEATURE_CMSE < 3)))
1463 : : // without main extensions, the non-secure PSPLIM is RAZ/WI
1464 : : (void)ProcStackPtrLimit;
1465 : : #else
1466 : 4 : __ASM volatile ("MSR psplim, %0" : : "r" (ProcStackPtrLimit));
1467 : : #endif
1468 : 4 : }
1469 : :
1470 : :
1471 : : #if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3))
1472 : : /**
1473 : : \brief Set Process Stack Pointer (non-secure)
1474 : : Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure
1475 : : Stack Pointer Limit register hence the write is silently ignored.
1476 : :
1477 : : \details Assigns the given value to the non-secure Process Stack Pointer Limit (PSPLIM) when in secure state.
1478 : : \param [in] ProcStackPtrLimit Process Stack Pointer Limit value to set
1479 : : */
1480 : : __STATIC_FORCEINLINE void __TZ_set_PSPLIM_NS(uint32_t ProcStackPtrLimit)
1481 : : {
1482 : : #if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)))
1483 : : // without main extensions, the non-secure PSPLIM is RAZ/WI
1484 : : (void)ProcStackPtrLimit;
1485 : : #else
1486 : : __ASM volatile ("MSR psplim_ns, %0\n" : : "r" (ProcStackPtrLimit));
1487 : : #endif
1488 : : }
1489 : : #endif
1490 : :
1491 : :
1492 : : /**
1493 : : \brief Get Main Stack Pointer Limit
1494 : : Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure
1495 : : Stack Pointer Limit register hence zero is returned always in non-secure
1496 : : mode.
1497 : :
1498 : : \details Returns the current value of the Main Stack Pointer Limit (MSPLIM).
1499 : : \return MSPLIM Register value
1500 : : */
1501 : : __STATIC_FORCEINLINE uint32_t __get_MSPLIM(void)
1502 : : {
1503 : : #if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \
1504 : : (!defined (__ARM_FEATURE_CMSE) || (__ARM_FEATURE_CMSE < 3)))
1505 : : // without main extensions, the non-secure MSPLIM is RAZ/WI
1506 : : return 0U;
1507 : : #else
1508 : : uint32_t result;
1509 : : __ASM volatile ("MRS %0, msplim" : "=r" (result) );
1510 : : return result;
1511 : : #endif
1512 : : }
1513 : :
1514 : :
1515 : : #if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3))
1516 : : /**
1517 : : \brief Get Main Stack Pointer Limit (non-secure)
1518 : : Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure
1519 : : Stack Pointer Limit register hence zero is returned always.
1520 : :
1521 : : \details Returns the current value of the non-secure Main Stack Pointer Limit(MSPLIM) when in secure state.
1522 : : \return MSPLIM Register value
1523 : : */
1524 : : __STATIC_FORCEINLINE uint32_t __TZ_get_MSPLIM_NS(void)
1525 : : {
1526 : : #if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)))
1527 : : // without main extensions, the non-secure MSPLIM is RAZ/WI
1528 : : return 0U;
1529 : : #else
1530 : : uint32_t result;
1531 : : __ASM volatile ("MRS %0, msplim_ns" : "=r" (result) );
1532 : : return result;
1533 : : #endif
1534 : : }
1535 : : #endif
1536 : :
1537 : :
1538 : : /**
1539 : : \brief Set Main Stack Pointer Limit
1540 : : Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure
1541 : : Stack Pointer Limit register hence the write is silently ignored in non-secure
1542 : : mode.
1543 : :
1544 : : \details Assigns the given value to the Main Stack Pointer Limit (MSPLIM).
1545 : : \param [in] MainStackPtrLimit Main Stack Pointer Limit value to set
1546 : : */
1547 : : __STATIC_FORCEINLINE void __set_MSPLIM(uint32_t MainStackPtrLimit)
1548 : : {
1549 : : #if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \
1550 : : (!defined (__ARM_FEATURE_CMSE) || (__ARM_FEATURE_CMSE < 3)))
1551 : : // without main extensions, the non-secure MSPLIM is RAZ/WI
1552 : : (void)MainStackPtrLimit;
1553 : : #else
1554 : 1 : __ASM volatile ("MSR msplim, %0" : : "r" (MainStackPtrLimit));
1555 : : #endif
1556 : 1 : }
1557 : :
1558 : :
1559 : : #if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3))
1560 : : /**
1561 : : \brief Set Main Stack Pointer Limit (non-secure)
1562 : : Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure
1563 : : Stack Pointer Limit register hence the write is silently ignored.
1564 : :
1565 : : \details Assigns the given value to the non-secure Main Stack Pointer Limit (MSPLIM) when in secure state.
1566 : : \param [in] MainStackPtrLimit Main Stack Pointer value to set
1567 : : */
1568 : : __STATIC_FORCEINLINE void __TZ_set_MSPLIM_NS(uint32_t MainStackPtrLimit)
1569 : : {
1570 : : #if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)))
1571 : : // without main extensions, the non-secure MSPLIM is RAZ/WI
1572 : : (void)MainStackPtrLimit;
1573 : : #else
1574 : : __ASM volatile ("MSR msplim_ns, %0" : : "r" (MainStackPtrLimit));
1575 : : #endif
1576 : : }
1577 : : #endif
1578 : :
1579 : : #endif /* ((defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \
1580 : : (defined (__ARM_ARCH_8M_BASE__ ) && (__ARM_ARCH_8M_BASE__ == 1)) ) */
1581 : :
1582 : :
1583 : : /**
1584 : : \brief Get FPSCR
1585 : : \details Returns the current value of the Floating Point Status/Control register.
1586 : : \return Floating Point Status/Control register value
1587 : : */
1588 : : __STATIC_FORCEINLINE uint32_t __get_FPSCR(void)
1589 : : {
1590 : : #if ((defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U)) && \
1591 : : (defined (__FPU_USED ) && (__FPU_USED == 1U)) )
1592 : : #if __has_builtin(__builtin_arm_get_fpscr)
1593 : : // Re-enable using built-in when GCC has been fixed
1594 : : // || (__GNUC__ > 7) || (__GNUC__ == 7 && __GNUC_MINOR__ >= 2)
1595 : : /* see https://gcc.gnu.org/ml/gcc-patches/2017-04/msg00443.html */
1596 : : return __builtin_arm_get_fpscr();
1597 : : #else
1598 : : uint32_t result;
1599 : :
1600 : : __ASM volatile ("VMRS %0, fpscr" : "=r" (result) );
1601 : : return(result);
1602 : : #endif
1603 : : #else
1604 : : return(0U);
1605 : : #endif
1606 : : }
1607 : :
1608 : :
1609 : : /**
1610 : : \brief Set FPSCR
1611 : : \details Assigns the given value to the Floating Point Status/Control register.
1612 : : \param [in] fpscr Floating Point Status/Control value to set
1613 : : */
1614 : : __STATIC_FORCEINLINE void __set_FPSCR(uint32_t fpscr)
1615 : : {
1616 : : #if ((defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U)) && \
1617 : : (defined (__FPU_USED ) && (__FPU_USED == 1U)) )
1618 : : #if __has_builtin(__builtin_arm_set_fpscr)
1619 : : // Re-enable using built-in when GCC has been fixed
1620 : : // || (__GNUC__ > 7) || (__GNUC__ == 7 && __GNUC_MINOR__ >= 2)
1621 : : /* see https://gcc.gnu.org/ml/gcc-patches/2017-04/msg00443.html */
1622 : : __builtin_arm_set_fpscr(fpscr);
1623 : : #else
1624 : : __ASM volatile ("VMSR fpscr, %0" : : "r" (fpscr) : "vfpcc", "memory");
1625 : : #endif
1626 : : #else
1627 : : (void)fpscr;
1628 : : #endif
1629 : : }
1630 : :
1631 : :
1632 : : /*@} end of CMSIS_Core_RegAccFunctions */
1633 : :
1634 : :
1635 : : /* ################### Compiler specific Intrinsics ########################### */
1636 : : /** \defgroup CMSIS_SIMD_intrinsics CMSIS SIMD Intrinsics
1637 : : Access to dedicated SIMD instructions
1638 : : @{
1639 : : */
1640 : :
1641 : : #if (defined (__ARM_FEATURE_DSP) && (__ARM_FEATURE_DSP == 1))
1642 : :
1643 : : __STATIC_FORCEINLINE uint32_t __SADD8(uint32_t op1, uint32_t op2)
1644 : : {
1645 : : uint32_t result;
1646 : :
1647 : : __ASM volatile ("sadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
1648 : : return(result);
1649 : : }
1650 : :
1651 : : __STATIC_FORCEINLINE uint32_t __QADD8(uint32_t op1, uint32_t op2)
1652 : : {
1653 : : uint32_t result;
1654 : :
1655 : : __ASM ("qadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
1656 : : return(result);
1657 : : }
1658 : :
1659 : : __STATIC_FORCEINLINE uint32_t __SHADD8(uint32_t op1, uint32_t op2)
1660 : : {
1661 : : uint32_t result;
1662 : :
1663 : : __ASM ("shadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
1664 : : return(result);
1665 : : }
1666 : :
1667 : : __STATIC_FORCEINLINE uint32_t __UADD8(uint32_t op1, uint32_t op2)
1668 : : {
1669 : : uint32_t result;
1670 : :
1671 : : __ASM volatile ("uadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
1672 : : return(result);
1673 : : }
1674 : :
1675 : : __STATIC_FORCEINLINE uint32_t __UQADD8(uint32_t op1, uint32_t op2)
1676 : : {
1677 : : uint32_t result;
1678 : :
1679 : : __ASM ("uqadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
1680 : : return(result);
1681 : : }
1682 : :
1683 : : __STATIC_FORCEINLINE uint32_t __UHADD8(uint32_t op1, uint32_t op2)
1684 : : {
1685 : : uint32_t result;
1686 : :
1687 : : __ASM ("uhadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
1688 : : return(result);
1689 : : }
1690 : :
1691 : :
1692 : : __STATIC_FORCEINLINE uint32_t __SSUB8(uint32_t op1, uint32_t op2)
1693 : : {
1694 : : uint32_t result;
1695 : :
1696 : : __ASM volatile ("ssub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
1697 : : return(result);
1698 : : }
1699 : :
1700 : : __STATIC_FORCEINLINE uint32_t __QSUB8(uint32_t op1, uint32_t op2)
1701 : : {
1702 : : uint32_t result;
1703 : :
1704 : : __ASM ("qsub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
1705 : : return(result);
1706 : : }
1707 : :
1708 : : __STATIC_FORCEINLINE uint32_t __SHSUB8(uint32_t op1, uint32_t op2)
1709 : : {
1710 : : uint32_t result;
1711 : :
1712 : : __ASM ("shsub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
1713 : : return(result);
1714 : : }
1715 : :
1716 : : __STATIC_FORCEINLINE uint32_t __USUB8(uint32_t op1, uint32_t op2)
1717 : : {
1718 : : uint32_t result;
1719 : :
1720 : : __ASM volatile ("usub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
1721 : : return(result);
1722 : : }
1723 : :
1724 : : __STATIC_FORCEINLINE uint32_t __UQSUB8(uint32_t op1, uint32_t op2)
1725 : : {
1726 : : uint32_t result;
1727 : :
1728 : : __ASM ("uqsub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
1729 : : return(result);
1730 : : }
1731 : :
1732 : : __STATIC_FORCEINLINE uint32_t __UHSUB8(uint32_t op1, uint32_t op2)
1733 : : {
1734 : : uint32_t result;
1735 : :
1736 : : __ASM ("uhsub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
1737 : : return(result);
1738 : : }
1739 : :
1740 : :
1741 : : __STATIC_FORCEINLINE uint32_t __SADD16(uint32_t op1, uint32_t op2)
1742 : : {
1743 : : uint32_t result;
1744 : :
1745 : : __ASM volatile ("sadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
1746 : : return(result);
1747 : : }
1748 : :
1749 : : __STATIC_FORCEINLINE uint32_t __QADD16(uint32_t op1, uint32_t op2)
1750 : : {
1751 : : uint32_t result;
1752 : :
1753 : : __ASM ("qadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
1754 : : return(result);
1755 : : }
1756 : :
1757 : : __STATIC_FORCEINLINE uint32_t __SHADD16(uint32_t op1, uint32_t op2)
1758 : : {
1759 : : uint32_t result;
1760 : :
1761 : : __ASM ("shadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
1762 : : return(result);
1763 : : }
1764 : :
1765 : : __STATIC_FORCEINLINE uint32_t __UADD16(uint32_t op1, uint32_t op2)
1766 : : {
1767 : : uint32_t result;
1768 : :
1769 : : __ASM volatile ("uadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
1770 : : return(result);
1771 : : }
1772 : :
1773 : : __STATIC_FORCEINLINE uint32_t __UQADD16(uint32_t op1, uint32_t op2)
1774 : : {
1775 : : uint32_t result;
1776 : :
1777 : : __ASM ("uqadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
1778 : : return(result);
1779 : : }
1780 : :
1781 : : __STATIC_FORCEINLINE uint32_t __UHADD16(uint32_t op1, uint32_t op2)
1782 : : {
1783 : : uint32_t result;
1784 : :
1785 : : __ASM ("uhadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
1786 : : return(result);
1787 : : }
1788 : :
1789 : : __STATIC_FORCEINLINE uint32_t __SSUB16(uint32_t op1, uint32_t op2)
1790 : : {
1791 : : uint32_t result;
1792 : :
1793 : : __ASM volatile ("ssub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
1794 : : return(result);
1795 : : }
1796 : :
1797 : : __STATIC_FORCEINLINE uint32_t __QSUB16(uint32_t op1, uint32_t op2)
1798 : : {
1799 : : uint32_t result;
1800 : :
1801 : : __ASM ("qsub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
1802 : : return(result);
1803 : : }
1804 : :
1805 : : __STATIC_FORCEINLINE uint32_t __SHSUB16(uint32_t op1, uint32_t op2)
1806 : : {
1807 : : uint32_t result;
1808 : :
1809 : : __ASM ("shsub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
1810 : : return(result);
1811 : : }
1812 : :
1813 : : __STATIC_FORCEINLINE uint32_t __USUB16(uint32_t op1, uint32_t op2)
1814 : : {
1815 : : uint32_t result;
1816 : :
1817 : : __ASM volatile ("usub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
1818 : : return(result);
1819 : : }
1820 : :
1821 : : __STATIC_FORCEINLINE uint32_t __UQSUB16(uint32_t op1, uint32_t op2)
1822 : : {
1823 : : uint32_t result;
1824 : :
1825 : : __ASM ("uqsub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
1826 : : return(result);
1827 : : }
1828 : :
1829 : : __STATIC_FORCEINLINE uint32_t __UHSUB16(uint32_t op1, uint32_t op2)
1830 : : {
1831 : : uint32_t result;
1832 : :
1833 : : __ASM ("uhsub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
1834 : : return(result);
1835 : : }
1836 : :
1837 : : __STATIC_FORCEINLINE uint32_t __SASX(uint32_t op1, uint32_t op2)
1838 : : {
1839 : : uint32_t result;
1840 : :
1841 : : __ASM volatile ("sasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
1842 : : return(result);
1843 : : }
1844 : :
1845 : : __STATIC_FORCEINLINE uint32_t __QASX(uint32_t op1, uint32_t op2)
1846 : : {
1847 : : uint32_t result;
1848 : :
1849 : : __ASM ("qasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
1850 : : return(result);
1851 : : }
1852 : :
1853 : : __STATIC_FORCEINLINE uint32_t __SHASX(uint32_t op1, uint32_t op2)
1854 : : {
1855 : : uint32_t result;
1856 : :
1857 : : __ASM ("shasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
1858 : : return(result);
1859 : : }
1860 : :
1861 : : __STATIC_FORCEINLINE uint32_t __UASX(uint32_t op1, uint32_t op2)
1862 : : {
1863 : : uint32_t result;
1864 : :
1865 : : __ASM volatile ("uasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
1866 : : return(result);
1867 : : }
1868 : :
1869 : : __STATIC_FORCEINLINE uint32_t __UQASX(uint32_t op1, uint32_t op2)
1870 : : {
1871 : : uint32_t result;
1872 : :
1873 : : __ASM ("uqasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
1874 : : return(result);
1875 : : }
1876 : :
1877 : : __STATIC_FORCEINLINE uint32_t __UHASX(uint32_t op1, uint32_t op2)
1878 : : {
1879 : : uint32_t result;
1880 : :
1881 : : __ASM ("uhasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
1882 : : return(result);
1883 : : }
1884 : :
1885 : : __STATIC_FORCEINLINE uint32_t __SSAX(uint32_t op1, uint32_t op2)
1886 : : {
1887 : : uint32_t result;
1888 : :
1889 : : __ASM volatile ("ssax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
1890 : : return(result);
1891 : : }
1892 : :
1893 : : __STATIC_FORCEINLINE uint32_t __QSAX(uint32_t op1, uint32_t op2)
1894 : : {
1895 : : uint32_t result;
1896 : :
1897 : : __ASM ("qsax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
1898 : : return(result);
1899 : : }
1900 : :
1901 : : __STATIC_FORCEINLINE uint32_t __SHSAX(uint32_t op1, uint32_t op2)
1902 : : {
1903 : : uint32_t result;
1904 : :
1905 : : __ASM ("shsax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
1906 : : return(result);
1907 : : }
1908 : :
1909 : : __STATIC_FORCEINLINE uint32_t __USAX(uint32_t op1, uint32_t op2)
1910 : : {
1911 : : uint32_t result;
1912 : :
1913 : : __ASM volatile ("usax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
1914 : : return(result);
1915 : : }
1916 : :
1917 : : __STATIC_FORCEINLINE uint32_t __UQSAX(uint32_t op1, uint32_t op2)
1918 : : {
1919 : : uint32_t result;
1920 : :
1921 : : __ASM ("uqsax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
1922 : : return(result);
1923 : : }
1924 : :
1925 : : __STATIC_FORCEINLINE uint32_t __UHSAX(uint32_t op1, uint32_t op2)
1926 : : {
1927 : : uint32_t result;
1928 : :
1929 : : __ASM ("uhsax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
1930 : : return(result);
1931 : : }
1932 : :
1933 : : __STATIC_FORCEINLINE uint32_t __USAD8(uint32_t op1, uint32_t op2)
1934 : : {
1935 : : uint32_t result;
1936 : :
1937 : : __ASM ("usad8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
1938 : : return(result);
1939 : : }
1940 : :
1941 : : __STATIC_FORCEINLINE uint32_t __USADA8(uint32_t op1, uint32_t op2, uint32_t op3)
1942 : : {
1943 : : uint32_t result;
1944 : :
1945 : : __ASM ("usada8 %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) );
1946 : : return(result);
1947 : : }
1948 : :
1949 : : #define __SSAT16(ARG1, ARG2) \
1950 : : __extension__ \
1951 : : ({ \
1952 : : int32_t __RES, __ARG1 = (ARG1); \
1953 : : __ASM volatile ("ssat16 %0, %1, %2" : "=r" (__RES) : "I" (ARG2), "r" (__ARG1) : "cc" ); \
1954 : : __RES; \
1955 : : })
1956 : :
1957 : : #define __USAT16(ARG1, ARG2) \
1958 : : __extension__ \
1959 : : ({ \
1960 : : uint32_t __RES, __ARG1 = (ARG1); \
1961 : : __ASM volatile ("usat16 %0, %1, %2" : "=r" (__RES) : "I" (ARG2), "r" (__ARG1) : "cc" ); \
1962 : : __RES; \
1963 : : })
1964 : :
1965 : : __STATIC_FORCEINLINE uint32_t __UXTB16(uint32_t op1)
1966 : : {
1967 : : uint32_t result;
1968 : :
1969 : : __ASM ("uxtb16 %0, %1" : "=r" (result) : "r" (op1));
1970 : : return(result);
1971 : : }
1972 : :
1973 : : __STATIC_FORCEINLINE uint32_t __UXTAB16(uint32_t op1, uint32_t op2)
1974 : : {
1975 : : uint32_t result;
1976 : :
1977 : : __ASM ("uxtab16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
1978 : : return(result);
1979 : : }
1980 : :
1981 : : __STATIC_FORCEINLINE uint32_t __SXTB16(uint32_t op1)
1982 : : {
1983 : : uint32_t result;
1984 : :
1985 : : __ASM ("sxtb16 %0, %1" : "=r" (result) : "r" (op1));
1986 : : return(result);
1987 : : }
1988 : :
1989 : : __STATIC_FORCEINLINE uint32_t __SXTB16_RORn(uint32_t op1, uint32_t rotate)
1990 : : {
1991 : : uint32_t result;
1992 : : if (__builtin_constant_p(rotate) && ((rotate == 8U) || (rotate == 16U) || (rotate == 24U))) {
1993 : : __ASM volatile ("sxtb16 %0, %1, ROR %2" : "=r" (result) : "r" (op1), "i" (rotate) );
1994 : : } else {
1995 : : result = __SXTB16(__ROR(op1, rotate)) ;
1996 : : }
1997 : : return result;
1998 : : }
1999 : :
2000 : : __STATIC_FORCEINLINE uint32_t __SXTAB16(uint32_t op1, uint32_t op2)
2001 : : {
2002 : : uint32_t result;
2003 : :
2004 : : __ASM ("sxtab16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
2005 : : return(result);
2006 : : }
2007 : :
2008 : : __STATIC_FORCEINLINE uint32_t __SXTAB16_RORn(uint32_t op1, uint32_t op2, uint32_t rotate)
2009 : : {
2010 : : uint32_t result;
2011 : : if (__builtin_constant_p(rotate) && ((rotate == 8U) || (rotate == 16U) || (rotate == 24U))) {
2012 : : __ASM volatile ("sxtab16 %0, %1, %2, ROR %3" : "=r" (result) : "r" (op1) , "r" (op2) , "i" (rotate));
2013 : : } else {
2014 : : result = __SXTAB16(op1, __ROR(op2, rotate));
2015 : : }
2016 : : return result;
2017 : : }
2018 : :
2019 : :
2020 : : __STATIC_FORCEINLINE uint32_t __SMUAD (uint32_t op1, uint32_t op2)
2021 : : {
2022 : : uint32_t result;
2023 : :
2024 : : __ASM volatile ("smuad %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
2025 : : return(result);
2026 : : }
2027 : :
2028 : : __STATIC_FORCEINLINE uint32_t __SMUADX (uint32_t op1, uint32_t op2)
2029 : : {
2030 : : uint32_t result;
2031 : :
2032 : : __ASM volatile ("smuadx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
2033 : : return(result);
2034 : : }
2035 : :
2036 : : __STATIC_FORCEINLINE uint32_t __SMLAD (uint32_t op1, uint32_t op2, uint32_t op3)
2037 : : {
2038 : : uint32_t result;
2039 : :
2040 : : __ASM volatile ("smlad %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) );
2041 : : return(result);
2042 : : }
2043 : :
2044 : : __STATIC_FORCEINLINE uint32_t __SMLADX (uint32_t op1, uint32_t op2, uint32_t op3)
2045 : : {
2046 : : uint32_t result;
2047 : :
2048 : : __ASM volatile ("smladx %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) );
2049 : : return(result);
2050 : : }
2051 : :
2052 : : __STATIC_FORCEINLINE uint64_t __SMLALD (uint32_t op1, uint32_t op2, uint64_t acc)
2053 : : {
2054 : : union llreg_u{
2055 : : uint32_t w32[2];
2056 : : uint64_t w64;
2057 : : } llr;
2058 : : llr.w64 = acc;
2059 : :
2060 : : #ifndef __ARMEB__ /* Little endian */
2061 : : __ASM volatile ("smlald %0, %1, %2, %3" : "=r" (llr.w32[0]), "=r" (llr.w32[1]): "r" (op1), "r" (op2) , "0" (llr.w32[0]), "1" (llr.w32[1]) );
2062 : : #else /* Big endian */
2063 : : __ASM volatile ("smlald %0, %1, %2, %3" : "=r" (llr.w32[1]), "=r" (llr.w32[0]): "r" (op1), "r" (op2) , "0" (llr.w32[1]), "1" (llr.w32[0]) );
2064 : : #endif
2065 : :
2066 : : return(llr.w64);
2067 : : }
2068 : :
2069 : : __STATIC_FORCEINLINE uint64_t __SMLALDX (uint32_t op1, uint32_t op2, uint64_t acc)
2070 : : {
2071 : : union llreg_u{
2072 : : uint32_t w32[2];
2073 : : uint64_t w64;
2074 : : } llr;
2075 : : llr.w64 = acc;
2076 : :
2077 : : #ifndef __ARMEB__ /* Little endian */
2078 : : __ASM volatile ("smlaldx %0, %1, %2, %3" : "=r" (llr.w32[0]), "=r" (llr.w32[1]): "r" (op1), "r" (op2) , "0" (llr.w32[0]), "1" (llr.w32[1]) );
2079 : : #else /* Big endian */
2080 : : __ASM volatile ("smlaldx %0, %1, %2, %3" : "=r" (llr.w32[1]), "=r" (llr.w32[0]): "r" (op1), "r" (op2) , "0" (llr.w32[1]), "1" (llr.w32[0]) );
2081 : : #endif
2082 : :
2083 : : return(llr.w64);
2084 : : }
2085 : :
2086 : : __STATIC_FORCEINLINE uint32_t __SMUSD (uint32_t op1, uint32_t op2)
2087 : : {
2088 : : uint32_t result;
2089 : :
2090 : : __ASM volatile ("smusd %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
2091 : : return(result);
2092 : : }
2093 : :
2094 : : __STATIC_FORCEINLINE uint32_t __SMUSDX (uint32_t op1, uint32_t op2)
2095 : : {
2096 : : uint32_t result;
2097 : :
2098 : : __ASM volatile ("smusdx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
2099 : : return(result);
2100 : : }
2101 : :
2102 : : __STATIC_FORCEINLINE uint32_t __SMLSD (uint32_t op1, uint32_t op2, uint32_t op3)
2103 : : {
2104 : : uint32_t result;
2105 : :
2106 : : __ASM volatile ("smlsd %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) );
2107 : : return(result);
2108 : : }
2109 : :
2110 : : __STATIC_FORCEINLINE uint32_t __SMLSDX (uint32_t op1, uint32_t op2, uint32_t op3)
2111 : : {
2112 : : uint32_t result;
2113 : :
2114 : : __ASM volatile ("smlsdx %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) );
2115 : : return(result);
2116 : : }
2117 : :
2118 : : __STATIC_FORCEINLINE uint64_t __SMLSLD (uint32_t op1, uint32_t op2, uint64_t acc)
2119 : : {
2120 : : union llreg_u{
2121 : : uint32_t w32[2];
2122 : : uint64_t w64;
2123 : : } llr;
2124 : : llr.w64 = acc;
2125 : :
2126 : : #ifndef __ARMEB__ /* Little endian */
2127 : : __ASM volatile ("smlsld %0, %1, %2, %3" : "=r" (llr.w32[0]), "=r" (llr.w32[1]): "r" (op1), "r" (op2) , "0" (llr.w32[0]), "1" (llr.w32[1]) );
2128 : : #else /* Big endian */
2129 : : __ASM volatile ("smlsld %0, %1, %2, %3" : "=r" (llr.w32[1]), "=r" (llr.w32[0]): "r" (op1), "r" (op2) , "0" (llr.w32[1]), "1" (llr.w32[0]) );
2130 : : #endif
2131 : :
2132 : : return(llr.w64);
2133 : : }
2134 : :
2135 : : __STATIC_FORCEINLINE uint64_t __SMLSLDX (uint32_t op1, uint32_t op2, uint64_t acc)
2136 : : {
2137 : : union llreg_u{
2138 : : uint32_t w32[2];
2139 : : uint64_t w64;
2140 : : } llr;
2141 : : llr.w64 = acc;
2142 : :
2143 : : #ifndef __ARMEB__ /* Little endian */
2144 : : __ASM volatile ("smlsldx %0, %1, %2, %3" : "=r" (llr.w32[0]), "=r" (llr.w32[1]): "r" (op1), "r" (op2) , "0" (llr.w32[0]), "1" (llr.w32[1]) );
2145 : : #else /* Big endian */
2146 : : __ASM volatile ("smlsldx %0, %1, %2, %3" : "=r" (llr.w32[1]), "=r" (llr.w32[0]): "r" (op1), "r" (op2) , "0" (llr.w32[1]), "1" (llr.w32[0]) );
2147 : : #endif
2148 : :
2149 : : return(llr.w64);
2150 : : }
2151 : :
2152 : : __STATIC_FORCEINLINE uint32_t __SEL (uint32_t op1, uint32_t op2)
2153 : : {
2154 : : uint32_t result;
2155 : :
2156 : : __ASM volatile ("sel %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
2157 : : return(result);
2158 : : }
2159 : :
2160 : : __STATIC_FORCEINLINE int32_t __QADD( int32_t op1, int32_t op2)
2161 : : {
2162 : : int32_t result;
2163 : :
2164 : : __ASM volatile ("qadd %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
2165 : : return(result);
2166 : : }
2167 : :
2168 : : __STATIC_FORCEINLINE int32_t __QSUB( int32_t op1, int32_t op2)
2169 : : {
2170 : : int32_t result;
2171 : :
2172 : : __ASM volatile ("qsub %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
2173 : : return(result);
2174 : : }
2175 : :
2176 : :
2177 : : #define __PKHBT(ARG1,ARG2,ARG3) \
2178 : : __extension__ \
2179 : : ({ \
2180 : : uint32_t __RES, __ARG1 = (ARG1), __ARG2 = (ARG2); \
2181 : : __ASM ("pkhbt %0, %1, %2, lsl %3" : "=r" (__RES) : "r" (__ARG1), "r" (__ARG2), "I" (ARG3) ); \
2182 : : __RES; \
2183 : : })
2184 : :
2185 : : #define __PKHTB(ARG1,ARG2,ARG3) \
2186 : : __extension__ \
2187 : : ({ \
2188 : : uint32_t __RES, __ARG1 = (ARG1), __ARG2 = (ARG2); \
2189 : : if (ARG3 == 0) \
2190 : : __ASM ("pkhtb %0, %1, %2" : "=r" (__RES) : "r" (__ARG1), "r" (__ARG2) ); \
2191 : : else \
2192 : : __ASM ("pkhtb %0, %1, %2, asr %3" : "=r" (__RES) : "r" (__ARG1), "r" (__ARG2), "I" (ARG3) ); \
2193 : : __RES; \
2194 : : })
2195 : :
2196 : :
2197 : : __STATIC_FORCEINLINE int32_t __SMMLA (int32_t op1, int32_t op2, int32_t op3)
2198 : : {
2199 : : int32_t result;
2200 : :
2201 : : __ASM ("smmla %0, %1, %2, %3" : "=r" (result): "r" (op1), "r" (op2), "r" (op3) );
2202 : : return(result);
2203 : : }
2204 : :
2205 : : #endif /* (__ARM_FEATURE_DSP == 1) */
2206 : : /*@} end of group CMSIS_SIMD_intrinsics */
2207 : :
2208 : :
2209 : : #pragma GCC diagnostic pop
2210 : :
2211 : : #endif /* __CMSIS_GCC_H */
|