VirtualBox

Ignore:
Timestamp:
Feb 18, 2022 11:14:59 AM (3 years ago)
Author:
vboxsync
Message:

iprt/asm.h: Added ASMAtomicCmpXchgU128 and friends for AMD64 and ARM64, implemented ASMAtomicCmpWriteU128 et al for ARM64. bugref:9898

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Runtime/testcase/tstRTInlineAsm.cpp

    r93755 r93837  
    15491549                                                                     u128B = RTUINT128_INIT_C(0x80040008008efd, 0x40080004004def)),
    15501550                           true, 0xfff40ff8f08ef3, 0x4ee8ee04cc4de4);
     1551
     1552    /* Make sure the v2 version works too (arm) */
     1553    CHECK_OP_AND_VAL_128_C(bool, "%d", pu128, ASMAtomicCmpWriteU128v2(&pu128->u,
     1554                                                                      UINT64_C(0x95487930069587), UINT64_C(0x89958490385964),
     1555                                                                      UINT64_C(0xfff40ff8f08ef3), UINT64_C(0x4ee8ee04cc4de4)),
     1556                           true, 0x95487930069587, 0x89958490385964);
     1557    CHECK_OP_AND_VAL_128_C(bool, "%d", pu128, ASMAtomicCmpWriteU128v2(&pu128->u,
     1558                                                                      UINT64_C(0x99969404869434), UINT64_C(0x11049309994567),
     1559                                                                      UINT64_C(0x33f40ff8f08eff), UINT64_C(0x99e8ee04cc4dee)),
     1560                           false, 0x95487930069587, 0x89958490385964);
    15511561}
    15521562#endif /* RTASM_HAVE_CMP_WRITE_U128 */
     
    16981708}
    16991709
     1710DECLINLINE(void) tstASMAtomicCmpXchgU128Worker(RTUINT128U volatile *pu128)
     1711{
     1712    pu128->s.Lo = UINT64_C(0xffffffffffffff);
     1713    pu128->s.Hi = UINT64_C(0xffffffffffffff);
     1714
     1715    RTUINT128U u128A, u128B;
     1716    RTUINT128U const u128OldInit = RTUINT128_INIT_C(0x4242424242424242, 0x2222222222222222);
     1717    RTUINT128U       u128Old     = u128OldInit;
     1718    CHECK_OP_AND_VAL_128_C(bool, "%d", pu128, ASMAtomicCmpXchgU128U(pu128,
     1719                                                                    u128A = RTUINT128_INIT_C(0, 0),
     1720                                                                    u128B = RTUINT128_INIT_C(0, 0),
     1721                                                                    &u128Old),
     1722                           false, 0xffffffffffffff, 0xffffffffffffff);
     1723    CHECKVAL128_C(&u128Old, 0xffffffffffffff, 0xffffffffffffff);
     1724
     1725    u128Old = u128OldInit;
     1726    CHECK_OP_AND_VAL_128_C(bool, "%d", pu128, ASMAtomicCmpXchgU128U(pu128,
     1727                                                                    u128A = RTUINT128_INIT_C(0, 0),
     1728                                                                    u128B = RTUINT128_INIT_C(0xffffffffffffff, 0xffffffffffffff),
     1729                                                                    &u128Old),
     1730                           true, 0, 0);
     1731    CHECKVAL128_C(&u128Old, 0xffffffffffffff, 0xffffffffffffff);
     1732
     1733    u128Old = u128OldInit;
     1734    CHECK_OP_AND_VAL_128_C(bool, "%d", pu128, ASMAtomicCmpXchgU128U(pu128,
     1735                                                                    u128A = RTUINT128_INIT_C(0x80040008008efd, 0x40080004004def),
     1736                                                                    u128B = RTUINT128_INIT_C(0, 1),
     1737                                                                    &u128Old),
     1738                           false, 0, 0);
     1739    CHECKVAL128_C(&u128Old, 0, 0);
     1740
     1741    u128Old = u128OldInit;
     1742    CHECK_OP_AND_VAL_128_C(bool, "%d", pu128, ASMAtomicCmpXchgU128U(pu128,
     1743                                                                    u128A = RTUINT128_INIT_C(0x80040008008efd, 0x40080004004def),
     1744                                                                    u128B = RTUINT128_INIT_C(1, 0),
     1745                                                                    &u128Old),
     1746                           false, 0, 0);
     1747    CHECKVAL128_C(&u128Old, 0, 0);
     1748
     1749    u128Old = u128OldInit;
     1750    CHECK_OP_AND_VAL_128_C(bool, "%d", pu128, ASMAtomicCmpXchgU128U(pu128,
     1751                                                                    u128A = RTUINT128_INIT_C(0x80040008008efd, 0x40080004004def),
     1752                                                                    u128B = RTUINT128_INIT_C(0, 0),
     1753                                                                    &u128Old),
     1754                           true, 0x80040008008efd, 0x40080004004def);
     1755    CHECKVAL128_C(&u128Old, 0, 0);
     1756
     1757    u128Old = u128OldInit;
     1758    CHECK_OP_AND_VAL_128_C(bool, "%d", pu128, ASMAtomicCmpXchgU128U(pu128,
     1759                                                                    u128A = RTUINT128_INIT_C(0xfff40ff8f08ef3, 0x4ee8ee04cc4de4),
     1760                                                                    u128B = RTUINT128_INIT_C(0x80040008008efd, 0),
     1761                                                                    &u128Old),
     1762                           false, 0x80040008008efd, 0x40080004004def);
     1763    CHECKVAL128_C(&u128Old, 0x80040008008efd, 0x40080004004def);
     1764
     1765    u128Old = u128OldInit;
     1766    CHECK_OP_AND_VAL_128_C(bool, "%d", pu128, ASMAtomicCmpXchgU128U(pu128,
     1767                                                                    u128A = RTUINT128_INIT_C(0xfff40ff8f08ef3, 0x4ee8ee04cc4de4),
     1768                                                                    u128B = RTUINT128_INIT_C(0, 0x40080004004def),
     1769                                                                    &u128Old),
     1770                           false, 0x80040008008efd, 0x40080004004def);
     1771    CHECKVAL128_C(&u128Old, 0x80040008008efd, 0x40080004004def);
     1772
     1773    u128Old = u128OldInit;
     1774    CHECK_OP_AND_VAL_128_C(bool, "%d", pu128, ASMAtomicCmpXchgU128U(pu128,
     1775                                                                    u128A = RTUINT128_INIT_C(0xfff40ff8f08ef3, 0x4ee8ee04cc4de4),
     1776                                                                    u128B = RTUINT128_INIT_C(0x80040008008efd, 0x40080004004def),
     1777                                                                    &u128Old),
     1778                           true, 0xfff40ff8f08ef3, 0x4ee8ee04cc4de4);
     1779    CHECKVAL128_C(&u128Old, 0x80040008008efd, 0x40080004004def);
     1780
     1781    /* Make sure the v2 version works too (arm) */
     1782    u128Old = u128OldInit;
     1783    CHECK_OP_AND_VAL_128_C(bool, "%d", pu128, ASMAtomicCmpXchgU128v2(&pu128->u,
     1784                                                                     UINT64_C(0x78039485960543), UINT64_C(0x97058437294586),
     1785                                                                     UINT64_C(0xfff40ff8f08ef3), UINT64_C(0x4ee8ee04cc4de4),
     1786                                                                     &u128Old.u),
     1787                           true, 0x78039485960543, 0x97058437294586);
     1788    CHECKVAL128_C(&u128Old, 0xfff40ff8f08ef3, 0x4ee8ee04cc4de4);
     1789
     1790    u128Old = u128OldInit;
     1791    CHECK_OP_AND_VAL_128_C(bool, "%d", pu128, ASMAtomicCmpXchgU128v2(&pu128->u,
     1792                                                                     UINT64_C(0x13495874560495), UINT64_C(0x12304896098597),
     1793                                                                     UINT64_C(0xfff40ff8f08ef3), UINT64_C(0x4ee8ee04cc4de4),
     1794                                                                     &u128Old.u),
     1795                           false, 0x78039485960543, 0x97058437294586);
     1796    CHECKVAL128_C(&u128Old, 0x78039485960543, 0x97058437294586);
     1797}
     1798
    17001799
    17011800static void tstASMAtomicCmpXchgEx(void)
     
    17051804    DO_SIMPLE_TEST(ASMAtomicCmpXchgExU32, uint32_t);
    17061805    DO_SIMPLE_TEST(ASMAtomicCmpXchgExU64, uint64_t);
     1806#ifdef RTASM_HAVE_CMP_XCHG_U128
     1807# ifdef RT_ARCH_AMD64
     1808    if (ASMCpuId_ECX(1) & X86_CPUID_FEATURE_ECX_CX16)
     1809# endif
     1810    {
     1811        RTTestISub("ASMAtomicCmpXchgU128");
     1812        DO_SIMPLE_TEST_NO_SUB_NO_STACK(tstASMAtomicCmpXchgU128Worker, RTUINT128U);
     1813    }
     1814#endif
    17071815}
    17081816
     
    28012909    static uint64_t volatile s_u64;
    28022910    static int64_t  volatile s_i64;
     2911#if defined(RTASM_HAVE_CMP_WRITE_U128) || defined(RTASM_HAVE_CMP_XCHG_U128)
     2912    static RTUINT128U volatile s_u128;
     2913#endif
    28032914    static uint8_t  s_u8Old;
    28042915    static int8_t   s_i8Old;
     
    28092920    static uint64_t s_u64Old;
    28102921    static int64_t  s_i64Old;
     2922#if defined(RTASM_HAVE_CMP_WRITE_U128) || defined(RTASM_HAVE_CMP_XCHG_U128)
     2923    static RTUINT128U s_u128Old;
     2924    RTUINT128U u128Tmp1, u128Tmp2;
     2925# ifdef RT_ARCH_AMD64
     2926    bool const fHaveCmpXchg128 = RT_BOOL(ASMCpuId_ECX(1) & X86_CPUID_FEATURE_ECX_CX16);
     2927# else
     2928    bool const fHaveCmpXchg128 = true;
     2929# endif
     2930#endif
    28112931    unsigned i;
    28122932    const unsigned cRounds = _16M;       /* Must be multiple of 8 */
     
    29173037    BENCH(ASMAtomicCmpXchgU64(&s_u64, 0, 0),     "ASMAtomicCmpXchgU64");
    29183038    BENCH(ASMAtomicCmpXchgS64(&s_i64, 0, 0),     "ASMAtomicCmpXchgS64");
     3039#ifdef RTASM_HAVE_CMP_WRITE_U128
     3040    if (fHaveCmpXchg128)
     3041        BENCH(ASMAtomicCmpWriteU128U(&s_u128, u128Tmp1 = RTUINT128_INIT_C(0, 0), u128Tmp2 = RTUINT128_INIT_C(0, 0)),
     3042              "ASMAtomicCmpWriteU128U");
     3043#endif
    29193044    BENCH(ASMAtomicCmpXchgU8(&s_u8, 0, 1),       "ASMAtomicCmpXchgU8/neg");
    29203045    BENCH(ASMAtomicCmpXchgS8(&s_i8, 0, 1),       "ASMAtomicCmpXchgS8/neg");
     
    29253050    BENCH(ASMAtomicCmpXchgU64(&s_u64, 0, 1),     "ASMAtomicCmpXchgU64/neg");
    29263051    BENCH(ASMAtomicCmpXchgS64(&s_i64, 0, 1),     "ASMAtomicCmpXchgS64/neg");
     3052#ifdef RTASM_HAVE_CMP_WRITE_U128
     3053    if (fHaveCmpXchg128)
     3054        BENCH(ASMAtomicCmpWriteU128U(&s_u128, u128Tmp1 = RTUINT128_INIT_C(0, 0), u128Tmp2 = RTUINT128_INIT_C(0, 1)),
     3055              "ASMAtomicCmpWriteU128U/neg");
     3056#endif
    29273057    BENCH(ASMAtomicCmpXchgExU8(&s_u8, 0, 0, &s_u8Old),    "ASMAtomicCmpXchgExU8");
    29283058    BENCH(ASMAtomicCmpXchgExS8(&s_i8, 0, 0, &s_i8Old),    "ASMAtomicCmpXchgExS8");
     
    29333063    BENCH(ASMAtomicCmpXchgExU64(&s_u64, 0, 0, &s_u64Old), "ASMAtomicCmpXchgExU64");
    29343064    BENCH(ASMAtomicCmpXchgExS64(&s_i64, 0, 0, &s_i64Old), "ASMAtomicCmpXchgExS64");
     3065#ifdef RTASM_HAVE_CMP_XCHG_U128
     3066    if (fHaveCmpXchg128)
     3067        BENCH(ASMAtomicCmpXchgU128U(&s_u128, u128Tmp1 = RTUINT128_INIT_C(0, 0), u128Tmp2 = RTUINT128_INIT_C(0, 0), &s_u128Old),
     3068              "ASMAtomicCmpXchgU128U");
     3069#endif
    29353070    BENCH(ASMAtomicCmpXchgExU8(&s_u8, 0, 1, &s_u8Old),    "ASMAtomicCmpXchgExU8/neg");
    29363071    BENCH(ASMAtomicCmpXchgExS8(&s_i8, 0, 1, &s_i8Old),    "ASMAtomicCmpXchgExS8/neg");
     
    29413076    BENCH(ASMAtomicCmpXchgExU64(&s_u64, 0, 1, &s_u64Old), "ASMAtomicCmpXchgExU64/neg");
    29423077    BENCH(ASMAtomicCmpXchgExS64(&s_i64, 0, 1, &s_i64Old), "ASMAtomicCmpXchgExS64/neg");
     3078#ifdef RTASM_HAVE_CMP_XCHG_U128
     3079    if (fHaveCmpXchg128)
     3080        BENCH(ASMAtomicCmpXchgU128U(&s_u128, u128Tmp1 = RTUINT128_INIT_C(0, 0), u128Tmp2 = RTUINT128_INIT_C(0, 1), &s_u128Old),
     3081              "ASMAtomicCmpXchgU128U/neg");
     3082#endif
    29433083    BENCH(ASMAtomicIncU32(&s_u32),               "ASMAtomicIncU32");
    29443084    BENCH(ASMAtomicIncS32(&s_i32),               "ASMAtomicIncS32");
Note: See TracChangeset for help on using the changeset viewer.

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