Changeset 87171 in vbox for trunk/include/iprt
- Timestamp:
- Jan 4, 2021 9:35:43 PM (4 years ago)
- svn:sync-xref-src-repo-rev:
- 142100
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/include/iprt/asm.h
r87156 r87171 1875 1875 #elif defined(RT_ARCH_ARM64) || defined(RT_ARCH_ARM32) 1876 1876 /* Note! Only armv7 and later. */ 1877 __asm__ __volatile__ ("dsb sy\n\t" ::: "memory"); 1877 __asm__ __volatile__ ("dsb sy\n\t" ::: "memory"); /** @todo dmb? */ 1878 1878 #elif ARCH_BITS == 16 1879 1879 uint16_t volatile u16; … … 1906 1906 #elif defined(RT_ARCH_ARM64) || defined(RT_ARCH_ARM32) 1907 1907 /* Note! Only armv7 and later. */ 1908 __asm__ __volatile__ ("dmb s y\n\t" ::: "memory");1908 __asm__ __volatile__ ("dmb st\n\t" ::: "memory"); 1909 1909 #else 1910 1910 ASMMemoryFence(); … … 1933 1933 #elif defined(RT_ARCH_ARM64) || defined(RT_ARCH_ARM32) 1934 1934 /* Note! Only armv7 and later. */ 1935 __asm__ __volatile__ ("dmb sy\n\t";1935 __asm__ __volatile__ ("dmb ld\n\t" ::: "memory"); 1936 1936 #else 1937 1937 ASMMemoryFence(); … … 1998 1998 DECLINLINE(uint16_t) ASMAtomicReadU16(volatile uint16_t RT_FAR *pu16) RT_NOTHROW_DEF 1999 1999 { 2000 Assert(!((uintptr_t)pu16 & 1)); 2000 2001 ASMMemoryFence(); 2002 return *pu16; 2003 } 2004 2005 2006 /** 2007 * Atomically reads an unsigned 16-bit value, unordered. 2008 * 2009 * @returns Current *pu16 value 2010 * @param pu16 Pointer to the 16-bit variable to read. 2011 */ 2012 DECLINLINE(uint16_t) ASMAtomicUoReadU16(volatile uint16_t RT_FAR *pu16) RT_NOTHROW_DEF 2013 { 2001 2014 Assert(!((uintptr_t)pu16 & 1)); 2002 2015 return *pu16; … … 2005 2018 2006 2019 /** 2007 * Atomically reads an unsigned 16-bit value, unordered.2008 *2009 * @returns Current *pu16 value2010 * @param pu16 Pointer to the 16-bit variable to read.2011 */2012 DECLINLINE(uint16_t) ASMAtomicUoReadU16(volatile uint16_t RT_FAR *pu16) RT_NOTHROW_DEF2013 {2014 Assert(!((uintptr_t)pu16 & 1));2015 return *pu16;2016 }2017 2018 2019 /**2020 2020 * Atomically reads a signed 16-bit value, ordered. 2021 2021 * … … 2025 2025 DECLINLINE(int16_t) ASMAtomicReadS16(volatile int16_t RT_FAR *pi16) RT_NOTHROW_DEF 2026 2026 { 2027 Assert(!((uintptr_t)pi16 & 1)); 2027 2028 ASMMemoryFence(); 2029 return *pi16; 2030 } 2031 2032 2033 /** 2034 * Atomically reads a signed 16-bit value, unordered. 2035 * 2036 * @returns Current *pi16 value 2037 * @param pi16 Pointer to the 16-bit variable to read. 2038 */ 2039 DECLINLINE(int16_t) ASMAtomicUoReadS16(volatile int16_t RT_FAR *pi16) RT_NOTHROW_DEF 2040 { 2028 2041 Assert(!((uintptr_t)pi16 & 1)); 2029 2042 return *pi16; … … 2032 2045 2033 2046 /** 2034 * Atomically reads a signed 16-bit value, unordered.2035 *2036 * @returns Current *pi16 value2037 * @param pi16 Pointer to the 16-bit variable to read.2038 */2039 DECLINLINE(int16_t) ASMAtomicUoReadS16(volatile int16_t RT_FAR *pi16) RT_NOTHROW_DEF2040 {2041 Assert(!((uintptr_t)pi16 & 1));2042 return *pi16;2043 }2044 2045 2046 /**2047 2047 * Atomically reads an unsigned 32-bit value, ordered. 2048 2048 * … … 2052 2052 DECLINLINE(uint32_t) ASMAtomicReadU32(volatile uint32_t RT_FAR *pu32) RT_NOTHROW_DEF 2053 2053 { 2054 Assert(!((uintptr_t)pu32 & 3)); 2054 2055 ASMMemoryFence(); 2056 #if ARCH_BITS == 16 2057 AssertFailed(); /** @todo 16-bit */ 2058 #endif 2059 return *pu32; 2060 } 2061 2062 2063 /** 2064 * Atomically reads an unsigned 32-bit value, unordered. 2065 * 2066 * @returns Current *pu32 value 2067 * @param pu32 Pointer to the 32-bit variable to read. 2068 */ 2069 DECLINLINE(uint32_t) ASMAtomicUoReadU32(volatile uint32_t RT_FAR *pu32) RT_NOTHROW_DEF 2070 { 2055 2071 Assert(!((uintptr_t)pu32 & 3)); 2056 2072 #if ARCH_BITS == 16 … … 2062 2078 2063 2079 /** 2064 * Atomically reads an unsigned 32-bit value, unordered. 2065 * 2066 * @returns Current *pu32 value 2067 * @param pu32 Pointer to the 32-bit variable to read. 2068 */ 2069 DECLINLINE(uint32_t) ASMAtomicUoReadU32(volatile uint32_t RT_FAR *pu32) RT_NOTHROW_DEF 2070 { 2071 Assert(!((uintptr_t)pu32 & 3)); 2080 * Atomically reads a signed 32-bit value, ordered. 2081 * 2082 * @returns Current *pi32 value 2083 * @param pi32 Pointer to the 32-bit variable to read. 2084 */ 2085 DECLINLINE(int32_t) ASMAtomicReadS32(volatile int32_t RT_FAR *pi32) RT_NOTHROW_DEF 2086 { 2087 Assert(!((uintptr_t)pi32 & 3)); 2088 ASMMemoryFence(); 2072 2089 #if ARCH_BITS == 16 2073 2090 AssertFailed(); /** @todo 16-bit */ 2074 2091 #endif 2075 return *p u32;2076 } 2077 2078 2079 /** 2080 * Atomically reads a signed 32-bit value, ordered.2092 return *pi32; 2093 } 2094 2095 2096 /** 2097 * Atomically reads a signed 32-bit value, unordered. 2081 2098 * 2082 2099 * @returns Current *pi32 value 2083 2100 * @param pi32 Pointer to the 32-bit variable to read. 2084 2101 */ 2085 DECLINLINE(int32_t) ASMAtomicReadS32(volatile int32_t RT_FAR *pi32) RT_NOTHROW_DEF 2086 { 2087 ASMMemoryFence(); 2102 DECLINLINE(int32_t) ASMAtomicUoReadS32(volatile int32_t RT_FAR *pi32) RT_NOTHROW_DEF 2103 { 2088 2104 Assert(!((uintptr_t)pi32 & 3)); 2089 2105 #if ARCH_BITS == 16 … … 2095 2111 2096 2112 /** 2097 * Atomically reads a signed 32-bit value, unordered.2098 *2099 * @returns Current *pi32 value2100 * @param pi32 Pointer to the 32-bit variable to read.2101 */2102 DECLINLINE(int32_t) ASMAtomicUoReadS32(volatile int32_t RT_FAR *pi32) RT_NOTHROW_DEF2103 {2104 Assert(!((uintptr_t)pi32 & 3));2105 #if ARCH_BITS == 162106 AssertFailed(); /** @todo 16-bit */2107 #endif2108 return *pi32;2109 }2110 2111 2112 /**2113 2113 * Atomically reads an unsigned 64-bit value, ordered. 2114 2114 * … … 2120 2120 * @remarks x86: Requires a Pentium or later. 2121 2121 */ 2122 #if (RT_INLINE_ASM_EXTERNAL && !defined(RT_ARCH_AMD64)) \2122 #if (RT_INLINE_ASM_EXTERNAL_TMP_ARM && !defined(RT_ARCH_AMD64)) \ 2123 2123 || RT_INLINE_DONT_MIX_CMPXCHG8B_AND_PIC 2124 2124 RT_ASM_DECL_PRAGMA_WATCOM(uint64_t) ASMAtomicReadU64(volatile uint64_t RT_FAR *pu64) RT_NOTHROW_PROTO; … … 2145 2145 ASMMemoryFence(); 2146 2146 u64 = *pu64; 2147 # else /* !RT_ARCH_AMD64 */ 2147 2148 # elif defined(RT_ARCH_X86) 2148 2149 # if RT_INLINE_ASM_GNU_STYLE 2149 2150 # if defined(PIC) || defined(__PIC__) … … 2185 2186 } 2186 2187 # endif 2187 # endif /* !RT_ARCH_AMD64 */ 2188 2189 # elif defined(RT_ARCH_ARM64) 2190 Assert(!((uintptr_t)pu64 & 7)); 2191 ASMMemoryFence(); 2192 u64 = *pu64; 2193 2194 # elif defined(RT_ARCH_ARM32) 2195 Assert(!((uintptr_t)pu64 & 7)); 2196 __asm__ __volatile__("dsb sy\n\t" /** @todo dmb? */ 2197 "ldrexd %0, %H0, [%1]\n\t" 2198 : "=&r" (u64) 2199 : "r" (pu64) 2200 : "memory"); 2201 2202 # else 2203 # error "Port me" 2204 # endif 2188 2205 return u64; 2189 2206 } … … 2202 2219 */ 2203 2220 #if !defined(RT_ARCH_AMD64) \ 2204 && ( (RT_INLINE_ASM_EXTERNAL && !RT_INLINE_ASM_USES_INTRIN) \2221 && ( (RT_INLINE_ASM_EXTERNAL_TMP_ARM && !RT_INLINE_ASM_USES_INTRIN) \ 2205 2222 || RT_INLINE_DONT_MIX_CMPXCHG8B_AND_PIC) 2206 2223 RT_ASM_DECL_PRAGMA_WATCOM(uint64_t) ASMAtomicUoReadU64(volatile uint64_t RT_FAR *pu64) RT_NOTHROW_PROTO; … … 2225 2242 # endif */ 2226 2243 u64 = *pu64; 2227 # else /* !RT_ARCH_AMD64 */ 2244 2245 # elif defined(RT_ARCH_X86) 2228 2246 # if RT_INLINE_ASM_GNU_STYLE 2229 2247 # if defined(PIC) || defined(__PIC__) … … 2268 2286 } 2269 2287 # endif 2270 # endif /* !RT_ARCH_AMD64 */ 2288 2289 # elif defined(RT_ARCH_ARM64) 2290 Assert(!((uintptr_t)pu64 & 7)); 2291 u64 = *pu64; 2292 2293 # elif defined(RT_ARCH_ARM32) 2294 Assert(!((uintptr_t)pu64 & 7)); 2295 __asm__ __volatile__("ldrexd %0, %H0, [%1]\n\t" 2296 : "=&r" (u64) 2297 : "r" (pu64) 2298 : ); 2299 2300 # else 2301 # error "Port me" 2302 # endif 2271 2303 return u64; 2272 2304 } … … 2556 2588 DECLINLINE(void) ASMAtomicWriteU8(volatile uint8_t RT_FAR *pu8, uint8_t u8) RT_NOTHROW_DEF 2557 2589 { 2590 /** @todo Any possible ARM32/ARM64 optimizations here? */ 2558 2591 ASMAtomicXchgU8(pu8, u8); 2559 2592 } … … 2580 2613 DECLINLINE(void) ASMAtomicWriteS8(volatile int8_t RT_FAR *pi8, int8_t i8) RT_NOTHROW_DEF 2581 2614 { 2615 /** @todo Any possible ARM32/ARM64 optimizations here? */ 2582 2616 ASMAtomicXchgS8(pi8, i8); 2583 2617 } … … 2604 2638 DECLINLINE(void) ASMAtomicWriteU16(volatile uint16_t RT_FAR *pu16, uint16_t u16) RT_NOTHROW_DEF 2605 2639 { 2640 /** @todo Any possible ARM32/ARM64 optimizations here? */ 2606 2641 ASMAtomicXchgU16(pu16, u16); 2607 2642 } … … 2629 2664 DECLINLINE(void) ASMAtomicWriteS16(volatile int16_t RT_FAR *pi16, int16_t i16) RT_NOTHROW_DEF 2630 2665 { 2666 /** @todo Any possible ARM32/ARM64 optimizations here? */ 2631 2667 ASMAtomicXchgS16(pi16, i16); 2632 2668 } … … 2654 2690 DECLINLINE(void) ASMAtomicWriteU32(volatile uint32_t RT_FAR *pu32, uint32_t u32) RT_NOTHROW_DEF 2655 2691 { 2692 /** @todo Any possible ARM32/ARM64 optimizations here? */ 2656 2693 ASMAtomicXchgU32(pu32, u32); 2657 2694 } … … 2712 2749 DECLINLINE(void) ASMAtomicWriteU64(volatile uint64_t RT_FAR *pu64, uint64_t u64) RT_NOTHROW_DEF 2713 2750 { 2751 /** @todo Any possible ARM32/ARM64 optimizations here? */ 2714 2752 ASMAtomicXchgU64(pu64, u64); 2715 2753 } … … 2741 2779 DECLINLINE(void) ASMAtomicWriteS64(volatile int64_t RT_FAR *pi64, int64_t i64) RT_NOTHROW_DEF 2742 2780 { 2781 /** @todo Any possible ARM32/ARM64 optimizations here? */ 2743 2782 ASMAtomicXchgS64(pi64, i64); 2744 2783 } … … 3062 3101 * @remarks x86: Requires a 486 or later. 3063 3102 */ 3064 #if RT_INLINE_ASM_EXTERNAL && !RT_INLINE_ASM_USES_INTRIN3103 #if RT_INLINE_ASM_EXTERNAL_TMP_ARM && !RT_INLINE_ASM_USES_INTRIN 3065 3104 RT_ASM_DECL_PRAGMA_WATCOM(uint32_t) ASMAtomicAddU32(uint32_t volatile RT_FAR *pu32, uint32_t u32) RT_NOTHROW_PROTO; 3066 3105 #else … … 3071 3110 return u32; 3072 3111 3073 # elif RT_INLINE_ASM_GNU_STYLE 3112 # elif defined(RT_ARCH_AMD64) || defined(RT_ARCH_X86) 3113 # if RT_INLINE_ASM_GNU_STYLE 3074 3114 __asm__ __volatile__("lock; xaddl %0, %1\n\t" 3075 3115 : "=r" (u32), … … 3079 3119 : "memory"); 3080 3120 return u32; 3081 # else3121 # else 3082 3122 __asm 3083 3123 { 3084 3124 mov eax, [u32] 3085 # ifdef RT_ARCH_AMD643125 # ifdef RT_ARCH_AMD64 3086 3126 mov rdx, [pu32] 3087 3127 lock xadd [rdx], eax 3088 # else3128 # else 3089 3129 mov edx, [pu32] 3090 3130 lock xadd [edx], eax 3091 # endif3131 # endif 3092 3132 mov [u32], eax 3093 3133 } 3094 3134 return u32; 3135 # endif 3136 3137 # elif defined(RT_ARCH_ARM64) || defined(RT_ARCH_ARM32) 3138 uint32_t u32Ret; 3139 uint32_t rcSpill; 3140 uint32_t u32Spill; 3141 __asm__ __volatile__(".Ltry_again_add_u32_%=:\n\t" 3142 # if defined(RT_ARCH_ARM64) 3143 "ldaxr %w0, [%4]\n\t" 3144 "add %w1, %w0, %w3\n\t" 3145 "stlxr %w2, %w1, [%4]\n\t" 3146 "cbnz %w2, .Ltry_again_add_u32_%=\n\t" 3147 # else 3148 "ldrex %0, [%4]\n\t" 3149 "add %1, %0, %3\n\t" 3150 "strex %2, %1, [%4]\n\t" 3151 "cmp %2, #0\n\t" 3152 "bne .Ltry_again_add_u32_%=\n\t" 3153 # endif 3154 : "=&r" (u32Ret), 3155 "=&r" (u32Spill), 3156 "=&r" (rcSpill) 3157 : "r" (u32), 3158 "r" (pu32) 3159 : "memory", 3160 "cc"); 3161 return u32Ret; 3162 3163 # else 3164 # error "Port me" 3095 3165 # endif 3096 3166 } … … 3122 3192 * @remarks x86: Requires a Pentium or later. 3123 3193 */ 3124 #if RT_INLINE_ASM_EXTERNAL && !RT_INLINE_ASM_USES_INTRIN3194 #if RT_INLINE_ASM_EXTERNAL_TMP_ARM && !RT_INLINE_ASM_USES_INTRIN 3125 3195 DECLASM(uint64_t) ASMAtomicAddU64(uint64_t volatile RT_FAR *pu64, uint64_t u64) RT_NOTHROW_PROTO; 3126 3196 #else … … 3139 3209 : "memory"); 3140 3210 return u64; 3211 3212 # elif defined(RT_ARCH_ARM64) || defined(RT_ARCH_ARM32) 3213 uint64_t u64Ret; 3214 uint32_t rcSpill; 3215 uint64_t u64Spill; 3216 __asm__ __volatile__(".Ltry_again_add_u64_%=:\n\t" 3217 # if defined(RT_ARCH_ARM64) 3218 "ldaxr %0, [%4]\n\t" 3219 "add %1, %0, %3\n\t" 3220 "stlxr %w2, %1, [%4]\n\t" 3221 "cbnz %w2, .Ltry_again_add_u64_%=\n\t" 3222 # else 3223 "ldrexd %0, %H0, [%4]\n\t" 3224 "add %1, %0, %3\n\t" 3225 "adc %H1, %H0, %H3\n\t" 3226 "strexd %2, %1, %H1, [%4]\n\t" 3227 "cmp %2, #0\n\t" 3228 "bne .Ltry_again_add_u64_%=\n\t" 3229 # endif 3230 : "=&r" (u64Ret), 3231 "=&r" (u64Spill), 3232 "=&r" (rcSpill) 3233 : "r" (u64), 3234 "r" (pu64) 3235 : "memory", 3236 "cc"); 3237 return u64Ret; 3238 3141 3239 # else 3142 3240 uint64_t u64Old; … … 3369 3467 * @remarks x86: Requires a 486 or later. 3370 3468 */ 3371 #if RT_INLINE_ASM_EXTERNAL && !RT_INLINE_ASM_USES_INTRIN3469 #if RT_INLINE_ASM_EXTERNAL_TMP_ARM && !RT_INLINE_ASM_USES_INTRIN 3372 3470 RT_ASM_DECL_PRAGMA_WATCOM(uint32_t) ASMAtomicIncU32(uint32_t volatile RT_FAR *pu32) RT_NOTHROW_PROTO; 3373 3471 #else 3374 3472 DECLINLINE(uint32_t) ASMAtomicIncU32(uint32_t volatile RT_FAR *pu32) RT_NOTHROW_DEF 3375 3473 { 3474 # if RT_INLINE_ASM_USES_INTRIN 3475 return (uint32_t)_InterlockedIncrement((long RT_FAR *)pu32); 3476 3477 # elif defined(RT_ARCH_AMD64) || defined(RT_ARCH_X86) 3478 # if RT_INLINE_ASM_GNU_STYLE 3376 3479 uint32_t u32; 3377 # if RT_INLINE_ASM_USES_INTRIN3378 u32 = _InterlockedIncrement((long RT_FAR *)pu32);3379 return u32;3380 3381 # elif RT_INLINE_ASM_GNU_STYLE3382 3480 __asm__ __volatile__("lock; xaddl %0, %1\n\t" 3383 3481 : "=r" (u32), … … 3387 3485 : "memory"); 3388 3486 return u32+1; 3389 # else3487 # else 3390 3488 __asm 3391 3489 { 3392 3490 mov eax, 1 3393 # ifdef RT_ARCH_AMD643491 # ifdef RT_ARCH_AMD64 3394 3492 mov rdx, [pu32] 3395 3493 lock xadd [rdx], eax 3396 # else3494 # else 3397 3495 mov edx, [pu32] 3398 3496 lock xadd [edx], eax 3399 # endif3497 # endif 3400 3498 mov u32, eax 3401 3499 } 3402 3500 return u32+1; 3501 # endif 3502 3503 # elif defined(RT_ARCH_ARM64) || defined(RT_ARCH_ARM32) 3504 uint32_t u32Ret; 3505 uint32_t rcSpill; 3506 __asm__ __volatile__(".Ltry_again_inc_u32_%=:\n\t" 3507 # if defined(RT_ARCH_ARM64) 3508 "ldaxr %w0, [%2]\n\t" 3509 "add %w0, %w0, #1\n\t" 3510 "stlxr %w1, %w0, [%2]\n\t" 3511 "cbnz %w1, .Ltry_again_inc_u32_%=\n\t" 3512 # else 3513 "ldrex %0, [%2]\n\t" 3514 "add %0, %0, #1\n\t" /* arm6 / thumb2+ */ 3515 "strex %1, %0, [%2]\n\t" 3516 "cmp %1, #0\n\t" 3517 "bne .Ltry_again_inc_u32_%=\n\t" 3518 # endif 3519 : "=&r" (u32Ret), 3520 "=&r" (rcSpill) 3521 : "r" (pu32) 3522 : "memory", 3523 "cc"); 3524 return u32Ret; 3525 3526 # else 3527 return ASMAtomicAddU32(pu32, 1) + 1; 3403 3528 # endif 3404 3529 } … … 3428 3553 * @remarks x86: Requires a Pentium or later. 3429 3554 */ 3430 #if RT_INLINE_ASM_EXTERNAL && !RT_INLINE_ASM_USES_INTRIN3555 #if RT_INLINE_ASM_EXTERNAL_TMP_ARM && !RT_INLINE_ASM_USES_INTRIN 3431 3556 DECLASM(uint64_t) ASMAtomicIncU64(uint64_t volatile RT_FAR *pu64) RT_NOTHROW_PROTO; 3432 3557 #else … … 3434 3559 { 3435 3560 # if RT_INLINE_ASM_USES_INTRIN && defined(RT_ARCH_AMD64) 3436 uint64_t u64; 3437 u64 = _InterlockedIncrement64((__int64 RT_FAR *)pu64); 3438 return u64; 3561 return (uint64_t)_InterlockedIncrement64((__int64 RT_FAR *)pu64); 3439 3562 3440 3563 # elif RT_INLINE_ASM_GNU_STYLE && defined(RT_ARCH_AMD64) … … 3447 3570 : "memory"); 3448 3571 return u64 + 1; 3572 3573 # elif defined(RT_ARCH_ARM64) || defined(RT_ARCH_ARM32) 3574 uint64_t u64Ret; 3575 uint32_t rcSpill; 3576 __asm__ __volatile__(".Ltry_again_inc_u64_%=:\n\t" 3577 # if defined(RT_ARCH_ARM64) 3578 "ldaxr %0, [%2]\n\t" 3579 "add %0, %0, #1\n\t" 3580 "stlxr %w1, %0, [%2]\n\t" 3581 "cbnz %w1, .Ltry_again_inc_u64_%=\n\t" 3582 # else 3583 "ldrexd %0, %H0, [%2]\n\t" 3584 "add %0, %0, #1\n\t" /* arm6 / thumb2+ */ 3585 "adc %H0, %H0, %3\n\t" 3586 "strexd %1, %0, %H0, [%2]\n\t" 3587 "cmp %1, #0\n\t" 3588 "bne .Ltry_again_inc_u64_%=\n\t" 3589 # endif 3590 : "=&r" (u64Ret), 3591 "=&r" (rcSpill) 3592 : "r" (pu64) 3593 # if !defined(RT_ARCH_ARM64) 3594 , "r" (0) 3595 # endif 3596 : "memory", 3597 "cc"); 3598 return u64Ret; 3599 3449 3600 # else 3450 3601 return ASMAtomicAddU64(pu64, 1) + 1; … … 3511 3662 * @remarks x86: Requires a 486 or later. 3512 3663 */ 3513 #if RT_INLINE_ASM_EXTERNAL && !RT_INLINE_ASM_USES_INTRIN3664 #if RT_INLINE_ASM_EXTERNAL_TMP_ARM && !RT_INLINE_ASM_USES_INTRIN 3514 3665 RT_ASM_DECL_PRAGMA_WATCOM(uint32_t) ASMAtomicDecU32(uint32_t volatile RT_FAR *pu32) RT_NOTHROW_PROTO; 3515 3666 #else 3516 3667 DECLINLINE(uint32_t) ASMAtomicDecU32(uint32_t volatile RT_FAR *pu32) RT_NOTHROW_DEF 3517 3668 { 3669 # if RT_INLINE_ASM_USES_INTRIN 3670 return (uint32_t)_InterlockedDecrement((long RT_FAR *)pu32); 3671 3672 # elif RT_INLINE_ASM_GNU_STYLE && defined(RT_ARCH_AMD64) 3673 # if RT_INLINE_ASM_GNU_STYLE 3518 3674 uint32_t u32; 3519 # if RT_INLINE_ASM_USES_INTRIN3520 u32 = _InterlockedDecrement((long RT_FAR *)pu32);3521 return u32;3522 3523 # elif RT_INLINE_ASM_GNU_STYLE3524 3675 __asm__ __volatile__("lock; xaddl %0, %1\n\t" 3525 3676 : "=r" (u32), … … 3530 3681 return u32-1; 3531 3682 # else 3683 uint32_t u32; 3532 3684 __asm 3533 3685 { … … 3544 3696 return u32-1; 3545 3697 # endif 3698 3699 # elif defined(RT_ARCH_ARM64) || defined(RT_ARCH_ARM32) 3700 uint32_t u32Ret; 3701 uint32_t rcSpill; 3702 __asm__ __volatile__(".Ltry_again_dec_u32_%=:\n\t" 3703 # if defined(RT_ARCH_ARM64) 3704 "ldaxr %w0, [%2]\n\t" 3705 "sub %w0, %w0, #1\n\t" 3706 "stlxr %w1, %w0, [%2]\n\t" 3707 "cbnz %w1, .Ltry_again_dec_u32_%=\n\t" 3708 # else 3709 "ldrex %0, [%2]\n\t" 3710 "sub %0, %0, #1\n\t" /* arm6 / thumb2+ */ 3711 "strex %1, %0, [%2]\n\t" 3712 "cmp %1, #0\n\t" 3713 "bne .Ltry_again_dec_u32_%=\n\t" 3714 # endif 3715 : "=&r" (u32Ret), 3716 "=&r" (rcSpill) 3717 : "r" (pu32) 3718 : "memory", 3719 "cc"); 3720 return u32Ret; 3721 3722 # else 3723 return ASMAtomicSubU32(pu32, 1) - (uint32_t)1; 3724 # endif 3546 3725 } 3547 3726 #endif … … 3570 3749 * @remarks x86: Requires a Pentium or later. 3571 3750 */ 3572 #if RT_INLINE_ASM_EXTERNAL && !RT_INLINE_ASM_USES_INTRIN3751 #if RT_INLINE_ASM_EXTERNAL_TMP_ARM && !RT_INLINE_ASM_USES_INTRIN 3573 3752 RT_ASM_DECL_PRAGMA_WATCOM(uint64_t) ASMAtomicDecU64(uint64_t volatile RT_FAR *pu64) RT_NOTHROW_PROTO; 3574 3753 #else … … 3576 3755 { 3577 3756 # if RT_INLINE_ASM_USES_INTRIN && defined(RT_ARCH_AMD64) 3578 uint64_t u64 = _InterlockedDecrement64((__int64 volatile RT_FAR *)pu64); 3579 return u64; 3757 return (uint64_t)_InterlockedDecrement64((__int64 volatile RT_FAR *)pu64); 3580 3758 3581 3759 # elif RT_INLINE_ASM_GNU_STYLE && defined(RT_ARCH_AMD64) … … 3588 3766 : "memory"); 3589 3767 return u64-1; 3768 3769 # elif defined(RT_ARCH_ARM64) || defined(RT_ARCH_ARM32) 3770 uint64_t u64Ret; 3771 uint32_t rcSpill; 3772 __asm__ __volatile__(".Ltry_again_dec_u64_%=:\n\t" 3773 # if defined(RT_ARCH_ARM64) 3774 "ldaxr %0, [%2]\n\t" 3775 "sub %0, %0, #1\n\t" 3776 "stlxr %w1, %0, [%2]\n\t" 3777 "cbnz %w1, .Ltry_again_dec_u64_%=\n\t" 3778 # else 3779 "ldrexd %0, %H0, [%2]\n\t" 3780 "sub %0, %0, #1\n\t" /* arm6 / thumb2+ */ 3781 "sbc %H0, %H0, %3\n\t" 3782 "strexd %1, %0, %H0, [%2]\n\t" 3783 "cmp %1, #0\n\t" 3784 "bne .Ltry_again_dec_u64_%=\n\t" 3785 # endif 3786 : "=&r" (u64Ret), 3787 "=&r" (rcSpill) 3788 : "r" (pu64) 3789 # if !defined(RT_ARCH_ARM64) 3790 , "r" (0) 3791 # endif 3792 : "memory", 3793 "cc"); 3794 return u64Ret; 3795 3590 3796 # else 3591 3797 return ASMAtomicAddU64(pu64, UINT64_MAX) - 1;
Note:
See TracChangeset
for help on using the changeset viewer.