diff --git a/src/libraries/System.Private.CoreLib/src/System/UInt128.cs b/src/libraries/System.Private.CoreLib/src/System/UInt128.cs index a37ec00c1b2809..873ba65e7e5219 100644 --- a/src/libraries/System.Private.CoreLib/src/System/UInt128.cs +++ b/src/libraries/System.Private.CoreLib/src/System/UInt128.cs @@ -8,6 +8,7 @@ using System.Numerics; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; +using System.Runtime.Intrinsics.X86; namespace System { @@ -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)