core_cmInstr.h 25.9 KB
Newer Older
Y
yanmowudi 已提交
1
/**************************************************************************/ /**
Z
zohar123 已提交
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45
 * @file     core_cmInstr.h
 * @brief    CMSIS Cortex-M Core Instruction Access Header File
 * @version  V4.00
 * @date     28. August 2014
 *
 * @note
 *
 ******************************************************************************/
/* Copyright (c) 2009 - 2014 ARM LIMITED

   All rights reserved.
   Redistribution and use in source and binary forms, with or without
   modification, are permitted provided that the following conditions are met:
   - Redistributions of source code must retain the above copyright
     notice, this list of conditions and the following disclaimer.
   - Redistributions in binary form must reproduce the above copyright
     notice, this list of conditions and the following disclaimer in the
     documentation and/or other materials provided with the distribution.
   - Neither the name of ARM nor the names of its contributors may be used
     to endorse or promote products derived from this software without
     specific prior written permission.
   *
   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
   AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE
   LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
   CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
   SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
   INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
   CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
   ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
   POSSIBILITY OF SUCH DAMAGE.
   ---------------------------------------------------------------------------*/

#ifndef __CORE_CMINSTR_H
#define __CORE_CMINSTR_H

/* ##########################  Core Instruction Access  ######################### */
/** \defgroup CMSIS_Core_InstructionInterface CMSIS Core Instruction Interface
  Access to dedicated instructions
  @{
*/

Y
yanmowudi 已提交
46
#if defined(__CC_ARM) /*------------------RealView Compiler -----------------*/
Z
zohar123 已提交
47 48 49
/* ARM armcc specific functions */

#if (__ARMCC_VERSION < 400677)
Y
yanmowudi 已提交
50
#error "Please use ARM Compiler Toolchain V4.0.677 or later!"
Z
zohar123 已提交
51 52 53 54 55 56
#endif

/** \brief  No Operation

    No Operation does nothing. This instruction can be used for code alignment purposes.
 */
Y
yanmowudi 已提交
57
#define __NOP __nop
Z
zohar123 已提交
58 59 60 61 62 63

/** \brief  Wait For Interrupt

    Wait For Interrupt is a hint instruction that suspends execution
    until one of a number of events occurs.
 */
Y
yanmowudi 已提交
64
#define __WFI __wfi
Z
zohar123 已提交
65 66 67 68 69 70

/** \brief  Wait For Event

    Wait For Event is a hint instruction that permits the processor to enter
    a low-power state until one of a number of events occurs.
 */
Y
yanmowudi 已提交
71
#define __WFE __wfe
Z
zohar123 已提交
72 73 74 75 76

/** \brief  Send Event

    Send Event is a hint instruction. It causes an event to be signaled to the CPU.
 */
Y
yanmowudi 已提交
77
#define __SEV __sev
Z
zohar123 已提交
78 79 80 81 82 83 84

/** \brief  Instruction Synchronization Barrier

    Instruction Synchronization Barrier flushes the pipeline in the processor,
    so that all instructions following the ISB are fetched from cache or
    memory, after the instruction has been completed.
 */
Y
yanmowudi 已提交
85
#define __ISB() __isb(0xF)
Z
zohar123 已提交
86 87 88 89 90 91

/** \brief  Data Synchronization Barrier

    This function acts as a special kind of Data Memory Barrier.
    It completes when all explicit memory accesses before this instruction complete.
 */
Y
yanmowudi 已提交
92
#define __DSB() __dsb(0xF)
Z
zohar123 已提交
93 94 95 96 97 98

/** \brief  Data Memory Barrier

    This function ensures the apparent order of the explicit memory operations before
    and after the instruction, without ensuring their completion.
 */
Y
yanmowudi 已提交
99
#define __DMB() __dmb(0xF)
Z
zohar123 已提交
100 101 102 103 104 105 106 107

/** \brief  Reverse byte order (32 bit)

    This function reverses the byte order in integer value.

    \param [in]    value  Value to reverse
    \return               Reversed value
 */
Y
yanmowudi 已提交
108
#define __REV __rev
Z
zohar123 已提交
109 110 111 112 113 114 115 116 117 118 119

/** \brief  Reverse byte order (16 bit)

    This function reverses the byte order in two unsigned short values.

    \param [in]    value  Value to reverse
    \return               Reversed value
 */
#ifndef __NO_EMBEDDED_ASM
__attribute__((section(".rev16_text"))) __STATIC_INLINE __ASM uint32_t __REV16(uint32_t value)
{
Y
yanmowudi 已提交
120 121
    rev16 r0, r0
                  bx lr
Z
zohar123 已提交
122 123 124 125 126 127 128 129 130 131 132 133 134
}
#endif

