VirtualBox

Changeset 87195 in vbox


Ignore:
Timestamp:
Jan 8, 2021 11:18:04 AM (4 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
142148
Message:

iprt/asm.h: More fun. Mostly done with asm.h. Added AMD64/gcc variant of ASMByteSwapU64 (untested). bugref:9898

File:
1 edited

Legend:

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

    r87192 r87195  
    65676567 * @remarks Similar to ffs() in BSD.
    65686568 */
    6569 #if RT_INLINE_ASM_EXTERNAL && !RT_INLINE_ASM_USES_INTRIN
     6569#if RT_INLINE_ASM_EXTERNAL_TMP_ARM && !RT_INLINE_ASM_USES_INTRIN
    65706570RT_ASM_DECL_PRAGMA_WATCOM_386(unsigned) ASMBitFirstSetU32(uint32_t u32) RT_NOTHROW_PROTO;
    65716571#else
     
    65786578    else
    65796579        iBit = 0;
    6580 # elif RT_INLINE_ASM_GNU_STYLE
     6580
     6581# elif defined(RT_ARCH_AMD64) || defined(RT_ARCH_X86)
     6582#  if RT_INLINE_ASM_GNU_STYLE
    65816583    uint32_t iBit;
    65826584    __asm__ __volatile__("bsf  %1, %0\n\t"
     
    65906592                         : "rm" (u32)
    65916593                         : "cc");
    6592 # else
     6594#  else
    65936595    uint32_t iBit;
    65946596    _asm
     
    66036605        mov     [iBit], eax
    66046606    }
     6607#  endif
     6608
     6609# elif defined(RT_ARCH_ARM64) || defined(RT_ARCH_ARM32)
     6610    /*
     6611     * Using the "count leading zeros (clz)" instruction here because there
     6612     * is no dedicated instruction to get the first set bit.
     6613     * Need to reverse the bits in the value with "rbit" first because
     6614     * "clz" starts counting from the most significant bit.
     6615     */
     6616    uint32_t iBit;
     6617    __asm__ __volatile__(
     6618#  if defined(RT_ARCH_ARM64)
     6619                         "rbit %w[uVal], %w[uVal]\n\t"
     6620                         "clz  %w[iBit], %w[uVal]\n\t"
     6621#  else
     6622                         "rbit %[uVal], %[uVal]\n\t"
     6623                         "clz  %[iBit], %[uVal]\n\t"
     6624#  endif
     6625                         : [uVal] "=r" (u32)
     6626                         , [iBit] "=r" (iBit)
     6627                         : "[uVal]" (u32));
     6628    if (iBit != 32)
     6629        iBit++;
     6630    else
     6631        iBit = 0; /* No bit set. */
     6632
     6633# else
     6634#  error "Port me"
    66056635# endif
    66066636    return iBit;
     
    66346664 * @remarks Similar to ffs() in BSD.
    66356665 */
    6636 #if RT_INLINE_ASM_EXTERNAL && !RT_INLINE_ASM_USES_INTRIN
     6666#if RT_INLINE_ASM_EXTERNAL_TMP_ARM && !RT_INLINE_ASM_USES_INTRIN
    66376667RT_ASM_DECL_PRAGMA_WATCOM_386(unsigned) ASMBitFirstSetU64(uint64_t u64) RT_NOTHROW_PROTO;
    66386668#else
     
    66546684        iBit = 0;
    66556685#  endif
    6656 # elif RT_INLINE_ASM_GNU_STYLE && ARCH_BITS == 64
     6686
     6687# elif RT_INLINE_ASM_GNU_STYLE && defined(RT_ARCH_AMD64)
    66576688    uint64_t iBit;
    66586689    __asm__ __volatile__("bsfq %1, %0\n\t"
     
    66666697                         : "rm" (u64)
    66676698                         : "cc");
     6699
     6700# elif defined(RT_ARCH_ARM64)
     6701    uint64_t iBit;
     6702    __asm__ __volatile__("rbit %[uVal], %[uVal]\n\t"
     6703                         "clz  %[iBit], %[uVal]\n\t"
     6704                         : [uVal] "=r" (u64)
     6705                         , [iBit] "=r" (iBit)
     6706                         : "[uVal]" (u64));
     6707    if (iBit != 64)
     6708        iBit++;
     6709    else
     6710        iBit = 0; /* No bit set. */
     6711
    66686712# else
    66696713    unsigned iBit = ASMBitFirstSetU32((uint32_t)u64);
     
    66906734 * @remarks For 16-bit bs3kit code.
    66916735 */
    6692 #if RT_INLINE_ASM_EXTERNAL && !RT_INLINE_ASM_USES_INTRIN
     6736#if RT_INLINE_ASM_EXTERNAL_TMP_ARM && !RT_INLINE_ASM_USES_INTRIN
    66936737RT_ASM_DECL_PRAGMA_WATCOM_386(unsigned) ASMBitFirstSetU16(uint16_t u16) RT_NOTHROW_PROTO;
    66946738#else
     
    67096753 * @remark  Similar to fls() in BSD.
    67106754 */
    6711 #if RT_INLINE_ASM_EXTERNAL && !RT_INLINE_ASM_USES_INTRIN
     6755#if RT_INLINE_ASM_EXTERNAL_TMP_ARM && !RT_INLINE_ASM_USES_INTRIN
    67126756RT_ASM_DECL_PRAGMA_WATCOM_386(unsigned) ASMBitLastSetU32(uint32_t u32) RT_NOTHROW_PROTO;
    67136757#else
     
    67206764    else
    67216765        iBit = 0;
    6722 # elif RT_INLINE_ASM_GNU_STYLE
     6766
     6767# elif defined(RT_ARCH_AMD64) || defined(RT_ARCH_X86)
     6768#  if RT_INLINE_ASM_GNU_STYLE
    67236769    uint32_t iBit;
    67246770    __asm__ __volatile__("bsrl %1, %0\n\t"
     
    67326778                         : "rm" (u32)
    67336779                         : "cc");
    6734 # else
     6780#  else
    67356781    uint32_t iBit;
    67366782    _asm
     
    67456791        mov     [iBit], eax
    67466792    }
     6793#  endif
     6794
     6795# elif defined(RT_ARCH_ARM64) || defined(RT_ARCH_ARM32)
     6796    uint32_t iBit;
     6797    __asm__ __volatile__(
     6798#  if defined(RT_ARCH_ARM64)
     6799                         "clz  %w[iBit], %w[uVal]\n\t"
     6800#  else
     6801                         "clz  %[iBit], %[uVal]\n\t"
     6802#  endif
     6803                         : [iBit] "=r" (iBit)
     6804                         : [uVal] "r" (u32));
     6805    iBit = 32 - iBit;
     6806
     6807# else
     6808#  error "Port me"
    67476809# endif
    67486810    return iBit;
     
    67766838 * @remark  Similar to fls() in BSD.
    67776839 */
    6778 #if RT_INLINE_ASM_EXTERNAL && !RT_INLINE_ASM_USES_INTRIN
     6840#if RT_INLINE_ASM_EXTERNAL_TMP_ARM && !RT_INLINE_ASM_USES_INTRIN
    67796841RT_ASM_DECL_PRAGMA_WATCOM_386(unsigned) ASMBitLastSetU64(uint64_t u64) RT_NOTHROW_PROTO;
    67806842#else
     
    67966858        iBit = 0;
    67976859#  endif
    6798 # elif RT_INLINE_ASM_GNU_STYLE && ARCH_BITS == 64
     6860
     6861# elif RT_INLINE_ASM_GNU_STYLE && defined(RT_ARCH_AMD64)
    67996862    uint64_t iBit;
    68006863    __asm__ __volatile__("bsrq %1, %0\n\t"
     
    68086871                         : "rm" (u64)
    68096872                         : "cc");
     6873
     6874# elif defined(RT_ARCH_ARM64)
     6875    uint64_t iBit;
     6876    __asm__ __volatile__("clz  %[iBit], %[uVal]\n\t"
     6877                         : [iBit] "=r" (iBit)
     6878                         : [uVal] "r" (u64));
     6879    iBit = 64 - iBit;
     6880
    68106881# else
    68116882    unsigned iBit = ASMBitLastSetU32((uint32_t)(u64 >> 32));
     
    68146885    else
    68156886        iBit = ASMBitLastSetU32((uint32_t)u64);
    6816 #endif
     6887# endif
    68176888    return (unsigned)iBit;
    68186889}
     
    68306901 * @remarks For 16-bit bs3kit code.
    68316902 */
    6832 #if RT_INLINE_ASM_EXTERNAL && !RT_INLINE_ASM_USES_INTRIN
     6903#if RT_INLINE_ASM_EXTERNAL_TMP_ARM && !RT_INLINE_ASM_USES_INTRIN
    68336904RT_ASM_DECL_PRAGMA_WATCOM_386(unsigned) ASMBitLastSetU16(uint16_t u16) RT_NOTHROW_PROTO;
    68346905#else
     
    68466917 * @param   u16     16-bit integer value.
    68476918 */
    6848 #if RT_INLINE_ASM_EXTERNAL && !RT_INLINE_ASM_USES_INTRIN
     6919#if RT_INLINE_ASM_EXTERNAL_TMP_ARM && !RT_INLINE_ASM_USES_INTRIN
    68496920RT_ASM_DECL_PRAGMA_WATCOM(uint16_t) ASMByteSwapU16(uint16_t u16) RT_NOTHROW_PROTO;
    68506921#else
     
    68526923{
    68536924# if RT_INLINE_ASM_USES_INTRIN
    6854     u16 = _byteswap_ushort(u16);
    6855 # elif RT_INLINE_ASM_GNU_STYLE
     6925    return _byteswap_ushort(u16);
     6926
     6927# elif defined(RT_ARCH_AMD64) || defined(RT_ARCH_X86)
     6928#  if RT_INLINE_ASM_GNU_STYLE
    68566929    __asm__ ("rorw $8, %0" : "=r" (u16) : "0" (u16) : "cc");
    6857 # else
     6930#  else
    68586931    _asm
    68596932    {
     
    68626935        mov     [u16], ax
    68636936    }
    6864 # endif
     6937#  endif
    68656938    return u16;
     6939
     6940# elif defined(RT_ARCH_ARM64) || defined(RT_ARCH_ARM32)
     6941    uint32_t u32Ret;
     6942    __asm__ __volatile__(
     6943#  if defined(RT_ARCH_ARM64)
     6944                         "rev16     %w[uRet], %w[uVal]\n\t"
     6945#  else
     6946                         "rev16     %[uRet], %[uVal]\n\t"
     6947#  endif
     6948                         : [uRet] "=r" (u32Ret)
     6949                         : [uVal] "r" (u16));
     6950    return (uint16_t)u32Ret;
     6951
     6952# else
     6953#  error "Port me"
     6954# endif
    68666955}
    68676956#endif
     
    68746963 * @param   u32     32-bit integer value.
    68756964 */
    6876 #if RT_INLINE_ASM_EXTERNAL && !RT_INLINE_ASM_USES_INTRIN
     6965#if RT_INLINE_ASM_EXTERNAL_TMP_ARM && !RT_INLINE_ASM_USES_INTRIN
    68776966RT_ASM_DECL_PRAGMA_WATCOM(uint32_t) ASMByteSwapU32(uint32_t u32) RT_NOTHROW_PROTO;
    68786967#else
     
    68806969{
    68816970# if RT_INLINE_ASM_USES_INTRIN
    6882     u32 = _byteswap_ulong(u32);
    6883 # elif RT_INLINE_ASM_GNU_STYLE
     6971    return _byteswap_ulong(u32);
     6972
     6973# elif defined(RT_ARCH_AMD64) || defined(RT_ARCH_X86)
     6974#  if RT_INLINE_ASM_GNU_STYLE
    68846975    __asm__ ("bswapl %0" : "=r" (u32) : "0" (u32));
    6885 # else
     6976#  else
    68866977    _asm
    68876978    {
     
    68906981        mov     [u32], eax
    68916982    }
    6892 # endif
     6983#  endif
    68936984    return u32;
     6985
     6986# elif defined(RT_ARCH_ARM64)
     6987    uint64_t u64Ret;
     6988    __asm__ __volatile__("rev32     %[uRet], %[uVal]\n\t"
     6989                         : [uRet] "=r" (u64Ret)
     6990                         : [uVal] "r" ((uint64_t)u32));
     6991    return (uint32_t)u64Ret;
     6992
     6993# elif defined(RT_ARCH_ARM32)
     6994    __asm__ __volatile__("rev       %[uRet], %[uVal]\n\t"
     6995                         : [uRet] "=r" (u32)
     6996                         : [uVal] "[uRet]" (u32));
     6997    return u32;
     6998
     6999# else
     7000#  error "Port me"
     7001# endif
    68947002}
    68957003#endif
     
    69057013{
    69067014#if defined(RT_ARCH_AMD64) && RT_INLINE_ASM_USES_INTRIN
    6907     u64 = _byteswap_uint64(u64);
    6908 #else
    6909     u64 = (uint64_t)ASMByteSwapU32((uint32_t)u64) << 32
    6910         | (uint64_t)ASMByteSwapU32((uint32_t)(u64 >> 32));
    6911 #endif
     7015    return _byteswap_uint64(u64);
     7016
     7017# elif RT_INLINE_ASM_GNU_STYLE && defined(RT_ARCH_AMD64)
     7018    __asm__ ("bswapq %0" : "=r" (u64) : "0" (u64));
    69127019    return u64;
     7020
     7021# elif defined(RT_ARCH_ARM64)
     7022    __asm__ __volatile__("rev       %[uRet], %[uVal]\n\t"
     7023                         : [uRet] "=r" (u64)
     7024                         : [uVal] "[uRet]" (u64));
     7025    return u64;
     7026
     7027#else
     7028    return = (uint64_t)ASMByteSwapU32((uint32_t)u64) << 32
     7029           | (uint64_t)ASMByteSwapU32((uint32_t)(u64 >> 32));
     7030#endif
    69137031}
    69147032
     
    69287046# if RT_INLINE_ASM_USES_INTRIN
    69297047    return _rotl(u32, cShift);
     7048
    69307049# elif RT_INLINE_ASM_GNU_STYLE && (defined(RT_ARCH_AMD64) || defined(RT_ARCH_X86))
    69317050    __asm__ __volatile__("roll %b1, %0" : "=g" (u32) : "Ic" (cShift), "0" (u32) : "cc");
    69327051    return u32;
     7052
     7053# elif defined(RT_ARCH_ARM64) || defined(RT_ARCH_ARM32)
     7054    __asm__ __volatile__(
     7055#  if defined(RT_ARCH_ARM64)
     7056                         "ror       %w[uRet], %w[uVal], %w[cShift]\n\t"
     7057#  else
     7058                         "ror       %[uRet], %[uVal], %[cShift]\n\t"
     7059#  endif
     7060                         : [uRet] "=r" (u32)
     7061                         : [uVal] "[uRet]" (u32)
     7062                         , [cShift] "r" (32 - (cShift & 31))); /** @todo there is an immediate form here */
     7063    return u32;
     7064
    69337065# else
    69347066    cShift &= 31;
     
    69537085# if RT_INLINE_ASM_USES_INTRIN
    69547086    return _rotr(u32, cShift);
     7087
    69557088# elif RT_INLINE_ASM_GNU_STYLE && (defined(RT_ARCH_AMD64) || defined(RT_ARCH_X86))
    69567089    __asm__ __volatile__("rorl %b1, %0" : "=g" (u32) : "Ic" (cShift), "0" (u32) : "cc");
    69577090    return u32;
     7091
     7092# elif defined(RT_ARCH_ARM64) || defined(RT_ARCH_ARM32)
     7093    __asm__ __volatile__(
     7094#  if defined(RT_ARCH_ARM64)
     7095                         "ror       %w[uRet], %w[uVal], %w[cShift]\n\t"
     7096#  else
     7097                         "ror       %[uRet], %[uVal], %[cShift]\n\t"
     7098#  endif
     7099                         : [uRet] "=r" (u32)
     7100                         : [uVal] "[uRet]" (u32)
     7101                         , [cShift] "r" (cShift & 31)); /** @todo there is an immediate form here */
     7102    return u32;
     7103
    69587104# else
    69597105    cShift &= 31;
     
    69757121#if RT_INLINE_ASM_USES_INTRIN
    69767122    return _rotl64(u64, cShift);
     7123
    69777124#elif RT_INLINE_ASM_GNU_STYLE && defined(RT_ARCH_AMD64)
    69787125    __asm__ __volatile__("rolq %b1, %0" : "=g" (u64) : "Jc" (cShift), "0" (u64) : "cc");
    69797126    return u64;
     7127
    69807128#elif RT_INLINE_ASM_GNU_STYLE && defined(RT_ARCH_X86)
    69817129    uint32_t uSpill;
     
    69977145                         : "cc");
    69987146    return u64;
     7147
     7148# elif defined(RT_ARCH_ARM64)
     7149    __asm__ __volatile__("ror       %[uRet], %[uVal], %[cShift]\n\t"
     7150                         : [uRet] "=r" (u64)
     7151                         : [uVal] "[uRet]" (u64)
     7152                         , [cShift] "r" ((uint64_t)(64 - (cShift & 63)))); /** @todo there is an immediate form here */
     7153    return u64;
     7154
    69997155#else
    70007156    cShift &= 63;
     
    70157171#if RT_INLINE_ASM_USES_INTRIN
    70167172    return _rotr64(u64, cShift);
     7173
    70177174#elif RT_INLINE_ASM_GNU_STYLE && defined(RT_ARCH_AMD64)
    70187175    __asm__ __volatile__("rorq %b1, %0" : "=g" (u64) : "Jc" (cShift), "0" (u64) : "cc");
    70197176    return u64;
     7177
    70207178#elif RT_INLINE_ASM_GNU_STYLE && defined(RT_ARCH_X86)
    70217179    uint32_t uSpill;
     
    70377195                         : "cc");
    70387196    return u64;
     7197
     7198# elif defined(RT_ARCH_ARM64)
     7199    __asm__ __volatile__("ror       %[uRet], %[uVal], %[cShift]\n\t"
     7200                         : [uRet] "=r" (u64)
     7201                         : [uVal] "[uRet]" (u64)
     7202                         , [cShift] "r" ((uint64_t)(cShift & 63))); /** @todo there is an immediate form here */
     7203    return u64;
     7204
    70397205#else
    70407206    cShift &= 63;
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