iLLD_TC27xD  1.0
IfxCpu_IntrinsicsTasking.h
Go to the documentation of this file.
1 /**
2  * \file IfxCpu_IntrinsicsTasking.h
3  * \version iLLD_1_0_0_11_0
4  * \copyright Copyright (c) 2012 Infineon Technologies AG. All rights reserved.
5  *
6  *
7  *
8  * IMPORTANT NOTICE
9  *
10  *
11  * Infineon Technologies AG (Infineon) is supplying this file for use
12  * exclusively with Infineon's microcontroller products. This file can be freely
13  * distributed within development tools that are supporting such microcontroller
14  * products.
15  *
16  * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED
17  * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF
18  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE.
19  * INFINEON SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL,
20  * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER.
21  *
22  * \defgroup IfxLld_Cpu_Intrinsics_Tasking Intrinsics for TASKING compiler
23  * \ingroup IfxLld_Cpu_Intrinsics
24  *
25  */
26 #ifndef IFXCPU_INTRINSICSTASKING_H
27 #define IFXCPU_INTRINSICSTASKING_H
28 /******************************************************************************/
29 #include "Ifx_Types.h"
30 /******************************************************************************/
31 /* *INDENT-OFF* */
32 
33 /** Function call without return
34  */
35 #define __non_return_call(fun) __asm__ volatile ("\tji %0"::"a"(fun))
36 
37 /** Jump and link
38  */
39 IFX_INLINE void __jump_and_link(void (*fun)(void))
40 {
41  __asm__ volatile ("jli %0"::"a"(fun));
42 }
43 
44 /** \defgroup IfxLld_Cpu_Intrinsics_Tasking_any_type Cross type arithmetic operation
45  *
46  * Macro compatible with float, fix point, signed integer and unsigned integer
47  *
48  * \ingroup IfxLld_Cpu_Intrinsics_Tasking
49  * \{
50  */
51 #define __minX(X,Y) ( ((X) < (Y)) ? (X) : (Y) )
52 #define __maxX(X,Y) ( ((X) > (Y)) ? (X) : (Y) )
53 #define __saturateX(X,Min,Max) ( __minX(__maxX(X, Min), Max) )
54 #define __checkrangeX(X,Min,Max) (((X) >= (Min)) && ((X) <= (Max)))
55 /** \} */
56 
57 /** \defgroup IfxLld_Cpu_Intrinsics_Tasking_singed_integer Signed integer operation
58  * \ingroup IfxLld_Cpu_Intrinsics_Tasking
59  * \{
60  */
61 #define __saturate(X,Min,Max) ( __min(__max(X, Min), Max) )
62 /** \} */
63 
64 /** \defgroup IfxLld_Cpu_Intrinsics_Tasking_unsinged_integer Unsigned integer operation
65  * \ingroup IfxLld_Cpu_Intrinsics_Tasking
66  * \{
67  */
68 #define __saturateu(X,Min,Max) ( __minu(__maxu(X, Min), Max) )
69 /** \} */
70 
71 /** \defgroup IfxLld_Cpu_Intrinsics_Tasking_float Floating point operation
72  * \ingroup IfxLld_Cpu_Intrinsics_Tasking
73  * \{
74  */
75 #define __checkrange(X,Min,Max) (((X) >= (Min)) && ((X) <= (Max)))
76 
77 #define __sqrf(X) ((X) * (X))
78 #define __sqrtf(X) sqrtf(X)
79 
80 #define __roundf(X) ((((X) - (int)(X)) > 0.5) ? (1 + (int)(X)) : ((int)(X)))
81 #define __absf(X) ( ((X) < 0.0) ? -(X) : (X) )
82 #define __minf(X,Y) ( ((X) < (Y)) ? (X) : (Y) )
83 #define __maxf(X,Y) ( ((X) > (Y)) ? (X) : (Y) )
84 #define __saturatef(X,Min,Max) ( __minf(__maxf(X, Min), Max) )
85 #define __checkrangef(X,Min,Max) (((X) >= (Min)) && ((X) <= (Max)))
86 
87 #define __abs_stdreal(X) ( ((X) > 0.0) ? (X) : -(X) )
88 #define __min_stdreal(X,Y) ( ((X) < (Y)) ? (X) : (Y) )
89 #define __max_stdreal(X,Y) ( ((X) > (Y)) ? (X) : (Y) )
90 #define __saturate_stdreal(X,Min,Max) ( __min_stdreal(__max_stdreal(X, Min), Max) )
91 
92 #define __neqf(X,Y) ( ((X) > (Y)) || ((X) < (Y)) ) /**< X != Y */
93 #define __leqf(X,Y) ( !((X) > (Y)) ) /**< X <= Y */
94 #define __geqf(X,Y) ( !((X) < (Y)) ) /**< X >= Y */
95 /** \} */
96 /** \defgroup IfxLld_Cpu_Intrinsics_Tasking_fractional Fractional Arithmetic Support
97  The next table provides an overview of intrinsic functions to convert fractional values. Note that the
98  TASKING VX-toolset C compiler for TriCore fully supports the fractional type so normally you should not
99  need these intrinsic functions (except for __mulfractlong). For compatibility reasons the TASKING C
100  compiler does support these functions.
101  * \ingroup IfxLld_Cpu_Intrinsics_Tasking
102  * \{
103  */
104 #define __fract_to_float(value) ((float)(value))
105 
106 #define __mulfractlong __mulfractlong
107 
108 #define __mulfractfract(fractvalue1,fractvalue2) ((fractvalue1)*(fractvalue2))
109 
110 /** \} */
111 
112 /** \defgroup IfxLld_Cpu_Intrinsics_Tasking_insert Insert / Extract Bit-fields and Bits
113  * \ingroup IfxLld_Cpu_Intrinsics_Tasking
114  * \{
115  */
116 
117 #define __extru(a, p, w) __extru(a,p,w)
118 
119 #define __extr(a, p, w) __extr(a,p,w)
120 
121 #define __imaskldmst(a, v, b, p) __imaskldmst((int*)a, v, b, p)
122 
123 #define __insert(a,b,p,w) __insert(a,b,p,w)
124 
125 /** \} */
126 
127 /** \defgroup IfxLld_Cpu_Intrinsics_Tasking_interrupt_handling Interrupt Handling
128  The next table provides an overview of the intrinsic functions to read or set interrupt handling.
129  * \ingroup IfxLld_Cpu_Intrinsics_Tasking
130  * \{
131  */
132 #define __disable_and_save __disable_and_save
133 
134 #define __restore __restore
135 
136 /** \} */
137 
138 /** \defgroup IfxLld_Cpu_Intrinsics_Tasking_miscellaneous Miscellaneous Intrinsic Functions
139  * \ingroup IfxLld_Cpu_Intrinsics_Tasking
140  * \{
141  */
142 
143 /** \} */
144 
145 /** \defgroup IfxLld_Cpu_Intrinsics_Tasking_packed Packed Data Type Support
146  The next table provides an overview of the intrinsic functions for initialization of packed data type.
147  * \ingroup IfxLld_Cpu_Intrinsics_Tasking
148  * \{
149  */
150 
151 /** \} */
152 
153 /** \defgroup IfxLld_Cpu_Intrinsics_Tasking_register Register Handling
154  The next table provides an overview of the intrinsic functions that you can use to access control registers.
155  * \ingroup IfxLld_Cpu_Intrinsics_Tasking
156  * \{
157  */
158 #define __mtcr_no_isync(reg, val) \
159  __asm("mtcr %0,%1"::"i"(reg),"d"(val));
160 
161 /** \} */
162 
163 /** \defgroup IfxLld_Cpu_Intrinsics_Tasking_saturation Saturation Arithmetic Support
164  These intrinsics support saturation arithmetic
165  * \ingroup IfxLld_Cpu_Intrinsics_Tasking
166  * \{
167  */
168 
169 #define __adds(a,b) ((__sat int)(a)+(__sat int)(b))
170 
171 #define __addsu(a,b) ((__sat uint32)(a)+(__sat uint32)(b))
172 
173 #define __subs(a,b) ((__sat int)(a)-(__sat int)(b))
174 
175 #define __subsu(a,b) ((__sat uint32 )(a)-(__sat uint32 )(b))
176 
177 /** \} */
178 
179 /** \defgroup IfxLld_Cpu_Intrinsics_Tasking_single_assembly Insert Single Assembly Instruction
180  The next table provides an overview of the intrinsic functions that you can use to insert a single assembly
181  instruction.You can also use inline assembly but these intrinsics provide a shorthand for frequently used
182  assembly instructions.
183  * \ingroup IfxLld_Cpu_Intrinsics_Tasking
184  * \{
185  */
186 
187 IFX_INLINE void __nops(void* cnt)
188 {
189  __asm("nop16 \n\t"
190  "loop %0,*-2"
191  ::"a"(((char*)cnt) - 1));
192 }
193 
194 #define NOP(n) __asm(".DUP " #n "\n\tnop16\n\t.ENDM\n")
195 
196 #if CPU_NO_LDMST
197 IFX_INLINE void __ldmstC(volatile void *addr, uint32 mask, uint32 data)
198 {
199  *(volatile uint32 *)addr = (*(volatile uint32 *)addr & ~mask) | (mask & data);
200 }
201 
202 #define __ldmst(a,b,c) __ldmstC(a,b,c)
203 #else
204 
205 IFX_INLINE void __ldmstAsm(volatile void *addr, uint32 mask, uint32 data)
206 {
207  __asm("\tmov d3, %1 \n"
208  "\tmov d2, %2 \n"
209  "\tldmst [%0],e2"
210  ::"a"(addr), "d"(mask), "d"(data):"d2", "d3");
211 
212 }
213 
214 #define __ldmst(addr, mask, data) __ldmstAsm(addr, mask, data)
215 #endif
216 
218 { //__mtcr (CPU_CCTRL, 0);
219  __asm(
220  " mov d0,#0\n"
221  " mtcr #0xFC00,d0\n"
222  " isync\n"
223  :::"d0");
224 }
225 
226 /** \} */
227 
228 /* FIXME use inline instead of #define */
229 /* FIXME is it really required to have #define __setareg(areg,val) ___setareg(areg,val) or can __setareg() implemented directly */
230 #define ___setareg(areg,val) \
231  { __asm (" movh.a\t "#areg",#@his("#val")\n lea\t "#areg",["#areg"]@los("#val")"); }
232 #define __setareg(areg,val) ___setareg(areg,val)
233 
234 /** \brief This function is a implementation of a binary semaphore using compare and swap instruction
235  * \param address address of resource.
236  * \param value This variable is updated with status of address
237  * \param condition if the value of address matches with the value of condition, then swap of value & address occurs.
238  *
239  */
240 #define __cmpAndSwap(address,value,condition) \
241  __cmpswapw((address), ((unsigned long)value), (condition) )
242 
243 /** \brief Convert a fixpoint value to float32
244  *
245  * This function converts a value from a fixpoint format to a float32 format.
246  *
247  *
248  * \param value value to be converted.
249  * \param shift position of the fix point. Range = [-256, 255] => (Qx.y format where x = shift+1).
250  *
251  * \return Returns the converted value in the float32 format.
252  *
253  */
255 {
256  float32 result;
257 
258  __asm(
259  " q31tof\t%0, %1, %2 \n"
260  : "=d" (result)
261  : "d" (value), "d" (shift));
262  return result;
263 }
264 
265 IFX_INLINE void* __getA11(void)
266 {
267  uint32 *res;
268  __asm__ volatile ("mov.aa %0, a11": "=a" (res) : :"a11");
269  return res;
270 }
271 
272 IFX_INLINE void __setStackPointer(void *stackAddr)
273 {
274  __asm__ volatile ("mov.aa a10, %0": : "a" (stackAddr) :"a10");
275 }
276 /* *INDENT-ON* */
277 /******************************************************************************/
278 #endif /* IFXCPU_INTRINSICSTASKING_H */