/** \brief  Reverse byte order in signed short value

    This function reverses the byte order in a signed short value with sign extension to integer.

    \param [in]    value  Value to reverse
    \return               Reversed value
 */
#ifndef __NO_EMBEDDED_ASM
__attribute__((section(".revsh_text"))) __STATIC_INLINE __ASM int32_t __REVSH(int32_t value)
{
Y
yanmowudi 已提交
135 136
    revsh r0, r0
                  bx lr
Z
zohar123 已提交
137 138 139 140 141 142 143 144 145 146 147
}
#endif

/** \brief  Rotate Right in unsigned value (32 bit)

    This function Rotate Right (immediate) provides the value of the contents of a register rotated by a variable number of bits.

    \param [in]    value  Value to rotate
    \param [in]    value  Number of Bits to rotate
    \return               Rotated value
 */
Y
yanmowudi 已提交
148
#define __ROR __ror
Z
zohar123 已提交
149 150 151 152 153 154 155 156 157

/** \brief  Breakpoint

    This function causes the processor to enter Debug state.
    Debug tools can use this to investigate system state when the instruction at a particular address is reached.

    \param [in]    value  is ignored by the processor.
                   If required, a debugger can use it to store additional information about the breakpoint.
 */
Y
yanmowudi 已提交
158
#define __BKPT(value) __breakpoint(value)
Z
zohar123 已提交
159

Y
yanmowudi 已提交
160
#if (__CORTEX_M >= 0x03) || (__CORTEX_SC >= 300)
Z
zohar123 已提交
161 162 163 164 165 166 167 168

/** \brief  Reverse bit order of value

    This function reverses the bit order of the given value.

    \param [in]    value  Value to reverse
    \return               Reversed value
 */
Y
yanmowudi 已提交
169
#define __RBIT __rbit
Z
zohar123 已提交
170 171 172 173 174 175 176 177

/** \brief  LDR Exclusive (8 bit)

    This function executes a exclusive LDR instruction for 8 bit value.

    \param [in]    ptr  Pointer to data
    \return             value of type uint8_t at (*ptr)
 */
Y
yanmowudi 已提交
178
#define __LDREXB(ptr) ((uint8_t)__ldrex(ptr))
Z
zohar123 已提交
179 180 181 182 183 184 185 186

/** \brief  LDR Exclusive (16 bit)

    This function executes a exclusive LDR instruction for 16 bit values.

    \param [in]    ptr  Pointer to data
    \return        value of type uint16_t at (*ptr)
 */
Y
yanmowudi 已提交
187
#define __LDREXH(ptr) ((uint16_t)__ldrex(ptr))
Z
zohar123 已提交
188 189 190 191 192 193 194 195

/** \brief  LDR Exclusive (32 bit)

    This function executes a exclusive LDR instruction for 32 bit values.

    \param [in]    ptr  Pointer to data
    \return        value of type uint32_t at (*ptr)
 */
Y
yanmowudi 已提交
196
#define __LDREXW(ptr) ((uint32_t)__ldrex(ptr))
Z
zohar123 已提交
197 198 199 200 201 202 203 204 205 206

/** \brief  STR Exclusive (8 bit)

    This function executes a exclusive STR instruction for 8 bit values.

    \param [in]  value  Value to store
    \param [in]    ptr  Pointer to location
    \return          0  Function succeeded
    \return          1  Function failed
 */
Y
yanmowudi 已提交
207
#define __STREXB(value, ptr) __strex(value, ptr)
Z
zohar123 已提交
208 209 210 211 212 213 214 215 216 217

/** \brief  STR Exclusive (16 bit)

    This function executes a exclusive STR instruction for 16 bit values.

    \param [in]  value  Value to store
    \param [in]    ptr  Pointer to location
    \return          0  Function succeeded
    \return          1  Function failed
 */
Y
yanmowudi 已提交
218
#define __STREXH(value, ptr) __strex(value, ptr)
Z
zohar123 已提交
219 220 221 222 223 224 225 226 227 228

/** \brief  STR Exclusive (32 bit)

    This function executes a exclusive STR instruction for 32 bit values.

    \param [in]  value  Value to store
    \param [in]    ptr  Pointer to location
    \return          0  Function succeeded
    \return          1  Function failed
 */
Y
yanmowudi 已提交
229
#define __STREXW(value, ptr) __strex(value, ptr)
Z
zohar123 已提交
230 231 232 233 234 235

/** \brief  Remove the exclusive lock

    This function removes the exclusive lock which is created by LDREX.

 */
Y
yanmowudi 已提交
236
#define __CLREX __clrex
Z
zohar123 已提交
237 238 239 240 241 242 243 244 245

/** \brief  Signed Saturate

    This function saturates a signed value.

    \param [in]  value  Value to be saturated
    \param [in]    sat  Bit position to saturate to (1..32)
    \return             Saturated value
 */
