VirtualBox

Changeset 58771 in vbox for trunk/include/iprt


Ignore:
Timestamp:
Nov 19, 2015 3:55:04 PM (9 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
104218
Message:

iprt/asm.h: Added ASMBitFirstSetU16 and ASMBitLastSetU16, and while at it also U64 variants (latter: untested).

Location:
trunk/include/iprt
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/include/iprt/asm-watcom-x86-16.h

    r58749 r58771  
    537537    modify exact [ax dx] nomemory;
    538538
     539#undef      ASMBitFirstSetU64
     540#pragma aux ASMBitFirstSetU64 = \
     541    "shl ecx, 16" \
     542    "mov cx, dx" \
     543    "bsf ecx, ecx" \
     544    "jz  not_found_low" \
     545    "mov ax, cx" \
     546    "inc ax" \
     547    "jmp done" \
     548    \
     549    "not_found_low:" \
     550    "shr eax, 16" \
     551    "mov ax, bx" \
     552    "bsf eax, eax" \
     553    "jz  not_found_high" \
     554    "add ax, 33" \
     555    "jmp done" \
     556    \
     557    "not_found_high:" \
     558    "xor ax, ax" \
     559    "done:" \
     560    parm [dx cx bx ax] nomemory \
     561    value [ax] \
     562    modify exact [ax cx] nomemory;
     563
     564#undef      ASMBitFirstSetU16
     565#pragma aux ASMBitFirstSetU16 = \
     566    "bsf ax, ax" \
     567    "jz  not_found" \
     568    "inc ax" \
     569    "jmp done" \
     570    "not_found:" \
     571    "xor ax, ax" \
     572    "done:" \
     573    parm [ax] nomemory \
     574    value [ax] \
     575    modify exact [ax] nomemory;
     576
    539577#undef      ASMBitLastSetU32
    540578#pragma aux ASMBitLastSetU32 = \
     
    551589    value [ax] \
    552590    modify exact [ax dx] nomemory;
     591
     592#undef      ASMBitLastSetU64
     593#pragma aux ASMBitLastSetU64 = \
     594    "shl ecx, 16" \
     595    "mov cx, dx" \
     596    "bsf ecx, ecx" \
     597    "jz  not_found_low" \
     598    "mov ax, cx" \
     599    "inc ax" \
     600    "jmp done" \
     601    \
     602    "not_found_low:" \
     603    "shr eax, 16" \
     604    "mov ax, bx" \
     605    "bsf eax, eax" \
     606    "jz  not_found_high" \
     607    "add ax, 33" \
     608    "jmp done" \
     609    \
     610    "not_found_high:" \
     611    "xor ax, ax" \
     612    "done:" \
     613    parm [dx cx bx ax] nomemory \
     614    value [ax] \
     615    modify exact [ax cx] nomemory;
     616
     617#undef      ASMBitLastSetU16
     618#pragma aux ASMBitLastSetU16 = \
     619    "bsr ax, ax" \
     620    "jz  not_found" \
     621    "inc ax" \
     622    "jmp done" \
     623    "not_found:" \
     624    "xor ax, ax" \
     625    "done:" \
     626    parm [ax] nomemory \
     627    value [ax] \
     628    modify exact [ax] nomemory;
    553629
    554630#undef      ASMByteSwapU16
  • trunk/include/iprt/asm-watcom-x86-32.h

    r58749 r58771  
    468468    modify exact [eax] nomemory;
    469469
     470#undef      ASMBitFirstSetU64
     471#pragma aux ASMBitFirstSetU64 = \
     472    "bsf eax, eax" \
     473    "jz  not_found_low" \
     474    "inc eax" \
     475    "jmp done" \
     476    \
     477    "not_found_low:" \
     478    "bsf eax, edx" \
     479    "jz  not_found_high" \
     480    "add eax, 33" \
     481    "jmp done" \
     482    \
     483    "not_found_high:" \
     484    "xor eax, eax" \
     485    "done:" \
     486    parm [eax edx] nomemory \
     487    value [eax] \
     488    modify exact [eax] nomemory;
     489
     490#undef      ASMBitFirstSetU16
     491#pragma aux ASMBitFirstSetU16 = \
     492    "movzx eax, ax" \
     493    "bsf eax, eax" \
     494    "jz  not_found" \
     495    "inc eax" \
     496    "jmp done" \
     497    "not_found:" \
     498    "xor eax, eax" \
     499    "done:" \
     500    parm [ax] nomemory \
     501    value [eax] \
     502    modify exact [eax] nomemory;
     503
    470504#undef      ASMBitLastSetU32
    471505#pragma aux ASMBitLastSetU32 = \
     
    478512    "done:" \
    479513    parm [eax] nomemory \
     514    value [eax] \
     515    modify exact [eax] nomemory;
     516
     517#undef      ASMBitLastSetU64
     518#pragma aux ASMBitLastSetU64 = \
     519    "bsf eax, eax" \
     520    "jz  not_found_low" \
     521    "inc eax" \
     522    "jmp done" \
     523    \
     524    "not_found_low:" \
     525    "bsf eax, edx" \
     526    "jz  not_found_high" \
     527    "add eax, 33" \
     528    "jmp done" \
     529    \
     530    "not_found_high:" \
     531    "xor eax, eax" \
     532    "done:" \
     533    parm [eax edx] nomemory \
     534    value [eax] \
     535    modify exact [eax] nomemory;
     536
     537#undef      ASMBitLastSetU16
     538#pragma aux ASMBitLastSetU16 = \
     539    "movzx eax, ax" \
     540    "bsr eax, eax" \
     541    "jz  not_found" \
     542    "inc eax" \
     543    "jmp done" \
     544    "not_found:" \
     545    "xor eax, eax" \
     546    "done:" \
     547    parm [ax] nomemory \
    480548    value [eax] \
    481549    modify exact [eax] nomemory;
  • trunk/include/iprt/asm.h

    r58767 r58771  
    47974797 * @returns 0 if all bits are cleared.
    47984798 * @param   u32     Integer to search for set bits.
    4799  * @remark  Similar to ffs() in BSD.
     4799 * @remarks Similar to ffs() in BSD.
    48004800 */
    48014801#if RT_INLINE_ASM_EXTERNAL && !RT_INLINE_ASM_USES_INTRIN
     
    48564856
    48574857/**
     4858 * Finds the first bit which is set in the given 64-bit integer.
     4859 *
     4860 * Bits are numbered from 1 (least significant) to 64.
     4861 *
     4862 * @returns index [1..64] of the first set bit.
     4863 * @returns 0 if all bits are cleared.
     4864 * @param   u64     Integer to search for set bits.
     4865 * @remarks Similar to ffs() in BSD.
     4866 */
     4867#if RT_INLINE_ASM_EXTERNAL && !RT_INLINE_ASM_USES_INTRIN
     4868DECLASM(unsigned) ASMBitFirstSetU64(uint64_t u64);
     4869#else
     4870DECLINLINE(unsigned) ASMBitFirstSetU64(uint64_t u64)
     4871{
     4872# if RT_INLINE_ASM_USES_INTRIN
     4873    unsigned long iBit;
     4874#  if ARCH_BITS == 64
     4875    if (_BitScanForward64(&iBit, u64))
     4876        iBit++;
     4877    else
     4878        iBit = 0;
     4879#  else
     4880    if (_BitScanForward(&iBit, (uint32_t)u64))
     4881        iBit++;
     4882    else if (_BitScanForward(&iBit, (uint32_t)(u64 >> 32)))
     4883        iBit += 33;
     4884    else
     4885        iBit = 0;
     4886#  endif
     4887# elif RT_INLINE_ASM_GNU_STYLE && ARCH_BITS == 64
     4888    uint64_t iBit;
     4889    __asm__ __volatile__("bsfq %1, %0\n\t"
     4890                         "jnz  1f\n\t"
     4891                         "xorl %0, %0\n\t"
     4892                         "jmp  2f\n"
     4893                         "1:\n\t"
     4894                         "incl %0\n"
     4895                         "2:\n\t"
     4896                         : "=r" (iBit)
     4897                         : "rm" (u64));
     4898# else
     4899    unsigned iBit = ASMBitFirstSetU32((uint32_t)u64);
     4900    if (!iBit)
     4901    {
     4902        iBit = ASMBitFirstSetU32((uint32_t)(u64 >> 32));
     4903        if (iBit)
     4904            iBit += 32;
     4905    }
     4906# endif
     4907    return (unsigned)iBit;
     4908}
     4909#endif
     4910
     4911
     4912/**
     4913 * Finds the first bit which is set in the given 16-bit integer.
     4914 *
     4915 * Bits are numbered from 1 (least significant) to 16.
     4916 *
     4917 * @returns index [1..16] of the first set bit.
     4918 * @returns 0 if all bits are cleared.
     4919 * @param   u16     Integer to search for set bits.
     4920 * @remarks For 16-bit bs3kit code.
     4921 */
     4922#if RT_INLINE_ASM_EXTERNAL && !RT_INLINE_ASM_USES_INTRIN
     4923DECLASM(unsigned) ASMBitFirstSetU16(uint32_t u16);
     4924#else
     4925DECLINLINE(unsigned) ASMBitFirstSetU16(uint32_t u16)
     4926{
     4927    return ASMBitFirstSetU32((uint32_t)u16);
     4928}
     4929#endif
     4930
     4931
     4932/**
    48584933 * Finds the last bit which is set in the given 32-bit integer.
    48594934 * Bits are numbered from 1 (least significant) to 32.
     
    49184993    return ASMBitLastSetU32((uint32_t)i32);
    49194994}
     4995
     4996
     4997/**
     4998 * Finds the last bit which is set in the given 64-bit integer.
     4999 *
     5000 * Bits are numbered from 1 (least significant) to 64.
     5001 *
     5002 * @returns index [1..64] of the last set bit.
     5003 * @returns 0 if all bits are cleared.
     5004 * @param   u64     Integer to search for set bits.
     5005 * @remark  Similar to fls() in BSD.
     5006 */
     5007#if RT_INLINE_ASM_EXTERNAL && !RT_INLINE_ASM_USES_INTRIN
     5008DECLASM(unsigned) ASMBitLastSetU64(uint64_t u64);
     5009#else
     5010DECLINLINE(unsigned) ASMBitLastSetU64(uint64_t u64)
     5011{
     5012# if RT_INLINE_ASM_USES_INTRIN
     5013    unsigned long iBit;
     5014#  if ARCH_BITS == 64
     5015    if (_BitScanReverse64(&iBit, u64))
     5016        iBit++;
     5017    else
     5018        iBit = 0;
     5019#  else
     5020    if (_BitScanReverse(&iBit, (uint32_t)(u64 >> 32)))
     5021        iBit += 33;
     5022    else if (_BitScanReverse(&iBit, (uint32_t)u64))
     5023        iBit++;
     5024    else
     5025        iBit = 0;
     5026#  endif
     5027# elif RT_INLINE_ASM_GNU_STYLE && ARCH_BITS == 64
     5028    uint64_t iBit;
     5029    __asm__ __volatile__("bsrq %1, %0\n\t"
     5030                         "jnz   1f\n\t"
     5031                         "xorl %0, %0\n\t"
     5032                         "jmp  2f\n"
     5033                         "1:\n\t"
     5034                         "incl %0\n"
     5035                         "2:\n\t"
     5036                         : "=r" (iBit)
     5037                         : "rm" (u64));
     5038# else
     5039    unsigned iBit = ASMBitLastSetU32((uint32_t)(u64 >> 32);
     5040    if (iBit)
     5041        iBit += 32;
     5042    else
     5043        iBit = ASMBitLastSetU32((uint32_t)u64);
     5044#endif
     5045    return (unsigned)iBit;
     5046}
     5047#endif
     5048
     5049
     5050/**
     5051 * Finds the last bit which is set in the given 16-bit integer.
     5052 *
     5053 * Bits are numbered from 1 (least significant) to 16.
     5054 *
     5055 * @returns index [1..16] of the last set bit.
     5056 * @returns 0 if all bits are cleared.
     5057 * @param   u16     Integer to search for set bits.
     5058 * @remarks For 16-bit bs3kit code.
     5059 */
     5060#if RT_INLINE_ASM_EXTERNAL && !RT_INLINE_ASM_USES_INTRIN
     5061DECLASM(unsigned) ASMBitLastSetU16(uint32_t u16);
     5062#else
     5063DECLINLINE(unsigned) ASMBitLastSetU16(uint32_t u16)
     5064{
     5065    return ASMBitLastSetU32((uint32_t)u16);
     5066}
     5067#endif
     5068
    49205069
    49215070/**
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