Skip to content
This repository was archived by the owner on Jan 23, 2023. It is now read-only.
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
84 commits
Select commit Hold shift + click to select a range
5ff7696
Identofy duplicate callsites for BitOps
Jan 26, 2019
0139220
Add new methods
Jan 26, 2019
4b26701
- Add unsigned overload for TZCNT
Jan 26, 2019
c51d22e
Comments
Jan 28, 2019
781bc08
Add instrinsics support to some methods
Jan 28, 2019
bb2a8b1
CR changes: Standardize on uint instead of byte
Jan 28, 2019
05ce353
CR: Move statics to top of file
Jan 28, 2019
fe01190
Trim unused code
Jan 28, 2019
f917003
Remove commented-out code
Jan 28, 2019
d7b7e39
Cleanup
Jan 28, 2019
6beaa00
Update CoreClr call sites
Jan 29, 2019
2a0f621
More call sites
Jan 29, 2019
e9a7e96
Comments
Jan 29, 2019
e85fd48
Comments
Jan 29, 2019
db62682
Comments
Jan 29, 2019
2ffd503
Another callsite
Jan 29, 2019
c2295cb
LogBase2
Jan 29, 2019
5647564
Optimizations
Jan 29, 2019
5b8c1ce
CR fixes
Jan 29, 2019
adc5527
Optimize
Jan 30, 2019
f3eea46
Units passing
Jan 30, 2019
ee9e05a
Simplify
Jan 30, 2019
837102b
Fixes
Jan 31, 2019
499e97e
CR fixes
Jan 31, 2019
6574199
CR fixes
Jan 31, 2019
16ac132
Optimization
Feb 1, 2019
84e7711
Optimize
Feb 1, 2019
056c4bf
Log2(0) returns 0
Feb 1, 2019
00f7d46
Merge branch 'master' into grant-d.bits
Feb 6, 2019
404ec20
CR fixes
Feb 7, 2019
634615c
Bug
Feb 7, 2019
c41078a
Bug
Feb 7, 2019
4a48641
Return int instead of uint
Feb 7, 2019
90430cc
Update integrations
Feb 7, 2019
1392e00
Merge from master
Feb 8, 2019
3011abd
Perf: BitOps.LeadingZeroCount
Feb 9, 2019
334c816
CR fix
Feb 9, 2019
fb57241
CR fixes
Feb 9, 2019
c2b5219
Optimization
Feb 9, 2019
457730c
Revert
Feb 9, 2019
f4bbf4d
Confirmed fix
Feb 9, 2019
098bc6e
Simplify
Feb 9, 2019
10d3794
Return int
Feb 9, 2019
21dfb03
Fixes
Feb 9, 2019
749e64f
Fixes
Feb 9, 2019
66fd0f3
Simplify
Feb 9, 2019
2118e0c
Simplify
Feb 9, 2019
a1cb73d
CR fixes
Feb 11, 2019
406ee5f
CR fixes
Feb 11, 2019
6e5870a
Add PopCount
Feb 11, 2019
bff472e
Fix unit failure on Linux-musl x64 Debug
Feb 11, 2019
316f9d0
Add Rotate
Feb 11, 2019
df100cf
CR fixes
Feb 11, 2019
588e30f
Merge from grant-d.tzcnt
Feb 11, 2019
91fffb8
More call sites
Feb 12, 2019
91b906c
CR fixes
Feb 13, 2019
2ccb5b3
Cleanup
Feb 13, 2019
7feeca5
Merge from lzcnt
Feb 13, 2019
dd9fa8c
Merge from main
Feb 13, 2019
14893ba
Add new methods
Feb 13, 2019
65e6ab6
CR fixes (tanner)
Feb 13, 2019
e965aca
CR fixes
Feb 13, 2019
2be3fa2
- Fix naming
Feb 13, 2019
0738934
Remove redundant MSIL cast, conv.u8
Feb 14, 2019
dfcdc49
Fix comment
Feb 14, 2019
701e1e2
CR fixes
Feb 14, 2019
f1ecd1c
Use local functions for SoftwareFallback
Feb 14, 2019
f462f06
Use constants
Feb 14, 2019
0b20e57
Target BIT32/64
Feb 14, 2019
cdaf17b
Target BIT32/64
Feb 14, 2019
a4bfc2b
Merge branch 'grant-d.rotl' of https://github.com/grant-d/coreclr int…
Feb 14, 2019
0f1d0cb
CR fix
Feb 14, 2019
f95e258
CR fixes
Feb 14, 2019
528b52a
Align with main
Feb 14, 2019
5db853d
Remove temp vars
Feb 14, 2019
3b88d2d
Merge from grant-d.rotl
Feb 14, 2019
a03f26b
More alignments
Feb 14, 2019
9b1faf4
Perf fix
Feb 14, 2019
da2fff5
Perf
Feb 14, 2019
0ffb5d5
Merge from master
Feb 14, 2019
faac202
Cleanup
Feb 14, 2019
d6da0b4
Comment out unused methods
Feb 14, 2019
40a68f9
Revert until api review
Feb 14, 2019
45e6e6a
Unrevert
Feb 14, 2019
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
205 changes: 205 additions & 0 deletions src/System.Private.CoreLib/shared/System/BitOps.cs
Original file line number Diff line number Diff line change
Expand Up @@ -355,5 +355,210 @@ int SoftwareFallback(ulong v)
}
#endif
}