Y
yanmowudi 已提交
246
#define __SSAT __ssat
Z
zohar123 已提交
247 248 249 250 251 252 253 254 255

/** \brief  Unsigned Saturate

    This function saturates an unsigned value.

    \param [in]  value  Value to be saturated
    \param [in]    sat  Bit position to saturate to (0..31)
    \return             Saturated value
 */
Y
yanmowudi 已提交
256
#define __USAT __usat
Z
zohar123 已提交
257 258 259 260 261 262 263 264

/** \brief  Count leading zeros

    This function counts the number of leading zeros of a data value.

    \param [in]  value  Value to count the leading zeros
    \return             number of leading zeros in value
 */
Y
yanmowudi 已提交
265
#define __CLZ __clz
Z
zohar123 已提交
266 267 268 269 270 271 272 273 274 275 276

/** \brief  Rotate Right with Extend (32 bit)

    This function moves each bit of a bitstring right by one bit. The carry input is shifted in at the left end of the bitstring.

    \param [in]    value  Value to rotate
    \return               Rotated value
 */
#ifndef __NO_EMBEDDED_ASM
__attribute__((section(".rrx_text"))) __STATIC_INLINE __ASM uint32_t __RRX(uint32_t value)
{
Y
yanmowudi 已提交
277 278
    rrx r0, r0
                bx lr
Z
zohar123 已提交
279 280 281 282 283 284 285 286 287 288
}
#endif

/** \brief  LDRT Unprivileged (8 bit)

    This function executes a Unprivileged LDRT instruction for 8 bit value.

    \param [in]    ptr  Pointer to data
    \return             value of type uint8_t at (*ptr)
 */
Y
yanmowudi 已提交
289
#define __LDRBT(ptr) ((uint8_t)__ldrt(ptr))
Z
zohar123 已提交
290 291 292 293 294 295 296 297

/** \brief  LDRT Unprivileged (16 bit)

    This function executes a Unprivileged LDRT instruction for 16 bit values.

    \param [in]    ptr  Pointer to data
    \return        value of type uint16_t at (*ptr)
 */
Y
yanmowudi 已提交
298
#define __LDRHT(ptr) ((uint16_t)__ldrt(ptr))
Z
zohar123 已提交
299 300 301 302 303 304 305 306

/** \brief  LDRT Unprivileged (32 bit)

    This function executes a Unprivileged LDRT instruction for 32 bit values.

    \param [in]    ptr  Pointer to data
    \return        value of type uint32_t at (*ptr)
 */
Y
yanmowudi 已提交
307
#define __LDRT(ptr) ((uint32_t)__ldrt(ptr))
Z
zohar123 已提交
308 309 310 311 312 313 314 315

/** \brief  STRT Unprivileged (8 bit)

    This function executes a Unprivileged STRT instruction for 8 bit values.

    \param [in]  value  Value to store
    \param [in]    ptr  Pointer to location
 */
Y
yanmowudi 已提交
316
#define __STRBT(value, ptr) __strt(value, ptr)
Z
zohar123 已提交
317 318 319 320 321 322 323 324

/** \brief  STRT Unprivileged (16 bit)

    This function executes a Unprivileged STRT instruction for 16 bit values.

    \param [in]  value  Value to store
    \param [in]    ptr  Pointer to location
 */
Y
yanmowudi 已提交
325
#define __STRHT(value, ptr) __strt(value, ptr)
Z
zohar123 已提交
326 327 328 329 330 331 332 333

/** \brief  STRT Unprivileged (32 bit)

    This function executes a Unprivileged STRT instruction for 32 bit values.

    \param [in]  value  Value to store
    \param [in]    ptr  Pointer to location
 */
Y
yanmowudi 已提交
334
#define __STRT(value, ptr) __strt(value, ptr)
Z
zohar123 已提交
335 336 337

#endif /* (__CORTEX_M >= 0x03) || (__CORTEX_SC >= 300) */

Y
yanmowudi 已提交
338
#elif defined(__GNUC__) /*------------------ GNU Compiler ---------------------*/
Z
zohar123 已提交
339 340 341 342 343
/* GNU gcc specific functions */

/* Define macros for porting to both thumb1 and thumb2.
 * For thumb1, use low register (r0-r7), specified by constrant "l"
 * Otherwise, use general registers, specified by constrant "r" */
Y
yanmowudi 已提交
344 345 346
#if defined(__thumb__) && !defined(__thumb2__)
#define __CMSIS_GCC_OUT_REG(r) "=l"(r)
#define __CMSIS_GCC_USE_REG(r) "l"(r)
Z
zohar123 已提交
347
#else
Y
yanmowudi 已提交
348 349
#define __CMSIS_GCC_OUT_REG(r) "=r"(r)
#define __CMSIS_GCC_USE_REG(r) "r"(r)
Z
zohar123 已提交
350 351 352 353 354 355
#endif

