Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

UInt128 improve division by 64 bit on x64 #99747

Open
wants to merge 8 commits into
base: main
Choose a base branch
from
15 changes: 15 additions & 0 deletions src/libraries/System.Private.CoreLib/src/System/UInt128.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
using System.Numerics;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Intrinsics.X86;

namespace System
{
Expand Down Expand Up @@ -1103,6 +1104,20 @@ public static UInt128 Log2(UInt128 value)
// left and right are both uint64
return left._lower / right._lower;
}
else if (X86Base.X64.IsSupported)
{
ulong highRes = 0ul;
ulong remainder = left._upper;

#pragma warning disable SYSLIB5004 // DivRem is marked as [Experimental], partly because it does not get optmized by the JIT for constant inputs
if (remainder >= right._lower)
{
(highRes, remainder) = X86Base.X64.DivRem(left._upper, 0, right._lower);
}

return new UInt128(highRes, X86Base.X64.DivRem(left._lower, remainder, right._lower).Quotient);
#pragma warning restore SYSLIB5004 // DivRem is marked as [Experimental]
}
}

if (right >= left)
Expand Down
Loading