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