VirtualBox

Changeset 87171 in vbox for trunk/include/iprt


Ignore:
Timestamp:
Jan 4, 2021 9:35:43 PM (4 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
142100
Message:

iprt/asm.h: Generic memory barriers, writes and reads. Additions, subtration, incrementing and decrementing. bugref:9898 bugref:9026

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/include/iprt/asm.h

    r87156 r87171  
    18751875#elif defined(RT_ARCH_ARM64) || defined(RT_ARCH_ARM32)
    18761876    /* Note! Only armv7 and later. */
    1877     __asm__ __volatile__ ("dsb sy\n\t" ::: "memory");
     1877    __asm__ __volatile__ ("dsb sy\n\t" ::: "memory"); /** @todo dmb? */
    18781878#elif ARCH_BITS == 16
    18791879    uint16_t volatile u16;
     
    19061906#elif defined(RT_ARCH_ARM64) || defined(RT_ARCH_ARM32)
    19071907    /* Note! Only armv7 and later. */
    1908     __asm__ __volatile__ ("dmb sy\n\t" ::: "memory");
     1908    __asm__ __volatile__ ("dmb st\n\t" ::: "memory");
    19091909#else
    19101910    ASMMemoryFence();
     
    19331933#elif defined(RT_ARCH_ARM64) || defined(RT_ARCH_ARM32)
    19341934    /* Note! Only armv7 and later. */
    1935     __asm__ __volatile__ ("dmb sy\n\t";
     1935    __asm__ __volatile__ ("dmb ld\n\t" ::: "memory");
    19361936#else
    19371937    ASMMemoryFence();
     
    19981998DECLINLINE(uint16_t) ASMAtomicReadU16(volatile uint16_t RT_FAR *pu16) RT_NOTHROW_DEF
    19991999{
     2000    Assert(!((uintptr_t)pu16 & 1));
    20002001    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 */
     2012DECLINLINE(uint16_t) ASMAtomicUoReadU16(volatile uint16_t RT_FAR *pu16) RT_NOTHROW_DEF
     2013{
    20012014    Assert(!((uintptr_t)pu16 & 1));
    20022015    return *pu16;
     
    20052018
    20062019/**
    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 {
    2014     Assert(!((uintptr_t)pu16 & 1));
    2015     return *pu16;
    2016 }
    2017 
    2018 
    2019 /**
    20202020 * Atomically reads a signed 16-bit value, ordered.
    20212021 *
     
    20252025DECLINLINE(int16_t) ASMAtomicReadS16(volatile int16_t RT_FAR *pi16) RT_NOTHROW_DEF
    20262026{
     2027    Assert(!((uintptr_t)pi16 & 1));
    20272028    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 */
     2039DECLINLINE(int16_t) ASMAtomicUoReadS16(volatile int16_t RT_FAR *pi16) RT_NOTHROW_DEF
     2040{
    20282041    Assert(!((uintptr_t)pi16 & 1));
    20292042    return *pi16;
     
    20322045
    20332046/**
    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 {
    2041     Assert(!((uintptr_t)pi16 & 1));
    2042     return *pi16;
    2043 }
    2044 
    2045 
    2046 /**
    20472047 * Atomically reads an unsigned 32-bit value, ordered.
    20482048 *
     
    20522052DECLINLINE(uint32_t) ASMAtomicReadU32(volatile uint32_t RT_FAR *pu32) RT_NOTHROW_DEF
    20532053{
     2054    Assert(!((uintptr_t)pu32 & 3));
    20542055    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 */
     2069DECLINLINE(uint32_t) ASMAtomicUoReadU32(volatile uint32_t RT_FAR *pu32) RT_NOTHROW_DEF
     2070{
    20552071    Assert(!((uintptr_t)pu32 & 3));
    20562072#if ARCH_BITS == 16
     
    20622078
    20632079/**
    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 */
     2085DECLINLINE(int32_t) ASMAtomicReadS32(volatile int32_t RT_FAR *pi32) RT_NOTHROW_DEF
     2086{
     2087    Assert(!((uintptr_t)pi32 & 3));
     2088    ASMMemoryFence();
    20722089#if ARCH_BITS == 16
    20732090    AssertFailed();  /** @todo 16-bit */
    20742091#endif
    2075     return *pu32;
    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.
    20812098 *
    20822099 * @returns Current *pi32 value
    20832100 * @param   pi32    Pointer to the 32-bit variable to read.
    20842101 */
    2085 DECLINLINE(int32_t) ASMAtomicReadS32(volatile int32_t RT_FAR *pi32) RT_NOTHROW_DEF
    2086 {
    2087     ASMMemoryFence();
     2102DECLINLINE(int32_t) ASMAtomicUoReadS32(volatile int32_t RT_FAR *pi32) RT_NOTHROW_DEF
     2103{
    20882104    Assert(!((uintptr_t)pi32 & 3));
    20892105#if ARCH_BITS == 16
     
    20952111
    20962112/**
    2097  * Atomically reads a signed 32-bit value, unordered.
    2098  *
    2099  * @returns Current *pi32 value
    2100  * @param   pi32    Pointer to the 32-bit variable to read.
    2101  */
    2102 DECLINLINE(int32_t) ASMAtomicUoReadS32(volatile int32_t RT_FAR *pi32) RT_NOTHROW_DEF
    2103 {
    2104     Assert(!((uintptr_t)pi32 & 3));
    2105 #if ARCH_BITS == 16
    2106     AssertFailed();  /** @todo 16-bit */
    2107 #endif
    2108     return *pi32;
    2109 }
    2110 
    2111 
    2112 /**
    21132113 * Atomically reads an unsigned 64-bit value, ordered.
    21142114 *
     
    21202120 * @remarks x86: Requires a Pentium or later.
    21212121 */
    2122 #if (RT_INLINE_ASM_EXTERNAL && !defined(RT_ARCH_AMD64)) \
     2122#if (RT_INLINE_ASM_EXTERNAL_TMP_ARM && !defined(RT_ARCH_AMD64)) \
    21232123 || RT_INLINE_DONT_MIX_CMPXCHG8B_AND_PIC
    21242124RT_ASM_DECL_PRAGMA_WATCOM(uint64_t) ASMAtomicReadU64(volatile uint64_t RT_FAR *pu64) RT_NOTHROW_PROTO;
     
    21452145    ASMMemoryFence();
    21462146    u64 = *pu64;
    2147 # else /* !RT_ARCH_AMD64 */
     2147
     2148# elif defined(RT_ARCH_X86)
    21482149#  if RT_INLINE_ASM_GNU_STYLE
    21492150#   if defined(PIC) || defined(__PIC__)
     
    21852186    }
    21862187#  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
    21882205    return u64;
    21892206}
     
    22022219 */
    22032220#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) \
    22052222      || RT_INLINE_DONT_MIX_CMPXCHG8B_AND_PIC)
    22062223RT_ASM_DECL_PRAGMA_WATCOM(uint64_t) ASMAtomicUoReadU64(volatile uint64_t RT_FAR *pu64) RT_NOTHROW_PROTO;
     
    22252242#  endif */
    22262243    u64 = *pu64;
    2227 # else /* !RT_ARCH_AMD64 */
     2244
     2245# elif defined(RT_ARCH_X86)
    22282246#  if RT_INLINE_ASM_GNU_STYLE
    22292247#   if defined(PIC) || defined(__PIC__)
     
    22682286    }
    22692287#  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
    22712303    return u64;
    22722304}
     
    25562588DECLINLINE(void) ASMAtomicWriteU8(volatile uint8_t RT_FAR *pu8, uint8_t u8) RT_NOTHROW_DEF
    25572589{
     2590    /** @todo Any possible ARM32/ARM64 optimizations here? */
    25582591    ASMAtomicXchgU8(pu8, u8);
    25592592}
     
    25802613DECLINLINE(void) ASMAtomicWriteS8(volatile int8_t RT_FAR *pi8, int8_t i8) RT_NOTHROW_DEF
    25812614{
     2615    /** @todo Any possible ARM32/ARM64 optimizations here? */
    25822616    ASMAtomicXchgS8(pi8, i8);
    25832617}
     
    26042638DECLINLINE(void) ASMAtomicWriteU16(volatile uint16_t RT_FAR *pu16, uint16_t u16) RT_NOTHROW_DEF
    26052639{
     2640    /** @todo Any possible ARM32/ARM64 optimizations here? */
    26062641    ASMAtomicXchgU16(pu16, u16);
    26072642}
     
    26292664DECLINLINE(void) ASMAtomicWriteS16(volatile int16_t RT_FAR *pi16, int16_t i16) RT_NOTHROW_DEF
    26302665{
     2666    /** @todo Any possible ARM32/ARM64 optimizations here? */
    26312667    ASMAtomicXchgS16(pi16, i16);
    26322668}
     
    26542690DECLINLINE(void) ASMAtomicWriteU32(volatile uint32_t RT_FAR *pu32, uint32_t u32) RT_NOTHROW_DEF
    26552691{
     2692    /** @todo Any possible ARM32/ARM64 optimizations here? */
    26562693    ASMAtomicXchgU32(pu32, u32);
    26572694}
     
    27122749DECLINLINE(void) ASMAtomicWriteU64(volatile uint64_t RT_FAR *pu64, uint64_t u64) RT_NOTHROW_DEF
    27132750{
     2751    /** @todo Any possible ARM32/ARM64 optimizations here? */
    27142752    ASMAtomicXchgU64(pu64, u64);
    27152753}
     
    27412779DECLINLINE(void) ASMAtomicWriteS64(volatile int64_t RT_FAR *pi64, int64_t i64) RT_NOTHROW_DEF
    27422780{
     2781    /** @todo Any possible ARM32/ARM64 optimizations here? */
    27432782    ASMAtomicXchgS64(pi64, i64);
    27442783}
     
    30623101 * @remarks x86: Requires a 486 or later.
    30633102 */
    3064 #if RT_INLINE_ASM_EXTERNAL && !RT_INLINE_ASM_USES_INTRIN
     3103#if RT_INLINE_ASM_EXTERNAL_TMP_ARM && !RT_INLINE_ASM_USES_INTRIN
    30653104RT_ASM_DECL_PRAGMA_WATCOM(uint32_t) ASMAtomicAddU32(uint32_t volatile RT_FAR *pu32, uint32_t u32) RT_NOTHROW_PROTO;
    30663105#else
     
    30713110    return u32;
    30723111
    3073 # elif RT_INLINE_ASM_GNU_STYLE
     3112# elif defined(RT_ARCH_AMD64) || defined(RT_ARCH_X86)
     3113#  if RT_INLINE_ASM_GNU_STYLE
    30743114    __asm__ __volatile__("lock; xaddl %0, %1\n\t"
    30753115                         : "=r" (u32),
     
    30793119                         : "memory");
    30803120    return u32;
    3081 # else
     3121#  else
    30823122    __asm
    30833123    {
    30843124        mov     eax, [u32]
    3085 ifdef RT_ARCH_AMD64
     3125 ifdef RT_ARCH_AMD64
    30863126        mov     rdx, [pu32]
    30873127        lock xadd [rdx], eax
    3088 else
     3128 else
    30893129        mov     edx, [pu32]
    30903130        lock xadd [edx], eax
    3091 endif
     3131 endif
    30923132        mov     [u32], eax
    30933133    }
    30943134    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"
    30953165# endif
    30963166}
     
    31223192 * @remarks x86: Requires a Pentium or later.
    31233193 */
    3124 #if RT_INLINE_ASM_EXTERNAL && !RT_INLINE_ASM_USES_INTRIN
     3194#if RT_INLINE_ASM_EXTERNAL_TMP_ARM && !RT_INLINE_ASM_USES_INTRIN
    31253195DECLASM(uint64_t) ASMAtomicAddU64(uint64_t volatile RT_FAR *pu64, uint64_t u64) RT_NOTHROW_PROTO;
    31263196#else
     
    31393209                         : "memory");
    31403210    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
    31413239# else
    31423240    uint64_t u64Old;
     
    33693467 * @remarks x86: Requires a 486 or later.
    33703468 */
    3371 #if RT_INLINE_ASM_EXTERNAL && !RT_INLINE_ASM_USES_INTRIN
     3469#if RT_INLINE_ASM_EXTERNAL_TMP_ARM && !RT_INLINE_ASM_USES_INTRIN
    33723470RT_ASM_DECL_PRAGMA_WATCOM(uint32_t) ASMAtomicIncU32(uint32_t volatile RT_FAR *pu32) RT_NOTHROW_PROTO;
    33733471#else
    33743472DECLINLINE(uint32_t) ASMAtomicIncU32(uint32_t volatile RT_FAR *pu32) RT_NOTHROW_DEF
    33753473{
     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
    33763479    uint32_t u32;
    3377 # if RT_INLINE_ASM_USES_INTRIN
    3378     u32 = _InterlockedIncrement((long RT_FAR *)pu32);
    3379     return u32;
    3380 
    3381 # elif RT_INLINE_ASM_GNU_STYLE
    33823480    __asm__ __volatile__("lock; xaddl %0, %1\n\t"
    33833481                         : "=r" (u32),
     
    33873485                         : "memory");
    33883486    return u32+1;
    3389 # else
     3487#  else
    33903488    __asm
    33913489    {
    33923490        mov     eax, 1
    3393 ifdef RT_ARCH_AMD64
     3491 ifdef RT_ARCH_AMD64
    33943492        mov     rdx, [pu32]
    33953493        lock xadd [rdx], eax
    3396 else
     3494 else
    33973495        mov     edx, [pu32]
    33983496        lock xadd [edx], eax
    3399 endif
     3497 endif
    34003498        mov     u32, eax
    34013499    }
    34023500    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;
    34033528# endif
    34043529}
     
    34283553 * @remarks x86: Requires a Pentium or later.
    34293554 */
    3430 #if RT_INLINE_ASM_EXTERNAL && !RT_INLINE_ASM_USES_INTRIN
     3555#if RT_INLINE_ASM_EXTERNAL_TMP_ARM && !RT_INLINE_ASM_USES_INTRIN
    34313556DECLASM(uint64_t) ASMAtomicIncU64(uint64_t volatile RT_FAR *pu64) RT_NOTHROW_PROTO;
    34323557#else
     
    34343559{
    34353560# 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);
    34393562
    34403563# elif RT_INLINE_ASM_GNU_STYLE && defined(RT_ARCH_AMD64)
     
    34473570                         : "memory");
    34483571    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
    34493600# else
    34503601    return ASMAtomicAddU64(pu64, 1) + 1;
     
    35113662 * @remarks x86: Requires a 486 or later.
    35123663 */
    3513 #if RT_INLINE_ASM_EXTERNAL && !RT_INLINE_ASM_USES_INTRIN
     3664#if RT_INLINE_ASM_EXTERNAL_TMP_ARM && !RT_INLINE_ASM_USES_INTRIN
    35143665RT_ASM_DECL_PRAGMA_WATCOM(uint32_t) ASMAtomicDecU32(uint32_t volatile RT_FAR *pu32) RT_NOTHROW_PROTO;
    35153666#else
    35163667DECLINLINE(uint32_t) ASMAtomicDecU32(uint32_t volatile RT_FAR *pu32) RT_NOTHROW_DEF
    35173668{
     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
    35183674    uint32_t u32;
    3519 # if RT_INLINE_ASM_USES_INTRIN
    3520     u32 = _InterlockedDecrement((long RT_FAR *)pu32);
    3521     return u32;
    3522 
    3523 # elif RT_INLINE_ASM_GNU_STYLE
    35243675    __asm__ __volatile__("lock; xaddl %0, %1\n\t"
    35253676                         : "=r" (u32),
     
    35303681    return u32-1;
    35313682# else
     3683    uint32_t u32;
    35323684    __asm
    35333685    {
     
    35443696    return u32-1;
    35453697# 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
    35463725}
    35473726#endif
     
    35703749 * @remarks x86: Requires a Pentium or later.
    35713750 */
    3572 #if RT_INLINE_ASM_EXTERNAL && !RT_INLINE_ASM_USES_INTRIN
     3751#if RT_INLINE_ASM_EXTERNAL_TMP_ARM && !RT_INLINE_ASM_USES_INTRIN
    35733752RT_ASM_DECL_PRAGMA_WATCOM(uint64_t) ASMAtomicDecU64(uint64_t volatile RT_FAR *pu64) RT_NOTHROW_PROTO;
    35743753#else
     
    35763755{
    35773756# 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);
    35803758
    35813759# elif RT_INLINE_ASM_GNU_STYLE && defined(RT_ARCH_AMD64)
     
    35883766                         : "memory");
    35893767    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
    35903796# else
    35913797    return ASMAtomicAddU64(pu64, UINT64_MAX) - 1;
Note: See TracChangeset for help on using the changeset viewer.

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette