]> begriffs open source - cmsis/blob - CMSIS/Core/Include/cmsis_gcc.h
Updated Cortex-M7 CMSIS function SCB_EnableICache.
[cmsis] / CMSIS / Core / Include / cmsis_gcc.h
1 /**************************************************************************//**\r
2  * @file     cmsis_gcc.h\r
3  * @brief    CMSIS Cortex-M Core Function/Instruction Header File\r
4  * @version  V5.00\r
5  * @date     16. June 2016\r
6  ******************************************************************************/\r
7 /*\r
8  * Copyright (c) 2009-2016 ARM Limited. All rights reserved.\r
9  *\r
10  * SPDX-License-Identifier: Apache-2.0\r
11  *\r
12  * Licensed under the Apache License, Version 2.0 (the License); you may\r
13  * not use this file except in compliance with the License.\r
14  * You may obtain a copy of the License at\r
15  *\r
16  * http://www.apache.org/licenses/LICENSE-2.0\r
17  *\r
18  * Unless required by applicable law or agreed to in writing, software\r
19  * distributed under the License is distributed on an AS IS BASIS, WITHOUT\r
20  * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
21  * See the License for the specific language governing permissions and\r
22  * limitations under the License.\r
23  */\r
24 \r
25 #ifndef __CMSIS_GCC_H\r
26 #define __CMSIS_GCC_H\r
27 \r
28 /* ignore some GCC warnings */\r
29 #if defined ( __GNUC__ )\r
30 #pragma GCC diagnostic push\r
31 #pragma GCC diagnostic ignored "-Wsign-conversion"\r
32 #pragma GCC diagnostic ignored "-Wconversion"\r
33 #pragma GCC diagnostic ignored "-Wunused-parameter"\r
34 #endif\r
35 \r
36 \r
37 /* ###########################  Core Function Access  ########################### */\r
38 /** \ingroup  CMSIS_Core_FunctionInterface\r
39     \defgroup CMSIS_Core_RegAccFunctions CMSIS Core Register Access Functions\r
40   @{\r
41  */\r
42 \r
43 /**\r
44   \brief   Enable IRQ Interrupts\r
45   \details Enables IRQ interrupts by clearing the I-bit in the CPSR.\r
46            Can only be executed in Privileged modes.\r
47  */\r
48 __attribute__((always_inline)) __STATIC_INLINE void __enable_irq(void)\r
49 {\r
50   __ASM volatile ("cpsie i" : : : "memory");\r
51 }\r
52 \r
53 \r
54 /**\r
55   \brief   Disable IRQ Interrupts\r
56   \details Disables IRQ interrupts by setting the I-bit in the CPSR.\r
57            Can only be executed in Privileged modes.\r
58  */\r
59 __attribute__((always_inline)) __STATIC_INLINE void __disable_irq(void)\r
60 {\r
61   __ASM volatile ("cpsid i" : : : "memory");\r
62 }\r
63 \r
64 \r
65 /**\r
66   \brief   Get Control Register\r
67   \details Returns the content of the Control Register.\r
68   \return               Control Register value\r
69  */\r
70 __attribute__((always_inline)) __STATIC_INLINE uint32_t __get_CONTROL(void)\r
71 {\r
72   uint32_t result;\r
73 \r
74   __ASM volatile ("MRS %0, control" : "=r" (result) );\r
75   return(result);\r
76 }\r
77 \r
78 \r
79 /**\r
80   \brief   Set Control Register\r
81   \details Writes the given value to the Control Register.\r
82   \param [in]    control  Control Register value to set\r
83  */\r
84 __attribute__((always_inline)) __STATIC_INLINE void __set_CONTROL(uint32_t control)\r
85 {\r
86   __ASM volatile ("MSR control, %0" : : "r" (control) : "memory");\r
87 }\r
88 \r
89 \r
90 /**\r
91   \brief   Get IPSR Register\r
92   \details Returns the content of the IPSR Register.\r
93   \return               IPSR Register value\r
94  */\r
95 __attribute__((always_inline)) __STATIC_INLINE uint32_t __get_IPSR(void)\r
96 {\r
97   uint32_t result;\r
98 \r
99   __ASM volatile ("MRS %0, ipsr" : "=r" (result) );\r
100   return(result);\r
101 }\r
102 \r
103 \r
104 /**\r
105   \brief   Get APSR Register\r
106   \details Returns the content of the APSR Register.\r
107   \return               APSR Register value\r
108  */\r
109 __attribute__((always_inline)) __STATIC_INLINE uint32_t __get_APSR(void)\r
110 {\r
111   uint32_t result;\r
112 \r
113   __ASM volatile ("MRS %0, apsr" : "=r" (result) );\r
114   return(result);\r
115 }\r
116 \r
117 \r
118 /**\r
119   \brief   Get xPSR Register\r
120   \details Returns the content of the xPSR Register.\r
121   \return               xPSR Register value\r
122  */\r
123 __attribute__((always_inline)) __STATIC_INLINE uint32_t __get_xPSR(void)\r
124 {\r
125   uint32_t result;\r
126 \r
127   __ASM volatile ("MRS %0, xpsr" : "=r" (result) );\r
128   return(result);\r
129 }\r
130 \r
131 \r
132 /**\r
133   \brief   Get Process Stack Pointer\r
134   \details Returns the current value of the Process Stack Pointer (PSP).\r
135   \return               PSP Register value\r
136  */\r
137 __attribute__((always_inline)) __STATIC_INLINE uint32_t __get_PSP(void)\r
138 {\r
139   register uint32_t result;\r
140 \r
141   __ASM volatile ("MRS %0, psp"  : "=r" (result) );\r
142   return(result);\r
143 }\r
144 \r
145 \r
146 /**\r
147   \brief   Set Process Stack Pointer\r
148   \details Assigns the given value to the Process Stack Pointer (PSP).\r
149   \param [in]    topOfProcStack  Process Stack Pointer value to set\r
150  */\r
151 __attribute__((always_inline)) __STATIC_INLINE void __set_PSP(uint32_t topOfProcStack)\r
152 {\r
153   __ASM volatile ("MSR psp, %0" : : "r" (topOfProcStack) : "sp");\r
154 }\r
155 \r
156 \r
157 /**\r
158   \brief   Get Main Stack Pointer\r
159   \details Returns the current value of the Main Stack Pointer (MSP).\r
160   \return               MSP Register value\r
161  */\r
162 __attribute__((always_inline)) __STATIC_INLINE uint32_t __get_MSP(void)\r
163 {\r
164   register uint32_t result;\r
165 \r
166   __ASM volatile ("MRS %0, msp" : "=r" (result) );\r
167   return(result);\r
168 }\r
169 \r
170 \r
171 /**\r
172   \brief   Set Main Stack Pointer\r
173   \details Assigns the given value to the Main Stack Pointer (MSP).\r
174   \param [in]    topOfMainStack  Main Stack Pointer value to set\r
175  */\r
176 __attribute__((always_inline)) __STATIC_INLINE void __set_MSP(uint32_t topOfMainStack)\r
177 {\r
178   __ASM volatile ("MSR msp, %0" : : "r" (topOfMainStack) : "sp");\r
179 }\r
180 \r
181 \r
182 /**\r
183   \brief   Get Priority Mask\r
184   \details Returns the current state of the priority mask bit from the Priority Mask Register.\r
185   \return               Priority Mask value\r
186  */\r
187 __attribute__((always_inline)) __STATIC_INLINE uint32_t __get_PRIMASK(void)\r
188 {\r
189   uint32_t result;\r
190 \r
191   __ASM volatile ("MRS %0, primask" : "=r" (result) );\r
192   return(result);\r
193 }\r
194 \r
195 \r
196 /**\r
197   \brief   Set Priority Mask\r
198   \details Assigns the given value to the Priority Mask Register.\r
199   \param [in]    priMask  Priority Mask\r
200  */\r
201 __attribute__((always_inline)) __STATIC_INLINE void __set_PRIMASK(uint32_t priMask)\r
202 {\r
203   __ASM volatile ("MSR primask, %0" : : "r" (priMask) : "memory");\r
204 }\r
205 \r
206 \r
207 #if ((defined (__CORTEX_M ) && (__CORTEX_M  >=   3U)) || \\r
208      (defined (__CORTEX_SC) && (__CORTEX_SC >= 300U))     )\r
209 \r
210 /**\r
211   \brief   Enable FIQ\r
212   \details Enables FIQ interrupts by clearing the F-bit in the CPSR.\r
213            Can only be executed in Privileged modes.\r
214  */\r
215 __attribute__((always_inline)) __STATIC_INLINE void __enable_fault_irq(void)\r
216 {\r
217   __ASM volatile ("cpsie f" : : : "memory");\r
218 }\r
219 \r
220 \r
221 /**\r
222   \brief   Disable FIQ\r
223   \details Disables FIQ interrupts by setting the F-bit in the CPSR.\r
224            Can only be executed in Privileged modes.\r
225  */\r
226 __attribute__((always_inline)) __STATIC_INLINE void __disable_fault_irq(void)\r
227 {\r
228   __ASM volatile ("cpsid f" : : : "memory");\r
229 }\r
230 \r
231 \r
232 /**\r
233   \brief   Get Base Priority\r
234   \details Returns the current value of the Base Priority register.\r
235   \return               Base Priority register value\r
236  */\r
237 __attribute__((always_inline)) __STATIC_INLINE uint32_t __get_BASEPRI(void)\r
238 {\r
239   uint32_t result;\r
240 \r
241   __ASM volatile ("MRS %0, basepri" : "=r" (result) );\r
242   return(result);\r
243 }\r
244 \r
245 \r
246 /**\r
247   \brief   Set Base Priority\r
248   \details Assigns the given value to the Base Priority register.\r
249   \param [in]    basePri  Base Priority value to set\r
250  */\r
251 __attribute__((always_inline)) __STATIC_INLINE void __set_BASEPRI(uint32_t value)\r
252 {\r
253   __ASM volatile ("MSR basepri, %0" : : "r" (value) : "memory");\r
254 }\r
255 \r
256 \r
257 /**\r
258   \brief   Set Base Priority with condition\r
259   \details Assigns the given value to the Base Priority register only if BASEPRI masking is disabled,\r
260            or the new value increases the BASEPRI priority level.\r
261   \param [in]    basePri  Base Priority value to set\r
262  */\r
263 __attribute__((always_inline)) __STATIC_INLINE void __set_BASEPRI_MAX(uint32_t value)\r
264 {\r
265   __ASM volatile ("MSR basepri_max, %0" : : "r" (value) : "memory");\r
266 }\r
267 \r
268 \r
269 /**\r
270   \brief   Get Fault Mask\r
271   \details Returns the current value of the Fault Mask register.\r
272   \return               Fault Mask register value\r
273  */\r
274 __attribute__((always_inline)) __STATIC_INLINE uint32_t __get_FAULTMASK(void)\r
275 {\r
276   uint32_t result;\r
277 \r
278   __ASM volatile ("MRS %0, faultmask" : "=r" (result) );\r
279   return(result);\r
280 }\r
281 \r
282 \r
283 /**\r
284   \brief   Set Fault Mask\r
285   \details Assigns the given value to the Fault Mask register.\r
286   \param [in]    faultMask  Fault Mask value to set\r
287  */\r
288 __attribute__((always_inline)) __STATIC_INLINE void __set_FAULTMASK(uint32_t faultMask)\r
289 {\r
290   __ASM volatile ("MSR faultmask, %0" : : "r" (faultMask) : "memory");\r
291 }\r
292 \r
293 #endif /* ((defined (__CORTEX_M ) && (__CORTEX_M  >=   3U)) || \\r
294            (defined (__CORTEX_SC) && (__CORTEX_SC >= 300U))     ) */\r
295 \r
296 \r
297 #if (defined (__CORTEX_M) && (__CORTEX_M >= 4U))\r
298 \r
299 /**\r
300   \brief   Get FPSCR\r
301   \details Returns the current value of the Floating Point Status/Control register.\r
302   \return               Floating Point Status/Control register value\r
303  */\r
304 __attribute__((always_inline)) __STATIC_INLINE uint32_t __get_FPSCR(void)\r
305 {\r
306 #if ((defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U)) && \\r
307      (defined (__FPU_USED   ) && (__FPU_USED    == 1U))     )\r
308   uint32_t result;\r
309 \r
310   __ASM volatile ("");                                 /* Empty asm statement works as a scheduling barrier */\r
311   __ASM volatile ("VMRS %0, fpscr" : "=r" (result) );\r
312   __ASM volatile ("");\r
313   return(result);\r
314 #else\r
315    return(0U);\r
316 #endif\r
317 }\r
318 \r
319 \r
320 /**\r
321   \brief   Set FPSCR\r
322   \details Assigns the given value to the Floating Point Status/Control register.\r
323   \param [in]    fpscr  Floating Point Status/Control value to set\r
324  */\r
325 __attribute__((always_inline)) __STATIC_INLINE void __set_FPSCR(uint32_t fpscr)\r
326 {\r
327 #if ((defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U)) && \\r
328      (defined (__FPU_USED   ) && (__FPU_USED    == 1U))     )\r
329   __ASM volatile ("");                                           /* Empty asm statement works as a scheduling barrier */\r
330   __ASM volatile ("VMSR fpscr, %0" : : "r" (fpscr) : "vfpcc");\r
331   __ASM volatile ("");\r
332 #endif\r
333 }\r
334 \r
335 #endif /* (defined (__CORTEX_M) && (__CORTEX_M >= 4U)) */\r
336 \r
337 \r
338 \r
339 /*@} end of CMSIS_Core_RegAccFunctions */\r
340 \r
341 \r
342 /* ##########################  Core Instruction Access  ######################### */\r
343 /** \defgroup CMSIS_Core_InstructionInterface CMSIS Core Instruction Interface\r
344   Access to dedicated instructions\r
345   @{\r
346 */\r
347 \r
348 /* Define macros for porting to both thumb1 and thumb2.\r
349  * For thumb1, use low register (r0-r7), specified by constraint "l"\r
350  * Otherwise, use general registers, specified by constraint "r" */\r
351 #if defined (__thumb__) && !defined (__thumb2__)\r
352 #define __CMSIS_GCC_OUT_REG(r) "=l" (r)\r
353 #define __CMSIS_GCC_USE_REG(r) "l" (r)\r
354 #else\r
355 #define __CMSIS_GCC_OUT_REG(r) "=r" (r)\r
356 #define __CMSIS_GCC_USE_REG(r) "r" (r)\r
357 #endif\r
358 \r
359 /**\r
360   \brief   No Operation\r
361   \details No Operation does nothing. This instruction can be used for code alignment purposes.\r
362  */\r
363 //__attribute__((always_inline)) __STATIC_INLINE void __NOP(void)\r
364 //{\r
365 //  __ASM volatile ("nop");\r
366 //}\r
367 #define __NOP()                             __ASM volatile ("nop")       /* This implementation generates debug information */\r
368 \r
369 /**\r
370   \brief   Wait For Interrupt\r
371   \details Wait For Interrupt is a hint instruction that suspends execution until one of a number of events occurs.\r
372  */\r
373 //__attribute__((always_inline)) __STATIC_INLINE void __WFI(void)\r
374 //{\r
375 //  __ASM volatile ("wfi");\r
376 //}\r
377 #define __WFI()                             __ASM volatile ("wfi")       /* This implementation generates debug information */\r
378 \r
379 \r
380 /**\r
381   \brief   Wait For Event\r
382   \details Wait For Event is a hint instruction that permits the processor to enter\r
383            a low-power state until one of a number of events occurs.\r
384  */\r
385 //__attribute__((always_inline)) __STATIC_INLINE void __WFE(void)\r
386 //{\r
387 //  __ASM volatile ("wfe");\r
388 //}\r
389 #define __WFE()                             __ASM volatile ("wfe")       /* This implementation generates debug information */\r
390 \r
391 \r
392 /**\r
393   \brief   Send Event\r
394   \details Send Event is a hint instruction. It causes an event to be signaled to the CPU.\r
395  */\r
396 //__attribute__((always_inline)) __STATIC_INLINE void __SEV(void)\r
397 //{\r
398 //  __ASM volatile ("sev");\r
399 //}\r
400 #define __SEV()                             __ASM volatile ("sev")       /* This implementation generates debug information */\r
401 \r
402 \r
403 /**\r
404   \brief   Instruction Synchronization Barrier\r
405   \details Instruction Synchronization Barrier flushes the pipeline in the processor,\r
406            so that all instructions following the ISB are fetched from cache or memory,\r
407            after the instruction has been completed.\r
408  */\r
409 __attribute__((always_inline)) __STATIC_INLINE void __ISB(void)\r
410 {\r
411   __ASM volatile ("isb 0xF":::"memory");\r
412 }\r
413 \r
414 \r
415 /**\r
416   \brief   Data Synchronization Barrier\r
417   \details Acts as a special kind of Data Memory Barrier.\r
418            It completes when all explicit memory accesses before this instruction complete.\r
419  */\r
420 __attribute__((always_inline)) __STATIC_INLINE void __DSB(void)\r
421 {\r
422   __ASM volatile ("dsb 0xF":::"memory");\r
423 }\r
424 \r
425 \r
426 /**\r
427   \brief   Data Memory Barrier\r
428   \details Ensures the apparent order of the explicit memory operations before\r
429            and after the instruction, without ensuring their completion.\r
430  */\r
431 __attribute__((always_inline)) __STATIC_INLINE void __DMB(void)\r
432 {\r
433   __ASM volatile ("dmb 0xF":::"memory");\r
434 }\r
435 \r
436 \r
437 /**\r
438   \brief   Reverse byte order (32 bit)\r
439   \details Reverses the byte order in integer value.\r
440   \param [in]    value  Value to reverse\r
441   \return               Reversed value\r
442  */\r
443 __attribute__((always_inline)) __STATIC_INLINE uint32_t __REV(uint32_t value)\r
444 {\r
445 #if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 5)\r
446   return __builtin_bswap32(value);\r
447 #else\r
448   uint32_t result;\r
449 \r
450   __ASM volatile ("rev %0, %1" : __CMSIS_GCC_OUT_REG (result) : __CMSIS_GCC_USE_REG (value) );\r
451   return(result);\r
452 #endif\r
453 }\r
454 \r
455 \r
456 /**\r
457   \brief   Reverse byte order (16 bit)\r
458   \details Reverses the byte order in two unsigned short values.\r
459   \param [in]    value  Value to reverse\r
460   \return               Reversed value\r
461  */\r
462 __attribute__((always_inline)) __STATIC_INLINE uint32_t __REV16(uint32_t value)\r
463 {\r
464   uint32_t result;\r
465 \r
466   __ASM volatile ("rev16 %0, %1" : __CMSIS_GCC_OUT_REG (result) : __CMSIS_GCC_USE_REG (value) );\r
467   return(result);\r
468 }\r
469 \r
470 \r
471 /**\r
472   \brief   Reverse byte order in signed short value\r
473   \details Reverses the byte order in a signed short value with sign extension to integer.\r
474   \param [in]    value  Value to reverse\r
475   \return               Reversed value\r
476  */\r
477 __attribute__((always_inline)) __STATIC_INLINE int32_t __REVSH(int32_t value)\r
478 {\r
479 #if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8)\r
480   return (short)__builtin_bswap16(value);\r
481 #else\r
482   int32_t result;\r
483 \r
484   __ASM volatile ("revsh %0, %1" : __CMSIS_GCC_OUT_REG (result) : __CMSIS_GCC_USE_REG (value) );\r
485   return(result);\r
486 #endif\r
487 }\r
488 \r
489 \r
490 /**\r
491   \brief   Rotate Right in unsigned value (32 bit)\r
492   \details Rotate Right (immediate) provides the value of the contents of a register rotated by a variable number of bits.\r
493   \param [in]    op1  Value to rotate\r
494   \param [in]    op2  Number of Bits to rotate\r
495   \return               Rotated value\r
496  */\r
497 __attribute__((always_inline)) __STATIC_INLINE uint32_t __ROR(uint32_t op1, uint32_t op2)\r
498 {\r
499   return (op1 >> op2) | (op1 << (32U - op2));\r
500 }\r
501 \r
502 \r
503 /**\r
504   \brief   Breakpoint\r
505   \details Causes the processor to enter Debug state.\r
506            Debug tools can use this to investigate system state when the instruction at a particular address is reached.\r
507   \param [in]    value  is ignored by the processor.\r
508                  If required, a debugger can use it to store additional information about the breakpoint.\r
509  */\r
510 #define __BKPT(value)                       __ASM volatile ("bkpt "#value)\r
511 \r
512 \r
513 /**\r
514   \brief   Reverse bit order of value\r
515   \details Reverses the bit order of the given value.\r
516   \param [in]    value  Value to reverse\r
517   \return               Reversed value\r
518  */\r
519 __attribute__((always_inline)) __STATIC_INLINE uint32_t __RBIT(uint32_t value)\r
520 {\r
521   uint32_t result;\r
522 \r
523 #if ((defined (__CORTEX_M ) && (__CORTEX_M  >=   3U)) || \\r
524      (defined (__CORTEX_SC) && (__CORTEX_SC >= 300U))     )\r
525    __ASM volatile ("rbit %0, %1" : "=r" (result) : "r" (value) );\r
526 #else\r
527   int32_t s = 4 /*sizeof(v)*/ * 8 - 1; /* extra shift needed at end */\r
528 \r
529   result = value;                      /* r will be reversed bits of v; first get LSB of v */\r
530   for (value >>= 1U; value; value >>= 1U)\r
531   {\r
532     result <<= 1U;\r
533     result |= value & 1U;\r
534     s--;\r
535   }\r
536   result <<= s;                        /* shift when v's highest bits are zero */\r
537 #endif\r
538   return(result);\r
539 }\r
540 \r
541 \r
542 /**\r
543   \brief   Count leading zeros\r
544   \details Counts the number of leading zeros of a data value.\r
545   \param [in]  value  Value to count the leading zeros\r
546   \return             number of leading zeros in value\r
547  */\r
548 #define __CLZ             __builtin_clz\r
549 \r
550 \r
551 #if ((defined (__CORTEX_M ) && (__CORTEX_M  >=   3U)) || \\r
552      (defined (__CORTEX_SC) && (__CORTEX_SC >= 300U))     )\r
553 \r
554 /**\r
555   \brief   LDR Exclusive (8 bit)\r
556   \details Executes a exclusive LDR instruction for 8 bit value.\r
557   \param [in]    ptr  Pointer to data\r
558   \return             value of type uint8_t at (*ptr)\r
559  */\r
560 __attribute__((always_inline)) __STATIC_INLINE uint8_t __LDREXB(volatile uint8_t *addr)\r
561 {\r
562     uint32_t result;\r
563 \r
564 #if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8)\r
565    __ASM volatile ("ldrexb %0, %1" : "=r" (result) : "Q" (*addr) );\r
566 #else\r
567     /* Prior to GCC 4.8, "Q" will be expanded to [rx, #0] which is not\r
568        accepted by assembler. So has to use following less efficient pattern.\r
569     */\r
570    __ASM volatile ("ldrexb %0, [%1]" : "=r" (result) : "r" (addr) : "memory" );\r
571 #endif\r
572    return ((uint8_t) result);    /* Add explicit type cast here */\r
573 }\r
574 \r
575 \r
576 /**\r
577   \brief   LDR Exclusive (16 bit)\r
578   \details Executes a exclusive LDR instruction for 16 bit values.\r
579   \param [in]    ptr  Pointer to data\r
580   \return        value of type uint16_t at (*ptr)\r
581  */\r
582 __attribute__((always_inline)) __STATIC_INLINE uint16_t __LDREXH(volatile uint16_t *addr)\r
583 {\r
584     uint32_t result;\r
585 \r
586 #if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8)\r
587    __ASM volatile ("ldrexh %0, %1" : "=r" (result) : "Q" (*addr) );\r
588 #else\r
589     /* Prior to GCC 4.8, "Q" will be expanded to [rx, #0] which is not\r
590        accepted by assembler. So has to use following less efficient pattern.\r
591     */\r
592    __ASM volatile ("ldrexh %0, [%1]" : "=r" (result) : "r" (addr) : "memory" );\r
593 #endif\r
594    return ((uint16_t) result);    /* Add explicit type cast here */\r
595 }\r
596 \r
597 \r
598 /**\r
599   \brief   LDR Exclusive (32 bit)\r
600   \details Executes a exclusive LDR instruction for 32 bit values.\r
601   \param [in]    ptr  Pointer to data\r
602   \return        value of type uint32_t at (*ptr)\r
603  */\r
604 __attribute__((always_inline)) __STATIC_INLINE uint32_t __LDREXW(volatile uint32_t *addr)\r
605 {\r
606     uint32_t result;\r
607 \r
608    __ASM volatile ("ldrex %0, %1" : "=r" (result) : "Q" (*addr) );\r
609    return(result);\r
610 }\r
611 \r
612 \r
613 /**\r
614   \brief   STR Exclusive (8 bit)\r
615   \details Executes a exclusive STR instruction for 8 bit values.\r
616   \param [in]  value  Value to store\r
617   \param [in]    ptr  Pointer to location\r
618   \return          0  Function succeeded\r
619   \return          1  Function failed\r
620  */\r
621 __attribute__((always_inline)) __STATIC_INLINE uint32_t __STREXB(uint8_t value, volatile uint8_t *addr)\r
622 {\r
623    uint32_t result;\r
624 \r
625    __ASM volatile ("strexb %0, %2, %1" : "=&r" (result), "=Q" (*addr) : "r" ((uint32_t)value) );\r
626    return(result);\r
627 }\r
628 \r
629 \r
630 /**\r
631   \brief   STR Exclusive (16 bit)\r
632   \details Executes a exclusive STR instruction for 16 bit values.\r
633   \param [in]  value  Value to store\r
634   \param [in]    ptr  Pointer to location\r
635   \return          0  Function succeeded\r
636   \return          1  Function failed\r
637  */\r
638 __attribute__((always_inline)) __STATIC_INLINE uint32_t __STREXH(uint16_t value, volatile uint16_t *addr)\r
639 {\r
640    uint32_t result;\r
641 \r
642    __ASM volatile ("strexh %0, %2, %1" : "=&r" (result), "=Q" (*addr) : "r" ((uint32_t)value) );\r
643    return(result);\r
644 }\r
645 \r
646 \r
647 /**\r
648   \brief   STR Exclusive (32 bit)\r
649   \details Executes a exclusive STR instruction for 32 bit values.\r
650   \param [in]  value  Value to store\r
651   \param [in]    ptr  Pointer to location\r
652   \return          0  Function succeeded\r
653   \return          1  Function failed\r
654  */\r
655 __attribute__((always_inline)) __STATIC_INLINE uint32_t __STREXW(uint32_t value, volatile uint32_t *addr)\r
656 {\r
657    uint32_t result;\r
658 \r
659    __ASM volatile ("strex %0, %2, %1" : "=&r" (result), "=Q" (*addr) : "r" (value) );\r
660    return(result);\r
661 }\r
662 \r
663 \r
664 /**\r
665   \brief   Remove the exclusive lock\r
666   \details Removes the exclusive lock which is created by LDREX.\r
667  */\r
668 __attribute__((always_inline)) __STATIC_INLINE void __CLREX(void)\r
669 {\r
670   __ASM volatile ("clrex" ::: "memory");\r
671 }\r
672 \r
673 \r
674 /**\r
675   \brief   Signed Saturate\r
676   \details Saturates a signed value.\r
677   \param [in]  value  Value to be saturated\r
678   \param [in]    sat  Bit position to saturate to (1..32)\r
679   \return             Saturated value\r
680  */\r
681 #define __SSAT(ARG1,ARG2) \\r
682 ({                          \\r
683   int32_t __RES, __ARG1 = (ARG1); \\r
684   __ASM ("ssat %0, %1, %2" : "=r" (__RES) :  "I" (ARG2), "r" (__ARG1) ); \\r
685   __RES; \\r
686  })\r
687 \r
688 \r
689 /**\r
690   \brief   Unsigned Saturate\r
691   \details Saturates an unsigned value.\r
692   \param [in]  value  Value to be saturated\r
693   \param [in]    sat  Bit position to saturate to (0..31)\r
694   \return             Saturated value\r
695  */\r
696 #define __USAT(ARG1,ARG2) \\r
697 ({                          \\r
698   uint32_t __RES, __ARG1 = (ARG1); \\r
699   __ASM ("usat %0, %1, %2" : "=r" (__RES) :  "I" (ARG2), "r" (__ARG1) ); \\r
700   __RES; \\r
701  })\r
702 \r
703 \r
704 /**\r
705   \brief   Rotate Right with Extend (32 bit)\r
706   \details Moves each bit of a bitstring right by one bit.\r
707            The carry input is shifted in at the left end of the bitstring.\r
708   \param [in]    value  Value to rotate\r
709   \return               Rotated value\r
710  */\r
711 __attribute__((always_inline)) __STATIC_INLINE uint32_t __RRX(uint32_t value)\r
712 {\r
713   uint32_t result;\r
714 \r
715   __ASM volatile ("rrx %0, %1" : __CMSIS_GCC_OUT_REG (result) : __CMSIS_GCC_USE_REG (value) );\r
716   return(result);\r
717 }\r
718 \r
719 \r
720 /**\r
721   \brief   LDRT Unprivileged (8 bit)\r
722   \details Executes a Unprivileged LDRT instruction for 8 bit value.\r
723   \param [in]    ptr  Pointer to data\r
724   \return             value of type uint8_t at (*ptr)\r
725  */\r
726 __attribute__((always_inline)) __STATIC_INLINE uint8_t __LDRBT(volatile uint8_t *ptr)\r
727 {\r
728     uint32_t result;\r
729 \r
730 #if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8)\r
731    __ASM volatile ("ldrbt %0, %1" : "=r" (result) : "Q" (*ptr) );\r
732 #else\r
733     /* Prior to GCC 4.8, "Q" will be expanded to [rx, #0] which is not\r
734        accepted by assembler. So has to use following less efficient pattern.\r
735     */\r
736    __ASM volatile ("ldrbt %0, [%1]" : "=r" (result) : "r" (ptr) : "memory" );\r
737 #endif\r
738    return ((uint8_t) result);    /* Add explicit type cast here */\r
739 }\r
740 \r
741 \r
742 /**\r
743   \brief   LDRT Unprivileged (16 bit)\r
744   \details Executes a Unprivileged LDRT instruction for 16 bit values.\r
745   \param [in]    ptr  Pointer to data\r
746   \return        value of type uint16_t at (*ptr)\r
747  */\r
748 __attribute__((always_inline)) __STATIC_INLINE uint16_t __LDRHT(volatile uint16_t *ptr)\r
749 {\r
750     uint32_t result;\r
751 \r
752 #if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8)\r
753    __ASM volatile ("ldrht %0, %1" : "=r" (result) : "Q" (*ptr) );\r
754 #else\r
755     /* Prior to GCC 4.8, "Q" will be expanded to [rx, #0] which is not\r
756        accepted by assembler. So has to use following less efficient pattern.\r
757     */\r
758    __ASM volatile ("ldrht %0, [%1]" : "=r" (result) : "r" (ptr) : "memory" );\r
759 #endif\r
760    return ((uint16_t) result);    /* Add explicit type cast here */\r
761 }\r
762 \r
763 \r
764 /**\r
765   \brief   LDRT Unprivileged (32 bit)\r
766   \details Executes a Unprivileged LDRT instruction for 32 bit values.\r
767   \param [in]    ptr  Pointer to data\r
768   \return        value of type uint32_t at (*ptr)\r
769  */\r
770 __attribute__((always_inline)) __STATIC_INLINE uint32_t __LDRT(volatile uint32_t *ptr)\r
771 {\r
772     uint32_t result;\r
773 \r
774    __ASM volatile ("ldrt %0, %1" : "=r" (result) : "Q" (*ptr) );\r
775    return(result);\r
776 }\r
777 \r
778 \r
779 /**\r
780   \brief   STRT Unprivileged (8 bit)\r
781   \details Executes a Unprivileged STRT instruction for 8 bit values.\r
782   \param [in]  value  Value to store\r
783   \param [in]    ptr  Pointer to location\r
784  */\r
785 __attribute__((always_inline)) __STATIC_INLINE void __STRBT(uint8_t value, volatile uint8_t *ptr)\r
786 {\r
787    __ASM volatile ("strbt %1, %0" : "=Q" (*ptr) : "r" ((uint32_t)value) );\r
788 }\r
789 \r
790 \r
791 /**\r
792   \brief   STRT Unprivileged (16 bit)\r
793   \details Executes a Unprivileged STRT instruction for 16 bit values.\r
794   \param [in]  value  Value to store\r
795   \param [in]    ptr  Pointer to location\r
796  */\r
797 __attribute__((always_inline)) __STATIC_INLINE void __STRHT(uint16_t value, volatile uint16_t *ptr)\r
798 {\r
799    __ASM volatile ("strht %1, %0" : "=Q" (*ptr) : "r" ((uint32_t)value) );\r
800 }\r
801 \r
802 \r
803 /**\r
804   \brief   STRT Unprivileged (32 bit)\r
805   \details Executes a Unprivileged STRT instruction for 32 bit values.\r
806   \param [in]  value  Value to store\r
807   \param [in]    ptr  Pointer to location\r
808  */\r
809 __attribute__((always_inline)) __STATIC_INLINE void __STRT(uint32_t value, volatile uint32_t *ptr)\r
810 {\r
811    __ASM volatile ("strt %1, %0" : "=Q" (*ptr) : "r" (value) );\r
812 }\r
813 \r
814 #endif /* ((defined (__CORTEX_M ) && (__CORTEX_M >=    3U)) || \\r
815            (defined (__CORTEX_SC) && (__CORTEX_SC >= 300U))     ) */\r
816 \r
817 /*@}*/ /* end of group CMSIS_Core_InstructionInterface */\r
818 \r
819 \r
820 /* ###################  Compiler specific Intrinsics  ########################### */\r
821 /** \defgroup CMSIS_SIMD_intrinsics CMSIS SIMD Intrinsics\r
822   Access to dedicated SIMD instructions\r
823   @{\r
824 */\r
825 \r
826 #if (defined (__CORTEX_M) && (__CORTEX_M >= 4U))\r
827 \r
828 __attribute__((always_inline)) __STATIC_INLINE uint32_t __SADD8(uint32_t op1, uint32_t op2)\r
829 {\r
830   uint32_t result;\r
831 \r
832   __ASM volatile ("sadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );\r
833   return(result);\r
834 }\r
835 \r
836 __attribute__((always_inline)) __STATIC_INLINE uint32_t __QADD8(uint32_t op1, uint32_t op2)\r
837 {\r
838   uint32_t result;\r
839 \r
840   __ASM volatile ("qadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );\r
841   return(result);\r
842 }\r
843 \r
844 __attribute__((always_inline)) __STATIC_INLINE uint32_t __SHADD8(uint32_t op1, uint32_t op2)\r
845 {\r
846   uint32_t result;\r
847 \r
848   __ASM volatile ("shadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );\r
849   return(result);\r
850 }\r
851 \r
852 __attribute__((always_inline)) __STATIC_INLINE uint32_t __UADD8(uint32_t op1, uint32_t op2)\r
853 {\r
854   uint32_t result;\r
855 \r
856   __ASM volatile ("uadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );\r
857   return(result);\r
858 }\r
859 \r
860 __attribute__((always_inline)) __STATIC_INLINE uint32_t __UQADD8(uint32_t op1, uint32_t op2)\r
861 {\r
862   uint32_t result;\r
863 \r
864   __ASM volatile ("uqadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );\r
865   return(result);\r
866 }\r
867 \r
868 __attribute__((always_inline)) __STATIC_INLINE uint32_t __UHADD8(uint32_t op1, uint32_t op2)\r
869 {\r
870   uint32_t result;\r
871 \r
872   __ASM volatile ("uhadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );\r
873   return(result);\r
874 }\r
875 \r
876 \r
877 __attribute__((always_inline)) __STATIC_INLINE uint32_t __SSUB8(uint32_t op1, uint32_t op2)\r
878 {\r
879   uint32_t result;\r
880 \r
881   __ASM volatile ("ssub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );\r
882   return(result);\r
883 }\r
884 \r
885 __attribute__((always_inline)) __STATIC_INLINE uint32_t __QSUB8(uint32_t op1, uint32_t op2)\r
886 {\r
887   uint32_t result;\r
888 \r
889   __ASM volatile ("qsub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );\r
890   return(result);\r
891 }\r
892 \r
893 __attribute__((always_inline)) __STATIC_INLINE uint32_t __SHSUB8(uint32_t op1, uint32_t op2)\r
894 {\r
895   uint32_t result;\r
896 \r
897   __ASM volatile ("shsub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );\r
898   return(result);\r
899 }\r
900 \r
901 __attribute__((always_inline)) __STATIC_INLINE uint32_t __USUB8(uint32_t op1, uint32_t op2)\r
902 {\r
903   uint32_t result;\r
904 \r
905   __ASM volatile ("usub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );\r
906   return(result);\r
907 }\r
908 \r
909 __attribute__((always_inline)) __STATIC_INLINE uint32_t __UQSUB8(uint32_t op1, uint32_t op2)\r
910 {\r
911   uint32_t result;\r
912 \r
913   __ASM volatile ("uqsub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );\r
914   return(result);\r
915 }\r
916 \r
917 __attribute__((always_inline)) __STATIC_INLINE uint32_t __UHSUB8(uint32_t op1, uint32_t op2)\r
918 {\r
919   uint32_t result;\r
920 \r
921   __ASM volatile ("uhsub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );\r
922   return(result);\r
923 }\r
924 \r
925 \r
926 __attribute__((always_inline)) __STATIC_INLINE uint32_t __SADD16(uint32_t op1, uint32_t op2)\r
927 {\r
928   uint32_t result;\r
929 \r
930   __ASM volatile ("sadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );\r
931   return(result);\r
932 }\r
933 \r
934 __attribute__((always_inline)) __STATIC_INLINE uint32_t __QADD16(uint32_t op1, uint32_t op2)\r
935 {\r
936   uint32_t result;\r
937 \r
938   __ASM volatile ("qadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );\r
939   return(result);\r
940 }\r
941 \r
942 __attribute__((always_inline)) __STATIC_INLINE uint32_t __SHADD16(uint32_t op1, uint32_t op2)\r
943 {\r
944   uint32_t result;\r
945 \r
946   __ASM volatile ("shadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );\r
947   return(result);\r
948 }\r
949 \r
950 __attribute__((always_inline)) __STATIC_INLINE uint32_t __UADD16(uint32_t op1, uint32_t op2)\r
951 {\r
952   uint32_t result;\r
953 \r
954   __ASM volatile ("uadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );\r
955   return(result);\r
956 }\r
957 \r
958 __attribute__((always_inline)) __STATIC_INLINE uint32_t __UQADD16(uint32_t op1, uint32_t op2)\r
959 {\r
960   uint32_t result;\r
961 \r
962   __ASM volatile ("uqadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );\r
963   return(result);\r
964 }\r
965 \r
966 __attribute__((always_inline)) __STATIC_INLINE uint32_t __UHADD16(uint32_t op1, uint32_t op2)\r
967 {\r
968   uint32_t result;\r
969 \r
970   __ASM volatile ("uhadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );\r
971   return(result);\r
972 }\r
973 \r
974 __attribute__((always_inline)) __STATIC_INLINE uint32_t __SSUB16(uint32_t op1, uint32_t op2)\r
975 {\r
976   uint32_t result;\r
977 \r
978   __ASM volatile ("ssub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );\r
979   return(result);\r
980 }\r
981 \r
982 __attribute__((always_inline)) __STATIC_INLINE uint32_t __QSUB16(uint32_t op1, uint32_t op2)\r
983 {\r
984   uint32_t result;\r
985 \r
986   __ASM volatile ("qsub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );\r
987   return(result);\r
988 }\r
989 \r
990 __attribute__((always_inline)) __STATIC_INLINE uint32_t __SHSUB16(uint32_t op1, uint32_t op2)\r
991 {\r
992   uint32_t result;\r
993 \r
994   __ASM volatile ("shsub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );\r
995   return(result);\r
996 }\r
997 \r
998 __attribute__((always_inline)) __STATIC_INLINE uint32_t __USUB16(uint32_t op1, uint32_t op2)\r
999 {\r
1000   uint32_t result;\r
1001 \r
1002   __ASM volatile ("usub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );\r
1003   return(result);\r
1004 }\r
1005 \r
1006 __attribute__((always_inline)) __STATIC_INLINE uint32_t __UQSUB16(uint32_t op1, uint32_t op2)\r
1007 {\r
1008   uint32_t result;\r
1009 \r
1010   __ASM volatile ("uqsub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );\r
1011   return(result);\r
1012 }\r
1013 \r
1014 __attribute__((always_inline)) __STATIC_INLINE uint32_t __UHSUB16(uint32_t op1, uint32_t op2)\r
1015 {\r
1016   uint32_t result;\r
1017 \r
1018   __ASM volatile ("uhsub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );\r
1019   return(result);\r
1020 }\r
1021 \r
1022 __attribute__((always_inline)) __STATIC_INLINE uint32_t __SASX(uint32_t op1, uint32_t op2)\r
1023 {\r
1024   uint32_t result;\r
1025 \r
1026   __ASM volatile ("sasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );\r
1027   return(result);\r
1028 }\r
1029 \r
1030 __attribute__((always_inline)) __STATIC_INLINE uint32_t __QASX(uint32_t op1, uint32_t op2)\r
1031 {\r
1032   uint32_t result;\r
1033 \r
1034   __ASM volatile ("qasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );\r
1035   return(result);\r
1036 }\r
1037 \r
1038 __attribute__((always_inline)) __STATIC_INLINE uint32_t __SHASX(uint32_t op1, uint32_t op2)\r
1039 {\r
1040   uint32_t result;\r
1041 \r
1042   __ASM volatile ("shasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );\r
1043   return(result);\r
1044 }\r
1045 \r
1046 __attribute__((always_inline)) __STATIC_INLINE uint32_t __UASX(uint32_t op1, uint32_t op2)\r
1047 {\r
1048   uint32_t result;\r
1049 \r
1050   __ASM volatile ("uasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );\r
1051   return(result);\r
1052 }\r
1053 \r
1054 __attribute__((always_inline)) __STATIC_INLINE uint32_t __UQASX(uint32_t op1, uint32_t op2)\r
1055 {\r
1056   uint32_t result;\r
1057 \r
1058   __ASM volatile ("uqasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );\r
1059   return(result);\r
1060 }\r
1061 \r
1062 __attribute__((always_inline)) __STATIC_INLINE uint32_t __UHASX(uint32_t op1, uint32_t op2)\r
1063 {\r
1064   uint32_t result;\r
1065 \r
1066   __ASM volatile ("uhasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );\r
1067   return(result);\r
1068 }\r
1069 \r
1070 __attribute__((always_inline)) __STATIC_INLINE uint32_t __SSAX(uint32_t op1, uint32_t op2)\r
1071 {\r
1072   uint32_t result;\r
1073 \r
1074   __ASM volatile ("ssax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );\r
1075   return(result);\r
1076 }\r
1077 \r
1078 __attribute__((always_inline)) __STATIC_INLINE uint32_t __QSAX(uint32_t op1, uint32_t op2)\r
1079 {\r
1080   uint32_t result;\r
1081 \r
1082   __ASM volatile ("qsax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );\r
1083   return(result);\r
1084 }\r
1085 \r
1086 __attribute__((always_inline)) __STATIC_INLINE uint32_t __SHSAX(uint32_t op1, uint32_t op2)\r
1087 {\r
1088   uint32_t result;\r
1089 \r
1090   __ASM volatile ("shsax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );\r
1091   return(result);\r
1092 }\r
1093 \r
1094 __attribute__((always_inline)) __STATIC_INLINE uint32_t __USAX(uint32_t op1, uint32_t op2)\r
1095 {\r
1096   uint32_t result;\r
1097 \r
1098   __ASM volatile ("usax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );\r
1099   return(result);\r
1100 }\r
1101 \r
1102 __attribute__((always_inline)) __STATIC_INLINE uint32_t __UQSAX(uint32_t op1, uint32_t op2)\r
1103 {\r
1104   uint32_t result;\r
1105 \r
1106   __ASM volatile ("uqsax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );\r
1107   return(result);\r
1108 }\r
1109 \r
1110 __attribute__((always_inline)) __STATIC_INLINE uint32_t __UHSAX(uint32_t op1, uint32_t op2)\r
1111 {\r
1112   uint32_t result;\r
1113 \r
1114   __ASM volatile ("uhsax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );\r
1115   return(result);\r
1116 }\r
1117 \r
1118 __attribute__((always_inline)) __STATIC_INLINE uint32_t __USAD8(uint32_t op1, uint32_t op2)\r
1119 {\r
1120   uint32_t result;\r
1121 \r
1122   __ASM volatile ("usad8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );\r
1123   return(result);\r
1124 }\r
1125 \r
1126 __attribute__((always_inline)) __STATIC_INLINE uint32_t __USADA8(uint32_t op1, uint32_t op2, uint32_t op3)\r
1127 {\r
1128   uint32_t result;\r
1129 \r
1130   __ASM volatile ("usada8 %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) );\r
1131   return(result);\r
1132 }\r
1133 \r
1134 #define __SSAT16(ARG1,ARG2) \\r
1135 ({                          \\r
1136   int32_t __RES, __ARG1 = (ARG1); \\r
1137   __ASM ("ssat16 %0, %1, %2" : "=r" (__RES) :  "I" (ARG2), "r" (__ARG1) ); \\r
1138   __RES; \\r
1139  })\r
1140 \r
1141 #define __USAT16(ARG1,ARG2) \\r
1142 ({                          \\r
1143   uint32_t __RES, __ARG1 = (ARG1); \\r
1144   __ASM ("usat16 %0, %1, %2" : "=r" (__RES) :  "I" (ARG2), "r" (__ARG1) ); \\r
1145   __RES; \\r
1146  })\r
1147 \r
1148 __attribute__((always_inline)) __STATIC_INLINE uint32_t __UXTB16(uint32_t op1)\r
1149 {\r
1150   uint32_t result;\r
1151 \r
1152   __ASM volatile ("uxtb16 %0, %1" : "=r" (result) : "r" (op1));\r
1153   return(result);\r
1154 }\r
1155 \r
1156 __attribute__((always_inline)) __STATIC_INLINE uint32_t __UXTAB16(uint32_t op1, uint32_t op2)\r
1157 {\r
1158   uint32_t result;\r
1159 \r
1160   __ASM volatile ("uxtab16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );\r
1161   return(result);\r
1162 }\r
1163 \r
1164 __attribute__((always_inline)) __STATIC_INLINE uint32_t __SXTB16(uint32_t op1)\r
1165 {\r
1166   uint32_t result;\r
1167 \r
1168   __ASM volatile ("sxtb16 %0, %1" : "=r" (result) : "r" (op1));\r
1169   return(result);\r
1170 }\r
1171 \r
1172 __attribute__((always_inline)) __STATIC_INLINE uint32_t __SXTAB16(uint32_t op1, uint32_t op2)\r
1173 {\r
1174   uint32_t result;\r
1175 \r
1176   __ASM volatile ("sxtab16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );\r
1177   return(result);\r
1178 }\r
1179 \r
1180 __attribute__((always_inline)) __STATIC_INLINE uint32_t __SMUAD  (uint32_t op1, uint32_t op2)\r
1181 {\r
1182   uint32_t result;\r
1183 \r
1184   __ASM volatile ("smuad %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );\r
1185   return(result);\r
1186 }\r
1187 \r
1188 __attribute__((always_inline)) __STATIC_INLINE uint32_t __SMUADX (uint32_t op1, uint32_t op2)\r
1189 {\r
1190   uint32_t result;\r
1191 \r
1192   __ASM volatile ("smuadx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );\r
1193   return(result);\r
1194 }\r
1195 \r
1196 __attribute__((always_inline)) __STATIC_INLINE uint32_t __SMLAD (uint32_t op1, uint32_t op2, uint32_t op3)\r
1197 {\r
1198   uint32_t result;\r
1199 \r
1200   __ASM volatile ("smlad %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) );\r
1201   return(result);\r
1202 }\r
1203 \r
1204 __attribute__((always_inline)) __STATIC_INLINE uint32_t __SMLADX (uint32_t op1, uint32_t op2, uint32_t op3)\r
1205 {\r
1206   uint32_t result;\r
1207 \r
1208   __ASM volatile ("smladx %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) );\r
1209   return(result);\r
1210 }\r
1211 \r
1212 __attribute__((always_inline)) __STATIC_INLINE uint64_t __SMLALD (uint32_t op1, uint32_t op2, uint64_t acc)\r
1213 {\r
1214   union llreg_u{\r
1215     uint32_t w32[2];\r
1216     uint64_t w64;\r
1217   } llr;\r
1218   llr.w64 = acc;\r
1219 \r
1220 #ifndef __ARMEB__   /* Little endian */\r
1221   __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]) );\r
1222 #else               /* Big endian */\r
1223   __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]) );\r
1224 #endif\r
1225 \r
1226   return(llr.w64);\r
1227 }\r
1228 \r
1229 __attribute__((always_inline)) __STATIC_INLINE uint64_t __SMLALDX (uint32_t op1, uint32_t op2, uint64_t acc)\r
1230 {\r
1231   union llreg_u{\r
1232     uint32_t w32[2];\r
1233     uint64_t w64;\r
1234   } llr;\r
1235   llr.w64 = acc;\r
1236 \r
1237 #ifndef __ARMEB__   /* Little endian */\r
1238   __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]) );\r
1239 #else               /* Big endian */\r
1240   __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]) );\r
1241 #endif\r
1242 \r
1243   return(llr.w64);\r
1244 }\r
1245 \r
1246 __attribute__((always_inline)) __STATIC_INLINE uint32_t __SMUSD  (uint32_t op1, uint32_t op2)\r
1247 {\r
1248   uint32_t result;\r
1249 \r
1250   __ASM volatile ("smusd %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );\r
1251   return(result);\r
1252 }\r
1253 \r
1254 __attribute__((always_inline)) __STATIC_INLINE uint32_t __SMUSDX (uint32_t op1, uint32_t op2)\r
1255 {\r
1256   uint32_t result;\r
1257 \r
1258   __ASM volatile ("smusdx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );\r
1259   return(result);\r
1260 }\r
1261 \r
1262 __attribute__((always_inline)) __STATIC_INLINE uint32_t __SMLSD (uint32_t op1, uint32_t op2, uint32_t op3)\r
1263 {\r
1264   uint32_t result;\r
1265 \r
1266   __ASM volatile ("smlsd %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) );\r
1267   return(result);\r
1268 }\r
1269 \r
1270 __attribute__((always_inline)) __STATIC_INLINE uint32_t __SMLSDX (uint32_t op1, uint32_t op2, uint32_t op3)\r
1271 {\r
1272   uint32_t result;\r
1273 \r
1274   __ASM volatile ("smlsdx %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) );\r
1275   return(result);\r
1276 }\r
1277 \r
1278 __attribute__((always_inline)) __STATIC_INLINE uint64_t __SMLSLD (uint32_t op1, uint32_t op2, uint64_t acc)\r
1279 {\r
1280   union llreg_u{\r
1281     uint32_t w32[2];\r
1282     uint64_t w64;\r
1283   } llr;\r
1284   llr.w64 = acc;\r
1285 \r
1286 #ifndef __ARMEB__   /* Little endian */\r
1287   __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]) );\r
1288 #else               /* Big endian */\r
1289   __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]) );\r
1290 #endif\r
1291 \r
1292   return(llr.w64);\r
1293 }\r
1294 \r
1295 __attribute__((always_inline)) __STATIC_INLINE uint64_t __SMLSLDX (uint32_t op1, uint32_t op2, uint64_t acc)\r
1296 {\r
1297   union llreg_u{\r
1298     uint32_t w32[2];\r
1299     uint64_t w64;\r
1300   } llr;\r
1301   llr.w64 = acc;\r
1302 \r
1303 #ifndef __ARMEB__   /* Little endian */\r
1304   __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]) );\r
1305 #else               /* Big endian */\r
1306   __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]) );\r
1307 #endif\r
1308 \r
1309   return(llr.w64);\r
1310 }\r
1311 \r
1312 __attribute__((always_inline)) __STATIC_INLINE uint32_t __SEL  (uint32_t op1, uint32_t op2)\r
1313 {\r
1314   uint32_t result;\r
1315 \r
1316   __ASM volatile ("sel %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );\r
1317   return(result);\r
1318 }\r
1319 \r
1320 __attribute__((always_inline)) __STATIC_INLINE  int32_t __QADD( int32_t op1,  int32_t op2)\r
1321 {\r
1322   int32_t result;\r
1323 \r
1324   __ASM volatile ("qadd %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );\r
1325   return(result);\r
1326 }\r
1327 \r
1328 __attribute__((always_inline)) __STATIC_INLINE  int32_t __QSUB( int32_t op1,  int32_t op2)\r
1329 {\r
1330   int32_t result;\r
1331 \r
1332   __ASM volatile ("qsub %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );\r
1333   return(result);\r
1334 }\r
1335 \r
1336 #define __PKHBT(ARG1,ARG2,ARG3) \\r
1337 ({                          \\r
1338   uint32_t __RES, __ARG1 = (ARG1), __ARG2 = (ARG2); \\r
1339   __ASM ("pkhbt %0, %1, %2, lsl %3" : "=r" (__RES) :  "r" (__ARG1), "r" (__ARG2), "I" (ARG3)  ); \\r
1340   __RES; \\r
1341  })\r
1342 \r
1343 #define __PKHTB(ARG1,ARG2,ARG3) \\r
1344 ({                          \\r
1345   uint32_t __RES, __ARG1 = (ARG1), __ARG2 = (ARG2); \\r
1346   if (ARG3 == 0) \\r
1347     __ASM ("pkhtb %0, %1, %2" : "=r" (__RES) :  "r" (__ARG1), "r" (__ARG2)  ); \\r
1348   else \\r
1349     __ASM ("pkhtb %0, %1, %2, asr %3" : "=r" (__RES) :  "r" (__ARG1), "r" (__ARG2), "I" (ARG3)  ); \\r
1350   __RES; \\r
1351  })\r
1352 \r
1353 __attribute__((always_inline)) __STATIC_INLINE uint32_t __SMMLA (int32_t op1, int32_t op2, int32_t op3)\r
1354 {\r
1355  int32_t result;\r
1356 \r
1357  __ASM volatile ("smmla %0, %1, %2, %3" : "=r" (result): "r"  (op1), "r" (op2), "r" (op3) );\r
1358  return(result);\r
1359 }\r
1360 \r
1361 #endif /* (defined (__CORTEX_M) && (__CORTEX_M >= 4U)) */\r
1362 /*@} end of group CMSIS_SIMD_intrinsics */\r
1363 \r
1364 \r
1365 #if defined ( __GNUC__ )\r
1366 #pragma GCC diagnostic pop\r
1367 #endif\r
1368 \r
1369 #endif /* __CMSIS_GCC_H */\r