/** \brief  No Operation

    No Operation does nothing. This instruction can be used for code alignment purposes.
 */
Y
yanmowudi 已提交
356
__attribute__((always_inline)) __STATIC_INLINE void __NOP(void)
Z
zohar123 已提交
357
{
Y
yanmowudi 已提交
358
    __ASM volatile("nop");
Z
zohar123 已提交
359 360 361 362 363 364 365
}

/** \brief  Wait For Interrupt

    Wait For Interrupt is a hint instruction that suspends execution
    until one of a number of events occurs.
 */
Y
yanmowudi 已提交
366
__attribute__((always_inline)) __STATIC_INLINE void __WFI(void)
Z
zohar123 已提交
367
{
Y
yanmowudi 已提交
368
    __ASM volatile("wfi");
Z
zohar123 已提交
369 370 371 372 373 374 375
}

/** \brief  Wait For Event

    Wait For Event is a hint instruction that permits the processor to enter
    a low-power state until one of a number of events occurs.
 */
Y
yanmowudi 已提交
376
__attribute__((always_inline)) __STATIC_INLINE void __WFE(void)
Z
zohar123 已提交
377
{
Y
yanmowudi 已提交
378
    __ASM volatile("wfe");
Z
zohar123 已提交
379 380 381 382 383 384
}

/** \brief  Send Event

    Send Event is a hint instruction. It causes an event to be signaled to the CPU.
 */
Y
yanmowudi 已提交
385
__attribute__((always_inline)) __STATIC_INLINE void __SEV(void)
Z
zohar123 已提交
386
{
Y
yanmowudi 已提交
387
    __ASM volatile("sev");
Z
zohar123 已提交
388 389 390 391 392 393 394 395
}

/** \brief  Instruction Synchronization Barrier

    Instruction Synchronization Barrier flushes the pipeline in the processor,
    so that all instructions following the ISB are fetched from cache or
    memory, after the instruction has been completed.
 */
Y
yanmowudi 已提交
396
__attribute__((always_inline)) __STATIC_INLINE void __ISB(void)
Z
zohar123 已提交
397
{
Y
yanmowudi 已提交
398
    __ASM volatile("isb");
Z
zohar123 已提交
399 400 401 402 403 404 405
}

/** \brief  Data Synchronization Barrier

    This function acts as a special kind of Data Memory Barrier.
    It completes when all explicit memory accesses before this instruction complete.
 */
Y
yanmowudi 已提交
406
__attribute__((always_inline)) __STATIC_INLINE void __DSB(void)
Z
zohar123 已提交
407
{
Y
yanmowudi 已提交
408
    __ASM volatile("dsb");
Z
zohar123 已提交
409 410 411 412 413 414 415
}

/** \brief  Data Memory Barrier

    This function ensures the apparent order of the explicit memory operations before
    and after the instruction, without ensuring their completion.
 */
Y
yanmowudi 已提交
416
__attribute__((always_inline)) __STATIC_INLINE void __DMB(void)
Z
zohar123 已提交
417
{
Y
yanmowudi 已提交
418
    __ASM volatile("dmb");
Z
zohar123 已提交
419 420 421 422 423 424 425 426 427
}

/** \brief  Reverse byte order (32 bit)

    This function reverses the byte order in integer value.

    \param [in]    value  Value to reverse
    \return               Reversed value
 */
Y
yanmowudi 已提交
428
__attribute__((always_inline)) __STATIC_INLINE uint32_t __REV(uint32_t value)
Z
zohar123 已提交
429 430
{
#if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 5)
Y
yanmowudi 已提交
431
    return __builtin_bswap32(value);
Z
zohar123 已提交
432
#else
Y
yanmowudi 已提交
433
    uint32_t result;
Z
zohar123 已提交
434

Y
yanmowudi 已提交
435 436 437 438
    __ASM volatile("rev %0, %1"
                   : __CMSIS_GCC_OUT_REG(result)
                   : __CMSIS_GCC_USE_REG(value));
    return (result);
Z
zohar123 已提交
439 440 441 442 443 444 445 446 447 448
#endif
}

/** \brief  Reverse byte order (16 bit)

    This function reverses the byte order in two unsigned short values.

    \param [in]    value  Value to reverse
    \return               Reversed value
 */
Y
yanmowudi 已提交
449
__attribute__((always_inline)) __STATIC_INLINE uint32_t __REV16(uint32_t value)
Z
zohar123 已提交
450
{
Y
yanmowudi 已提交
451
    uint32_t result;
Z
zohar123 已提交
452

Y
yanmowudi 已提交
453 454 455 456
    __ASM volatile("rev16 %0, %1"
                   : __CMSIS_GCC_OUT_REG(result)
                   : __CMSIS_GCC_USE_REG(value));
    return (result);
Z
zohar123 已提交
457 458 459 460 461 462 463 464 465
}

