xref: /nrf52832-nimble/rt-thread/libcpu/c-sky/common/csi_instr.h (revision 104654410c56c573564690304ae786df310c91fc)
1*10465441SEvalZero /*
2*10465441SEvalZero  * Copyright (C) 2017 C-SKY Microsystems Co., Ltd. All rights reserved.
3*10465441SEvalZero  *
4*10465441SEvalZero  * Licensed under the Apache License, Version 2.0 (the "License");
5*10465441SEvalZero  * you may not use this file except in compliance with the License.
6*10465441SEvalZero  * You may obtain a copy of the License at
7*10465441SEvalZero  *
8*10465441SEvalZero  *   http://www.apache.org/licenses/LICENSE-2.0
9*10465441SEvalZero  *
10*10465441SEvalZero  * Unless required by applicable law or agreed to in writing, software
11*10465441SEvalZero  * distributed under the License is distributed on an "AS IS" BASIS,
12*10465441SEvalZero  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*10465441SEvalZero  * See the License for the specific language governing permissions and
14*10465441SEvalZero  * limitations under the License.
15*10465441SEvalZero  */
16*10465441SEvalZero 
17*10465441SEvalZero /******************************************************************************
18*10465441SEvalZero  * @file     csi_instr.h
19*10465441SEvalZero  * @brief    CSI Header File for instruct.
20*10465441SEvalZero  * @version  V1.0
21*10465441SEvalZero  * @date     02. June 2017
22*10465441SEvalZero  ******************************************************************************/
23*10465441SEvalZero 
24*10465441SEvalZero #ifndef _CSI_INSTR_H_
25*10465441SEvalZero #define _CSI_INSTR_H_
26*10465441SEvalZero 
27*10465441SEvalZero 
28*10465441SEvalZero #define __CSI_GCC_OUT_REG(r) "=r" (r)
29*10465441SEvalZero #define __CSI_GCC_USE_REG(r) "r" (r)
30*10465441SEvalZero 
31*10465441SEvalZero /**
32*10465441SEvalZero   \brief   No Operation
33*10465441SEvalZero   \details No Operation does nothing. This instruction can be used for code alignment purposes.
34*10465441SEvalZero  */
__NOP(void)35*10465441SEvalZero __ALWAYS_INLINE void __NOP(void)
36*10465441SEvalZero {
37*10465441SEvalZero     __ASM volatile("nop");
38*10465441SEvalZero }
39*10465441SEvalZero 
40*10465441SEvalZero 
41*10465441SEvalZero /**
42*10465441SEvalZero   \brief   Wait For Interrupt
43*10465441SEvalZero   \details Wait For Interrupt is a hint instruction that suspends execution until one of a number of events occurs.
44*10465441SEvalZero  */
__WFI(void)45*10465441SEvalZero __ALWAYS_INLINE void __WFI(void)
46*10465441SEvalZero {
47*10465441SEvalZero     __ASM volatile("wait");
48*10465441SEvalZero }
49*10465441SEvalZero 
50*10465441SEvalZero /**
51*10465441SEvalZero   \brief   Wait For Interrupt
52*10465441SEvalZero   \details Wait For Interrupt is a hint instruction that suspends execution until one interrupt occurs.
53*10465441SEvalZero  */
__WAIT(void)54*10465441SEvalZero __ALWAYS_INLINE void __WAIT(void)
55*10465441SEvalZero {
56*10465441SEvalZero     __ASM volatile("wait");
57*10465441SEvalZero }
58*10465441SEvalZero 
59*10465441SEvalZero /**
60*10465441SEvalZero   \brief   Doze For Interrupt
61*10465441SEvalZero   \details Doze For Interrupt is a hint instruction that suspends execution until one interrupt occurs.
62*10465441SEvalZero  */
__DOZE(void)63*10465441SEvalZero __ALWAYS_INLINE void __DOZE(void)
64*10465441SEvalZero {
65*10465441SEvalZero     __ASM volatile("doze");
66*10465441SEvalZero }
67*10465441SEvalZero 
68*10465441SEvalZero /**
69*10465441SEvalZero   \brief   Stop For Interrupt
70*10465441SEvalZero   \details Stop For Interrupt is a hint instruction that suspends execution until one interrupt occurs.
71*10465441SEvalZero  */
__STOP(void)72*10465441SEvalZero __ALWAYS_INLINE void __STOP(void)
73*10465441SEvalZero {
74*10465441SEvalZero     __ASM volatile("stop");
75*10465441SEvalZero }
76*10465441SEvalZero 
77*10465441SEvalZero /**
78*10465441SEvalZero   \brief   Instruction Synchronization Barrier
79*10465441SEvalZero   \details Instruction Synchronization Barrier flushes the pipeline in the processor,
80*10465441SEvalZero            so that all instructions following the ISB are fetched from cache or memory,
81*10465441SEvalZero            after the instruction has been completed.
82*10465441SEvalZero  */
__ISB(void)83*10465441SEvalZero __ALWAYS_INLINE void __ISB(void)
84*10465441SEvalZero {
85*10465441SEvalZero     __ASM volatile("sync"::: "memory");
86*10465441SEvalZero }
87*10465441SEvalZero 
88*10465441SEvalZero 
89*10465441SEvalZero /**
90*10465441SEvalZero   \brief   Data Synchronization Barrier
91*10465441SEvalZero   \details Acts as a special kind of Data Memory Barrier.
92*10465441SEvalZero            It completes when all explicit memory accesses before this instruction complete.
93*10465441SEvalZero  */
__DSB(void)94*10465441SEvalZero __ALWAYS_INLINE void __DSB(void)
95*10465441SEvalZero {
96*10465441SEvalZero     __ASM volatile("sync"::: "memory");
97*10465441SEvalZero }
98*10465441SEvalZero 
99*10465441SEvalZero 
100*10465441SEvalZero /**
101*10465441SEvalZero   \brief   Data Memory Barrier
102*10465441SEvalZero   \details Ensures the apparent order of the explicit memory operations before
103*10465441SEvalZero            and after the instruction, without ensuring their completion.
104*10465441SEvalZero  */
__DMB(void)105*10465441SEvalZero __ALWAYS_INLINE void __DMB(void)
106*10465441SEvalZero {
107*10465441SEvalZero     __ASM volatile("sync"::: "memory");
108*10465441SEvalZero }
109*10465441SEvalZero 
110*10465441SEvalZero 
111*10465441SEvalZero /**
112*10465441SEvalZero   \brief   Reverse byte order (32 bit)
113*10465441SEvalZero   \details Reverses the byte order in integer value.
114*10465441SEvalZero   \param [in]    value  Value to reverse
115*10465441SEvalZero   \return               Reversed value
116*10465441SEvalZero  */
__REV(uint32_t value)117*10465441SEvalZero __ALWAYS_INLINE uint32_t __REV(uint32_t value)
118*10465441SEvalZero {
119*10465441SEvalZero     return __builtin_bswap32(value);
120*10465441SEvalZero }
121*10465441SEvalZero 
122*10465441SEvalZero 
123*10465441SEvalZero /**
124*10465441SEvalZero   \brief   Reverse byte order (16 bit)
125*10465441SEvalZero   \details Reverses the byte order in two unsigned short values.
126*10465441SEvalZero   \param [in]    value  Value to reverse
127*10465441SEvalZero   \return               Reversed value
128*10465441SEvalZero  */
__REV16(uint32_t value)129*10465441SEvalZero __ALWAYS_INLINE uint32_t __REV16(uint32_t value)
130*10465441SEvalZero {
131*10465441SEvalZero     uint32_t result;
132*10465441SEvalZero #if (__CK80X >= 2)
133*10465441SEvalZero     __ASM volatile("revh %0, %1" : __CSI_GCC_OUT_REG(result) : __CSI_GCC_USE_REG(value));
134*10465441SEvalZero #else
135*10465441SEvalZero     result = ((value & 0xFF000000) >> 8) | ((value & 0x00FF0000) << 8) |
136*10465441SEvalZero              ((value & 0x0000FF00) >> 8) | ((value & 0x000000FF) << 8);
137*10465441SEvalZero #endif
138*10465441SEvalZero     return (result);
139*10465441SEvalZero }
140*10465441SEvalZero 
141*10465441SEvalZero 
142*10465441SEvalZero /**
143*10465441SEvalZero   \brief   Reverse byte order in signed short value
144*10465441SEvalZero   \details Reverses the byte order in a signed short value with sign extension to integer.
145*10465441SEvalZero   \param [in]    value  Value to reverse
146*10465441SEvalZero   \return               Reversed value
147*10465441SEvalZero  */
__REVSH(int32_t value)148*10465441SEvalZero __ALWAYS_INLINE int32_t __REVSH(int32_t value)
149*10465441SEvalZero {
150*10465441SEvalZero     return (short)(((value & 0xFF00) >> 8) | ((value & 0x00FF) << 8));
151*10465441SEvalZero }
152*10465441SEvalZero 
153*10465441SEvalZero 
154*10465441SEvalZero /**
155*10465441SEvalZero   \brief   Rotate Right in unsigned value (32 bit)
156*10465441SEvalZero   \details Rotate Right (immediate) provides the value of the contents of a register rotated by a variable number of bits.
157*10465441SEvalZero   \param [in]    op1  Value to rotate
158*10465441SEvalZero   \param [in]    op2  Number of Bits to rotate
159*10465441SEvalZero   \return               Rotated value
160*10465441SEvalZero  */
__ROR(uint32_t op1,uint32_t op2)161*10465441SEvalZero __ALWAYS_INLINE uint32_t __ROR(uint32_t op1, uint32_t op2)
162*10465441SEvalZero {
163*10465441SEvalZero     return (op1 >> op2) | (op1 << (32U - op2));
164*10465441SEvalZero }
165*10465441SEvalZero 
166*10465441SEvalZero 
167*10465441SEvalZero /**
168*10465441SEvalZero   \brief   Breakpoint
169*10465441SEvalZero   \details Causes the processor to enter Debug state
170*10465441SEvalZero            Debug tools can use this to investigate system state when the instruction at a particular address is reached.
171*10465441SEvalZero  */
__BKPT()172*10465441SEvalZero __ALWAYS_INLINE void __BKPT()
173*10465441SEvalZero {
174*10465441SEvalZero     __ASM volatile("bkpt");
175*10465441SEvalZero }
176*10465441SEvalZero 
177*10465441SEvalZero /**
178*10465441SEvalZero   \brief   Reverse bit order of value
179*10465441SEvalZero   \details Reverses the bit order of the given value.
180*10465441SEvalZero   \param [in]    value  Value to reverse
181*10465441SEvalZero   \return               Reversed value
182*10465441SEvalZero  */
__RBIT(uint32_t value)183*10465441SEvalZero __ALWAYS_INLINE uint32_t __RBIT(uint32_t value)
184*10465441SEvalZero {
185*10465441SEvalZero     uint32_t result;
186*10465441SEvalZero 
187*10465441SEvalZero #if       (__CK80X >= 0x03U)
188*10465441SEvalZero     __ASM volatile("brev %0, %1" : "=r"(result) : "r"(value));
189*10465441SEvalZero #else
190*10465441SEvalZero     int32_t s = 4 /*sizeof(v)*/ * 8 - 1; /* extra shift needed at end */
191*10465441SEvalZero 
192*10465441SEvalZero     result = value;                      /* r will be reversed bits of v; first get LSB of v */
193*10465441SEvalZero 
194*10465441SEvalZero     for (value >>= 1U; value; value >>= 1U)
195*10465441SEvalZero     {
196*10465441SEvalZero         result <<= 1U;
197*10465441SEvalZero         result |= value & 1U;
198*10465441SEvalZero         s--;
199*10465441SEvalZero     }
200*10465441SEvalZero 
201*10465441SEvalZero     result <<= s;                        /* shift when v's highest bits are zero */
202*10465441SEvalZero #endif
203*10465441SEvalZero     return (result);
204*10465441SEvalZero }
205*10465441SEvalZero 
206*10465441SEvalZero 
207*10465441SEvalZero /**
208*10465441SEvalZero   \brief   Count leading zeros
209*10465441SEvalZero   \details Counts the number of leading zeros of a data value.
210*10465441SEvalZero   \param [in]  value  Value to count the leading zeros
211*10465441SEvalZero   \return             number of leading zeros in value
212*10465441SEvalZero  */
213*10465441SEvalZero #define __CLZ             __builtin_clz
214*10465441SEvalZero /**
215*10465441SEvalZero   \details This function saturates a signed value.
216*10465441SEvalZero   \param [in]    x   Value to be saturated
217*10465441SEvalZero   \param [in]    y   Bit position to saturate to [1..32]
218*10465441SEvalZero   \return            Saturated value.
219*10465441SEvalZero  */
__SSAT(int32_t x,uint32_t y)220*10465441SEvalZero __ALWAYS_INLINE int32_t __SSAT(int32_t x, uint32_t y)
221*10465441SEvalZero {
222*10465441SEvalZero     int32_t posMax, negMin;
223*10465441SEvalZero     uint32_t i;
224*10465441SEvalZero 
225*10465441SEvalZero     posMax = 1;
226*10465441SEvalZero 
227*10465441SEvalZero     for (i = 0; i < (y - 1); i++)
228*10465441SEvalZero     {
229*10465441SEvalZero         posMax = posMax * 2;
230*10465441SEvalZero     }
231*10465441SEvalZero 
232*10465441SEvalZero     if (x > 0)
233*10465441SEvalZero     {
234*10465441SEvalZero         posMax = (posMax - 1);
235*10465441SEvalZero 
236*10465441SEvalZero         if (x > posMax)
237*10465441SEvalZero         {
238*10465441SEvalZero             x = posMax;
239*10465441SEvalZero         }
240*10465441SEvalZero 
241*10465441SEvalZero //    x &= (posMax * 2 + 1);
242*10465441SEvalZero     }
243*10465441SEvalZero     else
244*10465441SEvalZero     {
245*10465441SEvalZero         negMin = -posMax;
246*10465441SEvalZero 
247*10465441SEvalZero         if (x < negMin)
248*10465441SEvalZero         {
249*10465441SEvalZero             x = negMin;
250*10465441SEvalZero         }
251*10465441SEvalZero 
252*10465441SEvalZero //    x &= (posMax * 2 - 1);
253*10465441SEvalZero     }
254*10465441SEvalZero 
255*10465441SEvalZero     return (x);
256*10465441SEvalZero }
257*10465441SEvalZero 
258*10465441SEvalZero /**
259*10465441SEvalZero   \brief   Unsigned Saturate
260*10465441SEvalZero   \details Saturates an unsigned value.
261*10465441SEvalZero   \param [in]  value  Value to be saturated
262*10465441SEvalZero   \param [in]    sat  Bit position to saturate to (0..31)
263*10465441SEvalZero   \return             Saturated value
264*10465441SEvalZero  */
__USAT(uint32_t value,uint32_t sat)265*10465441SEvalZero __ALWAYS_INLINE uint32_t __USAT(uint32_t value, uint32_t sat)
266*10465441SEvalZero {
267*10465441SEvalZero     uint32_t result;
268*10465441SEvalZero 
269*10465441SEvalZero     if ((((0xFFFFFFFF >> sat) << sat) & value) != 0)
270*10465441SEvalZero     {
271*10465441SEvalZero         result = 0xFFFFFFFF >> (32 - sat);
272*10465441SEvalZero     }
273*10465441SEvalZero     else
274*10465441SEvalZero     {
275*10465441SEvalZero         result = value;
276*10465441SEvalZero     }
277*10465441SEvalZero 
278*10465441SEvalZero     return (result);
279*10465441SEvalZero }
280*10465441SEvalZero 
281*10465441SEvalZero /**
282*10465441SEvalZero   \brief   Unsigned Saturate for internal use
283*10465441SEvalZero   \details Saturates an unsigned value, should not call directly.
284*10465441SEvalZero   \param [in]  value  Value to be saturated
285*10465441SEvalZero   \param [in]    sat  Bit position to saturate to (0..31)
286*10465441SEvalZero   \return             Saturated value
287*10465441SEvalZero  */
__IUSAT(uint32_t value,uint32_t sat)288*10465441SEvalZero __ALWAYS_INLINE uint32_t __IUSAT(uint32_t value, uint32_t sat)
289*10465441SEvalZero {
290*10465441SEvalZero     uint32_t result;
291*10465441SEvalZero 
292*10465441SEvalZero     if (value & 0x80000000)   /* only overflow set bit-31 */
293*10465441SEvalZero     {
294*10465441SEvalZero         result = 0;
295*10465441SEvalZero     }
296*10465441SEvalZero     else if ((((0xFFFFFFFF >> sat) << sat) & value) != 0)
297*10465441SEvalZero     {
298*10465441SEvalZero         result = 0xFFFFFFFF >> (32 - sat);
299*10465441SEvalZero     }
300*10465441SEvalZero     else
301*10465441SEvalZero     {
302*10465441SEvalZero         result = value;
303*10465441SEvalZero     }
304*10465441SEvalZero 
305*10465441SEvalZero     return (result);
306*10465441SEvalZero }
307*10465441SEvalZero 
308*10465441SEvalZero /**
309*10465441SEvalZero   \brief   Rotate Right with Extend
310*10465441SEvalZero   \details This function moves each bit of a bitstring right by one bit.
311*10465441SEvalZero            The carry input is shifted in at the left end of the bitstring.
312*10465441SEvalZero   \note    carry input will always 0.
313*10465441SEvalZero   \param [in]    op1  Value to rotate
314*10465441SEvalZero   \return               Rotated value
315*10465441SEvalZero  */
__RRX(uint32_t op1)316*10465441SEvalZero __ALWAYS_INLINE uint32_t __RRX(uint32_t op1)
317*10465441SEvalZero {
318*10465441SEvalZero #if (__CK80X >= 2)
319*10465441SEvalZero     uint32_t res = 0;
320*10465441SEvalZero     __ASM volatile("bgeni    t0, 31\n\t"
321*10465441SEvalZero                    "lsri     %0, 1\n\t"
322*10465441SEvalZero                    "movt     %1, t0\n\t"
323*10465441SEvalZero                    "or       %1, %1, %0\n\t"
324*10465441SEvalZero                    : "=r"(op1), "=r"(res): "0"(op1), "1"(res): "t0");
325*10465441SEvalZero     return res;
326*10465441SEvalZero #else
327*10465441SEvalZero     uint32_t res = 0;
328*10465441SEvalZero     __ASM volatile("movi     r7, 0\n\t"
329*10465441SEvalZero                    "bseti    r7, 31\n\t"
330*10465441SEvalZero                    "lsri     %0, 1\n\t"
331*10465441SEvalZero                    "bf       1f\n\t"
332*10465441SEvalZero                    "mov     %1, r7\n\t"
333*10465441SEvalZero                    "1:\n\t"
334*10465441SEvalZero                    "or       %1, %1, %0\n\t"
335*10465441SEvalZero                    : "=r"(op1), "=r"(res): "0"(op1), "1"(res): "r7");
336*10465441SEvalZero     return res;
337*10465441SEvalZero #endif
338*10465441SEvalZero }
339*10465441SEvalZero 
340*10465441SEvalZero /**
341*10465441SEvalZero   \brief   LDRT Unprivileged (8 bit)
342*10465441SEvalZero   \details Executes a Unprivileged LDRT instruction for 8 bit value.
343*10465441SEvalZero   \param [in]    addr  Pointer to location
344*10465441SEvalZero   \return             value of type uint8_t at (*ptr)
345*10465441SEvalZero  */
__LDRBT(volatile uint8_t * addr)346*10465441SEvalZero __ALWAYS_INLINE uint8_t __LDRBT(volatile uint8_t *addr)
347*10465441SEvalZero {
348*10465441SEvalZero     uint32_t result;
349*10465441SEvalZero //#warning "__LDRBT"
350*10465441SEvalZero     __ASM volatile("ldb %0, (%1, 0)" : "=r"(result) : "r"(addr));
351*10465441SEvalZero     return ((uint8_t) result);    /* Add explicit type cast here */
352*10465441SEvalZero }
353*10465441SEvalZero 
354*10465441SEvalZero 
355*10465441SEvalZero /**
356*10465441SEvalZero   \brief   LDRT Unprivileged (16 bit)
357*10465441SEvalZero   \details Executes a Unprivileged LDRT instruction for 16 bit values.
358*10465441SEvalZero   \param [in]    addr  Pointer to location
359*10465441SEvalZero   \return        value of type uint16_t at (*ptr)
360*10465441SEvalZero  */
__LDRHT(volatile uint16_t * addr)361*10465441SEvalZero __ALWAYS_INLINE uint16_t __LDRHT(volatile uint16_t *addr)
362*10465441SEvalZero {
363*10465441SEvalZero     uint32_t result;
364*10465441SEvalZero 
365*10465441SEvalZero //#warning "__LDRHT"
366*10465441SEvalZero     __ASM volatile("ldh %0, (%1, 0)" : "=r"(result) : "r"(addr));
367*10465441SEvalZero     return ((uint16_t) result);    /* Add explicit type cast here */
368*10465441SEvalZero }
369*10465441SEvalZero 
370*10465441SEvalZero 
371*10465441SEvalZero /**
372*10465441SEvalZero   \brief   LDRT Unprivileged (32 bit)
373*10465441SEvalZero   \details Executes a Unprivileged LDRT instruction for 32 bit values.
374*10465441SEvalZero   \param [in]    addr  Pointer to location
375*10465441SEvalZero   \return        value of type uint32_t at (*ptr)
376*10465441SEvalZero  */
__LDRT(volatile uint32_t * addr)377*10465441SEvalZero __ALWAYS_INLINE uint32_t __LDRT(volatile uint32_t *addr)
378*10465441SEvalZero {
379*10465441SEvalZero     uint32_t result;
380*10465441SEvalZero 
381*10465441SEvalZero //#warning "__LDRT"
382*10465441SEvalZero     __ASM volatile("ldw %0, (%1, 0)" : "=r"(result) : "r"(addr));
383*10465441SEvalZero     return (result);
384*10465441SEvalZero }
385*10465441SEvalZero 
386*10465441SEvalZero 
387*10465441SEvalZero /**
388*10465441SEvalZero   \brief   STRT Unprivileged (8 bit)
389*10465441SEvalZero   \details Executes a Unprivileged STRT instruction for 8 bit values.
390*10465441SEvalZero   \param [in]  value  Value to store
391*10465441SEvalZero   \param [in]    addr  Pointer to location
392*10465441SEvalZero  */
__STRBT(uint8_t value,volatile uint8_t * addr)393*10465441SEvalZero __ALWAYS_INLINE void __STRBT(uint8_t value, volatile uint8_t *addr)
394*10465441SEvalZero {
395*10465441SEvalZero //#warning "__STRBT"
396*10465441SEvalZero     __ASM volatile("stb %1, (%0, 0)" :: "r"(addr), "r"((uint32_t)value) : "memory");
397*10465441SEvalZero }
398*10465441SEvalZero 
399*10465441SEvalZero 
400*10465441SEvalZero /**
401*10465441SEvalZero   \brief   STRT Unprivileged (16 bit)
402*10465441SEvalZero   \details Executes a Unprivileged STRT instruction for 16 bit values.
403*10465441SEvalZero   \param [in]  value  Value to store
404*10465441SEvalZero   \param [in]    addr  Pointer to location
405*10465441SEvalZero  */
__STRHT(uint16_t value,volatile uint16_t * addr)406*10465441SEvalZero __ALWAYS_INLINE void __STRHT(uint16_t value, volatile uint16_t *addr)
407*10465441SEvalZero {
408*10465441SEvalZero //#warning "__STRHT"
409*10465441SEvalZero     __ASM volatile("sth %1, (%0, 0)" :: "r"(addr), "r"((uint32_t)value) : "memory");
410*10465441SEvalZero }
411*10465441SEvalZero 
412*10465441SEvalZero 
413*10465441SEvalZero /**
414*10465441SEvalZero   \brief   STRT Unprivileged (32 bit)
415*10465441SEvalZero   \details Executes a Unprivileged STRT instruction for 32 bit values.
416*10465441SEvalZero   \param [in]  value  Value to store
417*10465441SEvalZero   \param [in]    addr  Pointer to location
418*10465441SEvalZero  */
__STRT(uint32_t value,volatile uint32_t * addr)419*10465441SEvalZero __ALWAYS_INLINE void __STRT(uint32_t value, volatile uint32_t *addr)
420*10465441SEvalZero {
421*10465441SEvalZero //#warning "__STRT"
422*10465441SEvalZero     __ASM volatile("stw %1, (%0, 0)" :: "r"(addr), "r"(value) : "memory");
423*10465441SEvalZero }
424*10465441SEvalZero 
425*10465441SEvalZero /*@}*/ /* end of group CSI_Core_InstructionInterface */
426*10465441SEvalZero 
427*10465441SEvalZero 
428*10465441SEvalZero /* ##########################  FPU functions  #################################### */
429*10465441SEvalZero 
430*10465441SEvalZero /**
431*10465441SEvalZero   \brief   get FPU type
432*10465441SEvalZero   \details returns the FPU type, always 0.
433*10465441SEvalZero   \returns
434*10465441SEvalZero    - \b  0: No FPU
435*10465441SEvalZero    - \b  1: Single precision FPU
436*10465441SEvalZero    - \b  2: Double + Single precision FPU
437*10465441SEvalZero  */
__get_FPUType(void)438*10465441SEvalZero __ALWAYS_INLINE uint32_t __get_FPUType(void)
439*10465441SEvalZero {
440*10465441SEvalZero     uint32_t result;
441*10465441SEvalZero 
442*10465441SEvalZero     __ASM volatile("mfcr %0, cr<13, 0>" : "=r"(result));
443*10465441SEvalZero     return 0;
444*10465441SEvalZero }
445*10465441SEvalZero 
446*10465441SEvalZero 
447*10465441SEvalZero #endif /* _CSI_INSTR_H_ */
448