diff options
author | Jack Pappas <jack-pappas@users.noreply.github.com> | 2018-11-06 18:07:47 -0500 |
---|---|---|
committer | Maoni Stephens <Maoni0@users.noreply.github.com> | 2018-11-06 15:07:47 -0800 |
commit | 2bf55bc5ca8b09dd26e32a9ee259ab22fb69806b (patch) | |
tree | 3cfd121c1504997f9cfff765310910f7a020d8e9 /src/pal/inc/pal.h | |
parent | 8826f6f8c07c325046b78f28c57b24b201e487d2 (diff) | |
download | coreclr-2bf55bc5ca8b09dd26e32a9ee259ab22fb69806b.tar.gz coreclr-2bf55bc5ca8b09dd26e32a9ee259ab22fb69806b.tar.bz2 coreclr-2bf55bc5ca8b09dd26e32a9ee259ab22fb69806b.zip |
Loop-free GC rounding helpers with _BitScanReverse. (#20157)
Diffstat (limited to 'src/pal/inc/pal.h')
-rw-r--r-- | src/pal/inc/pal.h | 49 |
1 files changed, 49 insertions, 0 deletions
diff --git a/src/pal/inc/pal.h b/src/pal/inc/pal.h index 2a51d584ad..c4a1d64a29 100644 --- a/src/pal/inc/pal.h +++ b/src/pal/inc/pal.h @@ -3302,6 +3302,55 @@ BitScanForward64( return qwMask != 0 ? TRUE : FALSE; } +// Define BitScanReverse64 and BitScanReverse +// Per MSDN, BitScanReverse64 will search the mask data from MSB to LSB for a set bit. +// If one is found, its bit position is stored in the out PDWORD argument and 1 is returned. +// Otherwise, an undefined value is stored in the out PDWORD argument and 0 is returned. +// +// GCC/clang don't have a directly equivalent intrinsic; they do provide the __builtin_clzll +// intrinsic, which returns the number of leading 0-bits in x starting at the most significant +// bit position (the result is undefined when x = 0). +// +// The same is true for BitScanReverse, except that the GCC function is __builtin_clzl. + +EXTERN_C +PALIMPORT +inline +unsigned char +PALAPI +BitScanReverse( + IN OUT PDWORD Index, + IN UINT qwMask) +{ + // The result of __builtin_clzl is undefined when qwMask is zero, + // but it's still OK to call the intrinsic in that case (just don't use the output). + // Unconditionally calling the intrinsic in this way allows the compiler to + // emit branchless code for this function when possible (depending on how the + // intrinsic is implemented for the target platform). + int lzcount = __builtin_clzl(qwMask); + *Index = (DWORD)(31 - lzcount); + return qwMask != 0; +} + +EXTERN_C +PALIMPORT +inline +unsigned char +PALAPI +BitScanReverse64( + IN OUT PDWORD Index, + IN UINT64 qwMask) +{ + // The result of __builtin_clzll is undefined when qwMask is zero, + // but it's still OK to call the intrinsic in that case (just don't use the output). + // Unconditionally calling the intrinsic in this way allows the compiler to + // emit branchless code for this function when possible (depending on how the + // intrinsic is implemented for the target platform). + int lzcount = __builtin_clzll(qwMask); + *Index = (DWORD)(63 - lzcount); + return qwMask != 0; +} + FORCEINLINE void PAL_ArmInterlockedOperationBarrier() { #ifdef _ARM64_ |