/** \brief  Reverse byte order in signed short value

    This function reverses the byte order in a signed short value with sign extension to integer.

    \param [in]    value  Value to reverse
    \return               Reversed value
 */
Y
yanmowudi 已提交
466
__attribute__((always_inline)) __STATIC_INLINE int32_t __REVSH(int32_t value)
Z
zohar123 已提交
467 468
{
#if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8)
Y
yanmowudi 已提交
469
    return (short)__builtin_bswap16(value);
Z
zohar123 已提交
470
#else
Y
yanmowudi 已提交
471
    uint32_t result;
Z
zohar123 已提交
472

Y
yanmowudi 已提交
473 474 475 476
    __ASM volatile("revsh %0, %1"
                   : __CMSIS_GCC_OUT_REG(result)
                   : __CMSIS_GCC_USE_REG(value));
    return (result);
Z
zohar123 已提交
477 478 479 480 481 482 483 484 485 486 487
#endif
}

/** \brief  Rotate Right in unsigned value (32 bit)

    This function Rotate Right (immediate) provides the value of the contents of a register rotated by a variable number of bits.

    \param [in]    value  Value to rotate
    \param [in]    value  Number of Bits to rotate
    \return               Rotated value
 */
Y
yanmowudi 已提交
488
__attribute__((always_inline)) __STATIC_INLINE uint32_t __ROR(uint32_t op1, uint32_t op2)
Z
zohar123 已提交
489
{
Y
yanmowudi 已提交
490
    return (op1 >> op2) | (op1 << (32 - op2));
Z
zohar123 已提交
491 492 493 494 495 496 497 498 499 500
}

/** \brief  Breakpoint

    This function causes the processor to enter Debug state.
    Debug tools can use this to investigate system state when the instruction at a particular address is reached.

    \param [in]    value  is ignored by the processor.
                   If required, a debugger can use it to store additional information about the breakpoint.
 */
Y
yanmowudi 已提交
501
#define __BKPT(value) __ASM volatile("bkpt " #value)
Z
zohar123 已提交
502

Y
yanmowudi 已提交
503
#if (__CORTEX_M >= 0x03) || (__CORTEX_SC >= 300)
Z
zohar123 已提交
504 505 506 507 508 509 510 511

/** \brief  Reverse bit order of value

    This function reverses the bit order of the given value.

    \param [in]    value  Value to reverse
    \return               Reversed value
 */
Y
yanmowudi 已提交
512
__attribute__((always_inline)) __STATIC_INLINE uint32_t __RBIT(uint32_t value)
Z
zohar123 已提交
513
{
Y
yanmowudi 已提交
514
    uint32_t result;
Z
zohar123 已提交
515

Y
yanmowudi 已提交
516 517 518 519
    __ASM volatile("rbit %0, %1"
                   : "=r"(result)
                   : "r"(value));
    return (result);
Z
zohar123 已提交
520 521 522 523 524 525 526 527 528
}

/** \brief  LDR Exclusive (8 bit)

    This function executes a exclusive LDR instruction for 8 bit value.

    \param [in]    ptr  Pointer to data
    \return             value of type uint8_t at (*ptr)
 */
Y
yanmowudi 已提交
529
__attribute__((always_inline)) __STATIC_INLINE uint8_t __LDREXB(volatile uint8_t *addr)
Z
zohar123 已提交
530 531 532 533
{
    uint32_t result;

#if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8)
Y
yanmowudi 已提交
534 535 536
    __ASM volatile("ldrexb %0, %1"
                   : "=r"(result)
                   : "Q"(*addr));
Z
zohar123 已提交
537 538 539 540
#else
    /* Prior to GCC 4.8, "Q" will be expanded to [rx, #0] which is not
       accepted by assembler. So has to use following less efficient pattern.
    */
Y
yanmowudi 已提交
541 542 543 544
    __ASM volatile("ldrexb %0, [%1]"
                   : "=r"(result)
                   : "r"(addr)
                   : "memory");
Z
zohar123 已提交
545
#endif
Y
yanmowudi 已提交
546
    return ((uint8_t)result); /* Add explicit type cast here */
Z
zohar123 已提交
547 548 549 550 551 552 553 554 555
}

/** \brief  LDR Exclusive (16 bit)

    This function executes a exclusive LDR instruction for 16 bit values.

    \param [in]    ptr  Pointer to data
    \return        value of type uint16_t at (*ptr)
 */
