iLLD_TC27xD  1.0
IfxCpu_IntrinsicsDcc.h
Go to the documentation of this file.
1 /**
2  * \file IfxCpu_IntrinsicsDcc.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_Dcc intrinsics for DCC compiler
23  * \ingroup IfxLld_Cpu_Intrinsics
24  *
25  */
26 #ifndef IFXCPU_INTRINSICSDCC_H
27 #define IFXCPU_INTRINSICSDCC_H
28 /******************************************************************************/
29 #include "Ifx_Types.h"
30 
31 /******************************************************************************/
32 /* *INDENT-OFF* */
33 /** \defgroup IfxLld_Cpu_Intrinsics_Dcc_min_smax Minimum and Maximum of (Short) Integers
34  These intrinsic functions return the minimum or maximum of a signed integer, unsigned integer or short integer.
35  * \ingroup IfxLld_Cpu_Intrinsics_Dcc
36  * \{
37  */
38 
39 /** Function call without return
40  */
41 asm volatile void __non_return_call(void (*fun)(void))
42 {
43 % reg fun
44  ji fun
45 }
46 
47 /** Jump and link
48  */
49 asm volatile void __jump_and_link(void (*fun)(void))
50 {
51 % reg fun
52  jli fun
53 }
54 
55 /** \} */
56 
57 /** \defgroup IfxLld_Cpu_Intrinsics_Dcc_any_type Cross type arithmetic operation
58  *
59  * Macro compatible with float, fix point, signed integer and unsigned integer
60  *
61  * \ingroup IfxLld_Cpu_Intrinsics_Dcc
62  * \{
63  */
64 #define __minX(X,Y) ( ((X) < (Y)) ? (X) : (Y) )
65 #define __maxX(X,Y) ( ((X) > (Y)) ? (X) : (Y) )
66 #define __saturateX(X,Min,Max) ( __minX(__maxX(X, Min), Max) )
67 #define __checkrangeX(X,Min,Max) (((X) >= (Min)) && ((X) <= (Max)))
68 
69 /** Return minimum of two integers
70  */
71 extern sint32 __min( sint32, sint32) __attribute__((intrinsic_pseudo(3, "min") ));
72 
73 /** Return minimum of two short integers
74  */
75 extern sint32 __mins( sint32, sint32) __attribute__((intrinsic_function(0x10b, 0, "min.h") ));
76 
77 /** Return minimum of two unsigned integers
78  */
79 extern uint32 __minu( uint32, uint32) __attribute__((intrinsic_pseudo(3, "min.u") ));
80 
81 /** Return maximum of two integers
82  */
83 extern sint32 __max( sint32, sint32) __attribute__((intrinsic_pseudo(3, "max") ));
84 
85 /** Return maximum of two short integers
86  */
87 extern uint32 __maxs( uint32, uint32) __attribute__((intrinsic_function(0x10b, 0, "max.h") ));
88 
89 /** Return maximum of two unsigned integers
90  */
91 extern uint32 __maxu( uint32, uint32) __attribute__((intrinsic_pseudo(3, "max.u") ));
92 
93 /** \} */
94 
95 /** \defgroup intrinsicstasking_float Floating point operation
96  * \ingroup IfxLld_Cpu_Intrinsics_Dcc
97  * \{
98  */
99 #define __saturate(X,Min,Max) ( __minf(__maxf(X, Min), Max) )
100 
101 #define __sqrf(X) ((X) * (X))
102 #define __sqrtf(X) sqrtf(X)
103 #define __checkrange(X,Min,Max) (((X) >= (Min)) && ((X) <= (Max)))
104 
105 #define __roundf(X) ((((X) - (sint32)(X)) > 0.5) ? (1 + (sint32)(X)) : ((sint32)(X)))
106 #define __absf(X) ( ((X) < 0.0) ? -(X) : (X) )
107 #define __minf(X,Y) ( ((X) < (Y)) ? (X) : (Y) )
108 #define __maxf(X,Y) ( ((X) > (Y)) ? (X) : (Y) )
109 #define __saturatef(X,Min,Max) ( __minf(__maxf(X, Min), Max) )
110 #define __checkrangef(X,Min,Max) (((X) >= (Min)) && ((X) <= (Max)))
111 
112 #define __abs_stdreal(X) ( ((X) > 0.0) ? (X) : -(X) )
113 #define __min_stdreal(X,Y) ( ((X) < (Y)) ? (X) : (Y) )
114 #define __max_stdreal(X,Y) ( ((X) > (Y)) ? (X) : (Y) )
115 #define __saturate_stdreal(X,Min,Max) ( __min_stdreal(__max_stdreal(X, Min), Max) )
116 
117 #define __neqf(X,Y) ( ((X) > (Y)) || ((X) < (Y)) ) /**< X != Y */
118 #define __leqf(X,Y) ( !((X) > (Y)) ) /**< X <= Y */
119 #define __geqf(X,Y) ( !((X) < (Y)) ) /**< X >= Y */
120 /** \} */
121 
122 /** \defgroup IfxLld_Cpu_Intrinsics_Dcc_fractional Fractional Arithmetic Support
123  The next table provides an overview of intrinsic functions to convert fractional values. Note that the
124  TASKING VX-toolset C compiler for TriCore fully supports the fractional type so normally you should not
125  need these intrinsic functions (except for __mulfractlong). For compatibility reasons the TASKING C
126  compiler does support these functions.
127  * \ingroup IfxLld_Cpu_Intrinsics_Dcc
128  * \{
129  */
130 
131 /** Count the consecutive number of bits that have the same value as bit 15 of an sfract
132  */
133 asm short __clssf(sfract a)
134 {
135 % reg a
136 ! "%d2"
137  cls %d2, a
138 }
139 
140 /** Convert float to fract
141  */
143 {
144 % reg a
145 ! "%d2"
146  ftoq31 %d2, a, 0
147 }
148 
149 /** \brief Convert fract to float
150  */
152 {
153 % reg a
154 ! "%d2", "%d3"
155  mov %d3, 0
156  q31tof %d2, a, %d3
157 }
158 
159 /** Convert __laccum to fract
160  */
162 {
163 % reg a
164 ! "%d2"
165  dextr %d2, a!H, a!L, 17
166 }
167 
168 /** Multiply-add with rounding. Returns the rounded result of ( a + b * c )
169  */
170 #ifdef INTRINSIC_WORKAROUND
171 extern sfract __mac_r_sf(sfract a, sfract b, sfract c);
172 #else
174 {
175 % reg a, b, c
176 ! "%d2"
177  maddrs.q %d2, a, bU, cU, 1
178 }
179 #endif
180 
181 /** Multiply-add sfract. Returns ( a + b * c )
182  */
183 #ifdef INTRINSIC_WORKAROUND
184 extern sfract __mac_sf(sfract a, sfract b, sfract c);
185 #else
187 {
188 % reg a, b, c
189 ! "%d2"
190  madds.q %d2, a, bU, cU, 1
191 }
192 #endif
193 
194 /** Integer part of the multiplication of a fract and a fract
195  */
197 {
198 % reg a, b
199 ! "%d2"
200  mul.q %d2, a, b, 1
201 }
202 
203 /** Integer part of the multiplication of a fract and a long
204  */
205 asm long __mulfractlong(fract a, long b)
206 {
207 % reg a, b
208 ! "%d2"
209  mul.q %d2, a, b, 1
210 }
211 
212 /** Convert fract to sfract
213  */
215 {
216 % reg a
217 ! "%d2"
218  mov.u %d2, 0x8000
219  adds %d2, a
220  insert %d2, %d0, 0, 0, 0x10
221 }
222 
223 /** Convert signed short to sfract
224  */
226 {
227 % reg a
228 ! "%d2"
229  sh %d2, a, 16
230 }
231 
232 /** Convert sfract to signed short
233  */
235 {
236 % reg a
237  sh %d2, a, -16
238 }
239 
240 /** Convert sfract to uint16
241  */
243 {
244 % reg a
245 ! "%d2"
246  sh %d2, a, -16
247 }
248 
249 /** Left/right shift of an __laccum
250  */
251 asm laccum __shaaccum(laccum a, sint32 b)
252 {
253 % lab L0, L1; reg a, b
254 ! "%d2", "%d3"
255  jge b, 0, L0
256  sha %d3, a!L, b
257  rsub b, b, 0
258  dextr %d2, a!H, a!L, b
259  j L1
260 L0:
261  dextr %d2, a!H, a!L, b
262  sha %d2, a!L, b
263 L1:
264 }
265 
266 /** Left/right shift of an fract
267  */
268 #ifdef INTRINSIC_WORKAROUND
269 extern fract __shafracts(fract a, sint32 b);
270 #else
271 asm fract __shafracts(fract a, sint32 b)
272 {
273 % reg a, b
274 ! "%d2"
275  shas %d2, a, b
276 }
277 #endif
278 
279 /** Left/right shift of an sfract
280  */
281 #ifdef INTRINSIC_WORKAROUND
282 extern sfract __shasfracts(sfract a, sint32 b);
283 #else
284 asm sfract __shasfracts(sfract a, sint32 b)
285 {
286 % reg a, b
287 ! "%d2"
288  shas %d2, a, b
289 }
290 #endif
291 
292 /** Convert uint16 to sfract
293  */
295 {
296 % reg a
297 ! "%d2"
298  sh %d2, a, 16
299 }
300 
301 /** \} */
302 
303 /** \defgroup IfxLld_Cpu_Intrinsics_Dcc_insert Insert / Extract Bit-fields and Bits
304  * \ingroup IfxLld_Cpu_Intrinsics_Dcc
305  * \{
306  */
307 
308 /** Extract a bit-field (bit pos to bit pos+width) from value
309  */
310 extern sint32 __extr( sint32, uint32, const uint32) __attribute__((intrinsic_function(0x108, 0, "extr") ));
311 
312 /** Same as __extr() but return bit-field as unsigned integer
313  */
314 extern uint32 __extru( uint32, uint32, const uint32) __attribute__((intrinsic_function(0x108, 0, "extr.u") ));
315 
316 /** Load a single bit.
317  */
318 #define __getbit( address, bitoffset ) __extru( *(address), bitoffset, 1 )
319 
320 /** Return trg but replace trgbit by srcbit in src.
321  */
322 extern uint32 __ins( uint32, const uint32, uint32, const uint32) __attribute__((intrinsic_function(0x121, 0, "ins.t") ));
323 
324 /** Extract bit-field (width w bits starting at bit 0) from a and insert it in
325  * b at position p.
326  */
327 extern uint32 __insert( uint32, uint32, uint32, const uint32) __attribute__((intrinsic_function(0x109, 0, "insert") ));
328 
329 /** Return trg but replace trgbit by inverse of srcbit in src.
330  */
331 extern uint32 __insn( uint32, const uint32, uint32, const uint32) __attribute__((intrinsic_function(0x121, 0, "insn.t") ));
332 
333 /** Atomic load-modify-store.
334  */
335 #ifdef INTRINSIC_WORKAROUND
336 extern void __imaskldmst(uint32* a, sint32 b, sint32 p, const sint32 w);
337 #else
338 asm volatile void __imaskldmst(uint32* a, sint32 b, sint32 p, const sint32 w)
339 {
340 % reg a, b, p; con w
341 ! "%d2", "%d3"
342  imask %e2, b, p, w
343  ldmst [a]0, %e2
344 }
345 #endif
346 
347 /** Store a single bit.
348  */
349 #define __putbit(value,address,bitoffset) __imaskldmst(address,value,bitoffset,1)
350 
351 /** \} */
352 
353 /** \defgroup IfxLld_Cpu_Intrinsics_Dcc_interrupt_handling Interrupt Handling
354  The next table provides an overview of the intrinsic functions to read or set interrupt handling.
355  * \ingroup IfxLld_Cpu_Intrinsics_Dcc
356  * \{
357  */
358 
359 /** Set CPU priority number [0..255] (or [0..1023] for TriCore 1.6.x) and enable interrupts immediately at function entry
360  */
361 extern void __bisr( const uint32) __attribute__((intrinsic_function(0x100, 0, "bisr") ));
362 
363 /** Disable interrupts. Only supported for TriCore1
364  */
365 extern void __disable( void) __attribute__((intrinsic_function(0x103, 0, "disable") ));
366 
367 /** Disable interrupts and return previous interrupt state (enabled or disabled). Direct supported for TriCore1.6. Emulated on TC1.3.1
368  */
369 #if defined INTRINSIC_WORKAROUND
370 extern sint32 __disable_and_save(void);
371 #endif
372 
373 /** Enable interrupts immediately at function entry
374  */
375 extern void __enable( void) __attribute__((intrinsic_function(0x103, 0, "enable") ));
376 
377 /** Restore interrupt state. Direct supported for TriCore1.6. Emulated on TC1.3.1
378  */
379 extern void __restore( sint32) __attribute__((intrinsic_function(0x104, 0, "restore") ));
380 
381 /** Call a system call function number
382  */
383 extern void __syscall( const uint32) __attribute__((intrinsic_function(0x100, 0, "syscall") ));
384 
385 /** \} */
386 
387 /** \defgroup IfxLld_Cpu_Intrinsics_Dcc_miscellaneous Miscellaneous Intrinsic Functions
388  * \ingroup IfxLld_Cpu_Intrinsics_Dcc
389  * \{
390  */
391 
392 /** Write back and invalidate cache address "p". Generates CACHEA.WI [Ab].
393  */
394 extern void __cacheawi( void*) __attribute__((intrinsic_function(0x110, 0, "cachea.wi") ));
395 
396 /** Write back and invalidate cache address \"p\" and return post incremented
397  * value of \"p\". Generates CACHEA.WI [Ab+].
398  */
400 {
401 % reg p
402 !
403  cachea.wi [p + ]0
404  mov.aa %a2, p
405 }
406 
407 /** Write back and invalidate cache index "p". Generates CACHEI.WI [Ab].
408  */
409 asm volatile void __cacheiwi(uint8* p)
410 {
411 % reg p
412 !
413  cachei.wi [p]
414 }
415 
416 /** Initialize a circular pointer with a dynamically allocated buffer at run-time.
417  */
418 asm circ_t __initcirc(void* buf, uint16 bufsize, uint16 byteindex)
419 {
420 % reg buf, bufsize, byteindex
421 ! "%a2", "%a3"
422  lea %a2, [buf]0
423  extr.u bufsize, bufsize, 0, 16
424  insert bufsize, byteindex, bufsize, 16, 16
425  mov.a %a3, bufsize
426 }
427 
428 /** Multiply two 32-bit numbers to an intermediate 64-bit result, and scale
429  * back the result to 32 bits. To scale back the result, 32 bits are extracted
430  * from the intermediate 64-bit result: bit 63-offset to bit 31-offset.
431  */
432 asm volatile sint32 __mulsc(sint32 a, sint32 b, sint32 offset)
433 {
434 % reg a, b, offset
435 ! "%d2", "%d3"
436  mul %e2, a, b
437  dextr %d2, %d3, %d2, offset
438 }
439 
440 /** Rotate operand left count times. The bits that are shifted out are inserted at the right side (bit 31 is shifted to bit 0).
441  */
442 asm volatile uint32 __rol(uint32 operand, uint32 count)
443 {
444 % reg operand, count
445 ! "%d2"
446  dextr %d2, operand, operand, count
447 }
448 
449 /** Rotate operand right count times. The bits that are shifted out are inserted at the left side (bit 0 is shifted to bit 31).
450  */
451 asm volatile uint32 __ror(uint32 operand, uint32 count)
452 {
453 % reg operand, count
454 ! "%d2"
455  rsub count, count, 0
456  dextr %d2, operand, operand, count
457 }
458 
459 /** \} */
460 
461 /** \defgroup IfxLld_Cpu_Intrinsics_Dcc_packed Packed Data Type Support
462  The next table provides an overview of the intrinsic functions for initialization of packed data type.
463  * \ingroup IfxLld_Cpu_Intrinsics_Dcc
464  * \{
465  */
466 
467 /** Absolute value of __packb
468 */
470 {
471 % reg a
472 ! "%d2"
473  abs.b %d2, a
474 }
475 
476 /** Absolute value of __packhw
477  */
479 {
480 % reg a
481 ! "%d2"
482  abs.h %d2, a
483 }
484 
485 /** Absolute value of __packhw using saturation
486  */
488 {
489 % reg a
490 ! "%d2"
491  abss.h %d2, a
492 }
493 
494 /** \brief Extract first byte from a __packb
495  */
497 {
498 % reg a
499 ! "%d2"
500  extr %d2, a, 0, 8
501 }
502 
503 /** \brief Extract second byte from a __packb
504  */
506 {
507 % reg a
508 ! "%d2"
509  extr %d2, a, 8, 8
510 }
511 
512 /** \brief Extract third byte from a __packb
513  */
515 {
516 % reg a
517 ! "%d2"
518  extr %d2, a, 16, 8
519 }
520 
521 /** \brief Extract fourth byte from a __packb
522  */
524 {
525 % reg a
526 ! "%d2"
527  extr %d2, a, 24, 8
528 }
529 
530 /** \brief Extract first short from a __packhw
531  */
532 asm short __extracthw1(__packhw a)
533 {
534 % reg a
535 ! "%d2"
536  extr %d2, a, 0, 16
537 }
538 
539 /** \brief Extract second short from a __packhw
540  */
541 asm short __extracthw2(__packhw a)
542 {
543 % reg a
544 ! "%d2"
545  extr %d2, a, 16, 16
546 }
547 
548 /** Extract first unsigned byte from a __packb
549  */
551 {
552 % reg a
553 ! "%d2"
554  extr %d2, a, 0, 8
555 }
556 
557 /** Extract second unsigned byte from a __packb
558  */
560 {
561 % reg a
562 ! "%d2"
563  extr %d2, a, 8, 8
564 }
565 
566 /** Extract third unsigned byte from a __packb
567  */
569 {
570 % reg a
571 ! "%d2"
572  extr %d2, a, 16, 8
573 }
574 
575 /** Extract fourth unsigned byte from a __packb
576  */
578 {
579 % reg a
580 ! "%d2"
581  extr %d2, a, 24, 8
582 }
583 
584 /** Extract first uint16 from a __packhw
585  */
587 {
588 % reg a
589 ! "%d2"
590  extr %d2, a, 0, 16
591 }
592 
593 /** Extract second uint16 from a __packhw
594  */
596 {
597 % reg a
598 ! "%d2"
599  extr %d2, a, 16, 16
600 }
601 
602 /** Extract first byte from a __packb
603  */
605 {
606 % reg a
607 ! "%d2"
608  ld.w %d2, [a]
609  extr %d2, %d2, 0, 8
610 }
611 
612 /** Extract second byte from a __packb
613  */
615 {
616 % reg a
617 ! "%d2"
618  ld.w %d2, [a]
619  extr %d2, %d2, 8, 8
620 }
621 
622 /** Extract third byte from a __packb
623  */
625 {
626 % reg a
627 ! "%d2"
628  ld.w %d2, [a]
629  extr %d2, %d2, 16, 8
630 }
631 
632 /** Extract fourth byte from a __packb
633  */
635 {
636 % reg a
637 ! "%d2"
638  ld.w %d2, [a]
639  extr %d2, %d2, 24, 8
640 }
641 
642 /** Extract first short from a __packhw
643  */
644 asm short __gethw1(__packhw* a)
645 {
646 % reg a
647 ! "%d2"
648  ld.w %d2, [a]
649  extr %d2, %d2, 0, 16
650 }
651 
652 /** Extract second short from a __packhw
653  */
654 asm short __gethw2(__packhw* a)
655 {
656 % reg a
657 ! "%d2"
658  ld.w %d2, [a]
659  extr %d2, %d2, 16, 16
660 }
661 
662 /** Extract first unsigned byte from a __packb
663  */
664 asm volatile uint8 __getubyte1(__upackb* a)
665 {
666 % reg a
667 ! "%d2"
668  ld.w %d2, [a]
669  extr %d2, %d2, 0, 8
670 }
671 
672 /** Extract second unsigned byte from a __packb
673  */
674 asm volatile uint8 __getubyte2(__upackb* a)
675 {
676 % reg a
677 ! "%d2"
678  ld.w %d2, [a]
679  extr %d2, %d2, 8, 8
680 }
681 
682 /** Extract third unsigned byte from a __packb
683  */
684 asm volatile uint8 __getubyte3(__upackb* a)
685 {
686 % reg a
687 ! "%d2"
688  ld.w %d2, [a]
689  extr %d2, %d2, 16, 8
690 }
691 
692 /** Extract fourth unsigned byte from a __packb
693  */
694 asm volatile uint8 __getubyte4(__upackb* a)
695 {
696 % reg a
697 ! "%d2"
698  ld.w %d2, [a]
699  extr %d2, %d2, 24, 8
700 }
701 
702 /** Extract first uint16 from a __packhw
703  */
704 asm volatile uint16 __getuhw1(__upackhw* a)
705 {
706 % reg a
707 ! "%d2"
708  ld.w %d2, [a]
709  extr %d2, %d2, 0, 16
710 }
711 
712 /** Extract second uint16 from a __packhw
713  */
714 asm volatile uint16 __getuhw2(__upackhw* a)
715 {
716 % reg a
717 ! "%d2"
718  ld.w %d2, [a]
719  extr %d2, %d2, 16, 16
720 }
721 
722 /** Initialize __packb with four integers
723  */
724 asm __packb __initpackb(sint32 a, sint32 b, sint32 c, sint32 d)
725 {
726 % reg a, b, c, d
727 ! "%d2"
728  insert c, c, d, 8, 8
729  insert d, a, b, 8, 8
730  insert %d2, d, c, 16, 16
731 }
732 
733 /** Initialize __packb with a long integer
734  */
736 {
737 % reg a
738 ! "%d2"
739  mov %d2, a
740 }
741 
742 /** \brief Initialize __packhw with two integers
743  */
744 asm __packhw __initpackhw(short a, short b)
745 {
746 % reg a, b
747 ! "%d2"
748  insert %d2, a, b, 16, 16
749 }
750 
751 /** Initialize __packhw with a long integer
752  */
754 {
755 % reg a
756 ! "%d2"
757  mov %d2, a
758 }
759 
760 /** Initialize __packb with four unsigned integers
761  */
762 asm __upackb __initupackb( uint32 a, uint32 b, uint32 c, uint32 d)
763 {
764 % reg a, b, c, d
765 ! "%d2"
766  insert c, c, d, 8, 8
767  insert a, a, b, 8, 8
768  insert %d2, a, c, 16, 16
769 }
770 
771 /** Initialize __packhw with two unsigned integers
772  */
774 {
775 % reg a, b
776 ! "%d2"
777  insert %d2, a, b, 16, 16
778 }
779 
780 /** \brief Insert sint8 into first byte of a __packb
781  */
783 {
784 % reg a, b
785 ! "%d2"
786  insert %d2, a, b, 0, 8
787 }
788 
789 /** \brief Insert sint8 into second byte of a __packb
790  */
792 {
793 % reg a, b
794 ! "%d2"
795  insert %d2, a, b, 8, 8
796 }
797 
798 /** \brief Insert sint8 into third byte of a __packb
799  */
801 {
802 % reg a, b
803 ! "%d2"
804  insert %d2, a, b, 16, 8
805 }
806 
807 /** \brief Insert sint8 into fourth byte of a __packb
808  */
810 {
811 % reg a, b
812 ! "%d2"
813  insert %d2, a, b, 24, 8
814 }
815 
816 /** Insert short into first halfword of a __packhw
817  */
819 {
820 % reg a, b
821 ! "%d2"
822  insert %d2, a, b, 0, 16
823 }
824 
825 /** Insert short into second halfword of a __packhw
826  */
828 {
829 % reg a, b
830 ! "%d2"
831  insert %d2, a, b, 16, 16
832 }
833 
834 /** \brief Insert uint8 into first unsigned byte of a __packb
835  */
837 {
838 % reg a, b
839 ! "%d2"
840  insert %d2, a, b, 0, 8
841 }
842 
843 /** \brief Insert uint8 into second unsigned byte of a __packb
844  */
846 {
847 % reg a, b
848 ! "%d2"
849  insert %d2, a, b, 8, 8
850 }
851 
852 /** \brief Insert uint8 into third unsigned byte of a __packb
853  */
855 {
856 % reg a, b
857 ! "%d2"
858  insert %d2, a, b, 16, 8
859 }
860 
861 /** \brief Insert uint8 into fourth unsigned byte of a __packb
862  */
864 {
865 % reg a, b
866 ! "%d2"
867  insert %d2, a, b, 24, 8
868 }
869 
870 /** Insert uint16 into first halfword of a __upackhw
871  */
873 {
874 % reg a, b
875 ! "%d2"
876  insert %d2, a, b, 0, 16
877 }
878 
879 /** Insert uint16 into second halfword of a __upackhw
880  */
882 {
883 % reg a, b
884 ! "%d2"
885  insert %d2, a, b, 16, 16
886 }
887 
888 /** Minimum of two __packb values
889  */
890 #ifdef INTRINSIC_WORKAROUND
891 extern __packb __minb(__packb a, __packb b);
892 #else
894 {
895 % reg a, b
896 ! "%d2"
897  min.b %d2, a, b
898 }
899 #endif
900 
901 /** Minimum of two __upackb values
902  */
904 {
905 % reg a, b
906 ! "%d2"
907  min.bu %d2, a, b
908 }
909 
910 /** Minimum of two __packhw values
911  */
913 {
914 % reg a, b
915 ! "%d2"
916  min.h %d2, a, b
917 }
918 
919 /** Minimum of two __upackhw values
920  */
922 {
923 % reg a, b
924 ! "%d2"
925  min.hu %d2, a, b
926 }
927 
928 /** Insert sint8 into first byte of a __packb
929  */
930 asm volatile void __setbyte1(__packb* a, sint8 b)
931 {
932 % reg a, b
933 ! "%d2"
934  ld.w %d2, [a]
935  insert %d2, %d2, b, 0, 8
936  st.w [a], %d2
937 }
938 
939 /** Insert sint8 into second byte of a __packb
940  */
941 asm volatile void __setbyte2(__packb* a, sint8 b)
942 {
943 % reg a, b
944 ! "%d2"
945  ld.w %d2, [a]
946  insert %d2, %d2, b, 8, 8
947  st.w [a], %d2
948 }
949 
950 /** Insert sint8 into third byte of a __packb
951  */
952 asm volatile void __setbyte3(__packb* a, sint8 b)
953 {
954 % reg a, b
955 ! "%d2"
956  ld.w %d2, [a]
957  insert %d2, %d2, b, 16, 8
958  st.w [a], %d2
959 }
960 
961 /** Insert sint8 into fourth byte of a __packb
962  */
963 asm volatile void __setbyte4(__packb* a, sint8 b)
964 {
965 % reg a, b
966 ! "%d2"
967  ld.w %d2, [a]
968  insert %d2, %d2, b, 24, 8
969  st.w [a], %d2
970 }
971 
972 /** Insert short into first halfword of a __packhw
973  */
974 asm volatile void __sethw1(__packhw* a, short b)
975 {
976 % reg a, b
977 ! "%d2"
978  ld.w %d2, [a]
979  insert %d2, %d2, b, 0, 16
980  st.w [a], %d2
981 }
982 
983 /** Insert short into second halfword of a __packhw
984  */
985 asm volatile void __sethw2(__packhw* a, short b)
986 {
987 % reg a, b
988 ! "%d2"
989  ld.w %d2, [a]
990  insert %d2, %d2, b, 16, 16
991  st.w [a], %d2
992 }
993 
994 /** Insert uint8 into first byte of a __upackb
995  */
996 asm volatile void __setubyte1(__upackb* a, uint8 b)
997 {
998 % reg a, b
999 ! "%d2"
1000  ld.w %d2, [a]
1001  insert %d2, %d2, b, 0, 8
1002  st.w [a], %d2
1003 }
1004 
1005 /** Insert uint8 into second byte of a __upackb
1006  */
1007 asm volatile void __setubyte2(__upackb* a, uint8 b)
1008 {
1009 % reg a, b
1010 ! "%d2"
1011  ld.w %d2, [a]
1012  insert %d2, %d2, b, 8, 8
1013  st.w [a], %d2
1014 }
1015 
1016 /** Insert uint8 into third byte of a __upackb
1017  */
1018 asm volatile void __setubyte3(__upackb* a, uint8 b)
1019 {
1020 % reg a, b
1021 ! "%d2"
1022  ld.w %d2, [a]
1023  insert %d2, %d2, b, 16, 8
1024  st.w [a], %d2
1025 }
1026 
1027 /** Insert uint8 into fourth byte of a __upackb
1028  */
1029 asm volatile void __setubyte4(__upackb* a, uint8 b)
1030 {
1031 % reg a, b
1032 ! "%d2"
1033  ld.w %d2, [a]
1034  insert %d2, %d2, b, 24, 8
1035  st.w [a], %d2
1036 }
1037 
1038 /** Insert uint16 into first halfword of a __upackhw
1039  */
1040 asm volatile void __setuhw1(__upackhw* a, uint16 b)
1041 {
1042 % reg a, b
1043 ! "%d2"
1044  ld.w %d2, [a]
1045  insert %d2, %d2, b, 0, 16
1046  st.w [a], %d2
1047 }
1048 
1049 /** Insert uint16 into second halfword of a __upackhw
1050  */
1051 asm volatile void __setuhw2(__upackhw* a, uint16 b)
1052 {
1053 % reg a, b
1054 ! "%d2"
1055  ld.w %d2, [a]
1056  insert %d2, %d2, b, 16, 16
1057  st.w [a], %d2
1058 }
1059 
1060 /** \} */
1061 
1062 /** \defgroup IfxLld_Cpu_Intrinsics_Dcc_register Register Handling
1063  The next table provides an overview of the intrinsic functions that you can use to access control registers.
1064  * \ingroup IfxLld_Cpu_Intrinsics_Dcc
1065  * \{
1066  */
1067 
1068 /** Return absolute value
1069  */
1070 extern sint32 __abs( sint32) __attribute__((intrinsic_pseudo(1, "abs") ));
1071 
1072 /** Return absolue difference of two integers
1073  */
1074 extern sint32 __absdif( sint32, sint32) __attribute__((intrinsic_pseudo(1, "absdif") ));
1075 
1076 /** Return absolute value with saturation
1077  */
1078 extern sint32 __abss( sint32) __attribute__((intrinsic_pseudo(1, "abss") ));
1079 
1080 /** Count leading ones in int
1081  */
1082 extern sint32 __clo( sint32) __attribute__((intrinsic_pseudo(1, "clo") ));
1083 
1084 /** Count number of redundant sign bits (all consecutive bits with the same value as bit 31
1085  */
1086 extern sint32 __cls( sint32) __attribute__((intrinsic_pseudo(1, "cls") ));
1087 
1088 /** Count leading zeros in int
1089  */
1090 extern sint32 __clz( sint32) __attribute__((intrinsic_pseudo(1, "clz") ));
1091 
1092 /** Return absolute double precision floating-point value
1093  */
1094 asm double __fabs(double d)
1095 {
1096 % reg d
1097 ! "%d2"
1098  insert %d2, d, 0, 31, 1
1099 }
1100 
1101 /** Return absolute floating-point value
1102  */
1103 asm float __fabsf(float f)
1104 {
1105 % reg f
1106 ! "%d2"
1107  insert %d2, f, 0, 31, 1
1108 }
1109 
1110 /** Move contents of the addressed core SFR into a data register
1111  */
1112 extern sint32 __mfcr( const uint32) __attribute__((intrinsic_function(0x101, 0, "mfcr") ));
1113 
1114 /** Move contents of a data register (second sint32) to the addressed core SFR (first sint32)
1115  */
1116 extern void __mtcr( const uint32, sint32) __attribute__((intrinsic_function(0x102, 0, "mtcr") ));
1117 
1118 /** Return parity
1119  */
1120 asm volatile sint32 __parity(sint32 a)
1121 {
1122 % reg a
1123 ! "%d2"
1124  parity %d2, a
1125 }
1126 
1127 /** Return saturated byte
1128  */
1129 asm sint8 __satb(sint32 a)
1130 {
1131 % reg a
1132 ! "%d2"
1133  sat.b %d2, a
1134 }
1135 
1136 /** Return saturated unsigned byte
1137  */
1138 asm volatile uint8 __satbu(sint32 a)
1139 {
1140 % reg a
1141 ! "%d2"
1142  sat.bu %d2, a
1143 }
1144 
1145 /** Return saturated halfword
1146  */
1147 asm short __sath(sint32 a)
1148 {
1149 % reg a
1150 ! "%d2"
1151  sat.h %d2, a
1152 }
1153 
1154 /** Return saturated unsignedhalfword
1155  */
1156 asm volatile uint16 __sathu(sint32 a)
1157 {
1158 % reg a
1159 ! "%d2"
1160  sat.hu %d2, a
1161 }
1162 
1163 /** \} */
1164 
1165 /** \defgroup IfxLld_Cpu_Intrinsics_Dcc_saturation Saturation Arithmetic Support
1166  These intrinsics support saturation arithmetic
1167  * \ingroup IfxLld_Cpu_Intrinsics_Dcc
1168  * \{
1169  */
1170 /** add signed with saturation
1171  */
1172 extern sint32 __adds( sint32, sint32) __attribute__((intrinsic_pseudo(1, "adds") ));
1173 
1174 /** add unsigned with saturation
1175  */
1176 asm volatile uint32 __addsu(uint32 a, uint32 b)
1177 {
1178 % reg a, b
1179 ! "%d2"
1180  adds.u %d2, a, b
1181 }
1182 
1183 /** substract signed with saturation
1184  */
1185 asm volatile sint32 __subs(sint32 a, sint32 b)
1186 {
1187 % reg a, b
1188 ! "%d2"
1189  subs %d2, a, b
1190 }
1191 
1192 /** substract unsigned with saturation
1193  */
1194 asm volatile uint32 __subsu(uint32 a, uint32 b)
1195 {
1196 % reg a, b
1197 ! "%d2"
1198  subs.u %d2, a, b
1199 }
1200 
1201 /** \} */
1202 
1203 /** \defgroup IfxLld_Cpu_Intrinsics_Dcc_single_assembly Insert Single Assembly Instruction
1204  The next table provides an overview of the intrinsic functions that you can use to insert a single assembly
1205  instruction.You can also use inline assembly but these intrinsics provide a shorthand for frequently used
1206  assembly instructions.
1207  * \ingroup IfxLld_Cpu_Intrinsics_Dcc
1208  * \{
1209  */
1210 
1211 /** Insert DEBUG instruction
1212  */
1213 extern void __debug( void) __attribute__((intrinsic_function(0x103, 0, "debug") ));
1214 
1215 /** Insert DSYNC instruction
1216  */
1217 extern void __dsync( void) __attribute__((intrinsic_function(0x103, 0, "dsync") ));
1218 
1219 /** Insert ISYNC instruction
1220  */
1221 extern void __isync( void) __attribute__((intrinsic_function(0x103, 0, "isync") ));
1222 
1223 /** Insert LDMST instruction. Note that all operands must be word-aligned.
1224  */
1225 #ifdef INTRINSIC_WORKAROUND
1226 #define __ldmst __ldmst_c
1227 #else
1228 asm volatile void __ldmst(volatile void *address, uint32 mask, uint32 value)
1229 {
1230 %reg address, mask, value;
1231 !"%d2", "%d3"
1232  mov %d3, mask
1233  mov %d2, value
1234  ldmst [address],%e2
1235 }
1236 
1237 #endif
1238 
1239 /** Insert NOP instruction
1240  */
1241 extern void __nop( void) __attribute__((intrinsic_function(0x103, 0, "nop") ));
1242 
1243 /** Insert a loop over n NOP instruction
1244  */
1245 asm volatile void __nops(void* cnt)
1246 {
1247 % lab L0;
1248  reg cnt
1249  add.a cnt, -1
1250 L0:
1251  nop
1252  loop cnt, L0
1253 }
1254 
1255 /** Insert a loop over n times 1000 NOP instruction
1256  */
1257 asm volatile void __nops1000(uint32 x)
1258 {
1259 % reg x;
1260  lab L0, L1
1261 ! "%a2", "%a3"
1262  mov.a %a2, x
1263 L1:
1264  lea %a3, 999
1265 L0:
1266  nop
1267  nop
1268  loop %a3, L0
1269  loop %a2, L1
1270 }
1271 
1272 /** Insert RSLCX instruction
1273  */
1274 extern void __rslcx( void) __attribute__((intrinsic_function(0x103, 0, "rslcx") ));
1275 
1276 /** Insert SVLCX instruction
1277  */
1278 extern void __svlcx( void) __attribute__((intrinsic_function(0x103, 0, "svlcx") ));
1279 
1280 /** Insert SWAP instruction. Note that all operands must be word-aligned.
1281  */
1282 #ifdef INTRINSIC_WORKAROUND
1283 extern uint32 __swap(void* place, uint32 value);
1284 #else
1285 asm volatile uint32 __swap(void* place, uint32 value)
1286 {
1287 % reg place, value
1288 ! "%d2"
1289  mov %d2, value
1290  swap.w [place], %d2
1291 }
1292 #endif
1293 
1294 // FIXME
1295 asm volatile unsigned int __cmpAndSwap(unsigned int *address, unsigned long value, unsigned long CmpVal)
1296 {
1297 %reg value, address, CmpVal
1298 ! "%d0", "%d1"
1299  mov %d0,value
1300  mov %d1,CmpVal
1301  cmpswap.w %e0, [address]
1302 }
1303 /** \} */
1304 
1305 /** Insert n NOP instruction
1306  */
1307 //#info "NOP: Feature not yet implemented."
1308 
1309 #define __setareg(areg,val) ___setareg(areg,val)
1310 /* we need to use a15 for the address register and not direct that the compiler this will not remove */
1311 #define ___setareg(areg,val) \
1312  { __asm ("#$$bp"); \
1313  __asm (" movh.a\t %a15,"#val"@ha\n"); \
1314  __asm (" lea\t %a15,[%a15]"#val"@l\n"); \
1315  __asm (" mov.aa %"#areg", %a15\n"); \
1316  __asm ("#$$ep"); }
1317 
1318 /* FIXME check that the compiler take in account that d0 is used by the inline function */
1319 asm volatile void __stopPerfCounters(void)
1320 {
1321 ! "%d0"
1322  mov %d0,0
1323  mtcr 0xFC00,%d0
1324  isync
1325 }
1326 
1327 /** \brief Convert a fixpoint value to float32
1328  *
1329  * This function converts a value from a fixpoint format to a float32 format.
1330  *
1331  *
1332  * \param value value to be converted.
1333  * \param shift position of the fix point. Range = [-256, 255] => (Qx.y format where x = shift+1).
1334  *
1335  * \return Returns the converted value in the float32 format.
1336  *
1337  */
1338 asm float __fixpoint_to_float32(fract value, sint32 shift)
1339 {
1340 % reg value, shift
1341 ! "%d2"
1342  q31tof %d2, value, shift
1343 }
1344 
1345 asm volatile void* __getA11(void)
1346 {
1347 ! "%a11", "%a2"
1348  mov.aa %a2, %a11
1349 }
1350 
1351 asm void __setStackPointer(void *stackAddr)
1352 {
1353 % reg stackAddr
1354 ! "%a10"
1355  mov.aa %a10, stackAddr
1356 }
1357 /* *INDENT-ON* */
1358 
1359 /******************************************************************************/
1360 #endif /* IFXCPU_INTRINSICSDCC_H */