/// <summary>
/// Reads whether the specified bit in a mask is set.
/// Similar in behavior to the x86 instruction BT.
/// </summary>
/// <param name="value">The value.</param>
/// <param name="bitOffset">The ordinal position of the bit to read.
/// Any value outside the range [0..7] is treated as congruent mod 8.</param>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static bool ExtractBit(byte value, int bitOffset)
// For bit-length N, it is conventional to treat N as congruent modulo-N under the shift operation.
// So for uint, 1 << 33 == 1 << 1, and likewise 1 << -46 == 1 << +18.
// Note -46 % 32 == -14. But -46 & 31 (0011_1111) == +18.
// So we use & not %.
=> ExtractBit((uint)value, bitOffset & 7);

/// <summary>
/// Reads whether the specified bit in a mask is set.
/// Similar in behavior to the x86 instruction BT.
/// </summary>
/// <param name="value">The value.</param>
/// <param name="bitOffset">The ordinal position of the bit to read.
/// Any value outside the range [0..31] is treated as congruent mod 32.</param>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static bool ExtractBit(uint value, int bitOffset)
=> (value & (1u << bitOffset)) != 0;

/// <summary>
/// Reads whether the specified bit in a mask is set.
/// Similar in behavior to the x86 instruction BT.
/// </summary>
/// <param name="value">The value.</param>
/// <param name="bitOffset">The ordinal position of the bit to read.
/// Any value outside the range [0..7] is treated as congruent mod 8.</param>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static bool ExtractBit(int value, int bitOffset)
=> (value & (1 << bitOffset)) != 0;

/// <summary>
/// Clears the specified bit in a mask and returns whether it was originally set.
/// Similar in behavior to the x86 instruction BTR.
/// </summary>
/// <param name="value">The value.</param>
/// <param name="bitOffset">The ordinal position of the bit to clear.
/// Any value outside the range [0..7] is treated as congruent mod 8.</param>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static bool ClearBit(ref byte value, int bitOffset)
{
uint mask = 1u << (bitOffset & 7);

bool btr = (value & mask) != 0;
value = (byte)(value & ~mask);

return btr;
}

/// <summary>
/// Clears the specified bit in a mask and returns whether it was originally set.
/// Similar in behavior to the x86 instruction BTR.
/// </summary>
/// <param name="value">The value.</param>
/// <param name="bitOffset">The ordinal position of the bit to clear.
/// Any value outside the range [0..31] is treated as congruent mod 32.</param>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static bool ClearBit(ref uint value, int bitOffset)
{
uint mask = 1u << bitOffset;

bool btr = (value & mask) != 0;
value &= ~mask;

return btr;
}

/// <summary>
/// Clears the specified bit in a mask and returns whether it was originally set.
/// Similar in behavior to the x86 instruction BTR.
/// </summary>
/// <param name="value">The value.</param>
/// <param name="bitOffset">The ordinal position of the bit to clear.
/// Any value outside the range [0..31] is treated as congruent mod 32.</param>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static bool ClearBit(ref int value, int bitOffset)
{
int mask = 1 << bitOffset;

bool btr = (value & mask) != 0;
value &= ~mask;

return btr;
}

/// <summary>
/// Clears the specified bit in a mask and returns the new value.
/// </summary>
/// <param name="value">The value.</param>
/// <param name="bitOffset">The ordinal position of the bit to clear.
/// Any value outside the range [0..7] is treated as congruent mod 8.</param>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static byte ClearBit(byte value, int bitOffset)
=> (byte)ClearBit((uint)value, bitOffset & 7);