Y
yanmowudi 已提交
556
__attribute__((always_inline)) __STATIC_INLINE uint16_t __LDREXH(volatile uint16_t *addr)
Z
zohar123 已提交
557 558 559 560
{
    uint32_t result;

#if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8)
Y
yanmowudi 已提交
561 562 563
    __ASM volatile("ldrexh %0, %1"
                   : "=r"(result)
                   : "Q"(*addr));
Z
zohar123 已提交
564 565 566 567
#else
    /* Prior to GCC 4.8, "Q" will be expanded to [rx, #0] which is not
       accepted by assembler. So has to use following less efficient pattern.
    */
Y
yanmowudi 已提交
568 569 570 571
    __ASM volatile("ldrexh %0, [%1]"
                   : "=r"(result)
                   : "r"(addr)
                   : "memory");
Z
zohar123 已提交
572
#endif
Y
yanmowudi 已提交
573
    return ((uint16_t)result); /* Add explicit type cast here */
Z
zohar123 已提交
574 575 576 577 578 579 580 581 582
}

/** \brief  LDR Exclusive (32 bit)

    This function executes a exclusive LDR instruction for 32 bit values.

    \param [in]    ptr  Pointer to data
    \return        value of type uint32_t at (*ptr)
 */
Y
yanmowudi 已提交
583
__attribute__((always_inline)) __STATIC_INLINE uint32_t __LDREXW(volatile uint32_t *addr)
Z
zohar123 已提交
584 585 586
{
    uint32_t result;

Y
yanmowudi 已提交
587 588 589 590
    __ASM volatile("ldrex %0, %1"
                   : "=r"(result)
                   : "Q"(*addr));
    return (result);
Z
zohar123 已提交
591 592 593 594 595 596 597 598 599 600 601
}

/** \brief  STR Exclusive (8 bit)

    This function executes a exclusive STR instruction for 8 bit values.

    \param [in]  value  Value to store
    \param [in]    ptr  Pointer to location
    \return          0  Function succeeded
    \return          1  Function failed
 */
Y
yanmowudi 已提交
602
__attribute__((always_inline)) __STATIC_INLINE uint32_t __STREXB(uint8_t value, volatile uint8_t *addr)
Z
zohar123 已提交
603
{
Y
yanmowudi 已提交
604
    uint32_t result;
Z
zohar123 已提交
605

Y
yanmowudi 已提交
606 607 608 609
    __ASM volatile("strexb %0, %2, %1"
                   : "=&r"(result), "=Q"(*addr)
                   : "r"((uint32_t)value));
    return (result);
Z
zohar123 已提交
610 611 612 613 614 615 616 617 618 619 620
}

/** \brief  STR Exclusive (16 bit)

    This function executes a exclusive STR instruction for 16 bit values.

    \param [in]  value  Value to store
    \param [in]    ptr  Pointer to location
    \return          0  Function succeeded
    \return          1  Function failed
 */
Y
yanmowudi 已提交
621
__attribute__((always_inline)) __STATIC_INLINE uint32_t __STREXH(uint16_t value, volatile uint16_t *addr)
Z
zohar123 已提交
622
{
Y
yanmowudi 已提交
623
    uint32_t result;
Z
zohar123 已提交
624

Y
yanmowudi 已提交
625 626 627 628
    __ASM volatile("strexh %0, %2, %1"
                   : "=&r"(result), "=Q"(*addr)
                   : "r"((uint32_t)value));
    return (result);
Z
zohar123 已提交
629 630 631 632 633 634 635 636 637 638 639
}

/** \brief  STR Exclusive (32 bit)

    This function executes a exclusive STR instruction for 32 bit values.

    \param [in]  value  Value to store
    \param [in]    ptr  Pointer to location
    \return          0  Function succeeded
    \return          1  Function failed
 */
Y
yanmowudi 已提交
640
__attribute__((always_inline)) __STATIC_INLINE uint32_t __STREXW(uint32_t value, volatile uint32_t *addr)
Z
zohar123 已提交
641
{
Y
yanmowudi 已提交
642
    uint32_t result;
Z
zohar123 已提交
643

Y
yanmowudi 已提交
644 645 646 647
    __ASM volatile("strex %0, %2, %1"
                   : "=&r"(result), "=Q"(*addr)
                   : "r"(value));
    return (result);
Z
zohar123 已提交
648 649 650 651 652 653 654
}

/** \brief  Remove the exclusive lock

    This function removes the exclusive lock which is created by LDREX.

 */
Y
yanmowudi 已提交
655
__attribute__((always_inline)) __STATIC_INLINE void __CLREX(void)
Z
zohar123 已提交
656
{
Y
yanmowudi 已提交
657 658
    __ASM volatile("clrex" ::
                       : "memory");
Z
zohar123 已提交
659 660 661 662 663 664 665 666 667 668
}

