diff --git a/src/libraries/System.Private.CoreLib/src/System/Int128.cs b/src/libraries/System.Private.CoreLib/src/System/Int128.cs
index 65380d43f3c739..bfc8e8c8bf0e25 100644
--- a/src/libraries/System.Private.CoreLib/src/System/Int128.cs
+++ b/src/libraries/System.Private.CoreLib/src/System/Int128.cs
@@ -1180,7 +1180,12 @@ public static Int128 Log2(Int128 value)
return lower;
}
- internal static Int128 BigMul(Int128 left, Int128 right, out Int128 lower)
+ /// Produces the full product of two unsigned native integers.
+ /// The integer to multiply with .
+ /// The integer to multiply with .
+ /// The lower half of the full product.
+ /// The upper half of the full product.
+ public static Int128 BigMul(Int128 left, Int128 right, out Int128 lower)
{
// This follows the same logic as is used in `long Math.BigMul(long, long, out long)`
diff --git a/src/libraries/System.Private.CoreLib/src/System/IntPtr.cs b/src/libraries/System.Private.CoreLib/src/System/IntPtr.cs
index e10fa3ca90c581..4abd1b935f0eb5 100644
--- a/src/libraries/System.Private.CoreLib/src/System/IntPtr.cs
+++ b/src/libraries/System.Private.CoreLib/src/System/IntPtr.cs
@@ -179,6 +179,24 @@ public static nint MinValue
get => unchecked((nint)nint_t.MinValue);
}
+ /// Produces the full product of two unsigned native integers.
+ /// The integer to multiply with .
+ /// The integer to multiply with .
+ /// The lower half of the full product.
+ /// The upper half of the full product.
+ public static nint BigMul(nint left, nint right, out nint lower)
+ {
+#if TARGET_64BIT
+ Int128 result = long.BigMul(left, right);
+ lower = (nint)result.Lower;
+ return (nint)result.Upper;
+#else
+ long result = Math.BigMul((int)left, (int)right);
+ lower = (int)result;
+ return (int)(result >>> 32);
+#endif
+ }
+
public int CompareTo(object? value)
{
if (value is nint other)
diff --git a/src/libraries/System.Private.CoreLib/src/System/UInt128.cs b/src/libraries/System.Private.CoreLib/src/System/UInt128.cs
index b6b4e59bb5545d..b76e5a04f5ce11 100644
--- a/src/libraries/System.Private.CoreLib/src/System/UInt128.cs
+++ b/src/libraries/System.Private.CoreLib/src/System/UInt128.cs
@@ -1365,7 +1365,12 @@ static uint SubtractDivisor(Span left, ReadOnlySpan right, ulong q)
return lower;
}
- internal static UInt128 BigMul(UInt128 left, UInt128 right, out UInt128 lower)
+ /// Produces the full product of two unsigned native integers.
+ /// The integer to multiply with .
+ /// The integer to multiply with .
+ /// The lower half of the full product.
+ /// The upper half of the full product.
+ public static UInt128 BigMul(UInt128 left, UInt128 right, out UInt128 lower)
{
// Adaptation of algorithm for multiplication
// of 32-bit unsigned integers described
diff --git a/src/libraries/System.Private.CoreLib/src/System/UIntPtr.cs b/src/libraries/System.Private.CoreLib/src/System/UIntPtr.cs
index 7ab359b04199bc..d940ababf1c149 100644
--- a/src/libraries/System.Private.CoreLib/src/System/UIntPtr.cs
+++ b/src/libraries/System.Private.CoreLib/src/System/UIntPtr.cs
@@ -175,6 +175,24 @@ public static nuint MinValue
get => unchecked((nuint)nuint_t.MinValue);
}
+ /// Produces the full product of two unsigned native integers.
+ /// The integer to multiply with .
+ /// The integer to multiply with .
+ /// The lower half of the full product.
+ /// The upper half of the full product.
+ public static nuint BigMul(nuint left, nuint right, out nuint lower)
+ {
+#if TARGET_64BIT
+ UInt128 result = ulong.BigMul(left, right);
+ lower = (nuint)result.Lower;
+ return (nuint)result.Upper;
+#else
+ ulong result = uint.BigMul((uint)left, (uint)right);
+ lower = (uint)result;
+ return (uint)(result >>> 32);
+#endif
+ }
+
public int CompareTo(object? value)
{
if (value is nuint other)
diff --git a/src/libraries/System.Runtime/ref/System.Runtime.cs b/src/libraries/System.Runtime/ref/System.Runtime.cs
index e27c05b00e3be4..ee744c9e438b5a 100644
--- a/src/libraries/System.Runtime/ref/System.Runtime.cs
+++ b/src/libraries/System.Runtime/ref/System.Runtime.cs
@@ -3574,6 +3574,7 @@ public InsufficientMemoryException(string? message, System.Exception? innerExcep
static int System.Numerics.INumberBase.Radix { get { throw null; } }
public static System.Int128 Zero { get { throw null; } }
public static System.Int128 Abs(System.Int128 value) { throw null; }
+ public static System.Int128 BigMul(System.Int128 left, System.Int128 right, out System.Int128 lower) { throw null; }
public static System.Int128 Clamp(System.Int128 value, System.Int128 min, System.Int128 max) { throw null; }
public int CompareTo(System.Int128 value) { throw null; }
public int CompareTo(object? value) { throw null; }
@@ -4189,6 +4190,7 @@ public InsufficientMemoryException(string? message, System.Exception? innerExcep
static nint System.Numerics.ISignedNumber.NegativeOne { get { throw null; } }
public static nint Abs(nint value) { throw null; }
public static nint Add(nint pointer, int offset) { throw null; }
+ public static nint BigMul(nint left, nint right, out nint lower) { throw null; }
public static nint Clamp(nint value, nint min, nint max) { throw null; }
public int CompareTo(nint value) { throw null; }
public int CompareTo(object? value) { throw null; }
@@ -6823,6 +6825,7 @@ public TypeUnloadedException(string? message, System.Exception? innerException)
static System.UInt128 System.Numerics.IMultiplicativeIdentity.MultiplicativeIdentity { get { throw null; } }
static int System.Numerics.INumberBase.Radix { get { throw null; } }
public static System.UInt128 Zero { get { throw null; } }
+ public static System.UInt128 BigMul(System.UInt128 left, System.UInt128 right, out System.UInt128 lower) { throw null; }
public static System.UInt128 Clamp(System.UInt128 value, System.UInt128 min, System.UInt128 max) { throw null; }
public int CompareTo(object? value) { throw null; }
public int CompareTo(System.UInt128 value) { throw null; }
@@ -7443,6 +7446,7 @@ public TypeUnloadedException(string? message, System.Exception? innerException)
static int System.Numerics.INumberBase.Radix { get { throw null; } }
static nuint System.Numerics.INumberBase.Zero { get { throw null; } }
public static nuint Add(nuint pointer, int offset) { throw null; }
+ public static nuint BigMul(nuint left, nuint right, out nuint lower) { throw null; }
public static nuint Clamp(nuint value, nuint min, nuint max) { throw null; }
public int CompareTo(object? value) { throw null; }
public int CompareTo(nuint value) { throw null; }
diff --git a/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/Int128Tests.cs b/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/Int128Tests.cs
index 4bb3f0a73a5494..ab94d43f1355aa 100644
--- a/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/Int128Tests.cs
+++ b/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/Int128Tests.cs
@@ -562,5 +562,29 @@ public static void Runtime75416()
Int128 b = (Int128.MaxValue - 10) * -100;
Assert.Equal(b, +1100);
}
+
+ public static IEnumerable