Changeset 87155 in vbox for trunk/include/iprt
- Timestamp:
- Jan 2, 2021 5:56:13 PM (4 years ago)
- svn:sync-xref-src-repo-rev:
- 142067
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/include/iprt/asm.h
r87154 r87155 301 301 302 302 # elif defined(RT_ARCH_ARM32) || defined(RT_ARCH_ARM64) 303 RTCCUINTREGuOld;304 RTCCUINTREGrcSpill;303 uint32_t uOld; 304 uint32_t rcSpill; 305 305 __asm__ __volatile__("try_again%=:\n\t" 306 306 # if defined(RT_ARCH_ARM64) 307 "ldaxrb %w0, [%3]\n\t"308 "stlxrb %w1, %w2, [%3]\n\t"309 "cbnz %w1, try_again%=\n\t"310 # else 311 "ldrexb %0, [%3]\n\t" /* ARMv6+ */312 "strex %1, %2, [%3]\n\t"313 "cmp %1, #0\n\t"314 "bne try_again%=\n\t"307 "ldaxrb %w0, [%3]\n\t" 308 "stlxrb %w1, %w2, [%3]\n\t" 309 "cbnz %w1, try_again%=\n\t" 310 # else 311 "ldrexb %0, [%3]\n\t" /* ARMv6+ */ 312 "strexb %1, %2, [%3]\n\t" 313 "cmp %1, #0\n\t" 314 "bne try_again%=\n\t" 315 315 # endif 316 316 : "=&r" (uOld), 317 317 "=&r" (rcSpill) 318 : "r" (( RTCCUINTREG)u8),318 : "r" ((uint32_t)u8), 319 319 "r" (pu8) 320 : "memory"); 320 : "memory", 321 "cc"); 321 322 return (uint8_t)uOld; 322 323 … … 365 366 * @param u16 The 16-bit value to assign to *pu16. 366 367 */ 367 #if RT_INLINE_ASM_EXTERNAL 368 #if RT_INLINE_ASM_EXTERNAL_TMP_ARM 368 369 RT_ASM_DECL_PRAGMA_WATCOM(uint16_t) ASMAtomicXchgU16(volatile uint16_t RT_FAR *pu16, uint16_t u16) RT_NOTHROW_PROTO; 369 370 #else 370 371 DECLINLINE(uint16_t) ASMAtomicXchgU16(volatile uint16_t RT_FAR *pu16, uint16_t u16) RT_NOTHROW_DEF 371 372 { 372 # if RT_INLINE_ASM_GNU_STYLE 373 # if defined(RT_ARCH_AMD64) || defined(RT_ARCH_X86) 374 # if RT_INLINE_ASM_GNU_STYLE 373 375 __asm__ __volatile__("xchgw %0, %1\n\t" 374 376 : "=m" (*pu16), … … 376 378 : "1" (u16), 377 379 "m" (*pu16)); 378 # else380 # else 379 381 __asm 380 382 { 381 # ifdef RT_ARCH_AMD64383 # ifdef RT_ARCH_AMD64 382 384 mov rdx, [pu16] 383 385 mov ax, [u16] 384 386 xchg [rdx], ax 385 387 mov [u16], ax 386 # else388 # else 387 389 mov edx, [pu16] 388 390 mov ax, [u16] 389 391 xchg [edx], ax 390 392 mov [u16], ax 391 # endif392 } 393 # endif393 # endif 394 } 395 # endif 394 396 return u16; 397 398 # elif defined(RT_ARCH_ARM32) || defined(RT_ARCH_ARM64) 399 uint32_t uOld; 400 uint32_t rcSpill; 401 __asm__ __volatile__("try_again%=:\n\t" 402 # if defined(RT_ARCH_ARM64) 403 "ldaxrh %w0, [%3]\n\t" 404 "stlxrh %w1, %w2, [%3]\n\t" 405 "cbnz %w1, try_again%=\n\t" 406 # else 407 "ldrexh %0, [%3]\n\t" /* ARMv6+ */ 408 "strexh %1, %2, [%3]\n\t" 409 "cmp %1, #0\n\t" 410 "bne try_again%=\n\t" 411 # endif 412 : "=&r" (uOld), 413 "=&r" (rcSpill) 414 : "r" ((uint32_t)u16), 415 "r" (pu16) 416 : "memory", 417 "cc"); 418 return (uint16_t)uOld; 419 420 # else 421 # error "Port me" 422 # endif 395 423 } 396 424 #endif … … 419 447 * @remarks Does not work on 286 and earlier. 420 448 */ 421 #if RT_INLINE_ASM_EXTERNAL && !RT_INLINE_ASM_USES_INTRIN449 #if RT_INLINE_ASM_EXTERNAL_TMP_ARM && !RT_INLINE_ASM_USES_INTRIN 422 450 RT_ASM_DECL_PRAGMA_WATCOM(uint32_t) ASMAtomicXchgU32(volatile uint32_t RT_FAR *pu32, uint32_t u32) RT_NOTHROW_PROTO; 423 451 #else 424 452 DECLINLINE(uint32_t) ASMAtomicXchgU32(volatile uint32_t RT_FAR *pu32, uint32_t u32) RT_NOTHROW_DEF 425 453 { 426 # if RT_INLINE_ASM_GNU_STYLE 454 # if defined(RT_ARCH_AMD64) || defined(RT_ARCH_X86) 455 # if RT_INLINE_ASM_GNU_STYLE 427 456 __asm__ __volatile__("xchgl %0, %1\n\t" 428 457 : "=m" (*pu32), … … 431 460 "m" (*pu32)); 432 461 433 # elif RT_INLINE_ASM_USES_INTRIN462 # elif RT_INLINE_ASM_USES_INTRIN 434 463 u32 = _InterlockedExchange((long RT_FAR *)pu32, u32); 435 464 436 # else465 # else 437 466 __asm 438 467 { 439 # ifdef RT_ARCH_AMD64468 # ifdef RT_ARCH_AMD64 440 469 mov rdx, [pu32] 441 470 mov eax, u32 442 471 xchg [rdx], eax 443 472 mov [u32], eax 444 # else473 # else 445 474 mov edx, [pu32] 446 475 mov eax, u32 447 476 xchg [edx], eax 448 477 mov [u32], eax 449 # endif450 } 451 # endif478 # endif 479 } 480 # endif 452 481 return u32; 482 483 # elif defined(RT_ARCH_ARM32) || defined(RT_ARCH_ARM64) 484 uint32_t uOld; 485 uint32_t rcSpill; 486 __asm__ __volatile__("try_again%=:\n\t" 487 # if defined(RT_ARCH_ARM64) 488 "ldaxr %w0, [%3]\n\t" 489 "stlxr %w1, %w2, [%3]\n\t" 490 "cbnz %w1, try_again%=\n\t" 491 # else 492 "ldrex %0, [%3]\n\t" /* ARMv6+ */ 493 "strex %1, %2, [%3]\n\t" 494 "cmp %1, #0\n\t" 495 "bne try_again%=\n\t" 496 # endif 497 : "=&r" (uOld), 498 "=&r" (rcSpill) 499 : "r" ((uint32_t)u32), 500 "r" (pu32) 501 : "memory", 502 "cc"); 503 return (uint32_t)uOld; 504 505 # else 506 # error "Port me" 507 # endif 453 508 } 454 509 #endif … … 477 532 * @remarks Works on 32-bit x86 CPUs starting with Pentium. 478 533 */ 479 #if (RT_INLINE_ASM_EXTERNAL && !RT_INLINE_ASM_USES_INTRIN) \534 #if (RT_INLINE_ASM_EXTERNAL_TMP_ARM && !RT_INLINE_ASM_USES_INTRIN) \ 480 535 || RT_INLINE_DONT_MIX_CMPXCHG8B_AND_PIC 481 536 RT_ASM_DECL_PRAGMA_WATCOM(uint64_t) ASMAtomicXchgU64(volatile uint64_t RT_FAR *pu64, uint64_t u64) RT_NOTHROW_PROTO; … … 502 557 } 503 558 # endif 504 # else /* !RT_ARCH_AMD64 */ 559 560 # elif defined(RT_ARCH_X86) 505 561 # if RT_INLINE_ASM_GNU_STYLE 506 562 # if defined(PIC) || defined(__PIC__) … … 544 600 } 545 601 # endif 546 # endif /* !RT_ARCH_AMD64 */ 602 603 # elif defined(RT_ARCH_ARM32) || defined(RT_ARCH_ARM64) 604 uint32_t rcSpill; 605 __asm__ __volatile__("try_again%=:\n\t" 606 # if defined(RT_ARCH_ARM64) 607 "ldaxr %0, [%3]\n\t" 608 "stlxr %w1, %2, [%3]\n\t" 609 "cbnz %w1, try_again%=\n\t" 610 # else 611 "ldrexd %H0, [%3]\n\t" /* ARMv6+ */ 612 "strexd %1, %H2, [%3]\n\t" 613 "cmp %1, #0\n\t" 614 "bne try_again%=\n\t" 615 # endif 616 : "=&r" (u64), 617 "=&r" (rcSpill) 618 : "r" (u64), 619 "r" (pu64) 620 : "memory", 621 "cc"); 622 # else 623 # error "Port me" 624 # endif 547 625 return u64; 548 626 } … … 758 836 * @remarks x86: Requires a 486 or later. 759 837 */ 760 #if RT_INLINE_ASM_EXTERNAL || !RT_INLINE_ASM_GNU_STYLE838 #if RT_INLINE_ASM_EXTERNAL_TMP_ARM || !RT_INLINE_ASM_GNU_STYLE 761 839 RT_ASM_DECL_PRAGMA_WATCOM(bool) ASMAtomicCmpXchgU8(volatile uint8_t RT_FAR *pu8, const uint8_t u8New, const uint8_t u8Old) RT_NOTHROW_PROTO; 762 840 #else 763 841 DECLINLINE(bool) ASMAtomicCmpXchgU8(volatile uint8_t RT_FAR *pu8, const uint8_t u8New, uint8_t u8Old) RT_NOTHROW_DEF 764 842 { 843 # if defined(RT_ARCH_AMD64) || defined(RT_ARCH_X86) 765 844 uint8_t u8Ret; 766 845 __asm__ __volatile__("lock; cmpxchgb %3, %0\n\t" … … 773 852 "m" (*pu8)); 774 853 return (bool)u8Ret; 854 855 # elif defined(RT_ARCH_ARM64) || defined(RT_ARCH_ARM32) 856 uint32_t fXchg; 857 uint32_t u32Spill; 858 uint32_t rcSpill; 859 __asm__ __volatile__("try_again%=:\n\t" 860 # if defined(RT_ARCH_ARM64) 861 "ldaxrb %w0, [%5]\n\t" 862 "cmp %w0, %w3\n\t" 863 "bne 1f\n\t" /* stop here if not equal */ 864 "stlxrb %w1, %w4, [%5]\n\t" 865 "cbnz %w1, try_again%=\n\t" 866 "mov %w2, #1\n\t" 867 # else 868 "ldrexb %0, [%5]\n\t" 869 "teq %0, %3\n\t" 870 "strexbeq %1, %4, [%5]\n\t" 871 "bne 1f\n\t" /* stop here if not equal */ 872 "cmp %1, #0\n\t" 873 "bne try_again%=\n\t" 874 "mov %2, #1\n\t" 875 # endif 876 "1:\n\t" 877 : "=&r" (u32Spill), 878 "=&r" (rcSpill), 879 "=&r" (fXchg) 880 : "r" ((uint32_t)u8Old), 881 "r" ((uint32_t)u8New), 882 "r" (pu8), 883 "2" (0) /*fXchg*/ 884 : "memory", 885 "cc"); 886 return (bool)fXchg; 887 # else 888 # error "Port me" 889 # endif /* RT_ARCH_ARM */ 775 890 } 776 891 #endif … … 825 940 * @remarks x86: Requires a 486 or later. 826 941 */ 827 #if RT_INLINE_ASM_EXTERNAL && !RT_INLINE_ASM_USES_INTRIN942 #if RT_INLINE_ASM_EXTERNAL_TMP_ARM && !RT_INLINE_ASM_USES_INTRIN 828 943 RT_ASM_DECL_PRAGMA_WATCOM(bool) ASMAtomicCmpXchgU32(volatile uint32_t RT_FAR *pu32, const uint32_t u32New, const uint32_t u32Old) RT_NOTHROW_PROTO; 829 944 #else 830 945 DECLINLINE(bool) ASMAtomicCmpXchgU32(volatile uint32_t RT_FAR *pu32, const uint32_t u32New, uint32_t u32Old) RT_NOTHROW_DEF 831 946 { 832 # if RT_INLINE_ASM_GNU_STYLE 947 # if defined(RT_ARCH_AMD64) || defined(RT_ARCH_X86) 948 # if RT_INLINE_ASM_GNU_STYLE 833 949 uint8_t u8Ret; 834 950 __asm__ __volatile__("lock; cmpxchgl %3, %0\n\t" … … 842 958 return (bool)u8Ret; 843 959 844 # elif RT_INLINE_ASM_USES_INTRIN960 # elif RT_INLINE_ASM_USES_INTRIN 845 961 return (uint32_t)_InterlockedCompareExchange((long RT_FAR *)pu32, u32New, u32Old) == u32Old; 846 962 847 # else963 # else 848 964 uint32_t u32Ret; 849 965 __asm 850 966 { 851 # ifdef RT_ARCH_AMD64967 # ifdef RT_ARCH_AMD64 852 968 mov rdx, [pu32] 853 # else969 # else 854 970 mov edx, [pu32] 855 # endif971 # endif 856 972 mov eax, [u32Old] 857 973 mov ecx, [u32New] 858 # ifdef RT_ARCH_AMD64974 # ifdef RT_ARCH_AMD64 859 975 lock cmpxchg [rdx], ecx 860 # else976 # else 861 977 lock cmpxchg [edx], ecx 862 # endif978 # endif 863 979 setz al 864 980 movzx eax, al … … 866 982 } 867 983 return !!u32Ret; 868 # endif 984 # endif 985 986 # elif defined(RT_ARCH_ARM64) || defined(RT_ARCH_ARM32) 987 uint32_t fXchg; 988 uint32_t u32Spill; 989 uint32_t rcSpill; 990 __asm__ __volatile__("try_again%=:\n\t" 991 # if defined(RT_ARCH_ARM64) 992 "ldaxr %w0, [%5]\n\t" 993 "cmp %w0, %w3\n\t" 994 "bne 1f\n\t" /* stop here if not equal */ 995 "stlxr %w1, %w4, [%5]\n\t" 996 "cbnz %w1, try_again%=\n\t" 997 "mov %w2, #1\n\t" 998 # else 999 "ldrex %0, [%5]\n\t" 1000 "teq %0, %3\n\t" 1001 "strexeq %1, %4, [%5]\n\t" 1002 "bne 1f\n\t" /* stop here if not equal */ 1003 "cmp %1, #0\n\t" 1004 "bne try_again%=\n\t" 1005 "mov %2, #1\n\t" 1006 # endif 1007 "1:\n\t" 1008 : "=&r" (u32Spill), 1009 "=&r" (rcSpill), 1010 "=&r" (fXchg) 1011 : "r" (u32Old), 1012 "r" (u32New), 1013 "r" (pu32), 1014 "2" (0) /*fXchg*/ 1015 : "memory", 1016 "cc"); 1017 return (bool)fXchg; 1018 # else 1019 # error "Port me" 1020 # endif /* RT_ARCH_ARM */ 869 1021 } 870 1022 #endif
Note:
See TracChangeset
for help on using the changeset viewer.