/** \brief  Signed Saturate

    This function saturates a signed value.

    \param [in]  value  Value to be saturated
    \param [in]    sat  Bit position to saturate to (1..32)
    \return             Saturated value
 */
Y
yanmowudi 已提交
669 670 671 672 673 674 675 676 677
#define __SSAT(ARG1, ARG2)                   \
    (                                        \
        {                                    \
            uint32_t __RES, __ARG1 = (ARG1); \
            __ASM("ssat %0, %1, %2"          \
                  : "=r"(__RES)              \
                  : "I"(ARG2), "r"(__ARG1)); \
            __RES;                           \
        })
Z
zohar123 已提交
678 679 680 681 682 683 684 685 686

/** \brief  Unsigned Saturate

    This function saturates an unsigned value.

    \param [in]  value  Value to be saturated
    \param [in]    sat  Bit position to saturate to (0..31)
    \return             Saturated value
 */
Y
yanmowudi 已提交
687 688 689 690 691 692 693 694 695
#define __USAT(ARG1, ARG2)                   \
    (                                        \
        {                                    \
            uint32_t __RES, __ARG1 = (ARG1); \
            __ASM("usat %0, %1, %2"          \
                  : "=r"(__RES)              \
                  : "I"(ARG2), "r"(__ARG1)); \
            __RES;                           \
        })
Z
zohar123 已提交
696 697 698 699 700 701 702 703

/** \brief  Count leading zeros

    This function counts the number of leading zeros of a data value.

    \param [in]  value  Value to count the leading zeros
    \return             number of leading zeros in value
 */
Y
yanmowudi 已提交
704
__attribute__((always_inline)) __STATIC_INLINE uint8_t __CLZ(uint32_t value)
Z
zohar123 已提交
705
{
Y
yanmowudi 已提交
706
    uint32_t result;
Z
zohar123 已提交
707

Y
yanmowudi 已提交
708 709 710 711
    __ASM volatile("clz %0, %1"
                   : "=r"(result)
                   : "r"(value));
    return ((uint8_t)result); /* Add explicit type cast here */
Z
zohar123 已提交
712 713 714 715 716 717 718 719 720
}

/** \brief  Rotate Right with Extend (32 bit)

    This function moves each bit of a bitstring right by one bit. The carry input is shifted in at the left end of the bitstring.

    \param [in]    value  Value to rotate
    \return               Rotated value
 */
Y
yanmowudi 已提交
721
__attribute__((always_inline)) __STATIC_INLINE uint32_t __RRX(uint32_t value)
Z
zohar123 已提交
722
{
Y
yanmowudi 已提交
723
    uint32_t result;
Z
zohar123 已提交
724

Y
yanmowudi 已提交
725 726 727 728
    __ASM volatile("rrx %0, %1"
                   : __CMSIS_GCC_OUT_REG(result)
                   : __CMSIS_GCC_USE_REG(value));
    return (result);
Z
zohar123 已提交
729 730 731 732 733 734 735 736 737
}

/** \brief  LDRT Unprivileged (8 bit)

    This function executes a Unprivileged LDRT instruction for 8 bit value.

    \param [in]    ptr  Pointer to data
    \return             value of type uint8_t at (*ptr)
 */
Y
yanmowudi 已提交
738
__attribute__((always_inline)) __STATIC_INLINE uint8_t __LDRBT(volatile uint8_t *addr)
Z
zohar123 已提交
739 740 741 742
{
    uint32_t result;

#if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8)
Y
yanmowudi 已提交
743 744 745
    __ASM volatile("ldrbt %0, %1"
                   : "=r"(result)
                   : "Q"(*addr));
Z
zohar123 已提交
746 747 748 749
#else
    /* Prior to GCC 4.8, "Q" will be expanded to [rx, #0] which is not
       accepted by assembler. So has to use following less efficient pattern.
    */
Y
yanmowudi 已提交
750 751 752 753
    __ASM volatile("ldrbt %0, [%1]"
                   : "=r"(result)
                   : "r"(addr)
                   : "memory");
Z
zohar123 已提交
754
#endif
Y
yanmowudi 已提交
755
    return ((uint8_t)result); /* Add explicit type cast here */
Z
zohar123 已提交
756 757 758 759 760 761 762 763 764
}

/** \brief  LDRT Unprivileged (16 bit)

    This function executes a Unprivileged LDRT instruction for 16 bit values.

    \param [in]    ptr  Pointer to data
    \return        value of type uint16_t at (*ptr)
 */
