VirtualBox

Changeset 95071 in vbox


Ignore:
Timestamp:
May 24, 2022 11:06:24 AM (3 years ago)
Author:
vboxsync
Message:

IPRT/asm: Added ASMCountLeadingZerosU16/32/64 & ASMCountTrailingZerosU16/32/64. bugref:9898

Location:
trunk
Files:
2 edited

Legend:

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

    r94054 r95071  
    75637563
    75647564/**
     7565 * Count the number of leading zero bits in the given 32-bit integer.
     7566 *
     7567 * The counting starts with the most significate bit.
     7568 *
     7569 * @returns Number of most significant zero bits.
     7570 * @returns 32 if all bits are cleared.
     7571 * @param   u32     Integer to consider.
     7572 * @remarks Similar to __builtin_clz() in gcc, except defined zero input result.
     7573 */
     7574#if RT_INLINE_ASM_EXTERNAL_TMP_ARM && !RT_INLINE_ASM_USES_INTRIN
     7575RT_ASM_DECL_PRAGMA_WATCOM_386(unsigned) ASMCountLeadingZerosU32(uint32_t u32) RT_NOTHROW_PROTO;
     7576#else
     7577DECLINLINE(unsigned) ASMCountLeadingZerosU32(uint32_t u32) RT_NOTHROW_DEF
     7578{
     7579# if RT_INLINE_ASM_USES_INTRIN
     7580    unsigned long iBit;
     7581    if (!_BitScanReverse(&iBit, u32))
     7582        return 32;
     7583    return 31 - (unsigned)iBit;
     7584
     7585# elif defined(RT_ARCH_AMD64) || defined(RT_ARCH_X86)
     7586    uint32_t iBit;
     7587#  if RT_INLINE_ASM_GNU_STYLE && defined(RT_ARCH_AMD64) && 0 /* significantly slower on 10980xe; 929 vs 237 ps/call */
     7588    __asm__ __volatile__("bsrl   %1, %0\n\t"
     7589                         "cmovzl %2, %0\n\t"
     7590                         : "=&r" (iBit)
     7591                         : "rm" (u32)
     7592                         , "rm" ((int32_t)-1)
     7593                         : "cc");
     7594#  elif RT_INLINE_ASM_GNU_STYLE
     7595    __asm__ __volatile__("bsr  %1, %0\n\t"
     7596                         "jnz  1f\n\t"
     7597                         "mov  $-1, %0\n\t"
     7598                         "1:\n\t"
     7599                         : "=r" (iBit)
     7600                         : "rm" (u32)
     7601                         : "cc");
     7602#  else
     7603    _asm
     7604    {
     7605        bsr     eax, [u32]
     7606        jnz     found
     7607        mov     eax, -1
     7608    found:
     7609        mov     [iBit], eax
     7610    }
     7611#  endif
     7612    return 31 - iBit;
     7613
     7614# elif defined(RT_ARCH_ARM64) || defined(RT_ARCH_ARM32)
     7615    uint32_t iBit;
     7616    __asm__ __volatile__(
     7617#  if defined(RT_ARCH_ARM64)
     7618                         "clz  %w[iBit], %w[uVal]\n\t"
     7619#  else
     7620                         "clz  %[iBit], %[uVal]\n\t"
     7621#  endif
     7622                         : [uVal] "=r" (u32)
     7623                         , [iBit] "=r" (iBit)
     7624                         : "[uVal]" (u32));
     7625    return iBit;
     7626
     7627# elif defined(__GNUC__)
     7628    AssertCompile(sizeof(u32) == sizeof(unsigned int));
     7629    return u32 ? __builtin_clz(u32) : 32;
     7630
     7631# else
     7632#  error "Port me"
     7633# endif
     7634    return iBit;
     7635}
     7636#endif
     7637
     7638
     7639/**
     7640 * Count the number of leading zero bits in the given 64-bit integer.
     7641 *
     7642 * The counting starts with the most significate bit.
     7643 *
     7644 * @returns Number of most significant zero bits.
     7645 * @returns 64 if all bits are cleared.
     7646 * @param   u64     Integer to consider.
     7647 * @remarks Similar to __builtin_clzl() in gcc, except defined zero input
     7648 *          result.
     7649 */
     7650#if RT_INLINE_ASM_EXTERNAL_TMP_ARM && !RT_INLINE_ASM_USES_INTRIN
     7651RT_ASM_DECL_PRAGMA_WATCOM_386(unsigned) ASMCountLeadingZerosU64(uint64_t u64) RT_NOTHROW_PROTO;
     7652#else
     7653DECLINLINE(unsigned) ASMCountLeadingZerosU64(uint64_t u64) RT_NOTHROW_DEF
     7654{
     7655# if RT_INLINE_ASM_USES_INTRIN
     7656    unsigned long iBit;
     7657#  if ARCH_BITS == 64
     7658    if (_BitScanReverse64(&iBit, u64))
     7659        return 63 - (unsigned)iBit;
     7660#  else
     7661    if (_BitScanReverse(&iBit, (uint32_t)(u64 >> 32)))
     7662        return 31 - (unsigned)iBit;
     7663    if (_BitScanReverse(&iBit, (uint32_t)u64))
     7664        return 63 - (unsigned)iBit;
     7665#  endif
     7666    return 64;
     7667
     7668# elif RT_INLINE_ASM_GNU_STYLE && defined(RT_ARCH_AMD64)
     7669    uint64_t iBit;
     7670#  if 0 /* 10980xe benchmark: 932 ps/call - the slower variant */
     7671    __asm__ __volatile__("bsrq   %1, %0\n\t"
     7672                         "cmovzq %2, %0\n\t"
     7673                         : "=&r" (iBit)
     7674                         : "rm" (u64)
     7675                         , "rm" ((int64_t)-1)
     7676                         : "cc");
     7677#  else /* 10980xe benchmark: 262 ps/call */
     7678    __asm__ __volatile__("bsrq   %1, %0\n\t"
     7679                         "jnz    1f\n\t"
     7680                         "mov    $-1, %0\n\t"
     7681                         "1:\n\t"
     7682                         : "=&r" (iBit)
     7683                         : "rm" (u64)
     7684                         : "cc");
     7685#  endif
     7686    return 63 - (unsigned)iBit;
     7687
     7688# elif defined(RT_ARCH_ARM64)
     7689    uint64_t iBit;
     7690    __asm__ __volatile__("clz  %[iBit], %[uVal]\n\t"
     7691                         : [uVal] "=r" (u64)
     7692                         , [iBit] "=r" (iBit)
     7693                         : "[uVal]" (u64));
     7694    return (unsigned)iBit;
     7695
     7696# elif defined(__GNUC__) && ARCH_BITS == 64
     7697    AssertCompile(sizeof(u64) == sizeof(unsigned long));
     7698    return u64 ? __builtin_clzl(u64) : 64;
     7699
     7700# else
     7701    unsigned iBit = ASMCountLeadingZerosU32((uint32_t)(u64 >> 32));
     7702    if (iBit == 32)
     7703        iBit = ASMCountLeadingZerosU32((uint32_t)u64) + 32;
     7704    return iBit;
     7705# endif
     7706}
     7707#endif
     7708
     7709
     7710/**
     7711 * Count the number of leading zero bits in the given 16-bit integer.
     7712 *
     7713 * The counting starts with the most significate bit.
     7714 *
     7715 * @returns Number of most significant zero bits.
     7716 * @returns 16 if all bits are cleared.
     7717 * @param   u16     Integer to consider.
     7718 */
     7719#if RT_INLINE_ASM_EXTERNAL_TMP_ARM && !RT_INLINE_ASM_USES_INTRIN
     7720RT_ASM_DECL_PRAGMA_WATCOM_386(unsigned) ASMCountLeadingZerosU16(uint16_t u16) RT_NOTHROW_PROTO;
     7721#else
     7722DECLINLINE(unsigned) ASMCountLeadingZerosU16(uint16_t u16) RT_NOTHROW_DEF
     7723{
     7724# if RT_INLINE_ASM_GNU_STYLE && (defined(RT_ARCH_X86) || defined(RT_ARCH_AMD64)) && 0 /* slower (10980xe: 987 vs 292 ps/call) */
     7725    uint16_t iBit;
     7726    __asm__ __volatile__("bsrw %1, %0\n\t"
     7727                         "jnz  1f\n\t"
     7728                         "mov  $-1, %0\n\t"
     7729                         "1:\n\t"
     7730                         : "=r" (iBit)
     7731                         : "rm" (u16)
     7732                         : "cc");
     7733    return 15 - (int16_t)iBit;
     7734# else
     7735    return ASMCountLeadingZerosU32((uint32_t)u16) - 16;
     7736# endif
     7737}
     7738#endif
     7739
     7740
     7741/**
     7742 * Count the number of trailing zero bits in the given 32-bit integer.
     7743 *
     7744 * The counting starts with the least significate bit, i.e. the zero bit.
     7745 *
     7746 * @returns Number of lest significant zero bits.
     7747 * @returns 32 if all bits are cleared.
     7748 * @param   u32     Integer to consider.
     7749 * @remarks Similar to __builtin_ctz() in gcc, except defined zero input result.
     7750 */
     7751#if RT_INLINE_ASM_EXTERNAL_TMP_ARM && !RT_INLINE_ASM_USES_INTRIN
     7752RT_ASM_DECL_PRAGMA_WATCOM_386(unsigned) ASMCountTrailingZerosU32(uint32_t u32) RT_NOTHROW_PROTO;
     7753#else
     7754DECLINLINE(unsigned) ASMCountTrailingZerosU32(uint32_t u32) RT_NOTHROW_DEF
     7755{
     7756# if RT_INLINE_ASM_USES_INTRIN
     7757    unsigned long iBit;
     7758    if (!_BitScanForward(&iBit, u32))
     7759        return 32;
     7760    return (unsigned)iBit;
     7761
     7762# elif defined(RT_ARCH_AMD64) || defined(RT_ARCH_X86)
     7763    uint32_t iBit;
     7764#  if RT_INLINE_ASM_GNU_STYLE && defined(RT_ARCH_AMD64) && 0 /* significantly slower on 10980xe; 932 vs 240 ps/call */
     7765    __asm__ __volatile__("bsfl   %1, %0\n\t"
     7766                         "cmovzl %2, %0\n\t"
     7767                         : "=&r" (iBit)
     7768                         : "rm" (u32)
     7769                         , "rm" ((int32_t)32)
     7770                         : "cc");
     7771#  elif RT_INLINE_ASM_GNU_STYLE
     7772    __asm__ __volatile__("bsfl %1, %0\n\t"
     7773                         "jnz  1f\n\t"
     7774                         "mov  $32, %0\n\t"
     7775                         "1:\n\t"
     7776                         : "=r" (iBit)
     7777                         : "rm" (u32)
     7778                         : "cc");
     7779#  else
     7780    _asm
     7781    {
     7782        bsf     eax, [u32]
     7783        jnz     found
     7784        mov     eax, 32
     7785    found:
     7786        mov     [iBit], eax
     7787    }
     7788#  endif
     7789    return iBit;
     7790
     7791# elif defined(RT_ARCH_ARM64) || defined(RT_ARCH_ARM32)
     7792    /* Invert the bits and use clz. */
     7793    uint32_t iBit;
     7794    __asm__ __volatile__(
     7795#  if defined(RT_ARCH_ARM64)
     7796                         "rbit %w[uVal], %w[uVal]\n\t"
     7797                         "clz  %w[iBit], %w[uVal]\n\t"
     7798#  else
     7799                         "rbit %[uVal], %[uVal]\n\t"
     7800                         "clz  %[iBit], %[uVal]\n\t"
     7801#  endif
     7802                         : [uVal] "=r" (u32)
     7803                         , [iBit] "=r" (iBit)
     7804                         : "[uVal]" (u32));
     7805    return iBit;
     7806
     7807# elif defined(__GNUC__)
     7808    AssertCompile(sizeof(u32) == sizeof(unsigned int));
     7809    return u32 ? __builtin_ctz(u32) : 32;
     7810
     7811# else
     7812#  error "Port me"
     7813# endif
     7814    return iBit;
     7815}
     7816#endif
     7817
     7818
     7819/**
     7820 * Count the number of trailing zero bits in the given 64-bit integer.
     7821 *
     7822 * The counting starts with the least significate bit.
     7823 *
     7824 * @returns Number of least significant zero bits.
     7825 * @returns 64 if all bits are cleared.
     7826 * @param   u64     Integer to consider.
     7827 * @remarks Similar to __builtin_ctzl() in gcc, except defined zero input
     7828 *          result.
     7829 */
     7830#if RT_INLINE_ASM_EXTERNAL_TMP_ARM && !RT_INLINE_ASM_USES_INTRIN
     7831RT_ASM_DECL_PRAGMA_WATCOM_386(unsigned) ASMCountTrailingZerosU64(uint64_t u64) RT_NOTHROW_PROTO;
     7832#else
     7833DECLINLINE(unsigned) ASMCountTrailingZerosU64(uint64_t u64) RT_NOTHROW_DEF
     7834{
     7835# if RT_INLINE_ASM_USES_INTRIN
     7836    unsigned long iBit;
     7837#  if ARCH_BITS == 64
     7838    if (_BitScanForward64(&iBit, u64))
     7839        return (unsigned)iBit;
     7840#  else
     7841    if (_BitScanForward(&iBit, (uint32_t)u64))
     7842        return (unsigned)iBit;
     7843    if (_BitScanForward(&iBit, (uint32_t)(u64 >> 32)))
     7844        return (unsigned)iBit + 32;
     7845#  endif
     7846    return 64;
     7847
     7848# elif RT_INLINE_ASM_GNU_STYLE && defined(RT_ARCH_AMD64)
     7849    uint64_t iBit;
     7850#  if 0 /* 10980xe benchmark: 932 ps/call - the slower variant */
     7851    __asm__ __volatile__("bsfq   %1, %0\n\t"
     7852                         "cmovzq %2, %0\n\t"
     7853                         : "=&r" (iBit)
     7854                         : "rm" (u64)
     7855                         , "rm" ((int64_t)64)
     7856                         : "cc");
     7857#  else /* 10980xe benchmark: 262 ps/call */
     7858    __asm__ __volatile__("bsfq   %1, %0\n\t"
     7859                         "jnz    1f\n\t"
     7860                         "mov    $64, %0\n\t"
     7861                         "1:\n\t"
     7862                         : "=&r" (iBit)
     7863                         : "rm" (u64)
     7864                         : "cc");
     7865#  endif
     7866    return (unsigned)iBit;
     7867
     7868# elif defined(RT_ARCH_ARM64)
     7869    /* Invert the bits and use clz. */
     7870    uint64_t iBit;
     7871    __asm__ __volatile__("rbit %[uVal], %[uVal]\n\t"
     7872                         "clz  %[iBit], %[uVal]\n\t"
     7873                         : [uVal] "=r" (u64)
     7874                         , [iBit] "=r" (iBit)
     7875                         : "[uVal]" (u64));
     7876    return (unsigned)iBit;
     7877
     7878# elif defined(__GNUC__) && ARCH_BITS == 64
     7879    AssertCompile(sizeof(u64) == sizeof(unsigned long));
     7880    return u64 ? __builtin_ctzl(u64) : 64;
     7881
     7882# else
     7883    unsigned iBit = ASMCountTrailingZerosU32((uint32_t)u64);
     7884    if (iBit == 32)
     7885        iBit = ASMCountTrailingZerosU32((uint32_t)(u64 >> 32)) + 32;
     7886    return iBit;
     7887# endif
     7888}
     7889#endif
     7890
     7891
     7892/**
     7893 * Count the number of trailing zero bits in the given 16-bit integer.
     7894 *
     7895 * The counting starts with the most significate bit.
     7896 *
     7897 * @returns Number of most significant zero bits.
     7898 * @returns 16 if all bits are cleared.
     7899 * @param   u16     Integer to consider.
     7900 */
     7901#if RT_INLINE_ASM_EXTERNAL_TMP_ARM && !RT_INLINE_ASM_USES_INTRIN
     7902RT_ASM_DECL_PRAGMA_WATCOM_386(unsigned) ASMCountTrailingZerosU16(uint16_t u16) RT_NOTHROW_PROTO;
     7903#else
     7904DECLINLINE(unsigned) ASMCountTrailingZerosU16(uint16_t u16) RT_NOTHROW_DEF
     7905{
     7906# if RT_INLINE_ASM_GNU_STYLE && (defined(RT_ARCH_X86) || defined(RT_ARCH_AMD64)) && 0 /* slower (10980xe: 992 vs 349 ps/call) */
     7907    uint16_t iBit;
     7908    __asm__ __volatile__("bsfw %1, %0\n\t"
     7909                         "jnz  1f\n\t"
     7910                         "mov  $16, %0\n\t"
     7911                         "1:\n\t"
     7912                         : "=r" (iBit)
     7913                         : "rm" (u16)
     7914                         : "cc");
     7915    return iBit;
     7916# else
     7917    return ASMCountTrailingZerosU32((uint32_t)u16 | UINT32_C(0x10000));
     7918#endif
     7919}
     7920#endif
     7921
     7922
     7923/**
    75657924 * Rotate 32-bit unsigned value to the left by @a cShift.
    75667925 *
  • trunk/src/VBox/Runtime/testcase/tstRTInlineAsm.cpp

    r93838 r95071  
    27432743    }
    27442744}
     2745
     2746
     2747void tstASMBit(void)
     2748{
     2749    RTTestSub(g_hTest, "ASMBitFirstSetU16");
     2750    RTTESTI_CHECK(ASMBitFirstSetU16(0x0000) == 0);
     2751    RTTESTI_CHECK(ASMBitFirstSetU16(0x0001) == 1);
     2752    RTTESTI_CHECK(ASMBitFirstSetU16(0x8000) == 16);
     2753    RTTESTI_CHECK(ASMBitFirstSetU16(0x0ef0) == 5);
     2754    for (unsigned iBit = 0; iBit < 16; iBit++)
     2755    {
     2756        RTTESTI_CHECK(ASMBitFirstSetU16((uint16_t)1 << iBit) == iBit + 1);
     2757        RTTESTI_CHECK(ASMBitFirstSetU16(UINT16_MAX  << iBit) == iBit + 1);
     2758    }
     2759
     2760    RTTestSub(g_hTest, "ASMBitFirstSetU32");
     2761    RTTESTI_CHECK(ASMBitFirstSetU32(UINT32_C(0x00000000)) == 0);
     2762    RTTESTI_CHECK(ASMBitFirstSetU32(UINT32_C(0x00000001)) == 1);
     2763    RTTESTI_CHECK(ASMBitFirstSetU32(UINT32_C(0x80000000)) == 32);
     2764    RTTESTI_CHECK(ASMBitFirstSetU32(UINT32_C(0x0efff0f0)) == 5);
     2765    for (unsigned iBit = 0; iBit < 32; iBit++)
     2766    {
     2767        RTTESTI_CHECK(ASMBitFirstSetU32((uint32_t)1 << iBit) == iBit + 1);
     2768        RTTESTI_CHECK(ASMBitFirstSetU32(UINT32_MAX  << iBit) == iBit + 1);
     2769    }
     2770
     2771    RTTestSub(g_hTest, "ASMBitFirstSetU64");
     2772    RTTESTI_CHECK(ASMBitFirstSetU64(UINT64_C(0x0000000000000000)) == 0);
     2773    RTTESTI_CHECK(ASMBitFirstSetU64(UINT64_C(0x0000000000000001)) == 1);
     2774    RTTESTI_CHECK(ASMBitFirstSetU64(UINT64_C(0x8000000000000000)) == 64);
     2775    RTTESTI_CHECK(ASMBitFirstSetU64(UINT64_C(0x0effffff0ffff0f0)) == 5);
     2776    for (unsigned iBit = 0; iBit < 64; iBit++)
     2777    {
     2778        RTTESTI_CHECK(ASMBitFirstSetU64((uint64_t)1 << iBit) == iBit + 1);
     2779        RTTESTI_CHECK(ASMBitFirstSetU64(UINT64_MAX  << iBit) == iBit + 1);
     2780    }
     2781
     2782    RTTestSub(g_hTest, "ASMBitLastSetU16");
     2783    RTTESTI_CHECK(ASMBitLastSetU16(0x0000) == 0);
     2784    RTTESTI_CHECK(ASMBitLastSetU16(0x0001) == 1);
     2785    RTTESTI_CHECK(ASMBitLastSetU16(0x8000) == 16);
     2786    RTTESTI_CHECK(ASMBitLastSetU16(0x0fe0) == 12);
     2787    for (unsigned iBit = 0; iBit < 16; iBit++)
     2788    {
     2789        RTTESTI_CHECK(ASMBitLastSetU16(UINT16_C(0x8000) >> (15 - iBit)) == iBit + 1);
     2790        RTTESTI_CHECK(ASMBitLastSetU16(UINT16_MAX       >> (15 - iBit)) == iBit + 1);
     2791    }
     2792
     2793    RTTestSub(g_hTest, "ASMBitLastSetU32");
     2794    RTTESTI_CHECK(ASMBitLastSetU32(UINT32_C(0x00000000)) == 0);
     2795    RTTESTI_CHECK(ASMBitLastSetU32(UINT32_C(0x00000001)) == 1);
     2796    RTTESTI_CHECK(ASMBitLastSetU32(UINT32_C(0x80000000)) == 32);
     2797    RTTESTI_CHECK(ASMBitLastSetU32(UINT32_C(0x0fffffe0)) == 28);
     2798    for (unsigned iBit = 0; iBit < 32; iBit++)
     2799    {
     2800        RTTESTI_CHECK(ASMBitLastSetU32(UINT32_C(0x80000000) >> (31 - iBit)) == iBit + 1);
     2801        RTTESTI_CHECK(ASMBitLastSetU32(UINT32_MAX           >> (31 - iBit)) == iBit + 1);
     2802    }
     2803
     2804    RTTestSub(g_hTest, "ASMBitLastSetU64");
     2805    RTTESTI_CHECK(ASMBitLastSetU64(UINT64_C(0x0000000000000000)) == 0);
     2806    RTTESTI_CHECK(ASMBitLastSetU64(UINT64_C(0x0000000000000001)) == 1);
     2807    RTTESTI_CHECK(ASMBitLastSetU64(UINT64_C(0x8000000000000000)) == 64);
     2808    RTTESTI_CHECK(ASMBitLastSetU64(UINT64_C(0x0ffffefff0ffffe0)) == 60);
     2809    for (unsigned iBit = 0; iBit < 64; iBit++)
     2810    {
     2811        RTTESTI_CHECK(ASMBitLastSetU64(UINT64_C(0x8000000000000000) >> (63 - iBit)) == iBit + 1);
     2812        RTTESTI_CHECK(ASMBitLastSetU64(UINT64_MAX                   >> (63 - iBit)) == iBit + 1);
     2813    }
     2814
     2815    RTTestSub(g_hTest, "ASMCountLeadingZerosU16");
     2816    RTTESTI_CHECK(ASMCountLeadingZerosU16(0x0000) == 16);
     2817    RTTESTI_CHECK(ASMCountLeadingZerosU16(0x0001) == 15);
     2818    RTTESTI_CHECK(ASMCountLeadingZerosU16(0x8000) == 0);
     2819    RTTESTI_CHECK(ASMCountLeadingZerosU16(0x0fe0) == 4);
     2820    for (unsigned iBit = 0; iBit < 16; iBit++)
     2821    {
     2822        RTTESTI_CHECK(ASMCountLeadingZerosU16(UINT16_C(0x8000) >> iBit) == iBit);
     2823        RTTESTI_CHECK(ASMCountLeadingZerosU16(UINT16_MAX       >> iBit) == iBit);
     2824    }
     2825
     2826    RTTestSub(g_hTest, "ASMCountLeadingZerosU32");
     2827    RTTESTI_CHECK(ASMCountLeadingZerosU32(UINT32_C(0x00000000)) == 32);
     2828    RTTESTI_CHECK(ASMCountLeadingZerosU32(UINT32_C(0x00000001)) == 31);
     2829    RTTESTI_CHECK(ASMCountLeadingZerosU32(UINT32_C(0x80000000)) == 0);
     2830    RTTESTI_CHECK(ASMCountLeadingZerosU32(UINT32_C(0x0fffffe0)) == 4);
     2831    for (unsigned iBit = 0; iBit < 32; iBit++)
     2832    {
     2833        RTTESTI_CHECK(ASMCountLeadingZerosU32(UINT32_C(0x80000000) >> iBit) == iBit);
     2834        RTTESTI_CHECK(ASMCountLeadingZerosU32(UINT32_MAX           >> iBit) == iBit);
     2835    }
     2836
     2837    RTTestSub(g_hTest, "ASMCountLeadingZerosU64");
     2838    RTTESTI_CHECK(ASMCountLeadingZerosU64(UINT64_C(0x0000000000000000)) == 64);
     2839    RTTESTI_CHECK(ASMCountLeadingZerosU64(UINT64_C(0x0000000000000001)) == 63);
     2840    RTTESTI_CHECK(ASMCountLeadingZerosU64(UINT64_C(0x8000000000000000)) == 0);
     2841    RTTESTI_CHECK(ASMCountLeadingZerosU64(UINT64_C(0x0fffffff0f0fffe0)) == 4);
     2842    for (unsigned iBit = 0; iBit < 64; iBit++)
     2843    {
     2844        RTTESTI_CHECK(ASMCountLeadingZerosU64(UINT64_C(0x8000000000000000) >> iBit) == iBit);
     2845        RTTESTI_CHECK(ASMCountLeadingZerosU64(UINT64_MAX                   >> iBit) == iBit);
     2846    }
     2847
     2848    RTTestSub(g_hTest, "ASMCountTrailingZerosU16");
     2849    RTTESTI_CHECK(ASMCountTrailingZerosU16(0x0000) == 16);
     2850    RTTESTI_CHECK(ASMCountTrailingZerosU16(0x0001) == 0);
     2851    RTTESTI_CHECK(ASMCountTrailingZerosU16(0x8000) == 15);
     2852    RTTESTI_CHECK(ASMCountTrailingZerosU16(0x0ef0) == 4);
     2853    for (unsigned iBit = 0; iBit < 16; iBit++)
     2854    {
     2855        RTTESTI_CHECK(ASMCountTrailingZerosU16((uint16_t)1 << iBit) == iBit);
     2856        RTTESTI_CHECK(ASMCountTrailingZerosU16(UINT16_MAX  << iBit) == iBit);
     2857    }
     2858
     2859    RTTestSub(g_hTest, "ASMCountTrailingZerosU32");
     2860    RTTESTI_CHECK(ASMCountTrailingZerosU32(UINT32_C(0x00000000)) == 32);
     2861    RTTESTI_CHECK(ASMCountTrailingZerosU32(UINT32_C(0x00000001)) == 0);
     2862    RTTESTI_CHECK(ASMCountTrailingZerosU32(UINT32_C(0x80000000)) == 31);
     2863    RTTESTI_CHECK(ASMCountTrailingZerosU32(UINT32_C(0x0efffff0)) == 4);
     2864    for (unsigned iBit = 0; iBit < 32; iBit++)
     2865    {
     2866        RTTESTI_CHECK(ASMCountTrailingZerosU32((uint32_t)1 << iBit) == iBit);
     2867        RTTESTI_CHECK(ASMCountTrailingZerosU32(UINT32_MAX  << iBit) == iBit);
     2868    }
     2869
     2870    RTTestSub(g_hTest, "ASMCountTrailingZerosU64");
     2871    RTTESTI_CHECK(ASMCountTrailingZerosU64(UINT64_C(0x0000000000000000)) == 64);
     2872    RTTESTI_CHECK(ASMCountTrailingZerosU64(UINT64_C(0x0000000000000001)) == 0);
     2873    RTTESTI_CHECK(ASMCountTrailingZerosU64(UINT64_C(0x8000000000000000)) == 63);
     2874    RTTESTI_CHECK(ASMCountTrailingZerosU64(UINT64_C(0x0effff0fefef0ff0)) == 4);
     2875    for (unsigned iBit = 0; iBit < 64; iBit++)
     2876    {
     2877        RTTESTI_CHECK(ASMCountTrailingZerosU64((uint64_t)1 << iBit) == iBit);
     2878        RTTESTI_CHECK(ASMCountTrailingZerosU64(UINT64_MAX  << iBit) == iBit);
     2879    }
     2880}
     2881
    27452882
    27462883void tstASMMath(void)
     
    31043241    BENCH(ASMNopPause(),                         "ASMNopPause");
    31053242
     3243    BENCH(ASMBitFirstSetU16(s_u16),              "ASMBitFirstSetU16");
     3244    BENCH(ASMBitFirstSetU32(s_u32),              "ASMBitFirstSetU32");
     3245    BENCH(ASMBitFirstSetU64(s_u32),              "ASMBitFirstSetU64");
     3246    BENCH(ASMBitLastSetU16(s_u16),               "ASMBitLastSetU16");
     3247    BENCH(ASMBitLastSetU32(s_u32),               "ASMBitLastSetU32");
     3248    BENCH(ASMBitLastSetU64(s_u32),               "ASMBitLastSetU64");
     3249    BENCH(ASMCountLeadingZerosU16(s_u16),        "ASMCountLeadingZerosU16");
     3250    BENCH(ASMCountLeadingZerosU32(s_u32),        "ASMCountLeadingZerosU32");
     3251    BENCH(ASMCountLeadingZerosU64(s_u64),        "ASMCountLeadingZerosU64");
     3252    BENCH(ASMCountTrailingZerosU16(s_u16),       "ASMCountTrailingZerosU16");
     3253    BENCH(ASMCountTrailingZerosU32(s_u32),       "ASMCountTrailingZerosU32");
     3254    BENCH(ASMCountTrailingZerosU64(s_u64),       "ASMCountTrailingZerosU64");
     3255
     3256s_u32 = 0; if (s_u32) { /// remove me
    31063257    /* The Darwin gcc does not like this ... */
    31073258#if !defined(RT_OS_DARWIN) && !defined(GCC44_32BIT_PIC) && (defined(RT_ARCH_AMD64) || defined(RT_ARCH_X86))
     
    31783329    tstASMMisc();
    31793330
     3331    tstASMBit();
     3332
    31803333    tstASMMath();
    31813334
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