/// <summary>
/// Clears the specified bit in a mask and returns the new value.
/// </summary>
/// <param name="value">The value.</param>
/// <param name="bitOffset">The ordinal position of the bit to clear.
/// Any value outside the range [0..31] is treated as congruent mod 32.</param>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static uint ClearBit(uint value, int bitOffset)
=> value & ~(1u << bitOffset);

/// <summary>
/// Clears the specified bit in a mask and returns the new value.
/// </summary>
/// <param name="value">The value.</param>
/// <param name="bitOffset">The ordinal position of the bit to clear.
/// Any value outside the range [0..31] is treated as congruent mod 32.</param>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static int ClearBit(int value, int bitOffset)
=> value & ~(1 << bitOffset);

/// <summary>
/// Sets the specified bit in a mask and returns whether it was originally set.
/// Similar in behavior to the x86 instruction BTS.
/// </summary>
/// <param name="value">The value.</param>
/// <param name="bitOffset">The ordinal position of the bit to write.
/// Any value outside the range [0..7] is treated as congruent mod 8.</param>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static bool InsertBit(ref byte value, int bitOffset) // TODO: offset should maybe be uint
{
uint mask = 1u << (bitOffset & 7);

bool bts = (value & mask) != 0;
value = (byte)(value | mask);

return bts;
}

/// <summary>
/// Sets the specified bit in a mask and returns whether it was originally set.
/// Similar in behavior to the x86 instruction BTS.
/// </summary>
/// <param name="value">The value.</param>
/// <param name="bitOffset">The ordinal position of the bit to write.
/// Any value outside the range [0..31] is treated as congruent mod 32.</param>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static bool InsertBit(ref uint value, int bitOffset)
{
uint mask = 1u << bitOffset;

bool bts = (value & mask) != 0;
value |= mask;

return bts;
}

/// <summary>
/// Sets the specified bit in a mask and returns whether it was originally set.
/// Similar in behavior to the x86 instruction BTS.
/// </summary>
/// <param name="value">The value.</param>
/// <param name="bitOffset">The ordinal position of the bit to write.
/// Any value outside the range [0..31] is treated as congruent mod 32.</param>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static bool InsertBit(ref int value, int bitOffset)
{
int mask = 1 << bitOffset;

bool bts = (value & mask) != 0;
value |= mask;

return bts;
}

/// <summary>
/// Sets the specified bit in a mask and returns the new value.
/// </summary>
/// <param name="value">The value.</param>
/// <param name="bitOffset">The ordinal position of the bit to write.
/// Any value outside the range [0..7] is treated as congruent mod 8.</param>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static byte InsertBit(byte value, int bitOffset)
=> (byte)InsertBit((uint)value, bitOffset & 7);

/// <summary>
/// Sets the specified bit in a mask and returns the new value.
/// </summary>
/// <param name="value">The value.</param>
/// <param name="bitOffset">The ordinal position of the bit to write.
/// Any value outside the range [0..31] is treated as congruent mod 32.</param>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static uint InsertBit(uint value, int bitOffset)
=> value | (1u << bitOffset);

/// <summary>
/// Sets the specified bit in a mask and returns the new value.
/// </summary>
/// <param name="value">The value.</param>
/// <param name="bitOffset">The ordinal position of the bit to write.
/// Any value outside the range [0..7] is treated as congruent mod 8.</param>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static int InsertBit(int value, int bitOffset)
=> value | (1 << bitOffset);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -460,14 +460,7 @@ public static uint CountSignificantBits(uint value)

public static uint CountSignificantBits(ulong value)
{
uint upper = (uint)(value >> 32);

if (upper != 0)
{
return 32 + CountSignificantBits(upper);
}

return CountSignificantBits((uint)value);
return 64 - (uint)BitOps.LeadingZeroCount(value);
}

public static uint CountSignificantBits(ref BigInteger value)
Expand Down
4 changes: 2 additions & 2 deletions src/System.Private.CoreLib/shared/System/SpanHelpers.Char.cs
Original file line number Diff line number Diff line change
Expand Up @@ -146,7 +146,7 @@ public static unsafe bool Contains(ref char searchSpace, char value, int length)
length = (Vector<ushort>.Count - unaligned) & (Vector<ushort>.Count - 1);
}

SequentialScan:
SequentialScan:
while (length >= 4)
{
length -= 4;
Expand Down Expand Up @@ -208,7 +208,7 @@ public static unsafe bool Contains(ref char searchSpace, char value, int length)

return false;

Found:
Found:
return true;
}
}
Expand Down