Y
yanmowudi 已提交
765
__attribute__((always_inline)) __STATIC_INLINE uint16_t __LDRHT(volatile uint16_t *addr)
Z
zohar123 已提交
766 767 768 769
{
    uint32_t result;

#if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8)
Y
yanmowudi 已提交
770 771 772
    __ASM volatile("ldrht %0, %1"
                   : "=r"(result)
                   : "Q"(*addr));
Z
zohar123 已提交
773 774 775 776
#else
    /* Prior to GCC 4.8, "Q" will be expanded to [rx, #0] which is not
       accepted by assembler. So has to use following less efficient pattern.
    */
Y
yanmowudi 已提交
777 778 779 780
    __ASM volatile("ldrht %0, [%1]"
                   : "=r"(result)
                   : "r"(addr)
                   : "memory");
Z
zohar123 已提交
781
#endif
Y
yanmowudi 已提交
782
    return ((uint16_t)result); /* Add explicit type cast here */
Z
zohar123 已提交
783 784 785 786 787 788 789 790 791
}

/** \brief  LDRT Unprivileged (32 bit)

    This function executes a Unprivileged LDRT instruction for 32 bit values.

    \param [in]    ptr  Pointer to data
    \return        value of type uint32_t at (*ptr)
 */
Y
yanmowudi 已提交
792
__attribute__((always_inline)) __STATIC_INLINE uint32_t __LDRT(volatile uint32_t *addr)
Z
zohar123 已提交
793 794 795
{
    uint32_t result;

Y
yanmowudi 已提交
796 797 798 799
    __ASM volatile("ldrt %0, %1"
                   : "=r"(result)
                   : "Q"(*addr));
    return (result);
Z
zohar123 已提交
800 801 802 803 804 805 806 807 808
}

/** \brief  STRT Unprivileged (8 bit)

    This function executes a Unprivileged STRT instruction for 8 bit values.

    \param [in]  value  Value to store
    \param [in]    ptr  Pointer to location
 */
Y
yanmowudi 已提交
809
__attribute__((always_inline)) __STATIC_INLINE void __STRBT(uint8_t value, volatile uint8_t *addr)
Z
zohar123 已提交
810
{
Y
yanmowudi 已提交
811 812 813
    __ASM volatile("strbt %1, %0"
                   : "=Q"(*addr)
                   : "r"((uint32_t)value));
Z
zohar123 已提交
814 815 816 817 818 819 820 821 822
}

/** \brief  STRT Unprivileged (16 bit)

    This function executes a Unprivileged STRT instruction for 16 bit values.

    \param [in]  value  Value to store
    \param [in]    ptr  Pointer to location
 */
Y
yanmowudi 已提交
823
__attribute__((always_inline)) __STATIC_INLINE void __STRHT(uint16_t value, volatile uint16_t *addr)
Z
zohar123 已提交
824
{
Y
yanmowudi 已提交
825 826 827
    __ASM volatile("strht %1, %0"
                   : "=Q"(*addr)
                   : "r"((uint32_t)value));
Z
zohar123 已提交
828 829 830 831 832 833 834 835 836
}

/** \brief  STRT Unprivileged (32 bit)

    This function executes a Unprivileged STRT instruction for 32 bit values.

    \param [in]  value  Value to store
    \param [in]    ptr  Pointer to location
 */
Y
yanmowudi 已提交
837
__attribute__((always_inline)) __STATIC_INLINE void __STRT(uint32_t value, volatile uint32_t *addr)
Z
zohar123 已提交
838
{
Y
yanmowudi 已提交
839 840 841
    __ASM volatile("strt %1, %0"
                   : "=Q"(*addr)
                   : "r"(value));
Z
zohar123 已提交
842 843 844 845
}

#endif /* (__CORTEX_M >= 0x03) || (__CORTEX_SC >= 300) */

Y
yanmowudi 已提交
846
#elif defined(__ICCARM__) /*------------------ ICC Compiler -------------------*/
Z
zohar123 已提交
847 848 849
/* IAR iccarm specific functions */
#include <cmsis_iar.h>

Y
yanmowudi 已提交
850
#elif defined(__TMS470__) /*---------------- TI CCS Compiler ------------------*/
Z
zohar123 已提交
851 852 853
/* TI CCS specific functions */
#include <cmsis_ccs.h>

Y
yanmowudi 已提交
854
#elif defined(__TASKING__) /*------------------ TASKING Compiler --------------*/
Z
zohar123 已提交
855 856 857 858 859 860 861
/* TASKING carm specific functions */
/*
 * The CMSIS functions have been implemented as intrinsics in the compiler.
 * Please use "carm -?i" to get an up to date list of all intrinsics,
 * Including the CMSIS ones.
 */

Y
yanmowudi 已提交
862
#elif defined(__CSMC__) /*------------------ COSMIC Compiler -------------------*/
Z
zohar123 已提交
863 864 865 866 867 868 869 870
/* Cosmic specific functions */
#include <cmsis_csm.h>

#endif

/*@}*/ /* end of group CMSIS_Core_InstructionInterface */

#endif /* __CORE_CMINSTR_H */