VirtualBox

Changeset 87156 in vbox for trunk


Ignore:
Timestamp:
Jan 2, 2021 10:25:10 PM (4 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
142068
Message:

iprt/asm.h: Rest of the ASMAtomicCmpXchg* functions. bugref:9898 bugref:9026

File:
1 edited

Legend:

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

    r87155 r87156  
    303303    uint32_t uOld;
    304304    uint32_t rcSpill;
    305     __asm__ __volatile__("try_again%=:\n\t"
     305    __asm__ __volatile__(".Ltry_again%=:\n\t"
    306306#  if defined(RT_ARCH_ARM64)
    307307                         "ldaxrb    %w0, [%3]\n\t"
    308308                         "stlxrb    %w1, %w2, [%3]\n\t"
    309                          "cbnz      %w1, try_again%=\n\t"
     309                         "cbnz      %w1, .Ltry_again%=\n\t"
    310310#  else
    311311                         "ldrexb    %0, [%3]\n\t"      /* ARMv6+ */
    312312                         "strexb    %1, %2, [%3]\n\t"
    313313                         "cmp       %1, #0\n\t"
    314                          "bne       try_again%=\n\t"
     314                         "bne       .Ltry_again%=\n\t"
    315315#  endif
    316316                         : "=&r" (uOld),
     
    399399    uint32_t uOld;
    400400    uint32_t rcSpill;
    401     __asm__ __volatile__("try_again%=:\n\t"
     401    __asm__ __volatile__(".Ltry_again%=:\n\t"
    402402#  if defined(RT_ARCH_ARM64)
    403403                         "ldaxrh    %w0, [%3]\n\t"
    404404                         "stlxrh    %w1, %w2, [%3]\n\t"
    405                          "cbnz      %w1, try_again%=\n\t"
     405                         "cbnz      %w1, .Ltry_again%=\n\t"
    406406#  else
    407407                         "ldrexh    %0, [%3]\n\t"      /* ARMv6+ */
    408408                         "strexh    %1, %2, [%3]\n\t"
    409409                         "cmp       %1, #0\n\t"
    410                          "bne       try_again%=\n\t"
     410                         "bne       .Ltry_again%=\n\t"
    411411#  endif
    412412                         : "=&r" (uOld),
     
    484484    uint32_t uOld;
    485485    uint32_t rcSpill;
    486     __asm__ __volatile__("try_again%=:\n\t"
     486    __asm__ __volatile__(".Ltry_again%=:\n\t"
    487487#  if defined(RT_ARCH_ARM64)
    488488                         "ldaxr     %w0, [%3]\n\t"
    489489                         "stlxr     %w1, %w2, [%3]\n\t"
    490                          "cbnz      %w1, try_again%=\n\t"
     490                         "cbnz      %w1, .Ltry_again%=\n\t"
    491491#  else
    492492                         "ldrex     %0, [%3]\n\t"      /* ARMv6+ */
    493493                         "strex     %1, %2, [%3]\n\t"
    494494                         "cmp       %1, #0\n\t"
    495                          "bne       try_again%=\n\t"
     495                         "bne       .Ltry_again%=\n\t"
    496496#  endif
    497497                         : "=&r" (uOld),
     
    603603# elif defined(RT_ARCH_ARM32) || defined(RT_ARCH_ARM64)
    604604    uint32_t rcSpill;
    605     __asm__ __volatile__("try_again%=:\n\t"
     605    __asm__ __volatile__(".Ltry_again%=:\n\t"
    606606#  if defined(RT_ARCH_ARM64)
    607607                         "ldaxr     %0, [%3]\n\t"
    608608                         "stlxr     %w1, %2, [%3]\n\t"
    609                          "cbnz      %w1, try_again%=\n\t"
     609                         "cbnz      %w1, .Ltry_again%=\n\t"
    610610#  else
    611611                         "ldrexd    %H0, [%3]\n\t"      /* ARMv6+ */
    612612                         "strexd    %1, %H2, [%3]\n\t"
    613613                         "cmp       %1, #0\n\t"
    614                          "bne       try_again%=\n\t"
     614                         "bne       .Ltry_again%=\n\t"
    615615#  endif
    616616                         : "=&r" (u64),
     
    620620                         : "memory",
    621621                           "cc");
     622
    622623# else
    623624#  error "Port me"
     
    854855
    855856# elif defined(RT_ARCH_ARM64) || defined(RT_ARCH_ARM32)
    856     uint32_t fXchg;
     857    union { uint32_t u; bool f; } fXchg;
    857858    uint32_t u32Spill;
    858859    uint32_t rcSpill;
    859     __asm__ __volatile__("try_again%=:\n\t"
     860    __asm__ __volatile__(".Ltry_again%=:\n\t"
    860861#  if defined(RT_ARCH_ARM64)
    861862                         "ldaxrb    %w0, [%5]\n\t"
     
    863864                         "bne       1f\n\t"   /* stop here if not equal */
    864865                         "stlxrb    %w1, %w4, [%5]\n\t"
    865                          "cbnz      %w1, try_again%=\n\t"
     866                         "cbnz      %w1, .Ltry_again%=\n\t"
    866867                         "mov       %w2, #1\n\t"
    867868#  else
     
    871872                         "bne       1f\n\t"   /* stop here if not equal */
    872873                         "cmp       %1, #0\n\t"
    873                          "bne       try_again%=\n\t"
     874                         "bne       .Ltry_again%=\n\t"
    874875                         "mov       %2, #1\n\t"
    875876#  endif
     
    877878                         : "=&r" (u32Spill),
    878879                           "=&r" (rcSpill),
    879                            "=&r" (fXchg)
     880                           "=&r" (fXchg.u)
    880881                         : "r" ((uint32_t)u8Old),
    881882                           "r" ((uint32_t)u8New),
     
    884885                         : "memory",
    885886                           "cc");
    886     return (bool)fXchg;
     887    return fXchg.f;
     888
    887889# else
    888890#  error "Port me"
    889 # endif /* RT_ARCH_ARM */
     891# endif
    890892}
    891893#endif
     
    985987
    986988# elif defined(RT_ARCH_ARM64) || defined(RT_ARCH_ARM32)
    987     uint32_t fXchg;
     989    union { uint32_t u; bool f; } fXchg;
    988990    uint32_t u32Spill;
    989991    uint32_t rcSpill;
    990     __asm__ __volatile__("try_again%=:\n\t"
     992    __asm__ __volatile__(".Ltry_again%=:\n\t"
    991993#  if defined(RT_ARCH_ARM64)
    992994                         "ldaxr     %w0, [%5]\n\t"
     
    994996                         "bne       1f\n\t"   /* stop here if not equal */
    995997                         "stlxr     %w1, %w4, [%5]\n\t"
    996                          "cbnz      %w1, try_again%=\n\t"
     998                         "cbnz      %w1, .Ltry_again%=\n\t"
    997999                         "mov       %w2, #1\n\t"
    9981000#  else
     
    10021004                         "bne       1f\n\t"   /* stop here if not equal */
    10031005                         "cmp       %1, #0\n\t"
    1004                          "bne       try_again%=\n\t"
     1006                         "bne       .Ltry_again%=\n\t"
    10051007                         "mov       %2, #1\n\t"
    10061008#  endif
     
    10081010                         : "=&r" (u32Spill),
    10091011                           "=&r" (rcSpill),
    1010                            "=&r" (fXchg)
     1012                           "=&r" (fXchg.u)
    10111013                         : "r" (u32Old),
    10121014                           "r" (u32New),
     
    10151017                         : "memory",
    10161018                           "cc");
    1017     return (bool)fXchg;
     1019    return fXchg.f;
     1020
    10181021# else
    10191022#  error "Port me"
    1020 # endif /* RT_ARCH_ARM */
     1023# endif
    10211024}
    10221025#endif
     
    10531056 * @remarks x86: Requires a Pentium or later.
    10541057 */
    1055 #if (RT_INLINE_ASM_EXTERNAL && !RT_INLINE_ASM_USES_INTRIN) \
     1058#if (RT_INLINE_ASM_EXTERNAL_TMP_ARM && !RT_INLINE_ASM_USES_INTRIN) \
    10561059 || RT_INLINE_DONT_MIX_CMPXCHG8B_AND_PIC
    10571060RT_ASM_DECL_PRAGMA_WATCOM(bool) ASMAtomicCmpXchgU64(volatile uint64_t RT_FAR *pu64, const uint64_t u64New, const uint64_t u64Old) RT_NOTHROW_PROTO;
     
    10871090    return fRet;
    10881091#  endif
    1089 # else /* !RT_ARCH_AMD64 */
     1092
     1093# elif defined(RT_ARCH_X86)
    10901094    uint32_t u32Ret;
    10911095#  if RT_INLINE_ASM_GNU_STYLE
     
    11371141    return !!u32Ret;
    11381142#  endif
    1139 # endif /* !RT_ARCH_AMD64 */
     1143
     1144# elif defined(RT_ARCH_ARM64) || defined(RT_ARCH_ARM32)
     1145    union { uint32_t u; bool f; } fXchg;
     1146    uint64_t u64Spill;
     1147    uint32_t rcSpill;
     1148    __asm__ __volatile__(".Ltry_again%=:\n\t"
     1149#  if defined(RT_ARCH_ARM64)
     1150                         "ldaxr     %0, [%5]\n\t"
     1151                         "cmp       %0, %3\n\t"
     1152                         "bne       1f\n\t"   /* stop here if not equal */
     1153                         "stlxr     %w1, %4, [%5]\n\t"
     1154                         "cbnz      %w1, .Ltry_again%=\n\t"
     1155                         "mov       %w2, #1\n\t"
     1156#  else
     1157                         "ldrexd    %0, %H0, [%5]\n\t"
     1158                         "teq       %0, %3\n\t"
     1159                         "teqeq     %H0, %H3\n\t"
     1160                         "strexdeq  %1, %4, %H4, [%5]\n\t"
     1161                         "bne       1f\n\t"   /* stop here if not equal */
     1162                         "cmp       %1, #0\n\t"
     1163                         "bne       .Ltry_again%=\n\t"
     1164                         "mov       %2, #1\n\t"
     1165#  endif
     1166                         "1:\n\t"
     1167                         : "=&r" (u64Spill),
     1168                           "=&r" (rcSpill),
     1169                           "=&r" (fXchg.u)
     1170                         : "r" (u64Old),
     1171                           "r" (u64New),
     1172                           "r" (pu64),
     1173                           "2" (0) /*fXchg*/
     1174                         : "memory",
     1175                           "cc");
     1176    return fXchg.f;
     1177
     1178# else
     1179#  error "Port me"
     1180# endif
    11401181}
    11411182#endif
     
    12811322 * @remarks x86: Requires a 486 or later.
    12821323 */
    1283 #if RT_INLINE_ASM_EXTERNAL && !RT_INLINE_ASM_USES_INTRIN
     1324#if RT_INLINE_ASM_EXTERNAL_TMP_ARM && !RT_INLINE_ASM_USES_INTRIN
    12841325RT_ASM_DECL_PRAGMA_WATCOM(bool) ASMAtomicCmpXchgExU32(volatile uint32_t RT_FAR *pu32, const uint32_t u32New, const uint32_t u32Old, uint32_t RT_FAR *pu32Old) RT_NOTHROW_PROTO;
    12851326#else
    12861327DECLINLINE(bool) ASMAtomicCmpXchgExU32(volatile uint32_t RT_FAR *pu32, const uint32_t u32New, const uint32_t u32Old, uint32_t RT_FAR *pu32Old) RT_NOTHROW_DEF
    12871328{
    1288 # if RT_INLINE_ASM_GNU_STYLE
     1329# if defined(RT_ARCH_AMD64) || defined(RT_ARCH_X86)
     1330#  if RT_INLINE_ASM_GNU_STYLE
    12891331    uint8_t u8Ret;
    12901332    __asm__ __volatile__("lock; cmpxchgl %3, %0\n\t"
     
    12981340    return (bool)u8Ret;
    12991341
    1300 # elif RT_INLINE_ASM_USES_INTRIN
    1301     return (*pu32Old =_InterlockedCompareExchange((long RT_FAR *)pu32, u32New, u32Old)) == u32Old;
    1302 
    1303 # else
     1342#  elif RT_INLINE_ASM_USES_INTRIN
     1343    return (*pu32Old = _InterlockedCompareExchange((long RT_FAR *)pu32, u32New, u32Old)) == u32Old;
     1344
     1345#  else
    13041346    uint32_t u32Ret;
    13051347    __asm
    13061348    {
    1307 ifdef RT_ARCH_AMD64
     1349 ifdef RT_ARCH_AMD64
    13081350        mov     rdx, [pu32]
    1309 else
     1351 else
    13101352        mov     edx, [pu32]
    1311 endif
     1353 endif
    13121354        mov     eax, [u32Old]
    13131355        mov     ecx, [u32New]
    1314 ifdef RT_ARCH_AMD64
     1356 ifdef RT_ARCH_AMD64
    13151357        lock cmpxchg [rdx], ecx
    13161358        mov     rdx, [pu32Old]
    13171359        mov     [rdx], eax
    1318 else
     1360 else
    13191361        lock cmpxchg [edx], ecx
    13201362        mov     edx, [pu32Old]
    13211363        mov     [edx], eax
    1322 endif
     1364 endif
    13231365        setz    al
    13241366        movzx   eax, al
     
    13261368    }
    13271369    return !!u32Ret;
     1370#  endif
     1371
     1372# elif defined(RT_ARCH_ARM64) || defined(RT_ARCH_ARM32)
     1373    union { uint32_t u; bool f; } fXchg;
     1374    uint32_t u32ActualOld;
     1375    uint32_t rcSpill;
     1376    __asm__ __volatile__(".Ltry_again%=:\n\t"
     1377#  if defined(RT_ARCH_ARM64)
     1378                         "ldaxr     %w0, [%5]\n\t"
     1379                         "cmp       %w0, %w3\n\t"
     1380                         "bne       1f\n\t"   /* stop here if not equal */
     1381                         "stlxr     %w1, %w4, [%5]\n\t"
     1382                         "cbnz      %w1, .Ltry_again%=\n\t"
     1383                         "mov       %w2, #1\n\t"
     1384#  else
     1385                         "ldrex     %0, [%5]\n\t"
     1386                         "teq       %0, %3\n\t"
     1387                         "strexeq   %1, %4, [%5]\n\t"
     1388                         "bne       1f\n\t"   /* stop here if not equal */
     1389                         "cmp       %1, #0\n\t"
     1390                         "bne       .Ltry_again%=\n\t"
     1391                         "mov       %2, #1\n\t"
     1392#  endif
     1393                         "1:\n\t"
     1394                         : "=&r" (u32ActualOld),
     1395                           "=&r" (rcSpill),
     1396                           "=&r" (fXchg.u)
     1397                         : "r" (u32Old),
     1398                           "r" (u32New),
     1399                           "r" (pu32),
     1400                           "2" (0) /*fXchg*/
     1401                         : "memory",
     1402                           "cc");
     1403    *pu32Old = u32ActualOld;
     1404    return fXchg.f;
     1405
     1406# else
     1407#  error "Port me"
    13281408# endif
    13291409}
     
    13651445 * @remarks x86: Requires a Pentium or later.
    13661446 */
    1367 #if (RT_INLINE_ASM_EXTERNAL && !RT_INLINE_ASM_USES_INTRIN) \
     1447#if (RT_INLINE_ASM_EXTERNAL_TMP_ARM && !RT_INLINE_ASM_USES_INTRIN) \
    13681448 || RT_INLINE_DONT_MIX_CMPXCHG8B_AND_PIC
    13691449RT_ASM_DECL_PRAGMA_WATCOM(bool) ASMAtomicCmpXchgExU64(volatile uint64_t RT_FAR *pu64, const uint64_t u64New, const uint64_t u64Old, uint64_t RT_FAR *pu64Old) RT_NOTHROW_PROTO;
     
    14011481    return fRet;
    14021482#  endif
    1403 # else /* !RT_ARCH_AMD64 */
     1483
     1484# elif defined(RT_ARCH_X86)
    14041485#  if RT_INLINE_ASM_GNU_STYLE
    14051486    uint64_t u64Ret;
     
    14491530    return !!u32Ret;
    14501531#  endif
    1451 # endif /* !RT_ARCH_AMD64 */
     1532
     1533# elif defined(RT_ARCH_ARM64) || defined(RT_ARCH_ARM32)
     1534    union { uint32_t u; bool f; } fXchg;
     1535    uint64_t u64ActualOld;
     1536    uint32_t rcSpill;
     1537    __asm__ __volatile__(".Ltry_again%=:\n\t"
     1538#  if defined(RT_ARCH_ARM64)
     1539                         "ldaxr     %0, [%5]\n\t"
     1540                         "cmp       %0, %3\n\t"
     1541                         "bne       1f\n\t"   /* stop here if not equal */
     1542                         "stlxr     %w1, %4, [%5]\n\t"
     1543                         "cbnz      %w1, .Ltry_again%=\n\t"
     1544                         "mov       %w2, #1\n\t"
     1545#  else
     1546                         "ldrexd    %0, %H0, [%5]\n\t"
     1547                         "teq       %0, %3\n\t"
     1548                         "teqeq     %H0, %H3\n\t"
     1549                         "strexdeq  %1, %4, %H4, [%5]\n\t"
     1550                         "bne       1f\n\t"   /* stop here if not equal */
     1551                         "cmp       %1, #0\n\t"
     1552                         "bne       .Ltry_again%=\n\t"
     1553                         "mov       %2, #1\n\t"
     1554#  endif
     1555                         "1:\n\t"
     1556                         : "=&r" (u64ActualOld),
     1557                           "=&r" (rcSpill),
     1558                           "=&r" (fXchg.u)
     1559                         : "r" (u64Old),
     1560                           "r" (u64New),
     1561                           "r" (pu64),
     1562                           "2" (0) /*fXchg*/
     1563                         : "memory",
     1564                           "cc");
     1565    *pu64Old = u64ActualOld;
     1566    return fXchg.f;
     1567
     1568# else
     1569#  error "Port me"
     1570# endif
    14521571}
    14531572#endif
     
    15941713 * Virtualization unfriendly serializing instruction, always exits.
    15951714 */
    1596 #if RT_INLINE_ASM_EXTERNAL && !RT_INLINE_ASM_USES_INTRIN
     1715#if (RT_INLINE_ASM_EXTERNAL && !RT_INLINE_ASM_USES_INTRIN) || (!defined(RT_ARCH_AMD64) && !defined(RT_ARCH_X86))
    15971716RT_ASM_DECL_PRAGMA_WATCOM(void) ASMSerializeInstructionCpuId(void) RT_NOTHROW_PROTO;
    15981717#else
     
    16401759 * Virtualization friendly serializing instruction, though more expensive.
    16411760 */
    1642 #if RT_INLINE_ASM_EXTERNAL
     1761#if RT_INLINE_ASM_EXTERNAL || (!defined(RT_ARCH_AMD64) && !defined(RT_ARCH_X86))
    16431762RT_ASM_DECL_PRAGMA_WATCOM(void) ASMSerializeInstructionIRet(void) RT_NOTHROW_PROTO;
    16441763#else
     
    16851804 * Virtualization friendlier serializing instruction, may still cause exits.
    16861805 */
    1687 #if RT_INLINE_ASM_EXTERNAL && RT_INLINE_ASM_USES_INTRIN < 15
     1806#if (RT_INLINE_ASM_EXTERNAL && RT_INLINE_ASM_USES_INTRIN < 15) || (!defined(RT_ARCH_AMD64) && !defined(RT_ARCH_X86))
    16881807RT_ASM_DECL_PRAGMA_WATCOM(void) ASMSerializeInstructionRdTscp(void) RT_NOTHROW_PROTO;
    16891808#else
     
    17291848{
    17301849    /* Note! Only armv7 and later. */
    1731     __asm__ __volatile__ ("dsb\n\t" ::: "memory");
     1850    __asm__ __volatile__ ("dsb sy\n\t" ::: "memory");
    17321851}
    17331852#else
     
    17561875#elif defined(RT_ARCH_ARM64) || defined(RT_ARCH_ARM32)
    17571876    /* Note! Only armv7 and later. */
    1758     __asm__ __volatile__ ("dsb sy\n\t");
     1877    __asm__ __volatile__ ("dsb sy\n\t" ::: "memory");
    17591878#elif ARCH_BITS == 16
    17601879    uint16_t volatile u16;
     
    17871906#elif defined(RT_ARCH_ARM64) || defined(RT_ARCH_ARM32)
    17881907    /* Note! Only armv7 and later. */
    1789     __asm__ __volatile__ ("dmb sy\n\t");
     1908    __asm__ __volatile__ ("dmb sy\n\t" ::: "memory");
    17901909#else
    17911910    ASMMemoryFence();
     
    18141933#elif defined(RT_ARCH_ARM64) || defined(RT_ARCH_ARM32)
    18151934    /* Note! Only armv7 and later. */
    1816     __asm__ __volatile__ ("dmb sy\n\t");
     1935    __asm__ __volatile__ ("dmb sy\n\t";
    18171936#else
    18181937    ASMMemoryFence();
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