- Timestamp:
- Jan 2, 2021 10:25:10 PM (4 years ago)
- svn:sync-xref-src-repo-rev:
- 142068
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/include/iprt/asm.h
r87155 r87156 303 303 uint32_t uOld; 304 304 uint32_t rcSpill; 305 __asm__ __volatile__(" try_again%=:\n\t"305 __asm__ __volatile__(".Ltry_again%=:\n\t" 306 306 # if defined(RT_ARCH_ARM64) 307 307 "ldaxrb %w0, [%3]\n\t" 308 308 "stlxrb %w1, %w2, [%3]\n\t" 309 "cbnz %w1, try_again%=\n\t"309 "cbnz %w1, .Ltry_again%=\n\t" 310 310 # else 311 311 "ldrexb %0, [%3]\n\t" /* ARMv6+ */ 312 312 "strexb %1, %2, [%3]\n\t" 313 313 "cmp %1, #0\n\t" 314 "bne try_again%=\n\t"314 "bne .Ltry_again%=\n\t" 315 315 # endif 316 316 : "=&r" (uOld), … … 399 399 uint32_t uOld; 400 400 uint32_t rcSpill; 401 __asm__ __volatile__(" try_again%=:\n\t"401 __asm__ __volatile__(".Ltry_again%=:\n\t" 402 402 # if defined(RT_ARCH_ARM64) 403 403 "ldaxrh %w0, [%3]\n\t" 404 404 "stlxrh %w1, %w2, [%3]\n\t" 405 "cbnz %w1, try_again%=\n\t"405 "cbnz %w1, .Ltry_again%=\n\t" 406 406 # else 407 407 "ldrexh %0, [%3]\n\t" /* ARMv6+ */ 408 408 "strexh %1, %2, [%3]\n\t" 409 409 "cmp %1, #0\n\t" 410 "bne try_again%=\n\t"410 "bne .Ltry_again%=\n\t" 411 411 # endif 412 412 : "=&r" (uOld), … … 484 484 uint32_t uOld; 485 485 uint32_t rcSpill; 486 __asm__ __volatile__(" try_again%=:\n\t"486 __asm__ __volatile__(".Ltry_again%=:\n\t" 487 487 # if defined(RT_ARCH_ARM64) 488 488 "ldaxr %w0, [%3]\n\t" 489 489 "stlxr %w1, %w2, [%3]\n\t" 490 "cbnz %w1, try_again%=\n\t"490 "cbnz %w1, .Ltry_again%=\n\t" 491 491 # else 492 492 "ldrex %0, [%3]\n\t" /* ARMv6+ */ 493 493 "strex %1, %2, [%3]\n\t" 494 494 "cmp %1, #0\n\t" 495 "bne try_again%=\n\t"495 "bne .Ltry_again%=\n\t" 496 496 # endif 497 497 : "=&r" (uOld), … … 603 603 # elif defined(RT_ARCH_ARM32) || defined(RT_ARCH_ARM64) 604 604 uint32_t rcSpill; 605 __asm__ __volatile__(" try_again%=:\n\t"605 __asm__ __volatile__(".Ltry_again%=:\n\t" 606 606 # if defined(RT_ARCH_ARM64) 607 607 "ldaxr %0, [%3]\n\t" 608 608 "stlxr %w1, %2, [%3]\n\t" 609 "cbnz %w1, try_again%=\n\t"609 "cbnz %w1, .Ltry_again%=\n\t" 610 610 # else 611 611 "ldrexd %H0, [%3]\n\t" /* ARMv6+ */ 612 612 "strexd %1, %H2, [%3]\n\t" 613 613 "cmp %1, #0\n\t" 614 "bne try_again%=\n\t"614 "bne .Ltry_again%=\n\t" 615 615 # endif 616 616 : "=&r" (u64), … … 620 620 : "memory", 621 621 "cc"); 622 622 623 # else 623 624 # error "Port me" … … 854 855 855 856 # elif defined(RT_ARCH_ARM64) || defined(RT_ARCH_ARM32) 856 u int32_tfXchg;857 union { uint32_t u; bool f; } fXchg; 857 858 uint32_t u32Spill; 858 859 uint32_t rcSpill; 859 __asm__ __volatile__(" try_again%=:\n\t"860 __asm__ __volatile__(".Ltry_again%=:\n\t" 860 861 # if defined(RT_ARCH_ARM64) 861 862 "ldaxrb %w0, [%5]\n\t" … … 863 864 "bne 1f\n\t" /* stop here if not equal */ 864 865 "stlxrb %w1, %w4, [%5]\n\t" 865 "cbnz %w1, try_again%=\n\t"866 "cbnz %w1, .Ltry_again%=\n\t" 866 867 "mov %w2, #1\n\t" 867 868 # else … … 871 872 "bne 1f\n\t" /* stop here if not equal */ 872 873 "cmp %1, #0\n\t" 873 "bne try_again%=\n\t"874 "bne .Ltry_again%=\n\t" 874 875 "mov %2, #1\n\t" 875 876 # endif … … 877 878 : "=&r" (u32Spill), 878 879 "=&r" (rcSpill), 879 "=&r" (fXchg )880 "=&r" (fXchg.u) 880 881 : "r" ((uint32_t)u8Old), 881 882 "r" ((uint32_t)u8New), … … 884 885 : "memory", 885 886 "cc"); 886 return (bool)fXchg; 887 return fXchg.f; 888 887 889 # else 888 890 # error "Port me" 889 # endif /* RT_ARCH_ARM */891 # endif 890 892 } 891 893 #endif … … 985 987 986 988 # elif defined(RT_ARCH_ARM64) || defined(RT_ARCH_ARM32) 987 u int32_tfXchg;989 union { uint32_t u; bool f; } fXchg; 988 990 uint32_t u32Spill; 989 991 uint32_t rcSpill; 990 __asm__ __volatile__(" try_again%=:\n\t"992 __asm__ __volatile__(".Ltry_again%=:\n\t" 991 993 # if defined(RT_ARCH_ARM64) 992 994 "ldaxr %w0, [%5]\n\t" … … 994 996 "bne 1f\n\t" /* stop here if not equal */ 995 997 "stlxr %w1, %w4, [%5]\n\t" 996 "cbnz %w1, try_again%=\n\t"998 "cbnz %w1, .Ltry_again%=\n\t" 997 999 "mov %w2, #1\n\t" 998 1000 # else … … 1002 1004 "bne 1f\n\t" /* stop here if not equal */ 1003 1005 "cmp %1, #0\n\t" 1004 "bne try_again%=\n\t"1006 "bne .Ltry_again%=\n\t" 1005 1007 "mov %2, #1\n\t" 1006 1008 # endif … … 1008 1010 : "=&r" (u32Spill), 1009 1011 "=&r" (rcSpill), 1010 "=&r" (fXchg )1012 "=&r" (fXchg.u) 1011 1013 : "r" (u32Old), 1012 1014 "r" (u32New), … … 1015 1017 : "memory", 1016 1018 "cc"); 1017 return (bool)fXchg; 1019 return fXchg.f; 1020 1018 1021 # else 1019 1022 # error "Port me" 1020 # endif /* RT_ARCH_ARM */1023 # endif 1021 1024 } 1022 1025 #endif … … 1053 1056 * @remarks x86: Requires a Pentium or later. 1054 1057 */ 1055 #if (RT_INLINE_ASM_EXTERNAL && !RT_INLINE_ASM_USES_INTRIN) \1058 #if (RT_INLINE_ASM_EXTERNAL_TMP_ARM && !RT_INLINE_ASM_USES_INTRIN) \ 1056 1059 || RT_INLINE_DONT_MIX_CMPXCHG8B_AND_PIC 1057 1060 RT_ASM_DECL_PRAGMA_WATCOM(bool) ASMAtomicCmpXchgU64(volatile uint64_t RT_FAR *pu64, const uint64_t u64New, const uint64_t u64Old) RT_NOTHROW_PROTO; … … 1087 1090 return fRet; 1088 1091 # endif 1089 # else /* !RT_ARCH_AMD64 */ 1092 1093 # elif defined(RT_ARCH_X86) 1090 1094 uint32_t u32Ret; 1091 1095 # if RT_INLINE_ASM_GNU_STYLE … … 1137 1141 return !!u32Ret; 1138 1142 # 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 1140 1181 } 1141 1182 #endif … … 1281 1322 * @remarks x86: Requires a 486 or later. 1282 1323 */ 1283 #if RT_INLINE_ASM_EXTERNAL && !RT_INLINE_ASM_USES_INTRIN1324 #if RT_INLINE_ASM_EXTERNAL_TMP_ARM && !RT_INLINE_ASM_USES_INTRIN 1284 1325 RT_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; 1285 1326 #else 1286 1327 DECLINLINE(bool) ASMAtomicCmpXchgExU32(volatile uint32_t RT_FAR *pu32, const uint32_t u32New, const uint32_t u32Old, uint32_t RT_FAR *pu32Old) RT_NOTHROW_DEF 1287 1328 { 1288 # if RT_INLINE_ASM_GNU_STYLE 1329 # if defined(RT_ARCH_AMD64) || defined(RT_ARCH_X86) 1330 # if RT_INLINE_ASM_GNU_STYLE 1289 1331 uint8_t u8Ret; 1290 1332 __asm__ __volatile__("lock; cmpxchgl %3, %0\n\t" … … 1298 1340 return (bool)u8Ret; 1299 1341 1300 # elif RT_INLINE_ASM_USES_INTRIN1301 return (*pu32Old = _InterlockedCompareExchange((long RT_FAR *)pu32, u32New, u32Old)) == u32Old;1302 1303 # else1342 # elif RT_INLINE_ASM_USES_INTRIN 1343 return (*pu32Old = _InterlockedCompareExchange((long RT_FAR *)pu32, u32New, u32Old)) == u32Old; 1344 1345 # else 1304 1346 uint32_t u32Ret; 1305 1347 __asm 1306 1348 { 1307 # ifdef RT_ARCH_AMD641349 # ifdef RT_ARCH_AMD64 1308 1350 mov rdx, [pu32] 1309 # else1351 # else 1310 1352 mov edx, [pu32] 1311 # endif1353 # endif 1312 1354 mov eax, [u32Old] 1313 1355 mov ecx, [u32New] 1314 # ifdef RT_ARCH_AMD641356 # ifdef RT_ARCH_AMD64 1315 1357 lock cmpxchg [rdx], ecx 1316 1358 mov rdx, [pu32Old] 1317 1359 mov [rdx], eax 1318 # else1360 # else 1319 1361 lock cmpxchg [edx], ecx 1320 1362 mov edx, [pu32Old] 1321 1363 mov [edx], eax 1322 # endif1364 # endif 1323 1365 setz al 1324 1366 movzx eax, al … … 1326 1368 } 1327 1369 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" 1328 1408 # endif 1329 1409 } … … 1365 1445 * @remarks x86: Requires a Pentium or later. 1366 1446 */ 1367 #if (RT_INLINE_ASM_EXTERNAL && !RT_INLINE_ASM_USES_INTRIN) \1447 #if (RT_INLINE_ASM_EXTERNAL_TMP_ARM && !RT_INLINE_ASM_USES_INTRIN) \ 1368 1448 || RT_INLINE_DONT_MIX_CMPXCHG8B_AND_PIC 1369 1449 RT_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; … … 1401 1481 return fRet; 1402 1482 # endif 1403 # else /* !RT_ARCH_AMD64 */ 1483 1484 # elif defined(RT_ARCH_X86) 1404 1485 # if RT_INLINE_ASM_GNU_STYLE 1405 1486 uint64_t u64Ret; … … 1449 1530 return !!u32Ret; 1450 1531 # 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 1452 1571 } 1453 1572 #endif … … 1594 1713 * Virtualization unfriendly serializing instruction, always exits. 1595 1714 */ 1596 #if RT_INLINE_ASM_EXTERNAL && !RT_INLINE_ASM_USES_INTRIN1715 #if (RT_INLINE_ASM_EXTERNAL && !RT_INLINE_ASM_USES_INTRIN) || (!defined(RT_ARCH_AMD64) && !defined(RT_ARCH_X86)) 1597 1716 RT_ASM_DECL_PRAGMA_WATCOM(void) ASMSerializeInstructionCpuId(void) RT_NOTHROW_PROTO; 1598 1717 #else … … 1640 1759 * Virtualization friendly serializing instruction, though more expensive. 1641 1760 */ 1642 #if RT_INLINE_ASM_EXTERNAL 1761 #if RT_INLINE_ASM_EXTERNAL || (!defined(RT_ARCH_AMD64) && !defined(RT_ARCH_X86)) 1643 1762 RT_ASM_DECL_PRAGMA_WATCOM(void) ASMSerializeInstructionIRet(void) RT_NOTHROW_PROTO; 1644 1763 #else … … 1685 1804 * Virtualization friendlier serializing instruction, may still cause exits. 1686 1805 */ 1687 #if RT_INLINE_ASM_EXTERNAL && RT_INLINE_ASM_USES_INTRIN < 151806 #if (RT_INLINE_ASM_EXTERNAL && RT_INLINE_ASM_USES_INTRIN < 15) || (!defined(RT_ARCH_AMD64) && !defined(RT_ARCH_X86)) 1688 1807 RT_ASM_DECL_PRAGMA_WATCOM(void) ASMSerializeInstructionRdTscp(void) RT_NOTHROW_PROTO; 1689 1808 #else … … 1729 1848 { 1730 1849 /* Note! Only armv7 and later. */ 1731 __asm__ __volatile__ ("dsb \n\t" ::: "memory");1850 __asm__ __volatile__ ("dsb sy\n\t" ::: "memory"); 1732 1851 } 1733 1852 #else … … 1756 1875 #elif defined(RT_ARCH_ARM64) || defined(RT_ARCH_ARM32) 1757 1876 /* Note! Only armv7 and later. */ 1758 __asm__ __volatile__ ("dsb sy\n\t" );1877 __asm__ __volatile__ ("dsb sy\n\t" ::: "memory"); 1759 1878 #elif ARCH_BITS == 16 1760 1879 uint16_t volatile u16; … … 1787 1906 #elif defined(RT_ARCH_ARM64) || defined(RT_ARCH_ARM32) 1788 1907 /* Note! Only armv7 and later. */ 1789 __asm__ __volatile__ ("dmb sy\n\t" );1908 __asm__ __volatile__ ("dmb sy\n\t" ::: "memory"); 1790 1909 #else 1791 1910 ASMMemoryFence(); … … 1814 1933 #elif defined(RT_ARCH_ARM64) || defined(RT_ARCH_ARM32) 1815 1934 /* Note! Only armv7 and later. */ 1816 __asm__ __volatile__ ("dmb sy\n\t" );1935 __asm__ __volatile__ ("dmb sy\n\t"; 1817 1936 #else 1818 1937 ASMMemoryFence();
Note:
See TracChangeset
for help on using the changeset viewer.