• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2017 C-SKY Microsystems Co., Ltd. All rights reserved.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *   http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 /******************************************************************************
18  * @file     csi_gcc.h
19  * @brief    CSI Header File for GCC.
20  * @version  V1.0
21  * @date     02. June 2017
22  ******************************************************************************/
23 
24 #ifndef _CSI_GCC_H_
25 #define _CSI_GCC_H_
26 
27 #include <stdlib.h>
28 
29 #ifndef __ASM
30 #define __ASM                   __asm    /*!< asm keyword for GNU Compiler */
31 #endif
32 
33 #ifndef __INLINE
34 #define __INLINE                inline   /*!< inline keyword for GNU Compiler */
35 #endif
36 
37 #ifndef __ALWAYS_STATIC_INLINE
38 #define __ALWAYS_STATIC_INLINE  __attribute__((always_inline)) static inline
39 #endif
40 
41 #ifndef __STATIC_INLINE
42 #define __STATIC_INLINE         static inline
43 #endif
44 
45 /* ###########################  Core Function Access  ########################### */
46 /** \ingroup  CSI_Core_FunctionInterface
47     \defgroup CSI_Core_RegAccFunctions CSI Core Register Access Functions
48   @{
49  */
50 /**
51   \brief   Enable IRQ Interrupts
52   \details Enables IRQ interrupts by setting the IE-bit in the PSR.
53            Can only be executed in Privileged modes.
54  */
__enable_irq(void)55 __ALWAYS_STATIC_INLINE void __enable_irq(void)
56 {
57     __ASM volatile("psrset ie");
58 }
59 
60 
61 
62 /**
63   \brief   Disable IRQ Interrupts
64   \details Disables IRQ interrupts by clearing the IE-bit in the PSR.
65   Can only be executed in Privileged modes.
66  */
__disable_irq(void)67 __ALWAYS_STATIC_INLINE void __disable_irq(void)
68 {
69     __ASM volatile("psrclr ie");
70 }
71 
72 /**
73   \brief   Get PSR
74   \details Returns the content of the PSR Register.
75   \return               PSR Register value
76  */
__get_PSR(void)77 __ALWAYS_STATIC_INLINE uint32_t __get_PSR(void)
78 {
79     uint32_t result;
80 
81     __ASM volatile("mfcr %0, psr" : "=r"(result));
82     return (result);
83 }
84 
85 /**
86   \brief   Set PSR
87   \details Writes the given value to the PSR Register.
88   \param [in]    psr  PSR Register value to set
89  */
__set_PSR(uint32_t psr)90 __ALWAYS_STATIC_INLINE void __set_PSR(uint32_t psr)
91 {
92     __ASM volatile("mtcr %0, psr" : : "r"(psr));
93 }
94 
95 /**
96   \brief   Get SP
97   \details Returns the content of the SP Register.
98   \return               SP Register value
99  */
__get_SP(void)100 __ALWAYS_STATIC_INLINE uint32_t __get_SP(void)
101 {
102     uint32_t result;
103 
104     __ASM volatile("mov %0, sp" : "=r"(result));
105     return (result);
106 }
107 
108 /**
109   \brief   Set SP
110   \details Writes the given value to the SP Register.
111   \param [in]    sp  SP Register value to set
112  */
__set_SP(uint32_t sp)113 __ALWAYS_STATIC_INLINE void __set_SP(uint32_t sp)
114 {
115     __ASM volatile("mov sp, %0" : : "r"(sp): "sp");
116 }
117 
118 /**
119   \brief   Get Int SP
120   \details Returns the content of the Int SP Register.
121   \return               Int SP Register value
122  */
__get_Int_SP(void)123 __ALWAYS_STATIC_INLINE uint32_t __get_Int_SP(void)
124 {
125     uint32_t result;
126 
127     __ASM volatile("mfcr %0, cr<15, 1>" : "=r"(result));
128     return (result);
129 }
130 
131 /**
132   \brief   Set Int SP
133   \details Writes the given value to the Int SP Register.
134   \param [in]    sp  Int SP Register value to set
135  */
__set_Int_SP(uint32_t sp)136 __ALWAYS_STATIC_INLINE void __set_Int_SP(uint32_t sp)
137 {
138     __ASM volatile("mtcr %0, cr<15, 1>" : : "r"(sp));
139 }
140 
141 /**
142   \brief   Get VBR Register
143   \details Returns the content of the VBR Register.
144   \return               VBR Register value
145  */
__get_VBR(void)146 __ALWAYS_STATIC_INLINE uint32_t __get_VBR(void)
147 {
148     uint32_t result;
149 
150     __ASM volatile("mfcr %0, vbr" : "=r"(result));
151     return (result);
152 }
153 
154 /**
155   \brief   Set VBR
156   \details Writes the given value to the VBR Register.
157   \param [in]    vbr  VBR Register value to set
158  */
__set_VBR(uint32_t vbr)159 __ALWAYS_STATIC_INLINE void __set_VBR(uint32_t vbr)
160 {
161     __ASM volatile("mtcr %0, vbr" : : "r"(vbr));
162 }
163 
164 /**
165   \brief   Get EPC Register
166   \details Returns the content of the EPC Register.
167   \return               EPC Register value
168  */
__get_EPC(void)169 __ALWAYS_STATIC_INLINE uint32_t __get_EPC(void)
170 {
171     uint32_t result;
172 
173     __ASM volatile("mfcr %0, epc" : "=r"(result));
174     return (result);
175 }
176 
177 /**
178   \brief   Set EPC
179   \details Writes the given value to the EPC Register.
180   \param [in]    epc  EPC Register value to set
181  */
__set_EPC(uint32_t epc)182 __ALWAYS_STATIC_INLINE void __set_EPC(uint32_t epc)
183 {
184     __ASM volatile("mtcr %0, epc" : : "r"(epc));
185 }
186 
187 /**
188   \brief   Get EPSR
189   \details Returns the content of the EPSR Register.
190   \return               EPSR Register value
191  */
__get_EPSR(void)192 __ALWAYS_STATIC_INLINE uint32_t __get_EPSR(void)
193 {
194     uint32_t result;
195 
196     __ASM volatile("mfcr %0, epsr" : "=r"(result));
197     return (result);
198 }
199 
200 /**
201   \brief   Set EPSR
202   \details Writes the given value to the EPSR Register.
203   \param [in]    epsr  EPSR Register value to set
204  */
__set_EPSR(uint32_t epsr)205 __ALWAYS_STATIC_INLINE void __set_EPSR(uint32_t epsr)
206 {
207     __ASM volatile("mtcr %0, epsr" : : "r"(epsr));
208 }
209 
210 /**
211   \brief   Get CPUID Register
212   \details Returns the content of the CPUID Register.
213   \return               CPUID Register value
214  */
__get_CPUID(void)215 __ALWAYS_STATIC_INLINE uint32_t __get_CPUID(void)
216 {
217     uint32_t result;
218 
219 #ifdef __CK610
220     __ASM volatile("mfcr %0, cr13" : "=r"(result));
221 #else
222     __ASM volatile("mfcr %0, cr<13, 0>" : "=r"(result));
223 #endif
224     return (result);
225 }
226 
227 /**
228   \brief   Get CCR
229   \details Returns the current value of the CCR.
230   \return               CCR Register value
231  */
__get_CCR(void)232 __ALWAYS_STATIC_INLINE uint32_t __get_CCR(void)
233 {
234     register uint32_t result;
235 
236 #ifdef __CK610
237     __ASM volatile("mfcr %0, cr18\n"  : "=r"(result));
238 #else
239     __ASM volatile("mfcr %0, cr<18, 0>\n"  : "=r"(result));
240 #endif
241     return (result);
242 }
243 
244 
245 /**
246   \brief   Set CCR
247   \details Assigns the given value to the CCR.
248   \param [in]    ccr  CCR value to set
249  */
__set_CCR(uint32_t ccr)250 __ALWAYS_STATIC_INLINE void __set_CCR(uint32_t ccr)
251 {
252 #ifdef __CK610
253     __ASM volatile("mtcr %0, cr18\n" : : "r"(ccr));
254 #else
255     __ASM volatile("mtcr %0, cr<18, 0>\n" : : "r"(ccr));
256 #endif
257 }
258 
259 
260 /**
261   \brief   Get DCSR
262   \details Returns the content of the DCSR Register.
263   \return               DCSR Register value
264  */
__get_DCSR(void)265 __ALWAYS_STATIC_INLINE uint32_t __get_DCSR(void)
266 {
267     uint32_t result;
268 #ifdef __CK610
269     __ASM volatile("mfcr %0, cr14" : "=r"(result));
270 #else
271     __ASM volatile("mfcr %0, cr<14, 0>" : "=r"(result));
272 #endif
273     return (result);
274 }
275 
276 
277 /**
278   \brief   Set DCSR
279   \details Writes the given value to the DCSR Register.
280   \param [in]    dcsr  DCSR Register value to set
281  */
__set_DCSR(uint32_t dcsr)282 __ALWAYS_STATIC_INLINE void __set_DCSR(uint32_t dcsr)
283 {
284 #ifdef __CK610
285     __ASM volatile("mtcr %0, cr14" : : "r"(dcsr));
286 #else
287     __ASM volatile("mtcr %0, cr<14, 0>" : : "r"(dcsr));
288 #endif
289 }
290 
291 
292 /**
293   \brief   Get CFR
294   \details Returns the content of the CFR Register.
295   \return               CFR Register value
296  */
__get_CFR(void)297 __ALWAYS_STATIC_INLINE uint32_t __get_CFR(void)
298 {
299     uint32_t result;
300 #ifdef __CK610
301     __ASM volatile("mfcr %0, cr17" : "=r"(result));
302 #else
303     __ASM volatile("mfcr %0, cr<17, 0>" : "=r"(result));
304 #endif
305 
306     return (result);
307 }
308 
309 
310 /**
311   \brief   Set CFR
312   \details Writes the given value to the CFR Register.
313   \param [in]    cfr  CFR Register value to set
314  */
__set_CFR(uint32_t cfr)315 __ALWAYS_STATIC_INLINE void __set_CFR(uint32_t cfr)
316 {
317 #ifdef __CK610
318     __ASM volatile("mtcr %0, cr17" : : "r"(cfr));
319 #else
320     __ASM volatile("mtcr %0, cr<17, 0>" : : "r"(cfr));
321 #endif
322 }
323 
324 
325 /**
326   \brief   Get CIR
327   \details Returns the content of the CIR Register.
328   \return               CIR Register value
329  */
__get_CIR(void)330 __ALWAYS_STATIC_INLINE uint32_t __get_CIR(void)
331 {
332     uint32_t result;
333 #ifdef __CK610
334     __ASM volatile("mfcr %0, cr22" : "=r"(result));
335 #else
336     __ASM volatile("mfcr %0, cr<22, 0>" : "=r"(result));
337 #endif
338     return (result);
339 }
340 
341 
342 /**
343   \brief   Set CIR
344   \details Writes the given value to the CIR Register.
345   \param [in]    cir  CIR Register value to set
346  */
__set_CIR(uint32_t cir)347 __ALWAYS_STATIC_INLINE void __set_CIR(uint32_t cir)
348 {
349 #ifdef __CK610
350     __ASM volatile("mtcr %0, cr22" : : "r"(cir));
351 #else
352     __ASM volatile("mtcr %0, cr<22, 0>" : : "r"(cir));
353 #endif
354 }
355 
356 
357 /**
358   \brief   Get CAPR
359   \details Returns the current value of the CAPR.
360   \return               CAPR Register value
361  */
__get_CAPR(void)362 __ALWAYS_STATIC_INLINE uint32_t __get_CAPR(void)
363 {
364     register uint32_t result;
365 
366 #ifdef __CK610
367     __ASM volatile("mfcr %0, cr19\n" : "=r"(result));
368 #else
369     __ASM volatile("mfcr %0, cr<19, 0>\n" : "=r"(result));
370 #endif
371     return (result);
372 }
373 
374 /**
375   \brief   Set CAPR
376   \details Assigns the given value to the CAPR.
377   \param [in]    capr  CAPR value to set
378  */
__set_CAPR(uint32_t capr)379 __ALWAYS_STATIC_INLINE void __set_CAPR(uint32_t capr)
380 {
381 #ifdef __CK610
382     __ASM volatile("mtcr %0, cr19\n" : : "r"(capr));
383 #else
384     __ASM volatile("mtcr %0, cr<19, 0>\n" : : "r"(capr));
385 #endif
386 }
387 
388 
389 /**
390   \brief   Set PACR
391   \details Assigns the given value to the PACR.
392 
393     \param [in]    pacr  PACR value to set
394  */
__set_PACR(uint32_t pacr)395 __ALWAYS_STATIC_INLINE void __set_PACR(uint32_t pacr)
396 {
397 #ifdef __CK610
398     __ASM volatile("mtcr %0, cr20\n" : : "r"(pacr));
399 #else
400     __ASM volatile("mtcr %0, cr<20, 0>\n" : : "r"(pacr));
401 #endif
402 }
403 
404 
405 /**
406   \brief   Get PACR
407   \details Returns the current value of PACR.
408   \return               PACR value
409  */
__get_PACR(void)410 __ALWAYS_STATIC_INLINE uint32_t __get_PACR(void)
411 {
412     uint32_t result;
413 
414 #ifdef __CK610
415     __ASM volatile("mfcr %0, cr20" : "=r"(result));
416 #else
417     __ASM volatile("mfcr %0, cr<20, 0>" : "=r"(result));
418 #endif
419     return (result);
420 }
421 
422 /**
423   \brief   Set PRSR
424   \details Assigns the given value to the PRSR.
425 
426     \param [in]    prsr  PRSR value to set
427  */
__set_PRSR(uint32_t prsr)428 __ALWAYS_STATIC_INLINE void __set_PRSR(uint32_t prsr)
429 {
430 #ifdef __CK610
431     __ASM volatile("mtcr %0, cr21\n" : : "r"(prsr));
432 #else
433     __ASM volatile("mtcr %0, cr<21, 0>\n" : : "r"(prsr));
434 #endif
435 }
436 
437 /**
438   \brief   Get PRSR
439   \details Returns the current value of PRSR.
440   \return               PRSR value
441  */
__get_PRSR(void)442 __ALWAYS_STATIC_INLINE uint32_t __get_PRSR(void)
443 {
444     uint32_t result;
445 
446 #ifdef __CK610
447     __ASM volatile("mfcr %0, cr21" : "=r"(result));
448 #else
449     __ASM volatile("mfcr %0, cr<21, 0>" : "=r"(result));
450 #endif
451     return (result);
452 }
453 
454 /**
455   \brief   Get user sp
456   \details Returns the current value of user r14.
457   \return               UR14 value
458  */
__get_UR14(void)459 __ALWAYS_STATIC_INLINE uint32_t __get_UR14(void)
460 {
461     uint32_t result;
462 
463 #ifdef __CK610
464     __ASM volatile("mov %0, sp" : "=r"(result));
465 #else
466     __ASM volatile("mfcr %0, cr<14, 1>" : "=r"(result));
467 #endif
468     return (result);
469 }
470 
471 /**
472   \brief   Get CHR Register
473   \details Returns the content of the CHR Register.
474   \return               CHR Register value
475  */
__get_CHR(void)476 __ALWAYS_STATIC_INLINE uint32_t __get_CHR(void)
477 {
478     uint32_t result;
479 
480     __ASM volatile("mfcr %0, cr<31, 0>\n" :"=r"(result));
481     return (result);
482 }
483 
484 /**
485   \brief   Set CHR
486   \details Assigns the given value to the CHR.
487   \param [in]    chr  CHR value to set
488  */
__set_CHR(uint32_t chr)489 __ALWAYS_STATIC_INLINE void __set_CHR(uint32_t chr)
490 {
491     __ASM volatile("mtcr %0, cr<31, 0>\n" : : "r"(chr));
492 }
493 
494 /**
495   \brief   Get HINT
496   \details Returns the content of the HINT Register.
497   \return               HINT Register value
498  */
__get_HINT(void)499 __ALWAYS_STATIC_INLINE uint32_t __get_HINT(void)
500 {
501     uint32_t result;
502 #ifdef __CK610
503     __ASM volatile("mfcr %0, cr<30, 0>" : "=r"(result));
504 #else
505     __ASM volatile("mfcr %0, cr<31, 0>" : "=r"(result));
506 #endif
507     return (result);
508 }
509 
510 /**
511   \brief   Set HINT
512   \details Writes the given value to the HINT Register.
513   \param [in]    hint  HINT Register value to set
514  */
__set_HINT(uint32_t hint)515 __ALWAYS_STATIC_INLINE void __set_HINT(uint32_t hint)
516 {
517 #ifdef __CK610
518     __ASM volatile("mtcr %0, cr<30, 0>" : "=r"(hint));
519 #else
520     __ASM volatile("mtcr %0, cr<31, 0>" : : "r"(hint));
521 #endif
522 }
523 
524 /**
525   \brief   Get MIR
526   \details Returns the content of the MIR Register.
527   \return               MIR Register value
528  */
__get_MIR(void)529 __ALWAYS_STATIC_INLINE uint32_t __get_MIR(void)
530 {
531     uint32_t result;
532 #ifdef __CK610
533     __ASM volatile("cpseti 15");
534     __ASM volatile("cprcr %0, cpcr0" : "=r"(result));
535 #else
536     __ASM volatile("mfcr %0, cr<0, 15>" : "=r"(result));
537 #endif
538     return (result);
539 }
540 
541 /**
542   \brief   Set MIR
543   \details Writes the given value to the MIR Register.
544   \param [in]    mir  MIR Register value to set
545  */
__set_MIR(uint32_t mir)546 __ALWAYS_STATIC_INLINE void __set_MIR(uint32_t mir)
547 {
548 #ifdef __CK610
549     __ASM volatile("cpseti 15");
550     __ASM volatile("cpwcr %0, cpcr0" : : "r"(mir));
551 #else
552     __ASM volatile("mtcr %0, cr<0, 15>" : : "r"(mir));
553 #endif
554 }
555 
556 
557 /**
558   \brief   Get MEL0
559   \details Returns the content of the MEL0 Register.
560   \return               MEL0 Register value
561  */
__get_MEL0(void)562 __ALWAYS_STATIC_INLINE uint32_t __get_MEL0(void)
563 {
564     uint32_t result;
565 #ifdef __CK610
566     __ASM volatile("cpseti 15");
567     __ASM volatile("cprcr %0, cpcr2" : "=r"(result));
568 #else
569     __ASM volatile("mfcr %0, cr<2, 15>" : "=r"(result));
570 #endif
571     return (result);
572 }
573 
574 /**
575   \brief   Set MEL0
576   \details Writes the given value to the MEL0 Register.
577   \param [in]    mel0  MEL0 Register value to set
578  */
__set_MEL0(uint32_t mel0)579 __ALWAYS_STATIC_INLINE void __set_MEL0(uint32_t mel0)
580 {
581 #ifdef __CK610
582     __ASM volatile("cpseti 15");
583     __ASM volatile("cpwcr %0, cpcr2" : : "r"(mel0));
584 #else
585     __ASM volatile("mtcr %0, cr<2, 15>" : : "r"(mel0));
586 #endif
587 }
588 
589 
590 /**
591   \brief   Get MEL1
592   \details Returns the content of the MEL1 Register.
593   \return               MEL1 Register value
594  */
__get_MEL1(void)595 __ALWAYS_STATIC_INLINE uint32_t __get_MEL1(void)
596 {
597     uint32_t result;
598 #ifdef __CK610
599     __ASM volatile("cpseti 15");
600     __ASM volatile("cprcr %0, cpcr3" : "=r"(result));
601 #else
602     __ASM volatile("mfcr %0, cr<3, 15>" : "=r"(result));
603 #endif
604     return (result);
605 }
606 
607 /**
608   \brief   Set MEL1
609   \details Writes the given value to the MEL1 Register.
610   \param [in]    mel1  MEL1 Register value to set
611  */
__set_MEL1(uint32_t mel1)612 __ALWAYS_STATIC_INLINE void __set_MEL1(uint32_t mel1)
613 {
614 #ifdef __CK610
615     __ASM volatile("cpseti 15");
616     __ASM volatile("cpwcr %0, cpcr3" : : "r"(mel1));
617 #else
618     __ASM volatile("mtcr %0, cr<3, 15>" : : "r"(mel1));
619 #endif
620 }
621 
622 
623 /**
624   \brief   Get MEH
625   \details Returns the content of the MEH Register.
626   \return               MEH Register value
627  */
__get_MEH(void)628 __ALWAYS_STATIC_INLINE uint32_t __get_MEH(void)
629 {
630     uint32_t result;
631 #ifdef __CK610
632     __ASM volatile("cpseti 15");
633     __ASM volatile("cprcr %0, cpcr4" : "=r"(result));
634 #else
635     __ASM volatile("mfcr %0, cr<4, 15>" : "=r"(result));
636 #endif
637     return (result);
638 }
639 
640 /**
641   \brief   Set MEH
642   \details Writes the given value to the MEH Register.
643   \param [in]    meh  MEH Register value to set
644  */
__set_MEH(uint32_t meh)645 __ALWAYS_STATIC_INLINE void __set_MEH(uint32_t meh)
646 {
647 #ifdef __CK610
648     __ASM volatile("cpseti 15");
649     __ASM volatile("cpwcr %0, cpcr4" : : "b"(meh));
650 #else
651     __ASM volatile("mtcr %0, cr<4, 15>" : : "r"(meh));
652 #endif
653 }
654 
655 
656 /**
657   \brief   Get MPR
658   \details Returns the content of the MPR Register.
659   \return               MPR Register value
660  */
__get_MPR(void)661 __ALWAYS_STATIC_INLINE uint32_t __get_MPR(void)
662 {
663     uint32_t result;
664 #ifdef __CK610
665     __ASM volatile("cpseti 15");
666     __ASM volatile("cprcr %0, cpcr6" : "=r"(result));
667 #else
668     __ASM volatile("mfcr %0, cr<6, 15>" : "=r"(result));
669 #endif
670     return (result);
671 }
672 
673 /**
674   \brief   Set MPR
675   \details Writes the given value to the MPR Register.
676   \param [in]    mpr  MPR Register value to set
677  */
__set_MPR(uint32_t mpr)678 __ALWAYS_STATIC_INLINE void __set_MPR(uint32_t mpr)
679 {
680 #ifdef __CK610
681     __ASM volatile("cpseti 15");
682     __ASM volatile("cpwcr %0, cpcr6" : : "r"(mpr));
683 #else
684     __ASM volatile("mtcr %0, cr<6, 15>" : : "r"(mpr));
685 #endif
686 }
687 
688 
689 /**
690   \brief   Get MCIR
691   \details Returns the content of the MCIR Register.
692   \return               MCIR Register value
693  */
__get_MCIR(void)694 __ALWAYS_STATIC_INLINE uint32_t __get_MCIR(void)
695 {
696     uint32_t result;
697 #ifdef __CK610
698     __ASM volatile("cpseti 15");
699     __ASM volatile("cprcr %0, cpcr8" : "=r"(result));
700 #else
701     __ASM volatile("mfcr %0, cr<8, 15>" : "=r"(result));
702 #endif
703     return (result);
704 }
705 
706 /**
707   \brief   Set MCIR
708   \details Writes the given value to the MCIR Register.
709   \param [in]    mcir  MCIR Register value to set
710  */
__set_MCIR(uint32_t mcir)711 __ALWAYS_STATIC_INLINE void __set_MCIR(uint32_t mcir)
712 {
713 #ifdef __CK610
714     __ASM volatile("cpseti 15");
715     __ASM volatile("cpwcr %0, cpcr8" : : "r"(mcir));
716 #else
717     __ASM volatile("mtcr %0, cr<8, 15>" : : "r"(mcir));
718 #endif
719 }
720 
721 
722 /**
723   \brief   Get MPGD
724   \details Returns the content of the MPGD Register.
725   \return               MPGD Register value
726  */
__get_MPGD(void)727 __ALWAYS_STATIC_INLINE uint32_t __get_MPGD(void)
728 {
729     uint32_t result;
730 #ifdef __CK610
731     __ASM volatile("cpseti 15");
732     __ASM volatile("cprcr %0, cpcr29" : "=r"(result));
733 #else
734     __ASM volatile("mfcr %0, cr<29, 15>" : "=r"(result));
735 #endif
736     return (result);
737 }
738 
739 /**
740   \brief   Set MPGD
741   \details Writes the given value to the MPGD Register.
742   \param [in]    mpgd  MPGD Register value to set
743  */
__set_MPGD(uint32_t mpgd)744 __ALWAYS_STATIC_INLINE void __set_MPGD(uint32_t mpgd)
745 {
746 #ifdef __CK610
747     __ASM volatile("cpseti 15");
748     __ASM volatile("cpwcr %0, cpcr29" : : "r"(mpgd));
749 #else
750     __ASM volatile("mtcr %0, cr<29, 15>" : : "r"(mpgd));
751 #endif
752 }
753 
754 
755 /**
756   \brief   Get MSA0
757   \details Returns the content of the MSA0 Register.
758   \return               MSA0 Register value
759  */
__get_MSA0(void)760 __ALWAYS_STATIC_INLINE uint32_t __get_MSA0(void)
761 {
762     uint32_t result;
763 #ifdef __CK610
764     __ASM volatile("cpseti 15");
765     __ASM volatile("cprcr %0, cpcr30" : "=r"(result));
766 #else
767     __ASM volatile("mfcr %0, cr<30, 15>" : "=r"(result));
768 #endif
769     return (result);
770 }
771 
772 /**
773   \brief   Set MSA0
774   \details Writes the given value to the MSA0 Register.
775   \param [in]    msa0  MSA0 Register value to set
776  */
__set_MSA0(uint32_t msa0)777 __ALWAYS_STATIC_INLINE void __set_MSA0(uint32_t msa0)
778 {
779 #ifdef __CK610
780     __ASM volatile("cpseti 15");
781     __ASM volatile("cpwcr %0, cpcr30" : : "r"(msa0));
782 #else
783     __ASM volatile("mtcr %0, cr<30, 15>" : : "r"(msa0));
784 #endif
785 }
786 
787 
788 /**
789   \brief   Get MSA1
790   \details Returns the content of the MSA1 Register.
791   \return               MSA1 Register value
792  */
__get_MSA1(void)793 __ALWAYS_STATIC_INLINE uint32_t __get_MSA1(void)
794 {
795     uint32_t result;
796 
797 #ifdef __CK610
798     __ASM volatile("cpseti 15");
799     __ASM volatile("cprcr %0, cpcr31" : "=r"(result));
800 #else
801     __ASM volatile("mfcr %0, cr<31, 15>" : "=r"(result));
802 #endif
803     return (result);
804 }
805 
806 /**
807   \brief   Set MSA1
808   \details Writes the given value to the MSA1 Register.
809   \param [in]    msa1  MSA1 Register value to set
810  */
__set_MSA1(uint32_t msa1)811 __ALWAYS_STATIC_INLINE void __set_MSA1(uint32_t msa1)
812 {
813 #ifdef __CK610
814     __ASM volatile("cpseti 15");
815     __ASM volatile("cpwcr %0, cpcr31" : : "r"(msa1));
816 #else
817     __ASM volatile("mtcr %0, cr<31, 15>" : : "r"(msa1));
818 #endif
819 }
820 
821 
822 /**
823   \brief   Enable interrupts and exceptions
824   \details Enables interrupts and exceptions by setting the IE-bit and EE-bit in the PSR.
825            Can only be executed in Privileged modes.
826  */
__enable_excp_irq(void)827 __ALWAYS_STATIC_INLINE void __enable_excp_irq(void)
828 {
829     __ASM volatile("psrset ee, ie");
830 }
831 
832 
833 /**
834   \brief   Disable interrupts and exceptions
835   \details Disables interrupts and exceptions by clearing the IE-bit and EE-bit in the PSR.
836            Can only be executed in Privileged modes.
837  */
__disable_excp_irq(void)838 __ALWAYS_STATIC_INLINE void __disable_excp_irq(void)
839 {
840     __ASM volatile("psrclr ee, ie");
841 }
842 
843 /**
844   \brief   Get GSR
845   \details Returns the content of the GSR Register.
846   \return               GSR Register value
847  */
__get_GSR(void)848 __ALWAYS_STATIC_INLINE uint32_t __get_GSR(void)
849 {
850     uint32_t result;
851 
852 #ifdef __CK610
853     __ASM volatile("mfcr %0, cr12" : "=r"(result));
854 #else
855     __ASM volatile("mfcr %0, cr<12, 0>" : "=r"(result));
856 #endif
857     return (result);
858 }
859 
860 /**
861   \brief   Get GCR
862   \details Returns the content of the GCR Register.
863   \return               GCR Register value
864  */
__get_GCR(void)865 __ALWAYS_STATIC_INLINE uint32_t __get_GCR(void)
866 {
867     uint32_t result;
868 
869 #ifdef __CK610
870     __ASM volatile("mfcr %0, cr11" : "=r"(result));
871 #else
872     __ASM volatile("mfcr %0, cr<11, 0>" : "=r"(result));
873 #endif
874     return (result);
875 }
876 
877 /**
878   \brief   Set GCR
879   \details Writes the given value to the GCR Register.
880   \param [in]    gcr  GCR Register value to set
881  */
__set_GCR(uint32_t gcr)882 __ALWAYS_STATIC_INLINE void __set_GCR(uint32_t gcr)
883 {
884 #ifdef __CK610
885     __ASM volatile("mtcr %0, cr11" : : "r"(gcr));
886 #else
887     __ASM volatile("mtcr %0, cr<11, 0>" : : "r"(gcr));
888 #endif
889 }
890 
891 /**
892   \brief   Get WSSR
893   \details Returns the content of the WSSR Register, must be accessed in TEE
894   \return               WSSR Register value
895  */
__get_WSSR(void)896 __ALWAYS_STATIC_INLINE uint32_t __get_WSSR(void)
897 {
898     uint32_t result;
899 
900     __ASM volatile("mfcr %0, cr<0, 3>" : "=r"(result));
901     return (result);
902 }
903 
904 /**
905   \brief   Get WRCR
906   \details Returns the content of the WRCR Register, must be accessed in TEE
907   \return               WRCR Register value
908  */
__get_WRCR(void)909 __ALWAYS_STATIC_INLINE uint32_t __get_WRCR(void)
910 {
911     uint32_t result;
912 
913     __ASM volatile("mfcr %0, cr<1, 3>" : "=r"(result));
914     return (result);
915 }
916 
917 /**
918   \brief   Set WRCR
919   \details Writes the given value to the WRCR Register, must be accessed in TEE
920   \param [in]    wrcr  WRCR Register value to set
921  */
__set_WRCR(uint32_t wrcr)922 __ALWAYS_STATIC_INLINE void __set_WRCR(uint32_t wrcr)
923 {
924     __ASM volatile("mtcr %0, cr<1, 3>" : : "r"(wrcr));
925 }
926 
927 /**
928   \brief   Get DCR
929   \details Returns the content of the DCR Register, must be accessed in TEE
930   \return               DCR Register value
931  */
__get_DCR(void)932 __ALWAYS_STATIC_INLINE uint32_t __get_DCR(void)
933 {
934     uint32_t result;
935 
936     __ASM volatile("mfcr %0, cr<8, 3>" : "=r"(result));
937     return (result);
938 }
939 
940 /**
941   \brief   Set DCR
942   \details Writes the given value to the DCR Register, must be accessed in TEE
943   \param [in]    dcr  DCR Register value to set
944  */
__set_DCR(uint32_t dcr)945 __ALWAYS_STATIC_INLINE void __set_DCR(uint32_t dcr)
946 {
947     __ASM volatile("mtcr %0, cr<8, 3>" : : "r"(dcr));
948 }
949 
950 /**
951   \brief   Get PCR
952   \details Returns the content of the PCR Register, must be accessed in TEE
953   \return               PCR Register value
954  */
__get_PCR(void)955 __ALWAYS_STATIC_INLINE uint32_t __get_PCR(void)
956 {
957     uint32_t result;
958 
959     __ASM volatile("mfcr %0, cr<9, 3>" : "=r"(result));
960     return (result);
961 }
962 
963 /**
964   \brief   Set PCR
965   \details Writes the given value to the PCR Register, must be accessed in TEE
966   \param [in]    pcr  PCR Register value to set
967  */
__set_PCR(uint32_t pcr)968 __ALWAYS_STATIC_INLINE void __set_PCR(uint32_t pcr)
969 {
970     __ASM volatile("mtcr %0, cr<9, 3>" : : "r"(pcr));
971 }
972 
973 /**
974   \brief   Get EBR
975   \details Returns the content of the EBR Register.
976   \return               EBR Register value
977  */
__get_EBR(void)978 __ALWAYS_STATIC_INLINE uint32_t __get_EBR(void)
979 {
980     uint32_t result;
981 
982     __ASM volatile("mfcr %0, cr<1, 1>" : "=r"(result));
983     return (result);
984 }
985 
986 /**
987   \brief   Set EBR
988   \details Writes the given value to the EBR Register.
989   \param [in]    ebr  EBR Register value to set
990  */
__set_EBR(uint32_t ebr)991 __ALWAYS_STATIC_INLINE void __set_EBR(uint32_t ebr)
992 {
993     __ASM volatile("mtcr %0, cr<1, 1>" : : "r"(ebr));
994 }
995 
996 /*@} end of CSI_Core_RegAccFunctions */
997 
998 /* ##########################  Core Instruction Access  ######################### */
999 /** \defgroup CSI_Core_InstructionInterface CSI Core Instruction Interface
1000   Access to dedicated instructions
1001   @{
1002 */
1003 
1004 #define __CSI_GCC_OUT_REG(r) "=r" (r)
1005 #define __CSI_GCC_USE_REG(r) "r" (r)
1006 
1007 /**
1008   \brief   No Operation
1009   \details No Operation does nothing. This instruction can be used for code alignment purposes.
1010  */
__NOP(void)1011 __ALWAYS_STATIC_INLINE void __NOP(void)
1012 {
1013     __ASM volatile("nop");
1014 }
1015 
1016 
1017 /**
1018   \brief   Wait For Interrupt
1019   \details Wait For Interrupt is a hint instruction that suspends execution until one of a number of events occurs.
1020  */
__WFI(void)1021 __ALWAYS_STATIC_INLINE void __WFI(void)
1022 {
1023     __ASM volatile("wait");
1024 }
1025 
1026 /**
1027   \brief   Wait For Interrupt
1028   \details Wait For Interrupt is a hint instruction that suspends execution until one interrupt occurs.
1029  */
__WAIT(void)1030 __ALWAYS_STATIC_INLINE void __WAIT(void)
1031 {
1032     __ASM volatile("wait");
1033 }
1034 
1035 /**
1036   \brief   Doze For Interrupt
1037   \details Doze For Interrupt is a hint instruction that suspends execution until one interrupt occurs.
1038  */
__DOZE(void)1039 __ALWAYS_STATIC_INLINE void __DOZE(void)
1040 {
1041     __ASM volatile("doze");
1042 }
1043 
1044 /**
1045   \brief   Stop For Interrupt
1046   \details Stop For Interrupt is a hint instruction that suspends execution until one interrupt occurs.
1047  */
__STOP(void)1048 __ALWAYS_STATIC_INLINE void __STOP(void)
1049 {
1050     __ASM volatile("stop");
1051 }
1052 
1053 /**
1054   \brief   Instruction Synchronization Barrier
1055   \details Instruction Synchronization Barrier flushes the pipeline in the processor,
1056            so that all instructions following the ISB are fetched from cache or memory,
1057            after the instruction has been completed.
1058  */
__ISB(void)1059 __ALWAYS_STATIC_INLINE void __ISB(void)
1060 {
1061     __ASM volatile("sync"::: "memory");
1062 }
1063 
1064 
1065 /**
1066   \brief   Data Synchronization Barrier
1067   \details Acts as a special kind of Data Memory Barrier.
1068            It completes when all explicit memory accesses before this instruction complete.
1069  */
__DSB(void)1070 __ALWAYS_STATIC_INLINE void __DSB(void)
1071 {
1072     __ASM volatile("sync"::: "memory");
1073 }
1074 
1075 
1076 /**
1077   \brief   Data Memory Barrier
1078   \details Ensures the apparent order of the explicit memory operations before
1079            and after the instruction, without ensuring their completion.
1080  */
__DMB(void)1081 __ALWAYS_STATIC_INLINE void __DMB(void)
1082 {
1083     __ASM volatile("sync"::: "memory");
1084 }
1085 
1086 /**
1087   \brief   Search from the highest bit that the very first bit which's value is 1.
1088   \param [in]    value  Value to  bit search.
1089   \return               if the highest bit' value is 1,  return 0, and if lowest bit's value is 1, return 31, otherwise return 32.
1090  */
1091 #if !defined(__CK610) || !(__CK80X == 1)
__FF0(uint32_t value)1092 __ALWAYS_STATIC_INLINE uint32_t __FF0(uint32_t value)
1093 {
1094     uint32_t ret;
1095 
1096     __ASM volatile("ff0 %0, %1" : "=r"(ret) : "r"(value));
1097     return ret;
1098 }
1099 #endif
1100 
1101 /**
1102   \brief   Search from the highest bit that the very first bit which's value is 0.
1103   \param [in]    value  Value to  bit search.
1104   \return               if the highest bit' value is 0,  return 0, and if lowest bit's value is 0, return 31, otherwise return 32.
1105  */
1106 #if !(__CK80X == 1)
__FF1(uint32_t value)1107 __ALWAYS_STATIC_INLINE uint32_t __FF1(uint32_t value)
1108 {
1109     uint32_t ret;
1110 #if !defined (__CK610)
1111     __ASM volatile("ff1 %0, %1" : "=r"(ret) : "r"(value));
1112 #else
1113     ret = value;
1114     __ASM volatile("ff1 %0" : "=r"(ret):);
1115 #endif
1116     return ret;
1117 }
1118 #endif
1119 
1120 /**
1121   \brief   Reverse byte order (32 bit)
1122   \details Reverses the byte order in integer value.
1123   \param [in]    value  Value to reverse
1124   \return               Reversed value
1125  */
__REV(uint32_t value)1126 __ALWAYS_STATIC_INLINE uint32_t __REV(uint32_t value)
1127 {
1128     return __builtin_bswap32(value);
1129 }
1130 
1131 
1132 /**
1133   \brief   Reverse byte order (16 bit)
1134   \details Reverses the byte order in two unsigned short values.
1135   \param [in]    value  Value to reverse
1136   \return               Reversed value
1137  */
__REV16(uint32_t value)1138 __ALWAYS_STATIC_INLINE uint32_t __REV16(uint32_t value)
1139 {
1140     uint32_t result;
1141 #if (__CK80X >= 2)
1142     __ASM volatile("revh %0, %1" : __CSI_GCC_OUT_REG(result) : __CSI_GCC_USE_REG(value));
1143 #else
1144     result = ((value & 0xFF000000) >> 8) | ((value & 0x00FF0000) << 8) |
1145              ((value & 0x0000FF00) >> 8) | ((value & 0x000000FF) << 8);
1146 #endif
1147     return (result);
1148 }
1149 
1150 
1151 /**
1152   \brief   Reverse byte order in signed short value
1153   \details Reverses the byte order in a signed short value with sign extension to integer.
1154   \param [in]    value  Value to reverse
1155   \return               Reversed value
1156  */
__REVSH(int32_t value)1157 __ALWAYS_STATIC_INLINE int32_t __REVSH(int32_t value)
1158 {
1159     return (short)(((value & 0xFF00) >> 8) | ((value & 0x00FF) << 8));
1160 }
1161 
1162 
1163 /**
1164   \brief   Rotate Right in unsigned value (32 bit)
1165   \details Rotate Right (immediate) provides the value of the contents of a register rotated by a variable number of bits.
1166   \param [in]    op1  Value to rotate
1167   \param [in]    op2  Number of Bits to rotate
1168   \return               Rotated value
1169  */
__ROR(uint32_t op1,uint32_t op2)1170 __ALWAYS_STATIC_INLINE uint32_t __ROR(uint32_t op1, uint32_t op2)
1171 {
1172     return (op1 >> op2) | (op1 << (32U - op2));
1173 }
1174 
1175 
1176 /**
1177   \brief   Breakpoint
1178   \details Causes the processor to enter Debug state
1179            Debug tools can use this to investigate system state when the instruction at a particular address is reached.
1180  */
__BKPT(void)1181 __ALWAYS_STATIC_INLINE void __BKPT(void)
1182 {
1183     __ASM volatile("bkpt");
1184 }
1185 
1186 /**
1187   \brief   Reverse bit order of value
1188   \details Reverses the bit order of the given value.
1189   \param [in]    value  Value to reverse
1190   \return               Reversed value
1191  */
__RBIT(uint32_t value)1192 __ALWAYS_STATIC_INLINE uint32_t __RBIT(uint32_t value)
1193 {
1194     uint32_t result;
1195 
1196 #if (__CK80X >= 0x03U)
1197     __ASM volatile("brev %0, %1" : "=r"(result) : "r"(value));
1198 #else
1199     int32_t s = 4 /*sizeof(v)*/ * 8 - 1; /* extra shift needed at end */
1200 
1201     result = value;                      /* r will be reversed bits of v; first get LSB of v */
1202 
1203     for (value >>= 1U; value; value >>= 1U) {
1204         result <<= 1U;
1205         result |= value & 1U;
1206         s--;
1207     }
1208 
1209     result <<= s;                        /* shift when v's highest bits are zero */
1210 #endif
1211     return (result);
1212 }
1213 
1214 
1215 /**
1216   \brief   Count leading zeros
1217   \details Counts the number of leading zeros of a data value.
1218   \param [in]  value  Value to count the leading zeros
1219   \return             number of leading zeros in value
1220  */
1221 #define __CLZ             __builtin_clz
1222 /**
1223   \details This function saturates a signed value.
1224   \param [in]    x   Value to be saturated
1225   \param [in]    y   Bit position to saturate to [1..32]
1226   \return            Saturated value.
1227  */
__SSAT(int32_t x,uint32_t y)1228 __ALWAYS_STATIC_INLINE int32_t __SSAT(int32_t x, uint32_t y)
1229 {
1230     int32_t posMax, negMin;
1231     uint32_t i;
1232 
1233     posMax = 1;
1234 
1235     for (i = 0; i < (y - 1); i++) {
1236         posMax = posMax * 2;
1237     }
1238 
1239     if (x > 0) {
1240         posMax = (posMax - 1);
1241 
1242         if (x > posMax) {
1243             x = posMax;
1244         }
1245 
1246 //    x &= (posMax * 2 + 1);
1247     } else {
1248         negMin = -posMax;
1249 
1250         if (x < negMin) {
1251             x = negMin;
1252         }
1253 
1254 //    x &= (posMax * 2 - 1);
1255     }
1256 
1257     return (x);
1258 }
1259 
1260 /**
1261   \brief   Unsigned Saturate
1262   \details Saturates an unsigned value.
1263   \param [in]  value  Value to be saturated
1264   \param [in]    sat  Bit position to saturate to (0..31)
1265   \return             Saturated value
1266  */
__USAT(uint32_t value,uint32_t sat)1267 __ALWAYS_STATIC_INLINE uint32_t __USAT(uint32_t value, uint32_t sat)
1268 {
1269     uint32_t result;
1270 
1271     if ((((0xFFFFFFFF >> sat) << sat) & value) != 0) {
1272         result = 0xFFFFFFFF >> (32 - sat);
1273     } else {
1274         result = value;
1275     }
1276 
1277     return (result);
1278 }
1279 
1280 /**
1281   \brief   Unsigned Saturate for internal use
1282   \details Saturates an unsigned value, should not call directly.
1283   \param [in]  value  Value to be saturated
1284   \param [in]    sat  Bit position to saturate to (0..31)
1285   \return             Saturated value
1286  */
__IUSAT(uint32_t value,uint32_t sat)1287 __ALWAYS_STATIC_INLINE uint32_t __IUSAT(uint32_t value, uint32_t sat)
1288 {
1289     uint32_t result;
1290 
1291     if (value & 0x80000000) { /* only overflow set bit-31 */
1292         result = 0;
1293     } else if ((((0xFFFFFFFF >> sat) << sat) & value) != 0) {
1294         result = 0xFFFFFFFF >> (32 - sat);
1295     } else {
1296         result = value;
1297     }
1298 
1299     return (result);
1300 }
1301 
1302 /**
1303   \brief   Rotate Right with Extend
1304   \details This function moves each bit of a bitstring right by one bit.
1305            The carry input is shifted in at the left end of the bitstring.
1306   \note    carry input will always 0.
1307   \param [in]    op1  Value to rotate
1308   \return               Rotated value
1309  */
__RRX(uint32_t op1)1310 __ALWAYS_STATIC_INLINE uint32_t __RRX(uint32_t op1)
1311 {
1312 #if (__CK80X >= 2)
1313     uint32_t res = 0;
1314     __ASM volatile("bgeni    t0, 31\n\t"
1315                    "lsri     %0, 1\n\t"
1316                    "movt     %1, t0\n\t"
1317                    "or       %1, %1, %0\n\t"
1318                : "=r"(op1), "=r"(res): "0"(op1), "1"(res): "t0");
1319     return res;
1320 #else
1321     uint32_t res = 0;
1322     __ASM volatile("movi     r7, 0\n\t"
1323                    "bseti    r7, 31\n\t"
1324                    "lsri     %0, 1\n\t"
1325                    "bf       1f\n\t"
1326                    "mov     %1, r7\n\t"
1327                    "1:\n\t"
1328                    "or       %1, %1, %0\n\t"
1329                : "=r"(op1), "=r"(res): "0"(op1), "1"(res): "r7");
1330     return res;
1331 #endif
1332 }
1333 
1334 /**
1335   \brief   LDRT Unprivileged (8 bit)
1336   \details Executes a Unprivileged LDRT instruction for 8 bit value.
1337   \param [in]    addr  Pointer to location
1338   \return             value of type uint8_t at (*ptr)
1339  */
__LDRBT(volatile uint8_t * addr)1340 __ALWAYS_STATIC_INLINE uint8_t __LDRBT(volatile uint8_t *addr)
1341 {
1342     uint32_t result;
1343 //#warning "__LDRBT"
1344     __ASM volatile("ldb %0, (%1, 0)" : "=r"(result) : "r"(addr));
1345     return ((uint8_t) result);    /* Add explicit type cast here */
1346 }
1347 
1348 
1349 /**
1350   \brief   LDRT Unprivileged (16 bit)
1351   \details Executes a Unprivileged LDRT instruction for 16 bit values.
1352   \param [in]    addr  Pointer to location
1353   \return        value of type uint16_t at (*ptr)
1354  */
__LDRHT(volatile uint16_t * addr)1355 __ALWAYS_STATIC_INLINE uint16_t __LDRHT(volatile uint16_t *addr)
1356 {
1357     uint32_t result;
1358 
1359 //#warning "__LDRHT"
1360     __ASM volatile("ldh %0, (%1, 0)" : "=r"(result) : "r"(addr));
1361     return ((uint16_t) result);    /* Add explicit type cast here */
1362 }
1363 
1364 
1365 /**
1366   \brief   LDRT Unprivileged (32 bit)
1367   \details Executes a Unprivileged LDRT instruction for 32 bit values.
1368   \param [in]    addr  Pointer to location
1369   \return        value of type uint32_t at (*ptr)
1370  */
__LDRT(volatile uint32_t * addr)1371 __ALWAYS_STATIC_INLINE uint32_t __LDRT(volatile uint32_t *addr)
1372 {
1373     uint32_t result;
1374 
1375 //#warning "__LDRT"
1376     __ASM volatile("ldw %0, (%1, 0)" : "=r"(result) : "r"(addr));
1377     return (result);
1378 }
1379 
1380 
1381 /**
1382   \brief   STRT Unprivileged (8 bit)
1383   \details Executes a Unprivileged STRT instruction for 8 bit values.
1384   \param [in]  value  Value to store
1385   \param [in]    addr  Pointer to location
1386  */
__STRBT(uint8_t value,volatile uint8_t * addr)1387 __ALWAYS_STATIC_INLINE void __STRBT(uint8_t value, volatile uint8_t *addr)
1388 {
1389 //#warning "__STRBT"
1390     __ASM volatile("stb %1, (%0, 0)" :: "r"(addr), "r"((uint32_t)value) : "memory");
1391 }
1392 
1393 
1394 /**
1395   \brief   STRT Unprivileged (16 bit)
1396   \details Executes a Unprivileged STRT instruction for 16 bit values.
1397   \param [in]  value  Value to store
1398   \param [in]    addr  Pointer to location
1399  */
__STRHT(uint16_t value,volatile uint16_t * addr)1400 __ALWAYS_STATIC_INLINE void __STRHT(uint16_t value, volatile uint16_t *addr)
1401 {
1402 //#warning "__STRHT"
1403     __ASM volatile("sth %1, (%0, 0)" :: "r"(addr), "r"((uint32_t)value) : "memory");
1404 }
1405 
1406 
1407 /**
1408   \brief   STRT Unprivileged (32 bit)
1409   \details Executes a Unprivileged STRT instruction for 32 bit values.
1410   \param [in]  value  Value to store
1411   \param [in]    addr  Pointer to location
1412  */
__STRT(uint32_t value,volatile uint32_t * addr)1413 __ALWAYS_STATIC_INLINE void __STRT(uint32_t value, volatile uint32_t *addr)
1414 {
1415 //#warning "__STRT"
1416     __ASM volatile("stw %1, (%0, 0)" :: "r"(addr), "r"(value) : "memory");
1417 }
1418 
1419 /*@}*/ /* end of group CSI_Core_InstructionInterface */
1420 
1421 
1422 /* ##########################  FPU functions  #################################### */
1423 /**
1424   \ingroup  CSI_Core_FunctionInterface
1425   \defgroup CSI_Core_FpuFunctions FPU Functions
1426   \brief    Function that provides FPU type.
1427   @{
1428  */
1429 
1430 /**
1431   \brief   get FPU type
1432   \details returns the FPU type, always 0.
1433   \returns
1434    - \b  0: No FPU
1435    - \b  1: Single precision FPU
1436    - \b  2: Double + Single precision FPU
1437  */
__get_FPUType(void)1438 __ALWAYS_STATIC_INLINE uint32_t __get_FPUType(void)
1439 {
1440 //FIXME:
1441     return 0;
1442 }
1443 
1444 /*@} end of CSI_Core_FpuFunctions */
1445 
1446 /* ###################  Compiler specific Intrinsics  ########################### */
1447 /** \defgroup CSI_SIMD_intrinsics CSI SIMD Intrinsics
1448   Access to dedicated SIMD instructions \n
1449   Single Instruction Multiple Data (SIMD) extensions are provided to simplify development of application software. SIMD extensions increase the processing capability without materially increasing the power consumption. The SIMD extensions are completely transparent to the operating system (OS), allowing existing OS ports to be used.
1450 
1451   @{
1452 */
1453 
1454 /**
1455   \brief   Halfword packing instruction. Combines bits[15:0] of val1 with bits[31:16]
1456            of val2 levitated with the val3.
1457   \details Combine a halfword from one register with a halfword from another register.
1458            The second argument can be left-shifted before extraction of the halfword.
1459   \param [in]    val1   first 16-bit operands
1460   \param [in]    val2   second 16-bit operands
1461   \param [in]    val3   value for left-shifting val2. Value range [0..31].
1462   \return               the combination of halfwords.
1463   \remark
1464                  res[15:0]  = val1[15:0]              \n
1465                  res[31:16] = val2[31:16] << val3
1466  */
__PKHBT(uint32_t val1,uint32_t val2,uint32_t val3)1467 __ALWAYS_STATIC_INLINE uint32_t __PKHBT(uint32_t val1, uint32_t val2, uint32_t val3)
1468 {
1469     return ((((int32_t)(val1) << 0) & (int32_t)0x0000FFFF) | (((int32_t)(val2) << val3) & (int32_t)0xFFFF0000));
1470 }
1471 
1472 /**
1473   \brief   Halfword packing instruction. Combines bits[31:16] of val1 with bits[15:0]
1474            of val2 right-shifted with the val3.
1475   \details Combine a halfword from one register with a halfword from another register.
1476            The second argument can be right-shifted before extraction of the halfword.
1477   \param [in]    val1   first 16-bit operands
1478   \param [in]    val2   second 16-bit operands
1479   \param [in]    val3   value for right-shifting val2. Value range [1..32].
1480   \return               the combination of halfwords.
1481   \remark
1482                  res[15:0]  = val2[15:0] >> val3        \n
1483                  res[31:16] = val1[31:16]
1484  */
__PKHTB(uint32_t val1,uint32_t val2,uint32_t val3)1485 __ALWAYS_STATIC_INLINE uint32_t __PKHTB(uint32_t val1, uint32_t val2, uint32_t val3)
1486 {
1487     return ((((int32_t)(val1) << 0) & (int32_t)0xFFFF0000) | (((int32_t)(val2) >> val3) & (int32_t)0x0000FFFF));
1488 }
1489 
1490 /**
1491   \brief   Dual 16-bit signed saturate.
1492   \details This function saturates a signed value.
1493   \param [in]    x   two signed 16-bit values to be saturated.
1494   \param [in]    y   bit position for saturation, an integral constant expression in the range 1 to 16.
1495   \return        the sum of the absolute differences of the following bytes, added to the accumulation value:\n
1496                  the signed saturation of the low halfword in val1, saturated to the bit position specified in
1497                  val2 and returned in the low halfword of the return value.\n
1498                  the signed saturation of the high halfword in val1, saturated to the bit position specified in
1499                  val2 and returned in the high halfword of the return value.
1500  */
__SSAT16(int32_t x,const uint32_t y)1501 __ALWAYS_STATIC_INLINE uint32_t __SSAT16(int32_t x, const uint32_t y)
1502 {
1503     int32_t r = 0, s = 0;
1504 
1505     r = __SSAT((((int32_t)x << 16) >> 16), y) & (int32_t)0x0000FFFF;
1506     s = __SSAT((((int32_t)x) >> 16), y) & (int32_t)0x0000FFFF;
1507 
1508     return ((uint32_t)((s << 16) | (r)));
1509 }
1510 
1511 /**
1512   \brief   Dual 16-bit unsigned saturate.
1513   \details This function enables you to saturate two signed 16-bit values to a selected unsigned range.
1514   \param [in]    x   two signed 16-bit values to be saturated.
1515   \param [in]    y   bit position for saturation, an integral constant expression in the range 1 to 16.
1516   \return        the saturation of the two signed 16-bit values, as non-negative values:
1517                  the saturation of the low halfword in val1, saturated to the bit position specified in
1518                  val2 and returned in the low halfword of the return value.\n
1519                  the saturation of the high halfword in val1, saturated to the bit position specified in
1520                  val2 and returned in the high halfword of the return value.
1521  */
__USAT16(uint32_t x,const uint32_t y)1522 __ALWAYS_STATIC_INLINE uint32_t __USAT16(uint32_t x, const uint32_t y)
1523 {
1524     int32_t r = 0, s = 0;
1525 
1526     r = __IUSAT(((x << 16) >> 16), y) & 0x0000FFFF;
1527     s = __IUSAT(((x) >> 16), y) & 0x0000FFFF;
1528 
1529     return ((s << 16) | (r));
1530 }
1531 
1532 /**
1533   \brief   Quad 8-bit saturating addition.
1534   \details This function enables you to perform four 8-bit integer additions,
1535            saturating the results to the 8-bit signed integer range -2^7 <= x <= 2^7 - 1.
1536   \param [in]    x   first four 8-bit summands.
1537   \param [in]    y   second four 8-bit summands.
1538   \return        the saturated addition of the first byte of each operand in the first byte of the return value.\n
1539                  the saturated addition of the second byte of each operand in the second byte of the return value.\n
1540                  the saturated addition of the third byte of each operand in the third byte of the return value.\n
1541                  the saturated addition of the fourth byte of each operand in the fourth byte of the return value.\n
1542                  The returned results are saturated to the 8-bit signed integer range -2^7 <= x <= 2^7 - 1.
1543   \remark
1544                  res[7:0]   = val1[7:0]   + val2[7:0]        \n
1545                  res[15:8]  = val1[15:8]  + val2[15:8]       \n
1546                  res[23:16] = val1[23:16] + val2[23:16]      \n
1547                  res[31:24] = val1[31:24] + val2[31:24]
1548  */
__QADD8(uint32_t x,uint32_t y)1549 __ALWAYS_STATIC_INLINE uint32_t __QADD8(uint32_t x, uint32_t y)
1550 {
1551     int32_t r, s, t, u;
1552 
1553     r = __SSAT(((((int32_t)x << 24) >> 24) + (((int32_t)y << 24) >> 24)), 8) & (int32_t)0x000000FF;
1554     s = __SSAT(((((int32_t)x << 16) >> 24) + (((int32_t)y << 16) >> 24)), 8) & (int32_t)0x000000FF;
1555     t = __SSAT(((((int32_t)x <<  8) >> 24) + (((int32_t)y <<  8) >> 24)), 8) & (int32_t)0x000000FF;
1556     u = __SSAT(((((int32_t)x) >> 24) + (((int32_t)y) >> 24)), 8) & (int32_t)0x000000FF;
1557 
1558     return ((uint32_t)((u << 24) | (t << 16) | (s <<  8) | (r)));
1559 }
1560 
1561 /**
1562   \brief   Quad 8-bit unsigned saturating addition.
1563   \details This function enables you to perform four unsigned 8-bit integer additions,
1564            saturating the results to the 8-bit unsigned integer range 0 < x < 2^8 - 1.
1565   \param [in]    x   first four 8-bit summands.
1566   \param [in]    y   second four 8-bit summands.
1567   \return        the saturated addition of the first byte of each operand in the first byte of the return value.\n
1568                  the saturated addition of the second byte of each operand in the second byte of the return value.\n
1569                  the saturated addition of the third byte of each operand in the third byte of the return value.\n
1570                  the saturated addition of the fourth byte of each operand in the fourth byte of the return value.\n
1571                  The returned results are saturated to the 8-bit signed integer range 0 <= x <= 2^8 - 1.
1572   \remark
1573                  res[7:0]   = val1[7:0]   + val2[7:0]        \n
1574                  res[15:8]  = val1[15:8]  + val2[15:8]       \n
1575                  res[23:16] = val1[23:16] + val2[23:16]      \n
1576                  res[31:24] = val1[31:24] + val2[31:24]
1577  */
__UQADD8(uint32_t x,uint32_t y)1578 __ALWAYS_STATIC_INLINE uint32_t __UQADD8(uint32_t x, uint32_t y)
1579 {
1580     int32_t r, s, t, u;
1581 
1582     r = __IUSAT((((x << 24) >> 24) + ((y << 24) >> 24)), 8) & 0x000000FF;
1583     s = __IUSAT((((x << 16) >> 24) + ((y << 16) >> 24)), 8) & 0x000000FF;
1584     t = __IUSAT((((x <<  8) >> 24) + ((y <<  8) >> 24)), 8) & 0x000000FF;
1585     u = __IUSAT((((x) >> 24) + ((y) >> 24)), 8) & 0x000000FF;
1586 
1587     return ((u << 24) | (t << 16) | (s <<  8) | (r));
1588 }
1589 
1590 /**
1591   \brief   Quad 8-bit signed addition.
1592   \details This function performs four 8-bit signed integer additions.
1593   \param [in]    x  first four 8-bit summands.
1594   \param [in]    y  second four 8-bit summands.
1595   \return        the addition of the first bytes from each operand, in the first byte of the return value.\n
1596                  the addition of the second bytes of each operand, in the second byte of the return value.\n
1597                  the addition of the third bytes of each operand, in the third byte of the return value.\n
1598                  the addition of the fourth bytes of each operand, in the fourth byte of the return value.
1599   \remark
1600                  res[7:0]   = val1[7:0]   + val2[7:0]        \n
1601                  res[15:8]  = val1[15:8]  + val2[15:8]       \n
1602                  res[23:16] = val1[23:16] + val2[23:16]      \n
1603                  res[31:24] = val1[31:24] + val2[31:24]
1604  */
__SADD8(uint32_t x,uint32_t y)1605 __ALWAYS_STATIC_INLINE uint32_t __SADD8(uint32_t x, uint32_t y)
1606 {
1607     int32_t r, s, t, u;
1608 
1609     r = ((((int32_t)x << 24) >> 24) + (((int32_t)y << 24) >> 24)) & (int32_t)0x000000FF;
1610     s = ((((int32_t)x << 16) >> 24) + (((int32_t)y << 16) >> 24)) & (int32_t)0x000000FF;
1611     t = ((((int32_t)x <<  8) >> 24) + (((int32_t)y <<  8) >> 24)) & (int32_t)0x000000FF;
1612     u = ((((int32_t)x) >> 24) + (((int32_t)y) >> 24)) & (int32_t)0x000000FF;
1613 
1614     return ((uint32_t)((u << 24) | (t << 16) | (s <<  8) | (r)));
1615 }
1616 
1617 /**
1618   \brief   Quad 8-bit unsigned addition.
1619   \details This function performs four unsigned 8-bit integer additions.
1620   \param [in]    x  first four 8-bit summands.
1621   \param [in]    y  second four 8-bit summands.
1622   \return        the addition of the first bytes from each operand, in the first byte of the return value.\n
1623                  the addition of the second bytes of each operand, in the second byte of the return value.\n
1624                  the addition of the third bytes of each operand, in the third byte of the return value.\n
1625                  the addition of the fourth bytes of each operand, in the fourth byte of the return value.
1626   \remark
1627                  res[7:0]   = val1[7:0]   + val2[7:0]        \n
1628                  res[15:8]  = val1[15:8]  + val2[15:8]       \n
1629                  res[23:16] = val1[23:16] + val2[23:16]      \n
1630                  res[31:24] = val1[31:24] + val2[31:24]
1631  */
__UADD8(uint32_t x,uint32_t y)1632 __ALWAYS_STATIC_INLINE uint32_t __UADD8(uint32_t x, uint32_t y)
1633 {
1634     int32_t r, s, t, u;
1635 
1636     r = (((x << 24) >> 24) + ((y << 24) >> 24)) & 0x000000FF;
1637     s = (((x << 16) >> 24) + ((y << 16) >> 24)) & 0x000000FF;
1638     t = (((x <<  8) >> 24) + ((y <<  8) >> 24)) & 0x000000FF;
1639     u = (((x) >> 24) + ((y) >> 24)) & 0x000000FF;
1640 
1641     return ((u << 24) | (t << 16) | (s <<  8) | (r));
1642 }
1643 
1644 /**
1645   \brief   Quad 8-bit saturating subtract.
1646   \details This function enables you to perform four 8-bit integer subtractions,
1647            saturating the results to the 8-bit signed integer range -2^7 <= x <= 2^7 - 1.
1648   \param [in]    x   first four 8-bit summands.
1649   \param [in]    y   second four 8-bit summands.
1650   \return        the subtraction of the first byte of each operand in the first byte of the return value.\n
1651                  the subtraction of the second byte of each operand in the second byte of the return value.\n
1652                  the subtraction of the third byte of each operand in the third byte of the return value.\n
1653                  the subtraction of the fourth byte of each operand in the fourth byte of the return value.\n
1654                  The returned results are saturated to the 8-bit signed integer range -2^7 <= x <= 2^7 - 1.
1655   \remark
1656                  res[7:0]   = val1[7:0]   - val2[7:0]        \n
1657                  res[15:8]  = val1[15:8]  - val2[15:8]       \n
1658                  res[23:16] = val1[23:16] - val2[23:16]      \n
1659                  res[31:24] = val1[31:24] - val2[31:24]
1660  */
__QSUB8(uint32_t x,uint32_t y)1661 __ALWAYS_STATIC_INLINE uint32_t __QSUB8(uint32_t x, uint32_t y)
1662 {
1663     int32_t r, s, t, u;
1664 
1665     r = __SSAT(((((int32_t)x << 24) >> 24) - (((int32_t)y << 24) >> 24)), 8) & (int32_t)0x000000FF;
1666     s = __SSAT(((((int32_t)x << 16) >> 24) - (((int32_t)y << 16) >> 24)), 8) & (int32_t)0x000000FF;
1667     t = __SSAT(((((int32_t)x <<  8) >> 24) - (((int32_t)y <<  8) >> 24)), 8) & (int32_t)0x000000FF;
1668     u = __SSAT(((((int32_t)x) >> 24) - (((int32_t)y) >> 24)), 8) & (int32_t)0x000000FF;
1669 
1670     return ((uint32_t)((u << 24) | (t << 16) | (s <<  8) | (r)));
1671 }
1672 
1673 /**
1674   \brief   Quad 8-bit unsigned saturating subtraction.
1675   \details This function enables you to perform four unsigned 8-bit integer subtractions,
1676            saturating the results to the 8-bit unsigned integer range 0 < x < 2^8 - 1.
1677   \param [in]    x   first four 8-bit summands.
1678   \param [in]    y   second four 8-bit summands.
1679   \return        the subtraction of the first byte of each operand in the first byte of the return value.\n
1680                  the subtraction of the second byte of each operand in the second byte of the return value.\n
1681                  the subtraction of the third byte of each operand in the third byte of the return value.\n
1682                  the subtraction of the fourth byte of each operand in the fourth byte of the return value.\n
1683                  The returned results are saturated to the 8-bit unsigned integer range 0 <= x <= 2^8 - 1.
1684   \remark
1685                  res[7:0]   = val1[7:0]   - val2[7:0]        \n
1686                  res[15:8]  = val1[15:8]  - val2[15:8]       \n
1687                  res[23:16] = val1[23:16] - val2[23:16]      \n
1688                  res[31:24] = val1[31:24] - val2[31:24]
1689  */
__UQSUB8(uint32_t x,uint32_t y)1690 __ALWAYS_STATIC_INLINE uint32_t __UQSUB8(uint32_t x, uint32_t y)
1691 {
1692     int32_t r, s, t, u;
1693 
1694     r = __IUSAT((((x << 24) >> 24) - ((y << 24) >> 24)), 8) & 0x000000FF;
1695     s = __IUSAT((((x << 16) >> 24) - ((y << 16) >> 24)), 8) & 0x000000FF;
1696     t = __IUSAT((((x <<  8) >> 24) - ((y <<  8) >> 24)), 8) & 0x000000FF;
1697     u = __IUSAT((((x) >> 24) - ((y) >> 24)), 8) & 0x000000FF;
1698 
1699     return ((u << 24) | (t << 16) | (s <<  8) | (r));
1700 }
1701 
1702 /**
1703   \brief   Quad 8-bit signed subtraction.
1704   \details This function enables you to perform four 8-bit signed integer subtractions.
1705   \param [in]    x  first four 8-bit operands of each subtraction.
1706   \param [in]    y  second four 8-bit operands of each subtraction.
1707   \return        the subtraction of the first bytes from each operand, in the first byte of the return value.\n
1708                  the subtraction of the second bytes of each operand, in the second byte of the return value.\n
1709                  the subtraction of the third bytes of each operand, in the third byte of the return value.\n
1710                  the subtraction of the fourth bytes of each operand, in the fourth byte of the return value.
1711   \remark
1712                  res[7:0]   = val1[7:0]   - val2[7:0]        \n
1713                  res[15:8]  = val1[15:8]  - val2[15:8]       \n
1714                  res[23:16] = val1[23:16] - val2[23:16]      \n
1715                  res[31:24] = val1[31:24] - val2[31:24]
1716  */
__SSUB8(uint32_t x,uint32_t y)1717 __ALWAYS_STATIC_INLINE uint32_t __SSUB8(uint32_t x, uint32_t y)
1718 {
1719     int32_t r, s, t, u;
1720 
1721     r = ((((int32_t)x << 24) >> 24) - (((int32_t)y << 24) >> 24)) & (int32_t)0x000000FF;
1722     s = ((((int32_t)x << 16) >> 24) - (((int32_t)y << 16) >> 24)) & (int32_t)0x000000FF;
1723     t = ((((int32_t)x <<  8) >> 24) - (((int32_t)y <<  8) >> 24)) & (int32_t)0x000000FF;
1724     u = ((((int32_t)x) >> 24) - (((int32_t)y) >> 24)) & (int32_t)0x000000FF;
1725 
1726     return ((uint32_t)((u << 24) | (t << 16) | (s <<  8) | (r)));
1727 }
1728 
1729 /**
1730   \brief   Quad 8-bit unsigned subtract.
1731   \details This function enables you to perform four 8-bit unsigned integer subtractions.
1732   \param [in]    x  first four 8-bit operands of each subtraction.
1733   \param [in]    y  second four 8-bit operands of each subtraction.
1734   \return        the subtraction of the first bytes from each operand, in the first byte of the return value.\n
1735                  the subtraction of the second bytes of each operand, in the second byte of the return value.\n
1736                  the subtraction of the third bytes of each operand, in the third byte of the return value.\n
1737                  the subtraction of the fourth bytes of each operand, in the fourth byte of the return value.
1738   \remark
1739                  res[7:0]   = val1[7:0]   - val2[7:0]        \n
1740                  res[15:8]  = val1[15:8]  - val2[15:8]       \n
1741                  res[23:16] = val1[23:16] - val2[23:16]      \n
1742                  res[31:24] = val1[31:24] - val2[31:24]
1743  */
__USUB8(uint32_t x,uint32_t y)1744 __ALWAYS_STATIC_INLINE uint32_t __USUB8(uint32_t x, uint32_t y)
1745 {
1746     int32_t r, s, t, u;
1747 
1748     r = (((x << 24) >> 24) - ((y << 24) >> 24)) & 0x000000FF;
1749     s = (((x << 16) >> 24) - ((y << 16) >> 24)) & 0x000000FF;
1750     t = (((x <<  8) >> 24) - ((y <<  8) >> 24)) & 0x000000FF;
1751     u = (((x) >> 24) - ((y) >> 24)) & 0x000000FF;
1752 
1753     return ((u << 24) | (t << 16) | (s <<  8) | (r));
1754 }
1755 
1756 /**
1757   \brief   Unsigned sum of quad 8-bit unsigned absolute difference.
1758   \details This function enables you to perform four unsigned 8-bit subtractions, and add the absolute values
1759            of the differences together, returning the result as a single unsigned integer.
1760   \param [in]    x  first four 8-bit operands of each subtraction.
1761   \param [in]    y  second four 8-bit operands of each subtraction.
1762   \return        the subtraction of the first bytes from each operand, in the first byte of the return value.\n
1763                  the subtraction of the second bytes of each operand, in the second byte of the return value.\n
1764                  the subtraction of the third bytes of each operand, in the third byte of the return value.\n
1765                  the subtraction of the fourth bytes of each operand, in the fourth byte of the return value.\n
1766                  The sum is returned as a single unsigned integer.
1767   \remark
1768                  absdiff1   = val1[7:0]   - val2[7:0]        \n
1769                  absdiff2   = val1[15:8]  - val2[15:8]       \n
1770                  absdiff3   = val1[23:16] - val2[23:16]      \n
1771                  absdiff4   = val1[31:24] - val2[31:24]      \n
1772                  res[31:0]  = absdiff1 + absdiff2 + absdiff3 + absdiff4
1773  */
__USAD8(uint32_t x,uint32_t y)1774 __ALWAYS_STATIC_INLINE uint32_t __USAD8(uint32_t x, uint32_t y)
1775 {
1776     int32_t r, s, t, u;
1777 
1778     r = (((x << 24) >> 24) - ((y << 24) >> 24)) & 0x000000FF;
1779     s = (((x << 16) >> 24) - ((y << 16) >> 24)) & 0x000000FF;
1780     t = (((x <<  8) >> 24) - ((y <<  8) >> 24)) & 0x000000FF;
1781     u = (((x) >> 24) - ((y) >> 24)) & 0x000000FF;
1782 
1783     return (u + t + s + r);
1784 }
1785 
1786 /**
1787   \brief   Unsigned sum of quad 8-bit unsigned absolute difference with 32-bit accumulate.
1788   \details This function enables you to perform four unsigned 8-bit subtractions, and add the absolute values
1789            of the differences to a 32-bit accumulate operand.
1790   \param [in]    x  first four 8-bit operands of each subtraction.
1791   \param [in]    y  second four 8-bit operands of each subtraction.
1792   \param [in]  sum  accumulation value.
1793   \return        the sum of the absolute differences of the following bytes, added to the accumulation value:
1794                  the subtraction of the first bytes from each operand, in the first byte of the return value.\n
1795                  the subtraction of the second bytes of each operand, in the second byte of the return value.\n
1796                  the subtraction of the third bytes of each operand, in the third byte of the return value.\n
1797                  the subtraction of the fourth bytes of each operand, in the fourth byte of the return value.
1798   \remark
1799                  absdiff1 = val1[7:0]   - val2[7:0]        \n
1800                  absdiff2 = val1[15:8]  - val2[15:8]       \n
1801                  absdiff3 = val1[23:16] - val2[23:16]      \n
1802                  absdiff4 = val1[31:24] - val2[31:24]      \n
1803                  sum = absdiff1 + absdiff2 + absdiff3 + absdiff4 \n
1804                  res[31:0] = sum[31:0] + val3[31:0]
1805  */
__USADA8(uint32_t x,uint32_t y,uint32_t sum)1806 __ALWAYS_STATIC_INLINE uint32_t __USADA8(uint32_t x, uint32_t y, uint32_t sum)
1807 {
1808     int32_t r, s, t, u;
1809 
1810 #ifdef __cplusplus
1811     r = (abs((long long)((x << 24) >> 24) - ((y << 24) >> 24))) & 0x000000FF;
1812     s = (abs((long long)((x << 16) >> 24) - ((y << 16) >> 24))) & 0x000000FF;
1813     t = (abs((long long)((x <<  8) >> 24) - ((y <<  8) >> 24))) & 0x000000FF;
1814     u = (abs((long long)((x) >> 24) - ((y) >> 24))) & 0x000000FF;
1815 #else
1816     r = (abs(((x << 24) >> 24) - ((y << 24) >> 24))) & 0x000000FF;
1817     s = (abs(((x << 16) >> 24) - ((y << 16) >> 24))) & 0x000000FF;
1818     t = (abs(((x <<  8) >> 24) - ((y <<  8) >> 24))) & 0x000000FF;
1819     u = (abs(((x) >> 24) - ((y) >> 24))) & 0x000000FF;
1820 #endif
1821     return (u + t + s + r + sum);
1822 }
1823 
1824 /**
1825   \brief   Dual 16-bit saturating addition.
1826   \details This function enables you to perform two 16-bit integer arithmetic additions in parallel,
1827            saturating the results to the 16-bit signed integer range -2^15 <= x <= 2^15 - 1.
1828   \param [in]    x   first two 16-bit summands.
1829   \param [in]    y   second two 16-bit summands.
1830   \return        the saturated addition of the low halfwords, in the low halfword of the return value.\n
1831                  the saturated addition of the high halfwords, in the high halfword of the return value.\n
1832                  The returned results are saturated to the 16-bit signed integer range -2^15 <= x <= 2^15 - 1.
1833   \remark
1834                  res[15:0]  = val1[15:0]  + val2[15:0]        \n
1835                  res[31:16] = val1[31:16] + val2[31:16]
1836  */
__QADD16(uint32_t x,uint32_t y)1837 __ALWAYS_STATIC_INLINE uint32_t __QADD16(uint32_t x, uint32_t y)
1838 {
1839     int32_t r = 0, s = 0;
1840 
1841     r = __SSAT(((((int32_t)x << 16) >> 16) + (((int32_t)y << 16) >> 16)), 16) & (int32_t)0x0000FFFF;
1842     s = __SSAT(((((int32_t)x) >> 16) + (((int32_t)y) >> 16)), 16) & (int32_t)0x0000FFFF;
1843 
1844     return ((uint32_t)((s << 16) | (r)));
1845 }
1846 
1847 /**
1848   \brief   Dual 16-bit unsigned saturating addition.
1849   \details This function enables you to perform two unsigned 16-bit integer additions, saturating
1850            the results to the 16-bit unsigned integer range 0 < x < 2^16 - 1.
1851   \param [in]    x   first two 16-bit summands.
1852   \param [in]    y   second two 16-bit summands.
1853   \return        the saturated addition of the low halfwords, in the low halfword of the return value.\n
1854                  the saturated addition of the high halfwords, in the high halfword of the return value.\n
1855                  The results are saturated to the 16-bit unsigned integer range 0 < x < 2^16 - 1.
1856   \remark
1857                  res[15:0]  = val1[15:0]  + val2[15:0]        \n
1858                  res[31:16] = val1[31:16] + val2[31:16]
1859  */
__UQADD16(uint32_t x,uint32_t y)1860 __ALWAYS_STATIC_INLINE uint32_t __UQADD16(uint32_t x, uint32_t y)
1861 {
1862     int32_t r = 0, s = 0;
1863 
1864     r = __IUSAT((((x << 16) >> 16) + ((y << 16) >> 16)), 16) & 0x0000FFFF;
1865     s = __IUSAT((((x) >> 16) + ((y) >> 16)), 16) & 0x0000FFFF;
1866 
1867     return ((s << 16) | (r));
1868 }
1869 
1870 /**
1871   \brief   Dual 16-bit signed addition.
1872   \details This function enables you to perform two 16-bit signed integer additions.
1873   \param [in]    x   first two 16-bit summands.
1874   \param [in]    y   second two 16-bit summands.
1875   \return        the addition of the low halfwords in the low halfword of the return value.\n
1876                  the addition of the high halfwords in the high halfword of the return value.
1877   \remark
1878                  res[15:0]  = val1[15:0]  + val2[15:0]        \n
1879                  res[31:16] = val1[31:16] + val2[31:16]
1880  */
__SADD16(uint32_t x,uint32_t y)1881 __ALWAYS_STATIC_INLINE uint32_t __SADD16(uint32_t x, uint32_t y)
1882 {
1883     int32_t r = 0, s = 0;
1884 
1885     r = ((((int32_t)x << 16) >> 16) + (((int32_t)y << 16) >> 16)) & (int32_t)0x0000FFFF;
1886     s = ((((int32_t)x) >> 16) + (((int32_t)y) >> 16)) & (int32_t)0x0000FFFF;
1887 
1888     return ((uint32_t)((s << 16) | (r)));
1889 }
1890 
1891 /**
1892   \brief   Dual 16-bit unsigned addition
1893   \details This function enables you to perform two 16-bit unsigned integer additions.
1894   \param [in]    x   first two 16-bit summands for each addition.
1895   \param [in]    y   second two 16-bit summands for each addition.
1896   \return        the addition of the low halfwords in the low halfword of the return value.\n
1897                  the addition of the high halfwords in the high halfword of the return value.
1898   \remark
1899                  res[15:0]  = val1[15:0]  + val2[15:0]        \n
1900                  res[31:16] = val1[31:16] + val2[31:16]
1901  */
__UADD16(uint32_t x,uint32_t y)1902 __ALWAYS_STATIC_INLINE uint32_t __UADD16(uint32_t x, uint32_t y)
1903 {
1904     int32_t r = 0, s = 0;
1905 
1906     r = (((x << 16) >> 16) + ((y << 16) >> 16)) & 0x0000FFFF;
1907     s = (((x) >> 16) + ((y) >> 16)) & 0x0000FFFF;
1908 
1909     return ((s << 16) | (r));
1910 }
1911 
1912 
1913 /**
1914   \brief   Dual 16-bit signed addition with halved results.
1915   \details This function enables you to perform two signed 16-bit integer additions, halving the results.
1916   \param [in]    x   first two 16-bit summands.
1917   \param [in]    y   second two 16-bit summands.
1918   \return        the halved addition of the low halfwords, in the low halfword of the return value.\n
1919                  the halved addition of the high halfwords, in the high halfword of the return value.
1920   \remark
1921                  res[15:0]  = (val1[15:0]  + val2[15:0]) >> 1        \n
1922                  res[31:16] = (val1[31:16] + val2[31:16]) >> 1
1923  */
__SHADD16(uint32_t x,uint32_t y)1924 __ALWAYS_STATIC_INLINE uint32_t __SHADD16(uint32_t x, uint32_t y)
1925 {
1926     int32_t r, s;
1927 
1928     r = (((((int32_t)x << 16) >> 16) + (((int32_t)y << 16) >> 16)) >> 1) & (int32_t)0x0000FFFF;
1929     s = (((((int32_t)x) >> 16) + (((int32_t)y) >> 16)) >> 1) & (int32_t)0x0000FFFF;
1930 
1931     return ((uint32_t)((s << 16) | (r)));
1932 }
1933 
1934 /**
1935   \brief   Dual 16-bit unsigned addition with halved results.
1936   \details This function enables you to perform two unsigned 16-bit integer additions, halving the results.
1937   \param [in]    x   first two 16-bit summands.
1938   \param [in]    y   second two 16-bit summands.
1939   \return        the halved addition of the low halfwords, in the low halfword of the return value.\n
1940                  the halved addition of the high halfwords, in the high halfword of the return value.
1941   \remark
1942                  res[15:0]  = (val1[15:0]  + val2[15:0]) >> 1        \n
1943                  res[31:16] = (val1[31:16] + val2[31:16]) >> 1
1944  */
__UHADD16(uint32_t x,uint32_t y)1945 __ALWAYS_STATIC_INLINE uint32_t __UHADD16(uint32_t x, uint32_t y)
1946 {
1947     int32_t r, s;
1948 
1949     r = ((((x << 16) >> 16) + ((y << 16) >> 16)) >> 1) & 0x0000FFFF;
1950     s = ((((x) >> 16) + ((y) >> 16)) >> 1) & 0x0000FFFF;
1951 
1952     return ((s << 16) | (r));
1953 }
1954 
1955 /**
1956   \brief   Quad 8-bit signed addition with halved results.
1957   \details This function enables you to perform four signed 8-bit integer additions, halving the results.
1958   \param [in]    x   first four 8-bit summands.
1959   \param [in]    y   second four 8-bit summands.
1960   \return        the halved addition of the first bytes from each operand, in the first byte of the return value.\n
1961                  the halved addition of the second bytes from each operand, in the second byte of the return value.\n
1962                  the halved addition of the third bytes from each operand, in the third byte of the return value.\n
1963                  the halved addition of the fourth bytes from each operand, in the fourth byte of the return value.
1964   \remark
1965                  res[7:0]   = (val1[7:0]   + val2[7:0]  ) >> 1    \n
1966                  res[15:8]  = (val1[15:8]  + val2[15:8] ) >> 1    \n
1967                  res[23:16] = (val1[23:16] + val2[23:16]) >> 1    \n
1968                  res[31:24] = (val1[31:24] + val2[31:24]) >> 1
1969  */
__SHADD8(uint32_t x,uint32_t y)1970 __ALWAYS_STATIC_INLINE uint32_t __SHADD8(uint32_t x, uint32_t y)
1971 {
1972     int32_t r, s, t, u;
1973 
1974     r = (((((int32_t)x << 24) >> 24) + (((int32_t)y << 24) >> 24)) >> 1) & (int32_t)0x000000FF;
1975     s = (((((int32_t)x << 16) >> 24) + (((int32_t)y << 16) >> 24)) >> 1) & (int32_t)0x000000FF;
1976     t = (((((int32_t)x <<  8) >> 24) + (((int32_t)y <<  8) >> 24)) >> 1) & (int32_t)0x000000FF;
1977     u = (((((int32_t)x) >> 24) + (((int32_t)y) >> 24)) >> 1) & (int32_t)0x000000FF;
1978 
1979     return ((uint32_t)((u << 24) | (t << 16) | (s <<  8) | (r)));
1980 }
1981 
1982 /**
1983   \brief   Quad 8-bit unsigned addition with halved results.
1984   \details This function enables you to perform four unsigned 8-bit integer additions, halving the results.
1985   \param [in]    x   first four 8-bit summands.
1986   \param [in]    y   second four 8-bit summands.
1987   \return        the halved addition of the first bytes from each operand, in the first byte of the return value.\n
1988                  the halved addition of the second bytes from each operand, in the second byte of the return value.\n
1989                  the halved addition of the third bytes from each operand, in the third byte of the return value.\n
1990                  the halved addition of the fourth bytes from each operand, in the fourth byte of the return value.
1991   \remark
1992                  res[7:0]   = (val1[7:0]   + val2[7:0]  ) >> 1    \n
1993                  res[15:8]  = (val1[15:8]  + val2[15:8] ) >> 1    \n
1994                  res[23:16] = (val1[23:16] + val2[23:16]) >> 1    \n
1995                  res[31:24] = (val1[31:24] + val2[31:24]) >> 1
1996  */
__UHADD8(uint32_t x,uint32_t y)1997 __ALWAYS_STATIC_INLINE uint32_t __UHADD8(uint32_t x, uint32_t y)
1998 {
1999     int32_t r, s, t, u;
2000 
2001     r = ((((x << 24) >> 24) + ((y << 24) >> 24)) >> 1) & 0x000000FF;
2002     s = ((((x << 16) >> 24) + ((y << 16) >> 24)) >> 1) & 0x000000FF;
2003     t = ((((x <<  8) >> 24) + ((y <<  8) >> 24)) >> 1) & 0x000000FF;
2004     u = ((((x) >> 24) + ((y) >> 24)) >> 1) & 0x000000FF;
2005 
2006     return ((u << 24) | (t << 16) | (s <<  8) | (r));
2007 }
2008 
2009 /**
2010   \brief   Dual 16-bit saturating subtract.
2011   \details This function enables you to perform two 16-bit integer subtractions in parallel,
2012            saturating the results to the 16-bit signed integer range -2^15 <= x <= 2^15 - 1.
2013   \param [in]    x   first two 16-bit summands.
2014   \param [in]    y   second two 16-bit summands.
2015   \return        the saturated subtraction of the low halfwords, in the low halfword of the return value.\n
2016                  the saturated subtraction of the high halfwords, in the high halfword of the return value.\n
2017                  The returned results are saturated to the 16-bit signed integer range -2^15 <= x <= 2^15 - 1.
2018   \remark
2019                  res[15:0]  = val1[15:0]  - val2[15:0]        \n
2020                  res[31:16] = val1[31:16] - val2[31:16]
2021  */
__QSUB16(uint32_t x,uint32_t y)2022 __ALWAYS_STATIC_INLINE uint32_t __QSUB16(uint32_t x, uint32_t y)
2023 {
2024     int32_t r, s;
2025 
2026     r = __SSAT(((((int32_t)x << 16) >> 16) - (((int32_t)y << 16) >> 16)), 16) & (int32_t)0x0000FFFF;
2027     s = __SSAT(((((int32_t)x) >> 16) - (((int32_t)y) >> 16)), 16) & (int32_t)0x0000FFFF;
2028 
2029     return ((uint32_t)((s << 16) | (r)));
2030 }
2031 
2032 /**
2033   \brief   Dual 16-bit unsigned saturating subtraction.
2034   \details This function enables you to perform two unsigned 16-bit integer subtractions,
2035            saturating the results to the 16-bit unsigned integer range 0 < x < 2^16 - 1.
2036   \param [in]    x   first two 16-bit operands for each subtraction.
2037   \param [in]    y   second two 16-bit operands for each subtraction.
2038   \return        the saturated subtraction of the low halfwords, in the low halfword of the return value.\n
2039                  the saturated subtraction of the high halfwords, in the high halfword of the return value.\n
2040                  The returned results are saturated to the 16-bit signed integer range -2^15 <= x <= 2^15 - 1.
2041   \remark
2042                  res[15:0]  = val1[15:0]  - val2[15:0]        \n
2043                  res[31:16] = val1[31:16] - val2[31:16]
2044  */
__UQSUB16(uint32_t x,uint32_t y)2045 __ALWAYS_STATIC_INLINE uint32_t __UQSUB16(uint32_t x, uint32_t y)
2046 {
2047     int32_t r, s;
2048 
2049     r = __IUSAT((((x << 16) >> 16) - ((y << 16) >> 16)), 16) & 0x0000FFFF;
2050     s = __IUSAT((((x) >> 16) - ((y) >> 16)), 16) & 0x0000FFFF;
2051 
2052     return ((s << 16) | (r));
2053 }
2054 
2055 /**
2056   \brief   Dual 16-bit signed subtraction.
2057   \details This function enables you to perform two 16-bit signed integer subtractions.
2058   \param [in]    x   first two 16-bit operands of each subtraction.
2059   \param [in]    y   second two 16-bit operands of each subtraction.
2060   \return        the subtraction of the low halfword in the second operand from the low
2061                  halfword in the first operand, in the low halfword of the return value. \n
2062                  the subtraction of the high halfword in the second operand from the high
2063                  halfword in the first operand, in the high halfword of the return value.
2064   \remark
2065                  res[15:0]  = val1[15:0]  - val2[15:0]        \n
2066                  res[31:16] = val1[31:16] - val2[31:16]
2067  */
__SSUB16(uint32_t x,uint32_t y)2068 __ALWAYS_STATIC_INLINE uint32_t __SSUB16(uint32_t x, uint32_t y)
2069 {
2070     int32_t r, s;
2071 
2072     r = ((((int32_t)x << 16) >> 16) - (((int32_t)y << 16) >> 16)) & (int32_t)0x0000FFFF;
2073     s = ((((int32_t)x) >> 16) - (((int32_t)y) >> 16)) & (int32_t)0x0000FFFF;
2074 
2075     return ((uint32_t)((s << 16) | (r)));
2076 }
2077 
2078 /**
2079   \brief   Dual 16-bit unsigned subtract.
2080   \details This function enables you to perform two 16-bit unsigned integer subtractions.
2081   \param [in]    x   first two 16-bit operands of each subtraction.
2082   \param [in]    y   second two 16-bit operands of each subtraction.
2083   \return        the subtraction of the low halfword in the second operand from the low
2084                  halfword in the first operand, in the low halfword of the return value. \n
2085                  the subtraction of the high halfword in the second operand from the high
2086                  halfword in the first operand, in the high halfword of the return value.
2087   \remark
2088                  res[15:0]  = val1[15:0]  - val2[15:0]        \n
2089                  res[31:16] = val1[31:16] - val2[31:16]
2090  */
__USUB16(uint32_t x,uint32_t y)2091 __ALWAYS_STATIC_INLINE uint32_t __USUB16(uint32_t x, uint32_t y)
2092 {
2093     int32_t r, s;
2094 
2095     r = (((x << 16) >> 16) - ((y << 16) >> 16)) & 0x0000FFFF;
2096     s = (((x) >> 16) - ((y) >> 16)) & 0x0000FFFF;
2097 
2098     return ((s << 16) | (r));
2099 }
2100 
2101 /**
2102   \brief   Dual 16-bit signed subtraction with halved results.
2103   \details This function enables you to perform two signed 16-bit integer subtractions, halving the results.
2104   \param [in]    x   first two 16-bit summands.
2105   \param [in]    y   second two 16-bit summands.
2106   \return        the halved subtraction of the low halfwords, in the low halfword of the return value.\n
2107                  the halved subtraction of the high halfwords, in the high halfword of the return value.
2108   \remark
2109                  res[15:0]  = (val1[15:0]  - val2[15:0]) >> 1        \n
2110                  res[31:16] = (val1[31:16] - val2[31:16]) >> 1
2111  */
__SHSUB16(uint32_t x,uint32_t y)2112 __ALWAYS_STATIC_INLINE uint32_t __SHSUB16(uint32_t x, uint32_t y)
2113 {
2114     int32_t r, s;
2115 
2116     r = (((((int32_t)x << 16) >> 16) - (((int32_t)y << 16) >> 16)) >> 1) & (int32_t)0x0000FFFF;
2117     s = (((((int32_t)x) >> 16) - (((int32_t)y) >> 16)) >> 1) & (int32_t)0x0000FFFF;
2118 
2119     return ((uint32_t)((s << 16) | (r)));
2120 }
2121 
2122 /**
2123   \brief   Dual 16-bit unsigned subtraction with halved results.
2124   \details This function enables you to perform two unsigned 16-bit integer subtractions, halving the results.
2125   \param [in]    x   first two 16-bit summands.
2126   \param [in]    y   second two 16-bit summands.
2127   \return        the halved subtraction of the low halfwords, in the low halfword of the return value.\n
2128                  the halved subtraction of the high halfwords, in the high halfword of the return value.
2129   \remark
2130                  res[15:0]  = (val1[15:0]  - val2[15:0]) >> 1        \n
2131                  res[31:16] = (val1[31:16] - val2[31:16]) >> 1
2132  */
__UHSUB16(uint32_t x,uint32_t y)2133 __ALWAYS_STATIC_INLINE uint32_t __UHSUB16(uint32_t x, uint32_t y)
2134 {
2135     int32_t r, s;
2136 
2137     r = ((((x << 16) >> 16) - ((y << 16) >> 16)) >> 1) & 0x0000FFFF;
2138     s = ((((x) >> 16) - ((y) >> 16)) >> 1) & 0x0000FFFF;
2139 
2140     return ((s << 16) | (r));
2141 }
2142 
2143 /**
2144   \brief   Quad 8-bit signed addition with halved results.
2145   \details This function enables you to perform four signed 8-bit integer subtractions, halving the results.
2146   \param [in]    x   first four 8-bit summands.
2147   \param [in]    y   second four 8-bit summands.
2148   \return        the halved subtraction of the first bytes from each operand, in the first byte of the return value.\n
2149                  the halved subtraction of the second bytes from each operand, in the second byte of the return value.\n
2150                  the halved subtraction of the third bytes from each operand, in the third byte of the return value.\n
2151                  the halved subtraction of the fourth bytes from each operand, in the fourth byte of the return value.
2152   \remark
2153                  res[7:0]   = (val1[7:0]   - val2[7:0]  ) >> 1    \n
2154                  res[15:8]  = (val1[15:8]  - val2[15:8] ) >> 1    \n
2155                  res[23:16] = (val1[23:16] - val2[23:16]) >> 1    \n
2156                  res[31:24] = (val1[31:24] - val2[31:24]) >> 1
2157  */
__SHSUB8(uint32_t x,uint32_t y)2158 __ALWAYS_STATIC_INLINE uint32_t __SHSUB8(uint32_t x, uint32_t y)
2159 {
2160     int32_t r, s, t, u;
2161 
2162     r = (((((int32_t)x << 24) >> 24) - (((int32_t)y << 24) >> 24)) >> 1) & (int32_t)0x000000FF;
2163     s = (((((int32_t)x << 16) >> 24) - (((int32_t)y << 16) >> 24)) >> 1) & (int32_t)0x000000FF;
2164     t = (((((int32_t)x <<  8) >> 24) - (((int32_t)y <<  8) >> 24)) >> 1) & (int32_t)0x000000FF;
2165     u = (((((int32_t)x) >> 24) - (((int32_t)y) >> 24)) >> 1) & (int32_t)0x000000FF;
2166 
2167     return ((uint32_t)((u << 24) | (t << 16) | (s <<  8) | (r)));
2168 }
2169 
2170 /**
2171   \brief   Quad 8-bit unsigned subtraction with halved results.
2172   \details This function enables you to perform four unsigned 8-bit integer subtractions, halving the results.
2173   \param [in]    x   first four 8-bit summands.
2174   \param [in]    y   second four 8-bit summands.
2175   \return        the halved subtraction of the first bytes from each operand, in the first byte of the return value.\n
2176                  the halved subtraction of the second bytes from each operand, in the second byte of the return value.\n
2177                  the halved subtraction of the third bytes from each operand, in the third byte of the return value.\n
2178                  the halved subtraction of the fourth bytes from each operand, in the fourth byte of the return value.
2179   \remark
2180                  res[7:0]   = (val1[7:0]   - val2[7:0]  ) >> 1    \n
2181                  res[15:8]  = (val1[15:8]  - val2[15:8] ) >> 1    \n
2182                  res[23:16] = (val1[23:16] - val2[23:16]) >> 1    \n
2183                  res[31:24] = (val1[31:24] - val2[31:24]) >> 1
2184  */
__UHSUB8(uint32_t x,uint32_t y)2185 __ALWAYS_STATIC_INLINE uint32_t __UHSUB8(uint32_t x, uint32_t y)
2186 {
2187     int32_t r, s, t, u;
2188 
2189     r = ((((x << 24) >> 24) - ((y << 24) >> 24)) >> 1) & 0x000000FF;
2190     s = ((((x << 16) >> 24) - ((y << 16) >> 24)) >> 1) & 0x000000FF;
2191     t = ((((x <<  8) >> 24) - ((y <<  8) >> 24)) >> 1) & 0x000000FF;
2192     u = ((((x) >> 24) - ((y) >> 24)) >> 1) & 0x000000FF;
2193 
2194     return ((u << 24) | (t << 16) | (s <<  8) | (r));
2195 }
2196 
2197 /**
2198   \brief   Dual 16-bit add and subtract with exchange.
2199   \details This function enables you to exchange the halfwords of the one operand,
2200            then add the high halfwords and subtract the low halfwords,
2201            saturating the results to the 16-bit signed integer range -2^15 <= x <= 2^15 - 1.
2202   \param [in]    x   first operand for the subtraction in the low halfword,
2203                      and the first operand for the addition in the high halfword.
2204   \param [in]    y   second operand for the subtraction in the high halfword,
2205                      and the second operand for the addition in the low halfword.
2206   \return        the saturated subtraction of the high halfword in the second operand from the
2207                  low halfword in the first operand, in the low halfword of the return value.\n
2208                  the saturated addition of the high halfword in the first operand and the
2209                  low halfword in the second operand, in the high halfword of the return value.\n
2210                  The returned results are saturated to the 16-bit signed integer range -2^15 <= x <= 2^15 - 1.
2211   \remark
2212                  res[15:0]  = val1[15:0]  - val2[31:16]        \n
2213                  res[31:16] = val1[31:16] + val2[15:0]
2214  */
__QASX(uint32_t x,uint32_t y)2215 __ALWAYS_STATIC_INLINE uint32_t __QASX(uint32_t x, uint32_t y)
2216 {
2217     int32_t r, s;
2218 
2219     r = __SSAT(((((int32_t)x << 16) >> 16) - (((int32_t)y) >> 16)), 16) & (int32_t)0x0000FFFF;
2220     s = __SSAT(((((int32_t)x) >> 16) + (((int32_t)y << 16) >> 16)), 16) & (int32_t)0x0000FFFF;
2221 
2222     return ((uint32_t)((s << 16) | (r)));
2223 }
2224 
2225 /**
2226   \brief   Dual 16-bit unsigned saturating addition and subtraction with exchange.
2227   \details This function enables you to exchange the halfwords of the second operand and
2228            perform one unsigned 16-bit integer addition and one unsigned 16-bit subtraction,
2229            saturating the results to the 16-bit unsigned integer range 0 <= x <= 2^16 - 1.
2230   \param [in]    x   first operand for the subtraction in the low halfword,
2231                      and the first operand for the addition in the high halfword.
2232   \param [in]    y   second operand for the subtraction in the high halfword,
2233                      and the second operand for the addition in the low halfword.
2234   \return        the saturated subtraction of the high halfword in the second operand from the
2235                  low halfword in the first operand, in the low halfword of the return value.\n
2236                  the saturated addition of the high halfword in the first operand and the
2237                  low halfword in the second operand, in the high halfword of the return value.\n
2238                  The returned results are saturated to the 16-bit unsigned integer range 0 <= x <= 2^16 - 1.
2239   \remark
2240                  res[15:0]  = val1[15:0]  - val2[31:16]        \n
2241                  res[31:16] = val1[31:16] + val2[15:0]
2242  */
__UQASX(uint32_t x,uint32_t y)2243 __ALWAYS_STATIC_INLINE uint32_t __UQASX(uint32_t x, uint32_t y)
2244 {
2245     int32_t r, s;
2246 
2247     r = __IUSAT((((x << 16) >> 16) - ((y) >> 16)), 16) & 0x0000FFFF;
2248     s = __IUSAT((((x) >> 16) + ((y << 16) >> 16)), 16) & 0x0000FFFF;
2249 
2250     return ((s << 16) | (r));
2251 }
2252 
2253 /**
2254   \brief   Dual 16-bit addition and subtraction with exchange.
2255   \details It enables you to exchange the halfwords of the second operand, add the high halfwords
2256            and subtract the low halfwords.
2257   \param [in]    x   first operand for the subtraction in the low halfword,
2258                      and the first operand for the addition in the high halfword.
2259   \param [in]    y   second operand for the subtraction in the high halfword,
2260                      and the second operand for the addition in the low halfword.
2261   \return        the subtraction of the high halfword in the second operand from the
2262                  low halfword in the first operand, in the low halfword of the return value.\n
2263                  the addition of the high halfword in the first operand and the
2264                  low halfword in the second operand, in the high halfword of the return value.
2265   \remark
2266                  res[15:0]  = val1[15:0]  - val2[31:16]        \n
2267                  res[31:16] = val1[31:16] + val2[15:0]
2268  */
__SASX(uint32_t x,uint32_t y)2269 __ALWAYS_STATIC_INLINE uint32_t __SASX(uint32_t x, uint32_t y)
2270 {
2271     int32_t r, s;
2272 
2273     r = ((((int32_t)x << 16) >> 16) - (((int32_t)y) >> 16)) & (int32_t)0x0000FFFF;
2274     s = ((((int32_t)x) >> 16) + (((int32_t)y << 16) >> 16)) & (int32_t)0x0000FFFF;
2275 
2276     return ((uint32_t)((s << 16) | (r)));
2277 }
2278 
2279 /**
2280   \brief   Dual 16-bit unsigned addition and subtraction with exchange.
2281   \details This function enables you to exchange the two halfwords of the second operand,
2282            add the high halfwords and subtract the low halfwords.
2283   \param [in]    x   first operand for the subtraction in the low halfword,
2284                      and the first operand for the addition in the high halfword.
2285   \param [in]    y   second operand for the subtraction in the high halfword,
2286                      and the second operand for the addition in the low halfword.
2287   \return        the subtraction of the high halfword in the second operand from the
2288                  low halfword in the first operand, in the low halfword of the return value.\n
2289                  the addition of the high halfword in the first operand and the
2290                  low halfword in the second operand, in the high halfword of the return value.
2291   \remark
2292                  res[15:0]  = val1[15:0]  - val2[31:16]        \n
2293                  res[31:16] = val1[31:16] + val2[15:0]
2294  */
__UASX(uint32_t x,uint32_t y)2295 __ALWAYS_STATIC_INLINE uint32_t __UASX(uint32_t x, uint32_t y)
2296 {
2297     int32_t r, s;
2298 
2299     r = (((x << 16) >> 16) - ((y) >> 16)) & 0x0000FFFF;
2300     s = (((x) >> 16) + ((y << 16) >> 16)) & 0x0000FFFF;
2301 
2302     return ((s << 16) | (r));
2303 }
2304 
2305 /**
2306   \brief   Dual 16-bit signed addition and subtraction with halved results.
2307   \details This function enables you to exchange the two halfwords of one operand, perform one
2308            signed 16-bit integer addition and one signed 16-bit subtraction, and halve the results.
2309   \param [in]    x   first 16-bit operands.
2310   \param [in]    y   second 16-bit operands.
2311   \return        the halved subtraction of the high halfword in the second operand from the
2312                  low halfword in the first operand, in the low halfword of the return value.\n
2313                  the halved addition of the low halfword in the second operand from the high
2314                  halfword in the first operand, in the high halfword of the return value.
2315   \remark
2316                  res[15:0]  = (val1[15:0]  - val2[31:16]) >> 1        \n
2317                  res[31:16] = (val1[31:16] + val2[15:0]) >> 1
2318  */
__SHASX(uint32_t x,uint32_t y)2319 __ALWAYS_STATIC_INLINE uint32_t __SHASX(uint32_t x, uint32_t y)
2320 {
2321     int32_t r, s;
2322 
2323     r = (((((int32_t)x << 16) >> 16) - (((int32_t)y) >> 16)) >> 1) & (int32_t)0x0000FFFF;
2324     s = (((((int32_t)x) >> 16) + (((int32_t)y << 16) >> 16)) >> 1) & (int32_t)0x0000FFFF;
2325 
2326     return ((uint32_t)((s << 16) | (r)));
2327 }
2328 
2329 /**
2330   \brief   Dual 16-bit unsigned addition and subtraction with halved results and exchange.
2331   \details This function enables you to exchange the halfwords of the second operand,
2332            add the high halfwords and subtract the low halfwords, halving the results.
2333   \param [in]    x   first operand for the subtraction in the low halfword, and
2334                      the first operand for the addition in the high halfword.
2335   \param [in]    y   second operand for the subtraction in the high halfword, and
2336                      the second operand for the addition in the low halfword.
2337   \return        the halved subtraction of the high halfword in the second operand from the
2338                  low halfword in the first operand, in the low halfword of the return value.\n
2339                  the halved addition of the low halfword in the second operand from the high
2340                  halfword in the first operand, in the high halfword of the return value.
2341   \remark
2342                  res[15:0]  = (val1[15:0]  - val2[31:16]) >> 1        \n
2343                  res[31:16] = (val1[31:16] + val2[15:0]) >> 1
2344  */
__UHASX(uint32_t x,uint32_t y)2345 __ALWAYS_STATIC_INLINE uint32_t __UHASX(uint32_t x, uint32_t y)
2346 {
2347     int32_t r, s;
2348 
2349     r = ((((x << 16) >> 16) - ((y) >> 16)) >> 1) & 0x0000FFFF;
2350     s = ((((x) >> 16) + ((y << 16) >> 16)) >> 1) & 0x0000FFFF;
2351 
2352     return ((s << 16) | (r));
2353 }
2354 
2355 /**
2356   \brief   Dual 16-bit subtract and add with exchange.
2357   \details This function enables you to exchange the halfwords of one operand,
2358            then subtract the high halfwords and add the low halfwords,
2359            saturating the results to the 16-bit signed integer range -2^15 <= x <= 2^15 - 1.
2360   \param [in]    x   first operand for the addition in the low halfword,
2361                      and the first operand for the subtraction in the high halfword.
2362   \param [in]    y   second operand for the addition in the high halfword,
2363                      and the second operand for the subtraction in the low halfword.
2364   \return        the saturated addition of the low halfword of the first operand and the high
2365                  halfword of the second operand, in the low halfword of the return value.\n
2366                  the saturated subtraction of the low halfword of the second operand from the
2367                  high halfword of the first operand, in the high halfword of the return value.\n
2368                  The returned results are saturated to the 16-bit signed integer range -2^15 <= x <= 2^15 - 1.
2369   \remark
2370                  res[15:0]  = val1[15:0]  + val2[31:16]        \n
2371                  res[31:16] = val1[31:16] - val2[15:0]
2372  */
__QSAX(uint32_t x,uint32_t y)2373 __ALWAYS_STATIC_INLINE uint32_t __QSAX(uint32_t x, uint32_t y)
2374 {
2375     int32_t r, s;
2376 
2377     r = __SSAT(((((int32_t)x << 16) >> 16) + (((int32_t)y) >> 16)), 16) & (int32_t)0x0000FFFF;
2378     s = __SSAT(((((int32_t)x) >> 16) - (((int32_t)y << 16) >> 16)), 16) & (int32_t)0x0000FFFF;
2379 
2380     return ((uint32_t)((s << 16) | (r)));
2381 }
2382 
2383 /**
2384   \brief   Dual 16-bit unsigned saturating subtraction and addition with exchange.
2385   \details This function enables you to exchange the halfwords of the second operand and perform
2386            one unsigned 16-bit integer subtraction and one unsigned 16-bit addition, saturating
2387            the results to the 16-bit unsigned integer range 0 <= x <= 2^16 - 1.
2388   \param [in]    x   first operand for the addition in the low halfword,
2389                      and the first operand for the subtraction in the high halfword.
2390   \param [in]    y   second operand for the addition in the high halfword,
2391                      and the second operand for the subtraction in the low halfword.
2392   \return        the saturated addition of the low halfword of the first operand and the high
2393                  halfword of the second operand, in the low halfword of the return value.\n
2394                  the saturated subtraction of the low halfword of the second operand from the
2395                  high halfword of the first operand, in the high halfword of the return value.\n
2396                  The returned results are saturated to the 16-bit unsigned integer range 0 <= x <= 2^16 - 1.
2397   \remark
2398                  res[15:0]  = val1[15:0]  + val2[31:16]        \n
2399                  res[31:16] = val1[31:16] - val2[15:0]
2400  */
__UQSAX(uint32_t x,uint32_t y)2401 __ALWAYS_STATIC_INLINE uint32_t __UQSAX(uint32_t x, uint32_t y)
2402 {
2403     int32_t r, s;
2404 
2405     r = __IUSAT((((x << 16) >> 16) + ((y) >> 16)), 16) & 0x0000FFFF;
2406     s = __IUSAT((((x) >> 16) - ((y << 16) >> 16)), 16) & 0x0000FFFF;
2407 
2408     return ((s << 16) | (r));
2409 }
2410 
2411 /**
2412   \brief   Dual 16-bit unsigned subtract and add with exchange.
2413   \details This function enables you to exchange the halfwords of the second operand,
2414            subtract the high halfwords and add the low halfwords.
2415   \param [in]    x   first operand for the addition in the low halfword,
2416                      and the first operand for the subtraction in the high halfword.
2417   \param [in]    y   second operand for the addition in the high halfword,
2418                      and the second operand for the subtraction in the low halfword.
2419   \return        the addition of the low halfword of the first operand and the high
2420                  halfword of the second operand, in the low halfword of the return value.\n
2421                  the subtraction of the low halfword of the second operand from the
2422                  high halfword of the first operand, in the high halfword of the return value.\n
2423   \remark
2424                  res[15:0]  = val1[15:0]  + val2[31:16]        \n
2425                  res[31:16] = val1[31:16] - val2[15:0]
2426  */
__USAX(uint32_t x,uint32_t y)2427 __ALWAYS_STATIC_INLINE uint32_t __USAX(uint32_t x, uint32_t y)
2428 {
2429     int32_t r, s;
2430 
2431     r = (((x << 16) >> 16) + ((y) >> 16)) & 0x0000FFFF;
2432     s = (((x) >> 16) - ((y << 16) >> 16)) & 0x0000FFFF;
2433 
2434     return ((s << 16) | (r));
2435 }
2436 
2437 /**
2438   \brief   Dual 16-bit signed subtraction and addition with exchange.
2439   \details This function enables you to exchange the two halfwords of one operand and perform one
2440            16-bit integer subtraction and one 16-bit addition.
2441   \param [in]    x   first operand for the addition in the low halfword, and the first operand
2442                      for the subtraction in the high halfword.
2443   \param [in]    y   second operand for the addition in the high halfword, and the second
2444                      operand for the subtraction in the low halfword.
2445   \return        the addition of the low halfword of the first operand and the high
2446                  halfword of the second operand, in the low halfword of the return value.\n
2447                  the subtraction of the low halfword of the second operand from the
2448                  high halfword of the first operand, in the high halfword of the return value.\n
2449   \remark
2450                  res[15:0]  = val1[15:0]  + val2[31:16]        \n
2451                  res[31:16] = val1[31:16] - val2[15:0]
2452  */
__SSAX(uint32_t x,uint32_t y)2453 __ALWAYS_STATIC_INLINE uint32_t __SSAX(uint32_t x, uint32_t y)
2454 {
2455     int32_t r, s;
2456 
2457     r = ((((int32_t)x << 16) >> 16) + (((int32_t)y) >> 16)) & (int32_t)0x0000FFFF;
2458     s = ((((int32_t)x) >> 16) - (((int32_t)y << 16) >> 16)) & (int32_t)0x0000FFFF;
2459 
2460     return ((uint32_t)((s << 16) | (r)));
2461 }
2462 
2463 
2464 /**
2465   \brief   Dual 16-bit signed subtraction and addition with halved results.
2466   \details This function enables you to exchange the two halfwords of one operand, perform one signed
2467            16-bit integer subtraction and one signed 16-bit addition, and halve the results.
2468   \param [in]    x   first 16-bit operands.
2469   \param [in]    y   second 16-bit operands.
2470   \return        the halved addition of the low halfword in the first operand and the
2471                  high halfword in the second operand, in the low halfword of the return value.\n
2472                  the halved subtraction of the low halfword in the second operand from the
2473                  high halfword in the first operand, in the high halfword of the return value.
2474   \remark
2475                  res[15:0]  = (val1[15:0]  + val2[31:16]) >> 1        \n
2476                  res[31:16] = (val1[31:16] - val2[15:0]) >> 1
2477  */
__SHSAX(uint32_t x,uint32_t y)2478 __ALWAYS_STATIC_INLINE uint32_t __SHSAX(uint32_t x, uint32_t y)
2479 {
2480     int32_t r, s;
2481 
2482     r = (((((int32_t)x << 16) >> 16) + (((int32_t)y) >> 16)) >> 1) & (int32_t)0x0000FFFF;
2483     s = (((((int32_t)x) >> 16) - (((int32_t)y << 16) >> 16)) >> 1) & (int32_t)0x0000FFFF;
2484 
2485     return ((uint32_t)((s << 16) | (r)));
2486 }
2487 
2488 /**
2489   \brief   Dual 16-bit unsigned subtraction and addition with halved results and exchange.
2490   \details This function enables you to exchange the halfwords of the second operand,
2491            subtract the high halfwords and add the low halfwords, halving the results.
2492   \param [in]    x   first operand for the addition in the low halfword, and
2493                      the first operand for the subtraction in the high halfword.
2494   \param [in]    y   second operand for the addition in the high halfword, and
2495                      the second operand for the subtraction in the low halfword.
2496   \return        the halved addition of the low halfword in the first operand and the
2497                  high halfword in the second operand, in the low halfword of the return value.\n
2498                  the halved subtraction of the low halfword in the second operand from the
2499                  high halfword in the first operand, in the high halfword of the return value.
2500   \remark
2501                  res[15:0]  = (val1[15:0]  + val2[31:16]) >> 1        \n
2502                  res[31:16] = (val1[31:16] - val2[15:0]) >> 1
2503  */
__UHSAX(uint32_t x,uint32_t y)2504 __ALWAYS_STATIC_INLINE uint32_t __UHSAX(uint32_t x, uint32_t y)
2505 {
2506     int32_t r, s;
2507 
2508     r = ((((x << 16) >> 16) + ((y) >> 16)) >> 1) & 0x0000FFFF;
2509     s = ((((x) >> 16) - ((y << 16) >> 16)) >> 1) & 0x0000FFFF;
2510 
2511     return ((s << 16) | (r));
2512 }
2513 
2514 /**
2515   \brief   Dual 16-bit signed multiply with exchange returning difference.
2516   \details This function enables you to perform two 16-bit signed multiplications, subtracting
2517            one of the products from the other. The halfwords of the second operand are exchanged
2518            before performing the arithmetic. This produces top * bottom and bottom * top multiplication.
2519   \param [in]    x   first 16-bit operands for each multiplication.
2520   \param [in]    y   second 16-bit operands for each multiplication.
2521   \return        the difference of the products of the two 16-bit signed multiplications.
2522   \remark
2523                  p1 = val1[15:0]  * val2[31:16]       \n
2524                  p2 = val1[31:16] * val2[15:0]        \n
2525                  res[31:0] = p1 - p2
2526  */
__SMUSDX(uint32_t x,uint32_t y)2527 __ALWAYS_STATIC_INLINE uint32_t __SMUSDX(uint32_t x, uint32_t y)
2528 {
2529     return ((uint32_t)(((((int32_t)x << 16) >> 16) * (((int32_t)y) >> 16)) -
2530                        ((((int32_t)x) >> 16) * (((int32_t)y << 16) >> 16))));
2531 }
2532 
2533 /**
2534   \brief   Sum of dual 16-bit signed multiply with exchange.
2535   \details This function enables you to perform two 16-bit signed multiplications with exchanged
2536            halfwords of the second operand, adding the products together.
2537   \param [in]    x   first 16-bit operands for each multiplication.
2538   \param [in]    y   second 16-bit operands for each multiplication.
2539   \return        the sum of the products of the two 16-bit signed multiplications with exchanged halfwords of the second operand.
2540   \remark
2541                  p1 = val1[15:0]  * val2[31:16]       \n
2542                  p2 = val1[31:16] * val2[15:0]        \n
2543                  res[31:0] = p1 + p2
2544  */
__SMUADX(uint32_t x,uint32_t y)2545 __ALWAYS_STATIC_INLINE uint32_t __SMUADX(uint32_t x, uint32_t y)
2546 {
2547     return ((uint32_t)(((((int32_t)x << 16) >> 16) * (((int32_t)y) >> 16)) +
2548                        ((((int32_t)x) >> 16) * (((int32_t)y << 16) >> 16))));
2549 }
2550 
2551 
2552 /**
2553   \brief   Saturating add.
2554   \details This function enables you to obtain the saturating add of two integers.
2555   \param [in]    x   first summand of the saturating add operation.
2556   \param [in]    y   second summand of the saturating add operation.
2557   \return        the saturating addition of val1 and val2.
2558   \remark
2559                  res[31:0] = SAT(val1 + SAT(val2))
2560  */
__QADD(int32_t x,int32_t y)2561 __ALWAYS_STATIC_INLINE int32_t __QADD(int32_t x, int32_t y)
2562 {
2563     int32_t result;
2564 
2565     if (y >= 0) {
2566         if (x + y >= x) {
2567             result = x + y;
2568         } else {
2569             result = 0x7FFFFFFF;
2570         }
2571     } else {
2572         if (x + y < x) {
2573             result = x + y;
2574         } else {
2575             result = 0x80000000;
2576         }
2577     }
2578 
2579     return result;
2580 }
2581 
2582 /**
2583   \brief   Saturating subtract.
2584   \details This function enables you to obtain the saturating add of two integers.
2585   \param [in]    x   first summand of the saturating add operation.
2586   \param [in]    y   second summand of the saturating add operation.
2587   \return        the saturating addition of val1 and val2.
2588   \remark
2589                  res[31:0] = SAT(val1 - SAT(val2))
2590  */
__QSUB(int32_t x,int32_t y)2591 __ALWAYS_STATIC_INLINE int32_t __QSUB(int32_t x, int32_t y)
2592 {
2593     int64_t tmp;
2594     int32_t result;
2595 
2596     tmp = (int64_t)x - (int64_t)y;
2597 
2598     if (tmp > 0x7fffffff) {
2599         tmp = 0x7fffffff;
2600     } else if (tmp < (-2147483647 - 1)) {
2601         tmp = -2147483647 - 1;
2602     }
2603 
2604     result = tmp;
2605     return result;
2606 }
2607 
2608 /**
2609   \brief   Dual 16-bit signed multiply with single 32-bit accumulator.
2610   \details This function enables you to perform two signed 16-bit multiplications,
2611            adding both results to a 32-bit accumulate operand.
2612   \param [in]    x   first 16-bit operands for each multiplication.
2613   \param [in]    y   second 16-bit operands for each multiplication.
2614   \param [in]  sum   accumulate value.
2615   \return        the product of each multiplication added to the accumulate value, as a 32-bit integer.
2616   \remark
2617                  p1 = val1[15:0]  * val2[15:0]      \n
2618                  p2 = val1[31:16] * val2[31:16]     \n
2619                  res[31:0] = p1 + p2 + val3[31:0]
2620  */
__SMLAD(uint32_t x,uint32_t y,uint32_t sum)2621 __ALWAYS_STATIC_INLINE uint32_t __SMLAD(uint32_t x, uint32_t y, uint32_t sum)
2622 {
2623     return ((uint32_t)(((((int32_t)x << 16) >> 16) * (((int32_t)y << 16) >> 16)) +
2624                        ((((int32_t)x) >> 16) * (((int32_t)y) >> 16)) +
2625                        (((int32_t)sum))));
2626 }
2627 
2628 /**
2629   \brief   Pre-exchanged dual 16-bit signed multiply with single 32-bit accumulator.
2630   \details This function enables you to perform two signed 16-bit multiplications with exchanged
2631            halfwords of the second operand, adding both results to a 32-bit accumulate operand.
2632   \param [in]    x   first 16-bit operands for each multiplication.
2633   \param [in]    y   second 16-bit operands for each multiplication.
2634   \param [in]  sum   accumulate value.
2635   \return        the product of each multiplication with exchanged halfwords of the second
2636                  operand added to the accumulate value, as a 32-bit integer.
2637   \remark
2638                  p1 = val1[15:0]  * val2[31:16]     \n
2639                  p2 = val1[31:16] * val2[15:0]      \n
2640                  res[31:0] = p1 + p2 + val3[31:0]
2641  */
__SMLADX(uint32_t x,uint32_t y,uint32_t sum)2642 __ALWAYS_STATIC_INLINE uint32_t __SMLADX(uint32_t x, uint32_t y, uint32_t sum)
2643 {
2644     return ((uint32_t)(((((int32_t)x << 16) >> 16) * (((int32_t)y) >> 16)) +
2645                        ((((int32_t)x) >> 16) * (((int32_t)y << 16) >> 16)) +
2646                        (((int32_t)sum))));
2647 }
2648 
2649 /**
2650   \brief   Dual 16-bit signed multiply with exchange subtract with 32-bit accumulate.
2651   \details This function enables you to perform two 16-bit signed multiplications, take the
2652            difference of the products, subtracting the high halfword product from the low
2653            halfword product, and add the difference to a 32-bit accumulate operand.
2654   \param [in]    x   first 16-bit operands for each multiplication.
2655   \param [in]    y   second 16-bit operands for each multiplication.
2656   \param [in]  sum   accumulate value.
2657   \return        the difference of the product of each multiplication, added to the accumulate value.
2658   \remark
2659                  p1 = val1[15:0]  * val2[15:0]       \n
2660                  p2 = val1[31:16] * val2[31:16]      \n
2661                  res[31:0] = p1 - p2 + val3[31:0]
2662  */
__SMLSD(uint32_t x,uint32_t y,uint32_t sum)2663 __ALWAYS_STATIC_INLINE uint32_t __SMLSD(uint32_t x, uint32_t y, uint32_t sum)
2664 {
2665     return ((uint32_t)(((((int32_t)x << 16) >> 16) * (((int32_t)y << 16) >> 16)) -
2666                        ((((int32_t)x) >> 16) * (((int32_t)y) >> 16)) +
2667                        (((int32_t)sum))));
2668 }
2669 
2670 /**
2671   \brief   Dual 16-bit signed multiply with exchange subtract with 32-bit accumulate.
2672   \details This function enables you to exchange the halfwords in the second operand, then perform two 16-bit
2673            signed multiplications. The difference of the products is added to a 32-bit accumulate operand.
2674   \param [in]    x   first 16-bit operands for each multiplication.
2675   \param [in]    y   second 16-bit operands for each multiplication.
2676   \param [in]  sum   accumulate value.
2677   \return        the difference of the product of each multiplication, added to the accumulate value.
2678   \remark
2679                  p1 = val1[15:0]  * val2[31:16]     \n
2680                  p2 = val1[31:16] * val2[15:0]      \n
2681                  res[31:0] = p1 - p2 + val3[31:0]
2682  */
__SMLSDX(uint32_t x,uint32_t y,uint32_t sum)2683 __ALWAYS_STATIC_INLINE uint32_t __SMLSDX(uint32_t x, uint32_t y, uint32_t sum)
2684 {
2685     return ((uint32_t)(((((int32_t)x << 16) >> 16) * (((int32_t)y) >> 16)) -
2686                        ((((int32_t)x) >> 16) * (((int32_t)y << 16) >> 16)) +
2687                        (((int32_t)sum))));
2688 }
2689 
2690 /**
2691   \brief   Dual 16-bit signed multiply with single 64-bit accumulator.
2692   \details This function enables you to perform two signed 16-bit multiplications, adding both results
2693            to a 64-bit accumulate operand. Overflow is only possible as a result of the 64-bit addition.
2694            This overflow is not detected if it occurs. Instead, the result wraps around modulo2^64.
2695   \param [in]    x   first 16-bit operands for each multiplication.
2696   \param [in]    y   second 16-bit operands for each multiplication.
2697   \param [in]  sum   accumulate value.
2698   \return        the product of each multiplication added to the accumulate value.
2699   \remark
2700                  p1 = val1[15:0]  * val2[15:0]      \n
2701                  p2 = val1[31:16] * val2[31:16]     \n
2702                  sum = p1 + p2 + val3[63:32][31:0]  \n
2703                  res[63:32] = sum[63:32]            \n
2704                  res[31:0]  = sum[31:0]
2705  */
__SMLALD(uint32_t x,uint32_t y,uint64_t sum)2706 __ALWAYS_STATIC_INLINE uint64_t __SMLALD(uint32_t x, uint32_t y, uint64_t sum)
2707 {
2708     return ((uint64_t)(((((int32_t)x << 16) >> 16) * (((int32_t)y << 16) >> 16)) +
2709                        ((((int32_t)x) >> 16) * (((int32_t)y) >> 16)) +
2710                        (((uint64_t)sum))));
2711 }
2712 
2713 /**
2714   \brief   Dual 16-bit signed multiply with exchange with single 64-bit accumulator.
2715   \details This function enables you to exchange the halfwords of the second operand, and perform two
2716            signed 16-bit multiplications, adding both results to a 64-bit accumulate operand. Overflow
2717            is only possible as a result of the 64-bit addition. This overflow is not detected if it occurs.
2718            Instead, the result wraps around modulo2^64.
2719   \param [in]    x   first 16-bit operands for each multiplication.
2720   \param [in]    y   second 16-bit operands for each multiplication.
2721   \param [in]  sum   accumulate value.
2722   \return        the product of each multiplication added to the accumulate value.
2723   \remark
2724                  p1 = val1[15:0]  * val2[31:16]     \n
2725                  p2 = val1[31:16] * val2[15:0]      \n
2726                  sum = p1 + p2 + val3[63:32][31:0]  \n
2727                  res[63:32] = sum[63:32]            \n
2728                  res[31:0]  = sum[31:0]
2729  */
__SMLALDX(uint32_t x,uint32_t y,uint64_t sum)2730 __ALWAYS_STATIC_INLINE uint64_t __SMLALDX(uint32_t x, uint32_t y, uint64_t sum)
2731 {
2732     return ((uint64_t)(((((int32_t)x << 16) >> 16) * (((int32_t)y) >> 16)) +
2733                        ((((int32_t)x) >> 16) * (((int32_t)y << 16) >> 16)) +
2734                        (((uint64_t)sum))));
2735 }
2736 
2737 /**
2738   \brief   dual 16-bit signed multiply subtract with 64-bit accumulate.
2739   \details This function It enables you to perform two 16-bit signed multiplications, take the difference
2740            of the products, subtracting the high halfword product from the low halfword product, and add the
2741            difference to a 64-bit accumulate operand. Overflow cannot occur during the multiplications or the
2742            subtraction. Overflow can occur as a result of the 64-bit addition, and this overflow is not
2743            detected. Instead, the result wraps round to modulo2^64.
2744   \param [in]    x   first 16-bit operands for each multiplication.
2745   \param [in]    y   second 16-bit operands for each multiplication.
2746   \param [in]  sum   accumulate value.
2747   \return        the difference of the product of each multiplication, added to the accumulate value.
2748   \remark
2749                  p1 = val1[15:0]  * val2[15:0]      \n
2750                  p2 = val1[31:16] * val2[31:16]     \n
2751                  res[63:32][31:0] = p1 - p2 + val3[63:32][31:0]
2752  */
__SMLSLD(uint32_t x,uint32_t y,uint64_t sum)2753 __ALWAYS_STATIC_INLINE uint64_t __SMLSLD(uint32_t x, uint32_t y, uint64_t sum)
2754 {
2755     return ((uint64_t)(((((int32_t)x << 16) >> 16) * (((int32_t)y << 16) >> 16)) -
2756                        ((((int32_t)x) >> 16) * (((int32_t)y) >> 16)) +
2757                        (((uint64_t)sum))));
2758 }
2759 
2760 /**
2761   \brief   Dual 16-bit signed multiply with exchange subtract with 64-bit accumulate.
2762   \details This function enables you to exchange the halfwords of the second operand, perform two 16-bit multiplications,
2763            adding the difference of the products to a 64-bit accumulate operand. Overflow cannot occur during the
2764            multiplications or the subtraction. Overflow can occur as a result of the 64-bit addition, and this overflow
2765            is not detected. Instead, the result wraps round to modulo2^64.
2766   \param [in]    x   first 16-bit operands for each multiplication.
2767   \param [in]    y   second 16-bit operands for each multiplication.
2768   \param [in]  sum   accumulate value.
2769   \return        the difference of the product of each multiplication, added to the accumulate value.
2770   \remark
2771                  p1 = val1[15:0]  * val2[31:16]      \n
2772                  p2 = val1[31:16] * val2[15:0]       \n
2773                  res[63:32][31:0] = p1 - p2 + val3[63:32][31:0]
2774  */
__SMLSLDX(uint32_t x,uint32_t y,uint64_t sum)2775 __ALWAYS_STATIC_INLINE uint64_t __SMLSLDX(uint32_t x, uint32_t y, uint64_t sum)
2776 {
2777     return ((uint64_t)(((((int32_t)x << 16) >> 16) * (((int32_t)y) >> 16)) -
2778                        ((((int32_t)x) >> 16) * (((int32_t)y << 16) >> 16)) +
2779                        (((uint64_t)sum))));
2780 }
2781 
2782 /**
2783   \brief   32-bit signed multiply with 32-bit truncated accumulator.
2784   \details This function enables you to perform a signed 32-bit multiplications, adding the most
2785            significant 32 bits of the 64-bit result to a 32-bit accumulate operand.
2786   \param [in]    x   first operand for multiplication.
2787   \param [in]    y   second operand for multiplication.
2788   \param [in]  sum   accumulate value.
2789   \return        the product of multiplication (most significant 32 bits) is added to the accumulate value, as a 32-bit integer.
2790   \remark
2791                  p = val1 * val2      \n
2792                  res[31:0] = p[63:32] + val3[31:0]
2793  */
__SMMLA(int32_t x,int32_t y,int32_t sum)2794 __ALWAYS_STATIC_INLINE uint32_t __SMMLA(int32_t x, int32_t y, int32_t sum)
2795 {
2796     return (uint32_t)((int32_t)((int64_t)((int64_t)x * (int64_t)y) >> 32) + sum);
2797 }
2798 
2799 /**
2800   \brief   Sum of dual 16-bit signed multiply.
2801   \details This function enables you to perform two 16-bit signed multiplications, adding the products together.
2802   \param [in]    x   first 16-bit operands for each multiplication.
2803   \param [in]    y   second 16-bit operands for each multiplication.
2804   \return        the sum of the products of the two 16-bit signed multiplications.
2805   \remark
2806                  p1 = val1[15:0]  * val2[15:0]      \n
2807                  p2 = val1[31:16] * val2[31:16]     \n
2808                  res[31:0] = p1 + p2
2809  */
__SMUAD(uint32_t x,uint32_t y)2810 __ALWAYS_STATIC_INLINE uint32_t __SMUAD(uint32_t x, uint32_t y)
2811 {
2812     return ((uint32_t)(((((int32_t)x << 16) >> 16) * (((int32_t)y << 16) >> 16)) +
2813                        ((((int32_t)x) >> 16) * (((int32_t)y) >> 16))));
2814 }
2815 
2816 /**
2817   \brief   Dual 16-bit signed multiply returning difference.
2818   \details This function enables you to perform two 16-bit signed multiplications, taking the difference
2819            of the products by subtracting the high halfword product from the low halfword product.
2820   \param [in]    x   first 16-bit operands for each multiplication.
2821   \param [in]    y   second 16-bit operands for each multiplication.
2822   \return        the difference of the products of the two 16-bit signed multiplications.
2823   \remark
2824                  p1 = val1[15:0]  * val2[15:0]      \n
2825                  p2 = val1[31:16] * val2[31:16]     \n
2826                  res[31:0] = p1 - p2
2827  */
__SMUSD(uint32_t x,uint32_t y)2828 __ALWAYS_STATIC_INLINE uint32_t __SMUSD(uint32_t x, uint32_t y)
2829 {
2830     return ((uint32_t)(((((int32_t)x << 16) >> 16) * (((int32_t)y << 16) >> 16)) -
2831                        ((((int32_t)x) >> 16) * (((int32_t)y) >> 16))));
2832 }
2833 
2834 /**
2835   \brief   Dual extracted 8-bit to 16-bit signed addition.
2836   \details This function enables you to extract two 8-bit values from the second operand (at bit positions
2837            [7:0] and [23:16]), sign-extend them to 16-bits each, and add the results to the first operand.
2838   \param [in]    x   values added to the sign-extended to 16-bit values.
2839   \param [in]    y   two 8-bit values to be extracted and sign-extended.
2840   \return        the addition of val1 and val2, where the 8-bit values in val2[7:0] and
2841                  val2[23:16] have been extracted and sign-extended prior to the addition.
2842   \remark
2843                  res[15:0]  = val1[15:0] + SignExtended(val2[7:0])      \n
2844                  res[31:16] = val1[31:16] + SignExtended(val2[23:16])
2845  */
__SXTAB16(uint32_t x,uint32_t y)2846 __ALWAYS_STATIC_INLINE uint32_t __SXTAB16(uint32_t x, uint32_t y)
2847 {
2848     return ((uint32_t)((((((int32_t)y << 24) >> 24) + (((int32_t)x << 16) >> 16)) & (int32_t)0x0000FFFF) |
2849                        (((((int32_t)y <<  8) >>  8)  + (((int32_t)x >> 16) << 16)) & (int32_t)0xFFFF0000)));
2850 }
2851 
2852 /**
2853   \brief   Extracted 16-bit to 32-bit unsigned addition.
2854   \details This function enables you to extract two 8-bit values from one operand, zero-extend
2855            them to 16 bits each, and add the results to two 16-bit values from another operand.
2856   \param [in]    x   values added to the zero-extended to 16-bit values.
2857   \param [in]    y   two 8-bit values to be extracted and zero-extended.
2858   \return        the addition of val1 and val2, where the 8-bit values in val2[7:0] and
2859                  val2[23:16] have been extracted and zero-extended prior to the addition.
2860   \remark
2861                  res[15:0]  = ZeroExt(val2[7:0]   to 16 bits) + val1[15:0]      \n
2862                  res[31:16] = ZeroExt(val2[31:16] to 16 bits) + val1[31:16]
2863  */
__UXTAB16(uint32_t x,uint32_t y)2864 __ALWAYS_STATIC_INLINE uint32_t __UXTAB16(uint32_t x, uint32_t y)
2865 {
2866     return ((uint32_t)(((((y << 24) >> 24) + ((x << 16) >> 16)) & 0x0000FFFF) |
2867                        ((((y <<  8) >>  8) + ((x >> 16) << 16)) & 0xFFFF0000)));
2868 }
2869 
2870 /**
2871   \brief   Dual extract 8-bits and sign extend each to 16-bits.
2872   \details This function enables you to extract two 8-bit values from an operand and sign-extend them to 16 bits each.
2873   \param [in]    x   two 8-bit values in val[7:0] and val[23:16] to be sign-extended.
2874   \return        the 8-bit values sign-extended to 16-bit values.\n
2875                  sign-extended value of val[7:0] in the low halfword of the return value.\n
2876                  sign-extended value of val[23:16] in the high halfword of the return value.
2877   \remark
2878                  res[15:0]  = SignExtended(val[7:0])       \n
2879                  res[31:16] = SignExtended(val[23:16])
2880  */
__SXTB16(uint32_t x)2881 __ALWAYS_STATIC_INLINE uint32_t __SXTB16(uint32_t x)
2882 {
2883     return ((uint32_t)(((((int32_t)x << 24) >> 24) & (int32_t)0x0000FFFF) |
2884                        ((((int32_t)x <<  8) >>  8) & (int32_t)0xFFFF0000)));
2885 }
2886 
2887 /**
2888   \brief   Dual extract 8-bits and zero-extend to 16-bits.
2889   \details This function enables you to extract two 8-bit values from an operand and zero-extend them to 16 bits each.
2890   \param [in]    x   two 8-bit values in val[7:0] and val[23:16] to be zero-extended.
2891   \return        the 8-bit values sign-extended to 16-bit values.\n
2892                  sign-extended value of val[7:0] in the low halfword of the return value.\n
2893                  sign-extended value of val[23:16] in the high halfword of the return value.
2894   \remark
2895                  res[15:0]  = SignExtended(val[7:0])       \n
2896                  res[31:16] = SignExtended(val[23:16])
2897  */
__UXTB16(uint32_t x)2898 __ALWAYS_STATIC_INLINE uint32_t __UXTB16(uint32_t x)
2899 {
2900     return ((uint32_t)((((x << 24) >> 24) & 0x0000FFFF) |
2901                        (((x <<  8) >>  8) & 0xFFFF0000)));
2902 }
2903 
2904 #endif /* _CSI_GCC_H_ */
2905