tdse-tp0_02-hw_sw_test

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