From a6746b50d88df28ab7887ba72ffdf91a29154526 Mon Sep 17 00:00:00 2001 From: Adeel <3840695+am11@users.noreply.github.com> Date: Tue, 22 Oct 2024 03:06:57 +0300 Subject: [PATCH 01/27] Move arithmetic helpers to managed code --- src/coreclr/inc/jithelpers.h | 16 +- .../CompilerServices/RuntimeHelpers.cs | 2 + src/coreclr/nativeaot/Runtime/MathHelpers.cpp | 16 +- .../Runtime/CompilerHelpers/MathHelpers.cs | 128 ---------- .../src/System.Private.CoreLib.csproj | 1 - .../ILCompiler.Compiler/Compiler/JitHelper.cs | 16 +- src/coreclr/vm/JitQCallHelpers.h | 67 ++++++ src/coreclr/vm/corelib.h | 16 +- src/coreclr/vm/jithelpers.cpp | 204 +--------------- src/coreclr/vm/qcallentrypoints.cpp | 10 + .../System.Private.CoreLib/src/System/Math.cs | 226 ++++++++++++++++++ 11 files changed, 342 insertions(+), 360 deletions(-) delete mode 100644 src/coreclr/nativeaot/System.Private.CoreLib/src/Internal/Runtime/CompilerHelpers/MathHelpers.cs diff --git a/src/coreclr/inc/jithelpers.h b/src/coreclr/inc/jithelpers.h index 8b2a551fcfdb80..fd62d1ca49d821 100644 --- a/src/coreclr/inc/jithelpers.h +++ b/src/coreclr/inc/jithelpers.h @@ -35,10 +35,10 @@ JITHELPER(CORINFO_HELP_UNDEF, NULL, METHOD__NIL) // Arithmetic - JITHELPER(CORINFO_HELP_DIV, JIT_Div, METHOD__NIL) - JITHELPER(CORINFO_HELP_MOD, JIT_Mod, METHOD__NIL) - JITHELPER(CORINFO_HELP_UDIV, JIT_UDiv, METHOD__NIL) - JITHELPER(CORINFO_HELP_UMOD, JIT_UMod, METHOD__NIL) + DYNAMICJITHELPER(CORINFO_HELP_DIV, NULL, METHOD__MATH__DIVIDE_CHECKED) + DYNAMICJITHELPER(CORINFO_HELP_MOD, NULL, METHOD__MATH__MODULUS_CHECKED) + DYNAMICJITHELPER(CORINFO_HELP_UDIV, NULL, METHOD__MATH__DIVIDE_UNSIGNED) + DYNAMICJITHELPER(CORINFO_HELP_UMOD, NULL, METHOD__MATH__MODULUS_UNSIGNED) // CORINFO_HELP_DBL2INT, CORINFO_HELP_DBL2UINT, and CORINFO_HELP_DBL2LONG get // patched for CPUs that support SSE2 (P4 and above). @@ -59,10 +59,10 @@ DYNAMICJITHELPER(CORINFO_HELP_LMUL_OVF, NULL, METHOD__NIL) DYNAMICJITHELPER(CORINFO_HELP_ULMUL_OVF, NULL, METHOD__NIL) #endif // TARGET_64BIT - JITHELPER(CORINFO_HELP_LDIV, JIT_LDiv, METHOD__NIL) - JITHELPER(CORINFO_HELP_LMOD, JIT_LMod, METHOD__NIL) - JITHELPER(CORINFO_HELP_ULDIV, JIT_ULDiv, METHOD__NIL) - JITHELPER(CORINFO_HELP_ULMOD, JIT_ULMod, METHOD__NIL) + DYNAMICJITHELPER(CORINFO_HELP_LDIV, NULL, METHOD__MATH__DIVIDE_LONGS) + DYNAMICJITHELPER(CORINFO_HELP_LMOD, NULL, METHOD__MATH__MODULUS_LONGS) + DYNAMICJITHELPER(CORINFO_HELP_ULDIV, NULL, METHOD__MATH__DIVIDE_ULONGS) + DYNAMICJITHELPER(CORINFO_HELP_ULMOD, NULL, METHOD__MATH__MODULUS_ULONGS) JITHELPER(CORINFO_HELP_LNG2DBL, JIT_Lng2Dbl, METHOD__NIL) JITHELPER(CORINFO_HELP_ULNG2DBL, JIT_ULng2Dbl, METHOD__NIL) JITHELPER(CORINFO_HELP_DBL2INT, JIT_Dbl2Int, METHOD__NIL) diff --git a/src/coreclr/nativeaot/Runtime.Base/src/System/Runtime/CompilerServices/RuntimeHelpers.cs b/src/coreclr/nativeaot/Runtime.Base/src/System/Runtime/CompilerServices/RuntimeHelpers.cs index b06f2f3d5eb30c..6a9c7535178c3f 100644 --- a/src/coreclr/nativeaot/Runtime.Base/src/System/Runtime/CompilerServices/RuntimeHelpers.cs +++ b/src/coreclr/nativeaot/Runtime.Base/src/System/Runtime/CompilerServices/RuntimeHelpers.cs @@ -18,5 +18,7 @@ public static int OffsetToStringData [Intrinsic] public static extern void InitializeArray(Array array, RuntimeFieldHandle fldHandle); + + public const string QCall = "*"; } } diff --git a/src/coreclr/nativeaot/Runtime/MathHelpers.cpp b/src/coreclr/nativeaot/Runtime/MathHelpers.cpp index 6e3f4d73de8af2..8c35645dd8045f 100644 --- a/src/coreclr/nativeaot/Runtime/MathHelpers.cpp +++ b/src/coreclr/nativeaot/Runtime/MathHelpers.cpp @@ -56,25 +56,25 @@ FCIMPL1_D(uint32_t, RhpDbl2UInt, double val) FCIMPLEND #ifndef HOST_64BIT -EXTERN_C int64_t QCALLTYPE RhpLDiv(int64_t i, int64_t j) +EXTERN_C int64_t QCALLTYPE Math_ActualDivisionLong(int64_t i, int64_t j) { ASSERT(j && "Divide by zero!"); return i / j; } -EXTERN_C uint64_t QCALLTYPE RhpULDiv(uint64_t i, uint64_t j) +EXTERN_C uint64_t QCALLTYPE Math_ActualDivisionULong(uint64_t i, uint64_t j) { ASSERT(j && "Divide by zero!"); return i / j; } -EXTERN_C int64_t QCALLTYPE RhpLMod(int64_t i, int64_t j) +EXTERN_C int64_t QCALLTYPE Math_ActualModulusLong(int64_t i, int64_t j) { ASSERT(j && "Divide by zero!"); return i % j; } -EXTERN_C uint64_t QCALLTYPE RhpULMod(uint64_t i, uint64_t j) +EXTERN_C uint64_t QCALLTYPE Math_ActualModulusULong(uint64_t i, uint64_t j) { ASSERT(j && "Divide by zero!"); return i % j; @@ -95,25 +95,25 @@ FCIMPLEND #endif #ifdef HOST_ARM -EXTERN_C int32_t F_CALL_CONV RhpIDiv(int32_t i, int32_t j) +EXTERN_C int32_t QCALLTYPE Math_ActualDivisionInt(int32_t i, int32_t j) { ASSERT(j && "Divide by zero!"); return i / j; } -EXTERN_C uint32_t F_CALL_CONV RhpUDiv(uint32_t i, uint32_t j) +EXTERN_C uint32_t QCALLTYPE Math_ActualDivisionUInt(uint32_t i, uint32_t j) { ASSERT(j && "Divide by zero!"); return i / j; } -EXTERN_C int32_t F_CALL_CONV RhpIMod(int32_t i, int32_t j) +EXTERN_C int32_t QCALLTYPE Math_ActualModulusInt(int32_t i, int32_t j) { ASSERT(j && "Divide by zero!"); return i % j; } -EXTERN_C uint32_t F_CALL_CONV RhpUMod(uint32_t i, uint32_t j) +EXTERN_C uint32_t QCALLTYPE Math_ActualModulusUInt(uint32_t i, uint32_t j) { ASSERT(j && "Divide by zero!"); return i % j; diff --git a/src/coreclr/nativeaot/System.Private.CoreLib/src/Internal/Runtime/CompilerHelpers/MathHelpers.cs b/src/coreclr/nativeaot/System.Private.CoreLib/src/Internal/Runtime/CompilerHelpers/MathHelpers.cs deleted file mode 100644 index df8c6d407901ff..00000000000000 --- a/src/coreclr/nativeaot/System.Private.CoreLib/src/Internal/Runtime/CompilerHelpers/MathHelpers.cs +++ /dev/null @@ -1,128 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System; -using System.Diagnostics; -using System.Runtime; -using System.Runtime.CompilerServices; -using System.Runtime.InteropServices; - -namespace Internal.Runtime.CompilerHelpers -{ - /// - /// Math helpers for generated code. The helpers here are referenced by the runtime. - /// - [StackTraceHidden] - internal static partial class MathHelpers - { -#if !TARGET_64BIT - private const string RuntimeLibrary = "*"; - - [LibraryImport(RuntimeLibrary)] - [SuppressGCTransition] - private static partial ulong RhpULMod(ulong dividend, ulong divisor); - - public static ulong ULMod(ulong dividend, ulong divisor) - { - if (divisor == 0) - ThrowHelper.ThrowDivideByZeroException(); - - return RhpULMod(dividend, divisor); - } - - [LibraryImport(RuntimeLibrary)] - [SuppressGCTransition] - private static partial long RhpLMod(long dividend, long divisor); - - public static long LMod(long dividend, long divisor) - { - if (divisor == 0) - ThrowHelper.ThrowDivideByZeroException(); - if (divisor == -1 && dividend == long.MinValue) - ThrowHelper.ThrowOverflowException(); - - return RhpLMod(dividend, divisor); - } - - [LibraryImport(RuntimeLibrary)] - [SuppressGCTransition] - private static partial ulong RhpULDiv(ulong dividend, ulong divisor); - - public static ulong ULDiv(ulong dividend, ulong divisor) - { - if (divisor == 0) - ThrowHelper.ThrowDivideByZeroException(); - - return RhpULDiv(dividend, divisor); - } - - [LibraryImport(RuntimeLibrary)] - [SuppressGCTransition] - private static partial long RhpLDiv(long dividend, long divisor); - - public static long LDiv(long dividend, long divisor) - { - if (divisor == 0) - ThrowHelper.ThrowDivideByZeroException(); - if (divisor == -1 && dividend == long.MinValue) - ThrowHelper.ThrowOverflowException(); - - return RhpLDiv(dividend, divisor); - } - -#if TARGET_ARM - [RuntimeImport(RuntimeLibrary, "RhpIDiv")] - [MethodImpl(MethodImplOptions.InternalCall)] - private static extern int RhpIDiv(int dividend, int divisor); - - public static int IDiv(int dividend, int divisor) - { - if (divisor == 0) - ThrowHelper.ThrowDivideByZeroException(); - if (divisor == -1 && dividend == int.MinValue) - ThrowHelper.ThrowOverflowException(); - - return RhpIDiv(dividend, divisor); - } - - [RuntimeImport(RuntimeLibrary, "RhpUDiv")] - [MethodImpl(MethodImplOptions.InternalCall)] - private static extern uint RhpUDiv(uint dividend, uint divisor); - - public static long UDiv(uint dividend, uint divisor) - { - if (divisor == 0) - ThrowHelper.ThrowDivideByZeroException(); - - return RhpUDiv(dividend, divisor); - } - - [RuntimeImport(RuntimeLibrary, "RhpIMod")] - [MethodImpl(MethodImplOptions.InternalCall)] - private static extern int RhpIMod(int dividend, int divisor); - - public static int IMod(int dividend, int divisor) - { - if (divisor == 0) - ThrowHelper.ThrowDivideByZeroException(); - if (divisor == -1 && dividend == int.MinValue) - ThrowHelper.ThrowOverflowException(); - - return RhpIMod(dividend, divisor); - } - - [RuntimeImport(RuntimeLibrary, "RhpUMod")] - [MethodImpl(MethodImplOptions.InternalCall)] - private static extern uint RhpUMod(uint dividend, uint divisor); - - public static long UMod(uint dividend, uint divisor) - { - if (divisor == 0) - ThrowHelper.ThrowDivideByZeroException(); - - return RhpUMod(dividend, divisor); - } -#endif // TARGET_ARM -#endif // TARGET_64BIT - } -} diff --git a/src/coreclr/nativeaot/System.Private.CoreLib/src/System.Private.CoreLib.csproj b/src/coreclr/nativeaot/System.Private.CoreLib/src/System.Private.CoreLib.csproj index 038291f667bb49..ad121eb5e22b0a 100644 --- a/src/coreclr/nativeaot/System.Private.CoreLib/src/System.Private.CoreLib.csproj +++ b/src/coreclr/nativeaot/System.Private.CoreLib/src/System.Private.CoreLib.csproj @@ -116,7 +116,6 @@ - diff --git a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/JitHelper.cs b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/JitHelper.cs index 8861535467c8ca..4bbc0d09485fbe 100644 --- a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/JitHelper.cs +++ b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/JitHelper.cs @@ -234,29 +234,29 @@ public static void GetEntryPoint(TypeSystemContext context, ReadyToRunHelper id, break; case ReadyToRunHelper.Mod: - methodDesc = context.GetHelperEntryPoint("MathHelpers", "IMod"); + methodDesc = context.SystemModule.GetKnownType("System", "Math").GetKnownMethod("ModulusChecked", null); break; case ReadyToRunHelper.UMod: - methodDesc = context.GetHelperEntryPoint("MathHelpers", "UMod"); + methodDesc = context.SystemModule.GetKnownType("System", "Math").GetKnownMethod("ModulusUnsigned", null); break; case ReadyToRunHelper.ULMod: - methodDesc = context.GetHelperEntryPoint("MathHelpers", "ULMod"); + methodDesc = context.SystemModule.GetKnownType("System", "Math").GetKnownMethod("ModulusUnsignedLongs", null); break; case ReadyToRunHelper.LMod: - methodDesc = context.GetHelperEntryPoint("MathHelpers", "LMod"); + methodDesc = context.SystemModule.GetKnownType("System", "Math").GetKnownMethod("ModulusLongs", null); break; case ReadyToRunHelper.Div: - methodDesc = context.GetHelperEntryPoint("MathHelpers", "IDiv"); + methodDesc = context.SystemModule.GetKnownType("System", "Math").GetKnownMethod("DivideChecked", null); break; case ReadyToRunHelper.UDiv: - methodDesc = context.GetHelperEntryPoint("MathHelpers", "UDiv"); + methodDesc = context.SystemModule.GetKnownType("System", "Math").GetKnownMethod("DivideUnsigned", null); break; case ReadyToRunHelper.ULDiv: - methodDesc = context.GetHelperEntryPoint("MathHelpers", "ULDiv"); + methodDesc = context.SystemModule.GetKnownType("System", "Math").GetKnownMethod("DivideUnsignedLongs", null); break; case ReadyToRunHelper.LDiv: - methodDesc = context.GetHelperEntryPoint("MathHelpers", "LDiv"); + methodDesc = context.SystemModule.GetKnownType("System", "Math").GetKnownMethod("DivideLongs", null); break; case ReadyToRunHelper.LRsz: diff --git a/src/coreclr/vm/JitQCallHelpers.h b/src/coreclr/vm/JitQCallHelpers.h index fbef97b52a38e1..32eb58717980cf 100644 --- a/src/coreclr/vm/JitQCallHelpers.h +++ b/src/coreclr/vm/JitQCallHelpers.h @@ -22,4 +22,71 @@ extern "C" void * QCALLTYPE ResolveVirtualFunctionPointer(QCall::ObjectHandleOnS extern "C" CORINFO_GENERIC_HANDLE QCALLTYPE GenericHandleWorker(MethodDesc * pMD, MethodTable * pMT, LPVOID signature, DWORD dictionaryIndexAndSlot, Module* pModule); extern "C" void QCALLTYPE InitClassHelper(MethodTable* pMT); +#ifdef TARGET_32BIT +extern "C" int32_t QCALLTYPE Math_ActualDivisionInt(int32_t i, int32_t j) +{ + QCALL_CONTRACT_NO_GC_TRANSITION + + ASSERT(j && "Divide by zero!"); + return i / j; +} + +extern "C" uint32_t QCALLTYPE Math_ActualDivisionUInt(uint32_t i, uint32_t j) +{ + QCALL_CONTRACT_NO_GC_TRANSITION + + ASSERT(j && "Divide by zero!"); + return i / j; +} + +extern "C" int32_t QCALLTYPE Math_ActualModulusInt(int32_t i, int32_t j) +{ + QCALL_CONTRACT_NO_GC_TRANSITION + + ASSERT(j && "Divide by zero!"); + return i % j; +} + +extern "C" uint32_t QCALLTYPE Math_ActualModulusUInt(uint32_t i, uint32_t j) +{ + QCALL_CONTRACT_NO_GC_TRANSITION + + ASSERT(j && "Divide by zero!"); + return i % j; +} + +extern "C" int64_t QCALLTYPE Math_ActualDivisionLong(int64_t i, int64_t j) +{ + QCALL_CONTRACT_NO_GC_TRANSITION + + ASSERT(j && "Divide by zero!"); + return i / j; +} + +extern "C" uint64_t QCALLTYPE Math_ActualDivisionULong(uint64_t i, uint64_t j) +{ + QCALL_CONTRACT_NO_GC_TRANSITION + + ASSERT(j && "Divide by zero!"); + return i / j; +} + +extern "C" int64_t QCALLTYPE Math_ActualModulusLong(int64_t i, int64_t j) +{ + QCALL_CONTRACT_NO_GC_TRANSITION + + ASSERT(j && "Divide by zero!"); + return i % j; +} + +extern "C" uint64_t QCALLTYPE Math_ActualModulusULong(uint64_t i, uint64_t j) +{ + QCALL_CONTRACT_NO_GC_TRANSITION + + ASSERT(j && "Divide by zero!"); + return i % j; +} + +#endif // TARGET_32BIT + #endif //_JITQCALLHELPERS_H diff --git a/src/coreclr/vm/corelib.h b/src/coreclr/vm/corelib.h index b4302ef9bb2895..bdbcc921d3c6b2 100644 --- a/src/coreclr/vm/corelib.h +++ b/src/coreclr/vm/corelib.h @@ -263,10 +263,18 @@ DEFINE_CLASS(MATH, System, Math) DEFINE_METHOD(MATH, MULTIPLY_CHECKED_INT64, MultiplyChecked, SM_Long_Long_RetLong) DEFINE_METHOD(MATH, MULTIPLY_CHECKED_UINT64, MultiplyChecked, SM_ULong_ULong_RetULong) #endif -DEFINE_METHOD(MATH, CONVERT_TO_INT32_CHECKED, ConvertToInt32Checked, NoSig) -DEFINE_METHOD(MATH, CONVERT_TO_UINT32_CHECKED, ConvertToUInt32Checked, NoSig) -DEFINE_METHOD(MATH, CONVERT_TO_INT64_CHECKED, ConvertToInt64Checked, NoSig) -DEFINE_METHOD(MATH, CONVERT_TO_UINT64_CHECKED, ConvertToUInt64Checked, NoSig) +DEFINE_METHOD(MATH, CONVERT_TO_INT32_CHECKED, ConvertToInt32Checked, NoSig) +DEFINE_METHOD(MATH, CONVERT_TO_UINT32_CHECKED, ConvertToUInt32Checked, NoSig) +DEFINE_METHOD(MATH, CONVERT_TO_INT64_CHECKED, ConvertToInt64Checked, NoSig) +DEFINE_METHOD(MATH, CONVERT_TO_UINT64_CHECKED, ConvertToUInt64Checked, NoSig) +DEFINE_METHOD(MATH, DIVIDE_CHECKED, DivideChecked, NoSig) +DEFINE_METHOD(MATH, MODULUS_CHECKED, ModulusChecked, NoSig) +DEFINE_METHOD(MATH, DIVIDE_UNSIGNED, DivideUnsigned, NoSig) +DEFINE_METHOD(MATH, MODULUS_UNSIGNED, ModulusUnsigned, NoSig) +DEFINE_METHOD(MATH, DIVIDE_LONGS, DivideLongs, NoSig) +DEFINE_METHOD(MATH, MODULUS_LONGS, ModulusLongs, NoSig) +DEFINE_METHOD(MATH, DIVIDE_ULONGS, DivideUnsignedLongs, NoSig) +DEFINE_METHOD(MATH, MODULUS_ULONGS, ModulusUnsignedLongs, NoSig) DEFINE_CLASS(DYNAMICMETHOD, ReflectionEmit, DynamicMethod) diff --git a/src/coreclr/vm/jithelpers.cpp b/src/coreclr/vm/jithelpers.cpp index 182cdaa539002e..94343e3b8d8389 100644 --- a/src/coreclr/vm/jithelpers.cpp +++ b/src/coreclr/vm/jithelpers.cpp @@ -126,208 +126,6 @@ HCIMPL2_VV(INT64, JIT_LMul, INT64 val1, INT64 val2) HCIMPLEND #endif // !TARGET_X86 || TARGET_UNIX -/*********************************************************************/ -HCIMPL2(INT32, JIT_Div, INT32 dividend, INT32 divisor) -{ - FCALL_CONTRACT; - - RuntimeExceptionKind ehKind; - - if (((UINT32) (divisor + 1)) <= 1) // Unsigned test for divisor in [-1 .. 0] - { - if (divisor == 0) - { - ehKind = kDivideByZeroException; - goto ThrowExcep; - } - else if (divisor == -1) - { - if (dividend == INT32_MIN) - { - ehKind = kOverflowException; - goto ThrowExcep; - } - return -dividend; - } - } - - return(dividend / divisor); - -ThrowExcep: - FCThrow(ehKind); -} -HCIMPLEND - -/*********************************************************************/ -HCIMPL2(INT32, JIT_Mod, INT32 dividend, INT32 divisor) -{ - FCALL_CONTRACT; - - RuntimeExceptionKind ehKind; - - if (((UINT32) (divisor + 1)) <= 1) // Unsigned test for divisor in [-1 .. 0] - { - if (divisor == 0) - { - ehKind = kDivideByZeroException; - goto ThrowExcep; - } - else if (divisor == -1) - { - if (dividend == INT32_MIN) - { - ehKind = kOverflowException; - goto ThrowExcep; - } - return 0; - } - } - - return(dividend % divisor); - -ThrowExcep: - FCThrow(ehKind); -} -HCIMPLEND - -/*********************************************************************/ -HCIMPL2(UINT32, JIT_UDiv, UINT32 dividend, UINT32 divisor) -{ - FCALL_CONTRACT; - - if (divisor == 0) - FCThrow(kDivideByZeroException); - - return(dividend / divisor); -} -HCIMPLEND - -/*********************************************************************/ -HCIMPL2(UINT32, JIT_UMod, UINT32 dividend, UINT32 divisor) -{ - FCALL_CONTRACT; - - if (divisor == 0) - FCThrow(kDivideByZeroException); - - return(dividend % divisor); -} -HCIMPLEND - -/*********************************************************************/ -HCIMPL2_VV(INT64, JIT_LDiv, INT64 dividend, INT64 divisor) -{ - FCALL_CONTRACT; - - RuntimeExceptionKind ehKind; - - if (Is32BitSigned(divisor)) - { - if ((INT32)divisor == 0) - { - ehKind = kDivideByZeroException; - goto ThrowExcep; - } - - if ((INT32)divisor == -1) - { - if ((UINT64) dividend == UI64(0x8000000000000000)) - { - ehKind = kOverflowException; - goto ThrowExcep; - } - return -dividend; - } - - // Check for -ive or +ive numbers in the range -2**31 to 2**31 - if (Is32BitSigned(dividend)) - return((INT32)dividend / (INT32)divisor); - } - - // For all other combinations fallback to int64 div. - return(dividend / divisor); - -ThrowExcep: - FCThrow(ehKind); -} -HCIMPLEND - -/*********************************************************************/ -HCIMPL2_VV(INT64, JIT_LMod, INT64 dividend, INT64 divisor) -{ - FCALL_CONTRACT; - - RuntimeExceptionKind ehKind; - - if (Is32BitSigned(divisor)) - { - if ((INT32)divisor == 0) - { - ehKind = kDivideByZeroException; - goto ThrowExcep; - } - - if ((INT32)divisor == -1) - { - // TODO, we really should remove this as it lengthens the code path - // and the spec really says that it should not throw an exception. - if ((UINT64) dividend == UI64(0x8000000000000000)) - { - ehKind = kOverflowException; - goto ThrowExcep; - } - return 0; - } - - // Check for -ive or +ive numbers in the range -2**31 to 2**31 - if (Is32BitSigned(dividend)) - return((INT32)dividend % (INT32)divisor); - } - - // For all other combinations fallback to int64 div. - return(dividend % divisor); - -ThrowExcep: - FCThrow(ehKind); -} -HCIMPLEND - -/*********************************************************************/ -HCIMPL2_VV(UINT64, JIT_ULDiv, UINT64 dividend, UINT64 divisor) -{ - FCALL_CONTRACT; - - if (Hi32Bits(divisor) == 0) - { - if ((UINT32)(divisor) == 0) - FCThrow(kDivideByZeroException); - - if (Hi32Bits(dividend) == 0) - return((UINT32)dividend / (UINT32)divisor); - } - - return(dividend / divisor); -} -HCIMPLEND - -/*********************************************************************/ -HCIMPL2_VV(UINT64, JIT_ULMod, UINT64 dividend, UINT64 divisor) -{ - FCALL_CONTRACT; - - if (Hi32Bits(divisor) == 0) - { - if ((UINT32)(divisor) == 0) - FCThrow(kDivideByZeroException); - - if (Hi32Bits(dividend) == 0) - return((UINT32)dividend % (UINT32)divisor); - } - - return(dividend % divisor); -} -HCIMPLEND - #if !defined(HOST_64BIT) && !defined(TARGET_X86) /*********************************************************************/ HCIMPL2_VV(UINT64, JIT_LLsh, UINT64 num, int shift) @@ -4528,7 +4326,7 @@ bool IndirectionAllowedForJitHelper(CorInfoHelpFunc ftnNum) { return false; } - + return true; } diff --git a/src/coreclr/vm/qcallentrypoints.cpp b/src/coreclr/vm/qcallentrypoints.cpp index 356ce7a1792d40..6add0edc05e5fc 100644 --- a/src/coreclr/vm/qcallentrypoints.cpp +++ b/src/coreclr/vm/qcallentrypoints.cpp @@ -503,6 +503,16 @@ static const Entry s_QCall[] = DllImportEntry(InitClassHelper) DllImportEntry(ResolveVirtualFunctionPointer) DllImportEntry(GenericHandleWorker) +#ifdef TARGET_32BIT + DllImportEntry(Math_ActualDivisionInt) + DllImportEntry(Math_ActualDivisionUInt) + DllImportEntry(Math_ActualModulusInt) + DllImportEntry(Math_ActualModulusUInt) + DllImportEntry(Math_ActualDivisionLong) + DllImportEntry(Math_ActualDivisionULong) + DllImportEntry(Math_ActualModulusLong) + DllImportEntry(Math_ActualModulusULong) +#endif // TARGET_32BIT }; const void* QCallResolveDllImport(const char* name) diff --git a/src/libraries/System.Private.CoreLib/src/System/Math.cs b/src/libraries/System.Private.CoreLib/src/System/Math.cs index 32c3eee4712bfc..0cd9c785f690e0 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Math.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Math.cs @@ -14,6 +14,10 @@ using System.Runtime.Intrinsics.X86; using System.Runtime.Versioning; +#if TARGET_32BIT +using System.Runtime.InteropServices; +#endif + namespace System { /// @@ -1682,5 +1686,227 @@ internal static ulong ConvertToUInt64Checked(double value) ThrowHelper.ThrowOverflowException(); return 0; } + + [StackTraceHidden] + internal static int DivideChecked(int dividend, int divisor) + { +#if TARGET_32BIT + if ((uint)(divisor + 1) <= 1) + { + if (divisor == 0) + { + ThrowHelper.ThrowDivideByZeroException(); + } + else if (divisor == -1) + { + if (dividend == int.MinValue) + { + ThrowHelper.ThrowOverflowException(); + } + return -dividend; + } + } + + return ActualDivisionInt(dividend, divisor); +#else + return DivideChecked(dividend, divisor); +#endif + } + + [StackTraceHidden] + internal static int ModulusChecked(int dividend, int divisor) + { +#if TARGET_32BIT + if ((uint)(divisor + 1) <= 1) + { + if (divisor == 0) + { + ThrowHelper.ThrowDivideByZeroException(); + } + else if (divisor == -1) + { + if (dividend == int.MinValue) + { + ThrowHelper.ThrowOverflowException(); + } + return 0; + } + } + + return ActualModulusInt(dividend, divisor); +#else + return ModulusChecked(dividend, divisor); +#endif + } + + [StackTraceHidden] + internal static uint DivideUnsigned(uint dividend, uint divisor) + { +#if TARGET_32BIT + if (divisor == 0) + { + ThrowHelper.ThrowDivideByZeroException(); + } + + return ActualDivisionUInt(dividend, divisor); +#else + return DivideUnsigned(dividend, divisor); +#endif + } + + [StackTraceHidden] + internal static uint ModulusUnsigned(uint dividend, uint divisor) + { +#if TARGET_32BIT + if (divisor == 0) + { + ThrowHelper.ThrowDivideByZeroException(); + } + + return ActualModulusUInt(dividend, divisor); +#else + return ModulusUnsigned(dividend, divisor); +#endif + } + + [StackTraceHidden] + internal static long DivideLongs(long dividend, long divisor) + { +#if TARGET_32BIT + if ((uint)(divisor + 1) <= 1) + { + if ((int)divisor == 0) + { + ThrowHelper.ThrowDivideByZeroException(); + } + + if ((int)divisor == -1) + { + if ((ulong)dividend == 0x8000000000000000) + { + ThrowHelper.ThrowOverflowException(); + } + return -dividend; + } + + if ((ulong)dividend >> 32 == 0 || (ulong)dividend >> 32 == 0xFFFFFFFF) + { + return (int)dividend / (int)divisor; + } + } + + return ActualDivisionLong(dividend, divisor); +#else + return DivideLongs(dividend, divisor); +#endif + } + + [StackTraceHidden] + internal static long ModulusLongs(long dividend, long divisor) + { +#if TARGET_32BIT + if ((uint)(divisor + 1) <= 1) + { + if ((int)divisor == 0) + { + ThrowHelper.ThrowDivideByZeroException(); + } + + if ((int)divisor == -1) + { + if ((ulong)dividend == 0x8000000000000000) + { + ThrowHelper.ThrowOverflowException(); + } + return 0; + } + + if ((ulong)dividend >> 32 == 0 || (ulong)dividend >> 32 == 0xFFFFFFFF) + { + return (int)dividend % (int)divisor; + } + } + + return ActualModulusLong(dividend, divisor); +#else + return ModulusLongs(dividend, divisor); +#endif + } + + [StackTraceHidden] + internal static ulong DivideUnsignedLongs(ulong dividend, ulong divisor) + { +#if TARGET_32BIT + if ((divisor >> 32) == 0) + { + if ((uint)divisor == 0) + { + ThrowHelper.ThrowDivideByZeroException(); + } + + if ((dividend >> 32) == 0) + return (uint)dividend / (uint)divisor; + } + + return ActualDivisionULong(dividend, divisor); +#else + return DivideUnsignedLongs(dividend, divisor); +#endif + } + + [StackTraceHidden] + internal static ulong ModulusUnsignedLongs(ulong dividend, ulong divisor) + { +#if TARGET_32BIT + if ((divisor >> 32) == 0) + { + if ((uint)divisor == 0) + { + ThrowHelper.ThrowDivideByZeroException(); + } + + if ((dividend >> 32) == 0) + return (uint)dividend % (uint)divisor; + } + + return ActualModulusULong(dividend, divisor); +#else + return ModulusUnsignedLongs(dividend, divisor); +#endif + } + +#if TARGET_32BIT + [LibraryImport(RuntimeHelpers.QCall, EntryPoint = "Math_ActualDivisionInt")] + [SuppressGCTransition] + private static partial int ActualDivisionInt(int dividend, int divisor); + + [LibraryImport(RuntimeHelpers.QCall, EntryPoint = "Math_ActualModulusInt")] + [SuppressGCTransition] + private static partial int ActualModulusInt(int dividend, int divisor); + + [LibraryImport(RuntimeHelpers.QCall, EntryPoint = "Math_ActualDivisionUInt")] + [SuppressGCTransition] + private static partial uint ActualDivisionUInt(uint dividend, uint divisor); + + [LibraryImport(RuntimeHelpers.QCall, EntryPoint = "Math_ActualModulusUInt")] + [SuppressGCTransition] + private static partial uint ActualModulusUInt(uint dividend, uint divisor); + + [LibraryImport(RuntimeHelpers.QCall, EntryPoint = "Math_ActualDivisionLong")] + [SuppressGCTransition] + private static partial long ActualDivisionLong(long dividend, long divisor); + + [LibraryImport(RuntimeHelpers.QCall, EntryPoint = "Math_ActualModulusLong")] + [SuppressGCTransition] + private static partial long ActualModulusLong(long dividend, long divisor); + + [LibraryImport(RuntimeHelpers.QCall, EntryPoint = "Math_ActualDivisionULong")] + [SuppressGCTransition] + private static partial ulong ActualDivisionULong(ulong dividend, ulong divisor); + + [LibraryImport(RuntimeHelpers.QCall, EntryPoint = "Math_ActualModulusULong")] + [SuppressGCTransition] + private static partial ulong ActualModulusULong(ulong dividend, ulong divisor); +#endif } } From 2a86f4df758e45c53a910bebd30a5e51be3371ec Mon Sep 17 00:00:00 2001 From: Adeel <3840695+am11@users.noreply.github.com> Date: Thu, 24 Oct 2024 15:00:44 +0300 Subject: [PATCH 02/27] Convert to FCall --- .../classlibnative/float/CMakeLists.txt | 1 + .../classlibnative/float/divmodint.cpp | 60 +++++ src/coreclr/classlibnative/inc/divmodint.h | 22 ++ src/coreclr/inc/jithelpers.h | 39 +-- .../CompilerServices/RuntimeHelpers.cs | 2 - src/coreclr/nativeaot/Runtime/MathHelpers.cpp | 16 +- .../ILCompiler.Compiler/Compiler/JitHelper.cs | 32 +-- src/coreclr/vm/JitQCallHelpers.h | 67 ------ src/coreclr/vm/corelib.cpp | 1 + src/coreclr/vm/corelib.h | 25 +- src/coreclr/vm/ecalllist.h | 10 + src/coreclr/vm/qcallentrypoints.cpp | 10 - .../System.Private.CoreLib.Shared.projitems | 3 +- .../src/System/Math.DivModInt.cs | 208 ++++++++++++++++ .../System.Private.CoreLib/src/System/Math.cs | 226 ------------------ 15 files changed, 365 insertions(+), 357 deletions(-) create mode 100644 src/coreclr/classlibnative/float/divmodint.cpp create mode 100644 src/coreclr/classlibnative/inc/divmodint.h create mode 100644 src/libraries/System.Private.CoreLib/src/System/Math.DivModInt.cs diff --git a/src/coreclr/classlibnative/float/CMakeLists.txt b/src/coreclr/classlibnative/float/CMakeLists.txt index 1dbe160248f26e..c6153d5d34c096 100644 --- a/src/coreclr/classlibnative/float/CMakeLists.txt +++ b/src/coreclr/classlibnative/float/CMakeLists.txt @@ -3,6 +3,7 @@ include_directories("../inc") set(FLOAT_SOURCES floatdouble.cpp floatsingle.cpp + divmodint.cpp ) add_library_clr(comfloat_wks OBJECT ${FLOAT_SOURCES}) diff --git a/src/coreclr/classlibnative/float/divmodint.cpp b/src/coreclr/classlibnative/float/divmodint.cpp new file mode 100644 index 00000000000000..1cdffb70c09494 --- /dev/null +++ b/src/coreclr/classlibnative/float/divmodint.cpp @@ -0,0 +1,60 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +#ifdef TARGET_32BIT + +#include + +#include "divmodint.h" + +#include + +FCIMPL2(int32_t, COMDivModInt::DivInt32, int32_t dividend, int32_t divisor) + FCALL_CONTRACT; + + return dividend / divisor; +FCIMPLEND + +FCIMPL2(uint32_t, COMDivModInt::DivUInt32, uint32_t dividend, uint32_t divisor) + FCALL_CONTRACT; + + return dividend / divisor; +FCIMPLEND + +FCIMPL2(int64_t, COMDivModInt::DivInt64, int64_t dividend, int64_t divisor) + FCALL_CONTRACT; + + return dividend / divisor; +FCIMPLEND + +FCIMPL2(uint64_t, COMDivModInt::DivUInt64, uint64_t dividend, uint64_t divisor) + FCALL_CONTRACT; + + return dividend / divisor; +FCIMPLEND + +FCIMPL2(int32_t, COMDivModInt::ModInt32, int32_t dividend, int32_t divisor) + FCALL_CONTRACT; + + return dividend % divisor; +FCIMPLEND + +FCIMPL2(uint32_t, COMDivModInt::ModUInt32, uint32_t dividend, uint32_t divisor) + FCALL_CONTRACT; + + return dividend % divisor; +FCIMPLEND + +FCIMPL2(int64_t, COMDivModInt::ModInt64, int64_t dividend, int64_t divisor) + FCALL_CONTRACT; + + return dividend % divisor; +FCIMPLEND + +FCIMPL2(uint64_t, COMDivModInt::ModUInt64, uint64_t dividend, uint64_t divisor) + FCALL_CONTRACT; + + return dividend % divisor; +FCIMPLEND + +#endif // TARGET_32BIT diff --git a/src/coreclr/classlibnative/inc/divmodint.h b/src/coreclr/classlibnative/inc/divmodint.h new file mode 100644 index 00000000000000..bba1317e41e251 --- /dev/null +++ b/src/coreclr/classlibnative/inc/divmodint.h @@ -0,0 +1,22 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +#ifndef _DIVMODINT_H_ +#define _DIVMODINT_H_ + +#include +#include + +class COMDivModInt { +public: + FCDECL2(static int32_t, DivInt32, int32_t dividend, int32_t divisor); + FCDECL2(static uint32_t, DivUInt32, uint32_t dividend, uint32_t divisor); + FCDECL2(static int64_t, DivInt64, int64_t dividend, int64_t divisor); + FCDECL2(static uint64_t, DivUInt64, uint64_t dividend, uint64_t divisor); + FCDECL2(static int32_t, ModInt32, int32_t dividend, int32_t divisor); + FCDECL2(static uint32_t, ModUInt32, uint32_t dividend, uint32_t divisor); + FCDECL2(static int64_t, ModInt64, int64_t dividend, int64_t divisor); + FCDECL2(static uint64_t, ModUInt64, uint64_t dividend, uint64_t divisor); +}; + +#endif // _DIVMODINT_H_ diff --git a/src/coreclr/inc/jithelpers.h b/src/coreclr/inc/jithelpers.h index fd62d1ca49d821..e5fdfedb90b331 100644 --- a/src/coreclr/inc/jithelpers.h +++ b/src/coreclr/inc/jithelpers.h @@ -34,35 +34,44 @@ JITHELPER(CORINFO_HELP_UNDEF, NULL, METHOD__NIL) - // Arithmetic - DYNAMICJITHELPER(CORINFO_HELP_DIV, NULL, METHOD__MATH__DIVIDE_CHECKED) - DYNAMICJITHELPER(CORINFO_HELP_MOD, NULL, METHOD__MATH__MODULUS_CHECKED) - DYNAMICJITHELPER(CORINFO_HELP_UDIV, NULL, METHOD__MATH__DIVIDE_UNSIGNED) - DYNAMICJITHELPER(CORINFO_HELP_UMOD, NULL, METHOD__MATH__MODULUS_UNSIGNED) - // CORINFO_HELP_DBL2INT, CORINFO_HELP_DBL2UINT, and CORINFO_HELP_DBL2LONG get // patched for CPUs that support SSE2 (P4 and above). -#ifndef TARGET_64BIT +#ifdef TARGET_32BIT + // Arithmetic + DYNAMICJITHELPER(CORINFO_HELP_DIV, NULL, METHOD__MATH__DIV_INT32) + DYNAMICJITHELPER(CORINFO_HELP_MOD, NULL, METHOD__MATH__MOD_INT32) + DYNAMICJITHELPER(CORINFO_HELP_UDIV, NULL, METHOD__MATH__DIV_UINT32) + DYNAMICJITHELPER(CORINFO_HELP_UMOD, NULL, METHOD__MATH__MOD_UINT32) + JITHELPER(CORINFO_HELP_LLSH, JIT_LLsh, METHOD__NIL) JITHELPER(CORINFO_HELP_LRSH, JIT_LRsh, METHOD__NIL) JITHELPER(CORINFO_HELP_LRSZ, JIT_LRsz, METHOD__NIL) -#else // !TARGET_64BIT +#else // TARGET_32BIT + DYNAMICJITHELPER(CORINFO_HELP_DIV, NULL, METHOD__NIL) + DYNAMICJITHELPER(CORINFO_HELP_MOD, NULL, METHOD__NIL) + DYNAMICJITHELPER(CORINFO_HELP_UDIV, NULL, METHOD__NIL) + DYNAMICJITHELPER(CORINFO_HELP_UMOD, NULL, METHOD__NIL) + JITHELPER(CORINFO_HELP_LLSH, NULL, METHOD__NIL) JITHELPER(CORINFO_HELP_LRSH, NULL, METHOD__NIL) JITHELPER(CORINFO_HELP_LRSZ, NULL, METHOD__NIL) -#endif // TARGET_64BIT +#endif // TARGET_32BIT JITHELPER(CORINFO_HELP_LMUL, JIT_LMul, METHOD__NIL) -#ifndef TARGET_64BIT +#ifdef TARGET_32BIT DYNAMICJITHELPER(CORINFO_HELP_LMUL_OVF, NULL, METHOD__MATH__MULTIPLY_CHECKED_INT64) DYNAMICJITHELPER(CORINFO_HELP_ULMUL_OVF, NULL, METHOD__MATH__MULTIPLY_CHECKED_UINT64) + DYNAMICJITHELPER(CORINFO_HELP_LDIV, NULL, METHOD__MATH__DIV_INT64) + DYNAMICJITHELPER(CORINFO_HELP_LMOD, NULL, METHOD__MATH__MOD_INT64) + DYNAMICJITHELPER(CORINFO_HELP_ULDIV, NULL, METHOD__MATH__DIV_UINT64) + DYNAMICJITHELPER(CORINFO_HELP_ULMOD, NULL, METHOD__MATH__MOD_UINT64) #else DYNAMICJITHELPER(CORINFO_HELP_LMUL_OVF, NULL, METHOD__NIL) DYNAMICJITHELPER(CORINFO_HELP_ULMUL_OVF, NULL, METHOD__NIL) -#endif // TARGET_64BIT - DYNAMICJITHELPER(CORINFO_HELP_LDIV, NULL, METHOD__MATH__DIVIDE_LONGS) - DYNAMICJITHELPER(CORINFO_HELP_LMOD, NULL, METHOD__MATH__MODULUS_LONGS) - DYNAMICJITHELPER(CORINFO_HELP_ULDIV, NULL, METHOD__MATH__DIVIDE_ULONGS) - DYNAMICJITHELPER(CORINFO_HELP_ULMOD, NULL, METHOD__MATH__MODULUS_ULONGS) + DYNAMICJITHELPER(CORINFO_HELP_LDIV, NULL, METHOD__NIL) + DYNAMICJITHELPER(CORINFO_HELP_LMOD, NULL, METHOD__NIL) + DYNAMICJITHELPER(CORINFO_HELP_ULDIV, NULL, METHOD__NIL) + DYNAMICJITHELPER(CORINFO_HELP_ULMOD, NULL, METHOD__NIL) +#endif // TARGET_32BIT JITHELPER(CORINFO_HELP_LNG2DBL, JIT_Lng2Dbl, METHOD__NIL) JITHELPER(CORINFO_HELP_ULNG2DBL, JIT_ULng2Dbl, METHOD__NIL) JITHELPER(CORINFO_HELP_DBL2INT, JIT_Dbl2Int, METHOD__NIL) diff --git a/src/coreclr/nativeaot/Runtime.Base/src/System/Runtime/CompilerServices/RuntimeHelpers.cs b/src/coreclr/nativeaot/Runtime.Base/src/System/Runtime/CompilerServices/RuntimeHelpers.cs index 6a9c7535178c3f..b06f2f3d5eb30c 100644 --- a/src/coreclr/nativeaot/Runtime.Base/src/System/Runtime/CompilerServices/RuntimeHelpers.cs +++ b/src/coreclr/nativeaot/Runtime.Base/src/System/Runtime/CompilerServices/RuntimeHelpers.cs @@ -18,7 +18,5 @@ public static int OffsetToStringData [Intrinsic] public static extern void InitializeArray(Array array, RuntimeFieldHandle fldHandle); - - public const string QCall = "*"; } } diff --git a/src/coreclr/nativeaot/Runtime/MathHelpers.cpp b/src/coreclr/nativeaot/Runtime/MathHelpers.cpp index 8c35645dd8045f..76ac591e85a015 100644 --- a/src/coreclr/nativeaot/Runtime/MathHelpers.cpp +++ b/src/coreclr/nativeaot/Runtime/MathHelpers.cpp @@ -56,25 +56,25 @@ FCIMPL1_D(uint32_t, RhpDbl2UInt, double val) FCIMPLEND #ifndef HOST_64BIT -EXTERN_C int64_t QCALLTYPE Math_ActualDivisionLong(int64_t i, int64_t j) +EXTERN_C int64_t F_CALL_CONV InternalDivInt64(int64_t i, int64_t j) { ASSERT(j && "Divide by zero!"); return i / j; } -EXTERN_C uint64_t QCALLTYPE Math_ActualDivisionULong(uint64_t i, uint64_t j) +EXTERN_C uint64_t F_CALL_CONV InternalDivUInt64(uint64_t i, uint64_t j) { ASSERT(j && "Divide by zero!"); return i / j; } -EXTERN_C int64_t QCALLTYPE Math_ActualModulusLong(int64_t i, int64_t j) +EXTERN_C int64_t F_CALL_CONV InternalModInt64(int64_t i, int64_t j) { ASSERT(j && "Divide by zero!"); return i % j; } -EXTERN_C uint64_t QCALLTYPE Math_ActualModulusULong(uint64_t i, uint64_t j) +EXTERN_C uint64_t F_CALL_CONV InternalModUInt64(uint64_t i, uint64_t j) { ASSERT(j && "Divide by zero!"); return i % j; @@ -95,25 +95,25 @@ FCIMPLEND #endif #ifdef HOST_ARM -EXTERN_C int32_t QCALLTYPE Math_ActualDivisionInt(int32_t i, int32_t j) +EXTERN_C int32_t F_CALL_CONV InternalDivInt32(int32_t i, int32_t j) { ASSERT(j && "Divide by zero!"); return i / j; } -EXTERN_C uint32_t QCALLTYPE Math_ActualDivisionUInt(uint32_t i, uint32_t j) +EXTERN_C uint32_t F_CALL_CONV InternalDivUInt32(uint32_t i, uint32_t j) { ASSERT(j && "Divide by zero!"); return i / j; } -EXTERN_C int32_t QCALLTYPE Math_ActualModulusInt(int32_t i, int32_t j) +EXTERN_C int32_t F_CALL_CONV InternalModInt32(int32_t i, int32_t j) { ASSERT(j && "Divide by zero!"); return i % j; } -EXTERN_C uint32_t QCALLTYPE Math_ActualModulusUInt(uint32_t i, uint32_t j) +EXTERN_C uint32_t F_CALL_CONV InternalModUInt32(uint32_t i, uint32_t j) { ASSERT(j && "Divide by zero!"); return i % j; diff --git a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/JitHelper.cs b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/JitHelper.cs index 4bbc0d09485fbe..e3bfed27e42bdf 100644 --- a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/JitHelper.cs +++ b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/JitHelper.cs @@ -233,30 +233,30 @@ public static void GetEntryPoint(TypeSystemContext context, ReadyToRunHelper id, } break; - case ReadyToRunHelper.Mod: - methodDesc = context.SystemModule.GetKnownType("System", "Math").GetKnownMethod("ModulusChecked", null); + case ReadyToRunHelper.Div: + methodDesc = context.SystemModule.GetKnownType("System", "Math").GetKnownMethod("DivInt32", null); break; - case ReadyToRunHelper.UMod: - methodDesc = context.SystemModule.GetKnownType("System", "Math").GetKnownMethod("ModulusUnsigned", null); + case ReadyToRunHelper.UDiv: + methodDesc = context.SystemModule.GetKnownType("System", "Math").GetKnownMethod("DivUInt32", null); break; - case ReadyToRunHelper.ULMod: - methodDesc = context.SystemModule.GetKnownType("System", "Math").GetKnownMethod("ModulusUnsignedLongs", null); + case ReadyToRunHelper.LDiv: + methodDesc = context.SystemModule.GetKnownType("System", "Math").GetKnownMethod("DivInt64", null); break; - case ReadyToRunHelper.LMod: - methodDesc = context.SystemModule.GetKnownType("System", "Math").GetKnownMethod("ModulusLongs", null); + case ReadyToRunHelper.ULDiv: + methodDesc = context.SystemModule.GetKnownType("System", "Math").GetKnownMethod("DivUInt64", null); break; - case ReadyToRunHelper.Div: - methodDesc = context.SystemModule.GetKnownType("System", "Math").GetKnownMethod("DivideChecked", null); + case ReadyToRunHelper.Mod: + methodDesc = context.SystemModule.GetKnownType("System", "Math").GetKnownMethod("ModInt32", null); break; - case ReadyToRunHelper.UDiv: - methodDesc = context.SystemModule.GetKnownType("System", "Math").GetKnownMethod("DivideUnsigned", null); + case ReadyToRunHelper.UMod: + methodDesc = context.SystemModule.GetKnownType("System", "Math").GetKnownMethod("ModulUInt32", null); break; - case ReadyToRunHelper.ULDiv: - methodDesc = context.SystemModule.GetKnownType("System", "Math").GetKnownMethod("DivideUnsignedLongs", null); + case ReadyToRunHelper.LMod: + methodDesc = context.SystemModule.GetKnownType("System", "Math").GetKnownMethod("ModInt64", null); break; - case ReadyToRunHelper.LDiv: - methodDesc = context.SystemModule.GetKnownType("System", "Math").GetKnownMethod("DivideLongs", null); + case ReadyToRunHelper.ULMod: + methodDesc = context.SystemModule.GetKnownType("System", "Math").GetKnownMethod("ModUInt64", null); break; case ReadyToRunHelper.LRsz: diff --git a/src/coreclr/vm/JitQCallHelpers.h b/src/coreclr/vm/JitQCallHelpers.h index 32eb58717980cf..fbef97b52a38e1 100644 --- a/src/coreclr/vm/JitQCallHelpers.h +++ b/src/coreclr/vm/JitQCallHelpers.h @@ -22,71 +22,4 @@ extern "C" void * QCALLTYPE ResolveVirtualFunctionPointer(QCall::ObjectHandleOnS extern "C" CORINFO_GENERIC_HANDLE QCALLTYPE GenericHandleWorker(MethodDesc * pMD, MethodTable * pMT, LPVOID signature, DWORD dictionaryIndexAndSlot, Module* pModule); extern "C" void QCALLTYPE InitClassHelper(MethodTable* pMT); -#ifdef TARGET_32BIT -extern "C" int32_t QCALLTYPE Math_ActualDivisionInt(int32_t i, int32_t j) -{ - QCALL_CONTRACT_NO_GC_TRANSITION - - ASSERT(j && "Divide by zero!"); - return i / j; -} - -extern "C" uint32_t QCALLTYPE Math_ActualDivisionUInt(uint32_t i, uint32_t j) -{ - QCALL_CONTRACT_NO_GC_TRANSITION - - ASSERT(j && "Divide by zero!"); - return i / j; -} - -extern "C" int32_t QCALLTYPE Math_ActualModulusInt(int32_t i, int32_t j) -{ - QCALL_CONTRACT_NO_GC_TRANSITION - - ASSERT(j && "Divide by zero!"); - return i % j; -} - -extern "C" uint32_t QCALLTYPE Math_ActualModulusUInt(uint32_t i, uint32_t j) -{ - QCALL_CONTRACT_NO_GC_TRANSITION - - ASSERT(j && "Divide by zero!"); - return i % j; -} - -extern "C" int64_t QCALLTYPE Math_ActualDivisionLong(int64_t i, int64_t j) -{ - QCALL_CONTRACT_NO_GC_TRANSITION - - ASSERT(j && "Divide by zero!"); - return i / j; -} - -extern "C" uint64_t QCALLTYPE Math_ActualDivisionULong(uint64_t i, uint64_t j) -{ - QCALL_CONTRACT_NO_GC_TRANSITION - - ASSERT(j && "Divide by zero!"); - return i / j; -} - -extern "C" int64_t QCALLTYPE Math_ActualModulusLong(int64_t i, int64_t j) -{ - QCALL_CONTRACT_NO_GC_TRANSITION - - ASSERT(j && "Divide by zero!"); - return i % j; -} - -extern "C" uint64_t QCALLTYPE Math_ActualModulusULong(uint64_t i, uint64_t j) -{ - QCALL_CONTRACT_NO_GC_TRANSITION - - ASSERT(j && "Divide by zero!"); - return i % j; -} - -#endif // TARGET_32BIT - #endif //_JITQCALLHELPERS_H diff --git a/src/coreclr/vm/corelib.cpp b/src/coreclr/vm/corelib.cpp index 4c3f7438a559ab..22c1c983b49003 100644 --- a/src/coreclr/vm/corelib.cpp +++ b/src/coreclr/vm/corelib.cpp @@ -28,6 +28,7 @@ #include "comsynchronizable.h" #include "floatdouble.h" #include "floatsingle.h" +#include "divmodint.h" #include "comdatetime.h" #include "debugdebugger.h" #include "assemblynative.hpp" diff --git a/src/coreclr/vm/corelib.h b/src/coreclr/vm/corelib.h index bdbcc921d3c6b2..6b4a490c58da31 100644 --- a/src/coreclr/vm/corelib.h +++ b/src/coreclr/vm/corelib.h @@ -259,22 +259,23 @@ DEFINE_CLASS(INT128, System, Int128) DEFINE_CLASS(UINT128, System, UInt128) DEFINE_CLASS(MATH, System, Math) -#ifndef TARGET_64BIT -DEFINE_METHOD(MATH, MULTIPLY_CHECKED_INT64, MultiplyChecked, SM_Long_Long_RetLong) -DEFINE_METHOD(MATH, MULTIPLY_CHECKED_UINT64, MultiplyChecked, SM_ULong_ULong_RetULong) -#endif DEFINE_METHOD(MATH, CONVERT_TO_INT32_CHECKED, ConvertToInt32Checked, NoSig) DEFINE_METHOD(MATH, CONVERT_TO_UINT32_CHECKED, ConvertToUInt32Checked, NoSig) DEFINE_METHOD(MATH, CONVERT_TO_INT64_CHECKED, ConvertToInt64Checked, NoSig) DEFINE_METHOD(MATH, CONVERT_TO_UINT64_CHECKED, ConvertToUInt64Checked, NoSig) -DEFINE_METHOD(MATH, DIVIDE_CHECKED, DivideChecked, NoSig) -DEFINE_METHOD(MATH, MODULUS_CHECKED, ModulusChecked, NoSig) -DEFINE_METHOD(MATH, DIVIDE_UNSIGNED, DivideUnsigned, NoSig) -DEFINE_METHOD(MATH, MODULUS_UNSIGNED, ModulusUnsigned, NoSig) -DEFINE_METHOD(MATH, DIVIDE_LONGS, DivideLongs, NoSig) -DEFINE_METHOD(MATH, MODULUS_LONGS, ModulusLongs, NoSig) -DEFINE_METHOD(MATH, DIVIDE_ULONGS, DivideUnsignedLongs, NoSig) -DEFINE_METHOD(MATH, MODULUS_ULONGS, ModulusUnsignedLongs, NoSig) + +#ifdef TARGET_32BIT +DEFINE_METHOD(MATH, MULTIPLY_CHECKED_INT64, MultiplyChecked, SM_Long_Long_RetLong) +DEFINE_METHOD(MATH, MULTIPLY_CHECKED_UINT64, MultiplyChecked, SM_ULong_ULong_RetULong) +DEFINE_METHOD(MATH, DIV_INT32, DivInt32, NoSig) +DEFINE_METHOD(MATH, DIV_UINT32, DivUInt32, NoSig) +DEFINE_METHOD(MATH, DIV_INT64, DivInt64, NoSig) +DEFINE_METHOD(MATH, DIV_UINT64, DivUInt64, NoSig) +DEFINE_METHOD(MATH, MOD_INT32, ModInt32, NoSig) +DEFINE_METHOD(MATH, MOD_UINT32, ModUInt32, NoSig) +DEFINE_METHOD(MATH, MOD_INT64, ModInt64, NoSig) +DEFINE_METHOD(MATH, MOD_UINT64, ModUInt64, NoSig) +#endif // TARGET_32BIT DEFINE_CLASS(DYNAMICMETHOD, ReflectionEmit, DynamicMethod) diff --git a/src/coreclr/vm/ecalllist.h b/src/coreclr/vm/ecalllist.h index 1ea05d6f692d88..a0a0682372e7ae 100644 --- a/src/coreclr/vm/ecalllist.h +++ b/src/coreclr/vm/ecalllist.h @@ -227,6 +227,16 @@ FCFuncStart(gMathFuncs) FCFuncElement("Sqrt", COMDouble::Sqrt) FCFuncElement("Tan", COMDouble::Tan) FCFuncElement("Tanh", COMDouble::Tanh) +#ifdef TARGET_32BIT + FCFuncElement("InternalDivInt32", COMDivModInt::DivInt32) + FCFuncElement("InternalDivUInt32", COMDivModInt::DivUInt32) + FCFuncElement("InternalDivInt64", COMDivModInt::DivInt64) + FCFuncElement("InternalDivUInt64", COMDivModInt::DivUInt64) + FCFuncElement("InternalModInt32", COMDivModInt::ModInt32) + FCFuncElement("InternalModUInt32", COMDivModInt::ModUInt32) + FCFuncElement("InternalModInt64", COMDivModInt::ModInt64) + FCFuncElement("InternalModUInt64", COMDivModInt::ModUInt64) +#endif // TARGET_32BIT FCFuncEnd() FCFuncStart(gMathFFuncs) diff --git a/src/coreclr/vm/qcallentrypoints.cpp b/src/coreclr/vm/qcallentrypoints.cpp index 6add0edc05e5fc..356ce7a1792d40 100644 --- a/src/coreclr/vm/qcallentrypoints.cpp +++ b/src/coreclr/vm/qcallentrypoints.cpp @@ -503,16 +503,6 @@ static const Entry s_QCall[] = DllImportEntry(InitClassHelper) DllImportEntry(ResolveVirtualFunctionPointer) DllImportEntry(GenericHandleWorker) -#ifdef TARGET_32BIT - DllImportEntry(Math_ActualDivisionInt) - DllImportEntry(Math_ActualDivisionUInt) - DllImportEntry(Math_ActualModulusInt) - DllImportEntry(Math_ActualModulusUInt) - DllImportEntry(Math_ActualDivisionLong) - DllImportEntry(Math_ActualDivisionULong) - DllImportEntry(Math_ActualModulusLong) - DllImportEntry(Math_ActualModulusULong) -#endif // TARGET_32BIT }; const void* QCallResolveDllImport(const char* name) diff --git a/src/libraries/System.Private.CoreLib/src/System.Private.CoreLib.Shared.projitems b/src/libraries/System.Private.CoreLib/src/System.Private.CoreLib.Shared.projitems index 1b6323b940e867..edb61f3b93e900 100644 --- a/src/libraries/System.Private.CoreLib/src/System.Private.CoreLib.Shared.projitems +++ b/src/libraries/System.Private.CoreLib/src/System.Private.CoreLib.Shared.projitems @@ -568,6 +568,7 @@ + @@ -2803,4 +2804,4 @@ - \ No newline at end of file + diff --git a/src/libraries/System.Private.CoreLib/src/System/Math.DivModInt.cs b/src/libraries/System.Private.CoreLib/src/System/Math.DivModInt.cs new file mode 100644 index 00000000000000..92847247854eac --- /dev/null +++ b/src/libraries/System.Private.CoreLib/src/System/Math.DivModInt.cs @@ -0,0 +1,208 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System.Diagnostics; +using System.Numerics; +using System.Runtime.CompilerServices; + +namespace System +{ + /// + /// Provides constants and static methods for trigonometric, logarithmic, and other common mathematical functions. + /// + public static partial class Math + { + [StackTraceHidden] + internal static int DivInt32(int dividend, int divisor) + { + if ((uint)(divisor + 1) <= 1) // Unsigned test for divisor in [-1 .. 0] + { + if (divisor == 0) + { + ThrowHelper.ThrowDivideByZeroException(); + } + else if (divisor == -1) + { + if (dividend == int.MinValue) + { + ThrowHelper.ThrowOverflowException(); + } + return -dividend; + } + } + + return InternalDivInt32(dividend, divisor); + } + + [StackTraceHidden] + internal static uint DivUInt32(uint dividend, uint divisor) + { + if (divisor == 0) + { + ThrowHelper.ThrowDivideByZeroException(); + } + + return InternalDivUInt32(dividend, divisor); + } + + [StackTraceHidden] + internal static long DivInt64(long dividend, long divisor) + { + if (Is32BitSigned(divisor)) + { + if ((int)divisor == 0) + { + ThrowHelper.ThrowDivideByZeroException(); + } + + if ((int)divisor == -1) + { + if ((ulong)dividend == 0x8000000000000000) + { + ThrowHelper.ThrowOverflowException(); + } + return -dividend; + } + + // Check for -ive or +ive numbers in the range -2**31 to 2**31 + if (Is32BitSigned(dividend)) + { + return (int)dividend / (int)divisor; + } + } + + return InternalDivInt64(dividend, divisor); + } + + [StackTraceHidden] + internal static ulong DivUInt64(ulong dividend, ulong divisor) + { + if (Hi32Bits(divisor) == 0) + { + if ((uint)divisor == 0) + { + ThrowHelper.ThrowDivideByZeroException(); + } + + if (Hi32Bits(dividend) == 0) + return (uint)dividend / (uint)divisor; + } + + return InternalDivUInt64(dividend, divisor); + } + + [StackTraceHidden] + internal static int ModInt32(int dividend, int divisor) + { + if ((uint)(divisor + 1) <= 1) // Unsigned test for divisor in [-1 .. 0] + { + if (divisor == 0) + { + ThrowHelper.ThrowDivideByZeroException(); + } + else if (divisor == -1) + { + if (dividend == int.MinValue) + { + ThrowHelper.ThrowOverflowException(); + } + return 0; + } + } + + return InternalModInt32(dividend, divisor); + } + + [StackTraceHidden] + internal static uint ModUInt32(uint dividend, uint divisor) + { + if (divisor == 0) + { + ThrowHelper.ThrowDivideByZeroException(); + } + + return InternalModUInt32(dividend, divisor); + } + + [StackTraceHidden] + internal static long ModInt64(long dividend, long divisor) + { + if (Is32BitSigned(divisor)) + { + if ((int)divisor == 0) + { + ThrowHelper.ThrowDivideByZeroException(); + } + + if ((int)divisor == -1) + { + if ((ulong)dividend == 0x8000000000000000) + { + ThrowHelper.ThrowOverflowException(); + } + return 0; + } + + if (Is32BitSigned(dividend)) + { + return (int)dividend % (int)divisor; + } + } + + return InternalModInt64(dividend, divisor); + } + + [StackTraceHidden] + internal static ulong ModUInt64(ulong dividend, ulong divisor) + { + if (Hi32Bits(divisor) == 0) + { + if ((uint)divisor == 0) + { + ThrowHelper.ThrowDivideByZeroException(); + } + + if (Hi32Bits(dividend) == 0) + return (uint)dividend % (uint)divisor; + } + + return InternalModUInt64(dividend, divisor); + } + + // helper method to get high 32-bit of 64-bit int + private static uint Hi32Bits(T a) where T : INumber + { + return (uint)(ulong.CreateTruncating(a) >> 32); + } + + // helper method to check whether 64-bit signed int fits into 32-bit signed (compiles into one 32-bit compare) + private static bool Is32BitSigned(T a) where T : INumber + { + return Hi32Bits(a) == Hi32Bits(long.CreateTruncating(int.CreateTruncating(a))); + } + + [MethodImpl(MethodImplOptions.InternalCall)] + private static extern int InternalDivInt32(int dividend, int divisor); + + [MethodImpl(MethodImplOptions.InternalCall)] + private static extern uint InternalDivUInt32(uint dividend, uint divisor); + + [MethodImpl(MethodImplOptions.InternalCall)] + private static extern long InternalDivInt64(long dividend, long divisor); + + [MethodImpl(MethodImplOptions.InternalCall)] + private static extern ulong InternalDivUInt64(ulong dividend, ulong divisor); + + [MethodImpl(MethodImplOptions.InternalCall)] + private static extern int InternalModInt32(int dividend, int divisor); + + [MethodImpl(MethodImplOptions.InternalCall)] + private static extern uint InternalModUInt32(uint dividend, uint divisor); + + [MethodImpl(MethodImplOptions.InternalCall)] + private static extern long InternalModInt64(long dividend, long divisor); + + [MethodImpl(MethodImplOptions.InternalCall)] + private static extern ulong InternalModUInt64(ulong dividend, ulong divisor); + } +} diff --git a/src/libraries/System.Private.CoreLib/src/System/Math.cs b/src/libraries/System.Private.CoreLib/src/System/Math.cs index 0cd9c785f690e0..32c3eee4712bfc 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Math.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Math.cs @@ -14,10 +14,6 @@ using System.Runtime.Intrinsics.X86; using System.Runtime.Versioning; -#if TARGET_32BIT -using System.Runtime.InteropServices; -#endif - namespace System { /// @@ -1686,227 +1682,5 @@ internal static ulong ConvertToUInt64Checked(double value) ThrowHelper.ThrowOverflowException(); return 0; } - - [StackTraceHidden] - internal static int DivideChecked(int dividend, int divisor) - { -#if TARGET_32BIT - if ((uint)(divisor + 1) <= 1) - { - if (divisor == 0) - { - ThrowHelper.ThrowDivideByZeroException(); - } - else if (divisor == -1) - { - if (dividend == int.MinValue) - { - ThrowHelper.ThrowOverflowException(); - } - return -dividend; - } - } - - return ActualDivisionInt(dividend, divisor); -#else - return DivideChecked(dividend, divisor); -#endif - } - - [StackTraceHidden] - internal static int ModulusChecked(int dividend, int divisor) - { -#if TARGET_32BIT - if ((uint)(divisor + 1) <= 1) - { - if (divisor == 0) - { - ThrowHelper.ThrowDivideByZeroException(); - } - else if (divisor == -1) - { - if (dividend == int.MinValue) - { - ThrowHelper.ThrowOverflowException(); - } - return 0; - } - } - - return ActualModulusInt(dividend, divisor); -#else - return ModulusChecked(dividend, divisor); -#endif - } - - [StackTraceHidden] - internal static uint DivideUnsigned(uint dividend, uint divisor) - { -#if TARGET_32BIT - if (divisor == 0) - { - ThrowHelper.ThrowDivideByZeroException(); - } - - return ActualDivisionUInt(dividend, divisor); -#else - return DivideUnsigned(dividend, divisor); -#endif - } - - [StackTraceHidden] - internal static uint ModulusUnsigned(uint dividend, uint divisor) - { -#if TARGET_32BIT - if (divisor == 0) - { - ThrowHelper.ThrowDivideByZeroException(); - } - - return ActualModulusUInt(dividend, divisor); -#else - return ModulusUnsigned(dividend, divisor); -#endif - } - - [StackTraceHidden] - internal static long DivideLongs(long dividend, long divisor) - { -#if TARGET_32BIT - if ((uint)(divisor + 1) <= 1) - { - if ((int)divisor == 0) - { - ThrowHelper.ThrowDivideByZeroException(); - } - - if ((int)divisor == -1) - { - if ((ulong)dividend == 0x8000000000000000) - { - ThrowHelper.ThrowOverflowException(); - } - return -dividend; - } - - if ((ulong)dividend >> 32 == 0 || (ulong)dividend >> 32 == 0xFFFFFFFF) - { - return (int)dividend / (int)divisor; - } - } - - return ActualDivisionLong(dividend, divisor); -#else - return DivideLongs(dividend, divisor); -#endif - } - - [StackTraceHidden] - internal static long ModulusLongs(long dividend, long divisor) - { -#if TARGET_32BIT - if ((uint)(divisor + 1) <= 1) - { - if ((int)divisor == 0) - { - ThrowHelper.ThrowDivideByZeroException(); - } - - if ((int)divisor == -1) - { - if ((ulong)dividend == 0x8000000000000000) - { - ThrowHelper.ThrowOverflowException(); - } - return 0; - } - - if ((ulong)dividend >> 32 == 0 || (ulong)dividend >> 32 == 0xFFFFFFFF) - { - return (int)dividend % (int)divisor; - } - } - - return ActualModulusLong(dividend, divisor); -#else - return ModulusLongs(dividend, divisor); -#endif - } - - [StackTraceHidden] - internal static ulong DivideUnsignedLongs(ulong dividend, ulong divisor) - { -#if TARGET_32BIT - if ((divisor >> 32) == 0) - { - if ((uint)divisor == 0) - { - ThrowHelper.ThrowDivideByZeroException(); - } - - if ((dividend >> 32) == 0) - return (uint)dividend / (uint)divisor; - } - - return ActualDivisionULong(dividend, divisor); -#else - return DivideUnsignedLongs(dividend, divisor); -#endif - } - - [StackTraceHidden] - internal static ulong ModulusUnsignedLongs(ulong dividend, ulong divisor) - { -#if TARGET_32BIT - if ((divisor >> 32) == 0) - { - if ((uint)divisor == 0) - { - ThrowHelper.ThrowDivideByZeroException(); - } - - if ((dividend >> 32) == 0) - return (uint)dividend % (uint)divisor; - } - - return ActualModulusULong(dividend, divisor); -#else - return ModulusUnsignedLongs(dividend, divisor); -#endif - } - -#if TARGET_32BIT - [LibraryImport(RuntimeHelpers.QCall, EntryPoint = "Math_ActualDivisionInt")] - [SuppressGCTransition] - private static partial int ActualDivisionInt(int dividend, int divisor); - - [LibraryImport(RuntimeHelpers.QCall, EntryPoint = "Math_ActualModulusInt")] - [SuppressGCTransition] - private static partial int ActualModulusInt(int dividend, int divisor); - - [LibraryImport(RuntimeHelpers.QCall, EntryPoint = "Math_ActualDivisionUInt")] - [SuppressGCTransition] - private static partial uint ActualDivisionUInt(uint dividend, uint divisor); - - [LibraryImport(RuntimeHelpers.QCall, EntryPoint = "Math_ActualModulusUInt")] - [SuppressGCTransition] - private static partial uint ActualModulusUInt(uint dividend, uint divisor); - - [LibraryImport(RuntimeHelpers.QCall, EntryPoint = "Math_ActualDivisionLong")] - [SuppressGCTransition] - private static partial long ActualDivisionLong(long dividend, long divisor); - - [LibraryImport(RuntimeHelpers.QCall, EntryPoint = "Math_ActualModulusLong")] - [SuppressGCTransition] - private static partial long ActualModulusLong(long dividend, long divisor); - - [LibraryImport(RuntimeHelpers.QCall, EntryPoint = "Math_ActualDivisionULong")] - [SuppressGCTransition] - private static partial ulong ActualDivisionULong(ulong dividend, ulong divisor); - - [LibraryImport(RuntimeHelpers.QCall, EntryPoint = "Math_ActualModulusULong")] - [SuppressGCTransition] - private static partial ulong ActualModulusULong(ulong dividend, ulong divisor); -#endif } } From 804e052ab6d52896d68e5c39769edfb920861f82 Mon Sep 17 00:00:00 2001 From: Adeel <3840695+am11@users.noreply.github.com> Date: Thu, 24 Oct 2024 17:25:37 +0300 Subject: [PATCH 03/27] Update macros and keep comments --- src/coreclr/classlibnative/float/divmodint.cpp | 8 ++++---- src/coreclr/classlibnative/inc/divmodint.h | 8 ++++---- src/coreclr/nativeaot/Runtime/MathHelpers.cpp | 8 ++++---- .../System.Private.CoreLib/src/System/Math.DivModInt.cs | 6 ++++-- 4 files changed, 16 insertions(+), 14 deletions(-) diff --git a/src/coreclr/classlibnative/float/divmodint.cpp b/src/coreclr/classlibnative/float/divmodint.cpp index 1cdffb70c09494..1b2b9f563ce9a4 100644 --- a/src/coreclr/classlibnative/float/divmodint.cpp +++ b/src/coreclr/classlibnative/float/divmodint.cpp @@ -21,13 +21,13 @@ FCIMPL2(uint32_t, COMDivModInt::DivUInt32, uint32_t dividend, uint32_t divisor) return dividend / divisor; FCIMPLEND -FCIMPL2(int64_t, COMDivModInt::DivInt64, int64_t dividend, int64_t divisor) +FCIMPL2_VV(int64_t, COMDivModInt::DivInt64, int64_t dividend, int64_t divisor) FCALL_CONTRACT; return dividend / divisor; FCIMPLEND -FCIMPL2(uint64_t, COMDivModInt::DivUInt64, uint64_t dividend, uint64_t divisor) +FCIMPL2_VV(uint64_t, COMDivModInt::DivUInt64, uint64_t dividend, uint64_t divisor) FCALL_CONTRACT; return dividend / divisor; @@ -45,13 +45,13 @@ FCIMPL2(uint32_t, COMDivModInt::ModUInt32, uint32_t dividend, uint32_t divisor) return dividend % divisor; FCIMPLEND -FCIMPL2(int64_t, COMDivModInt::ModInt64, int64_t dividend, int64_t divisor) +FCIMPL2_VV(int64_t, COMDivModInt::ModInt64, int64_t dividend, int64_t divisor) FCALL_CONTRACT; return dividend % divisor; FCIMPLEND -FCIMPL2(uint64_t, COMDivModInt::ModUInt64, uint64_t dividend, uint64_t divisor) +FCIMPL2_VV(uint64_t, COMDivModInt::ModUInt64, uint64_t dividend, uint64_t divisor) FCALL_CONTRACT; return dividend % divisor; diff --git a/src/coreclr/classlibnative/inc/divmodint.h b/src/coreclr/classlibnative/inc/divmodint.h index bba1317e41e251..31a03a7f51c06b 100644 --- a/src/coreclr/classlibnative/inc/divmodint.h +++ b/src/coreclr/classlibnative/inc/divmodint.h @@ -11,12 +11,12 @@ class COMDivModInt { public: FCDECL2(static int32_t, DivInt32, int32_t dividend, int32_t divisor); FCDECL2(static uint32_t, DivUInt32, uint32_t dividend, uint32_t divisor); - FCDECL2(static int64_t, DivInt64, int64_t dividend, int64_t divisor); - FCDECL2(static uint64_t, DivUInt64, uint64_t dividend, uint64_t divisor); + FCDECL2_VV(static int64_t, DivInt64, int64_t dividend, int64_t divisor); + FCDECL2_VV(static uint64_t, DivUInt64, uint64_t dividend, uint64_t divisor); FCDECL2(static int32_t, ModInt32, int32_t dividend, int32_t divisor); FCDECL2(static uint32_t, ModUInt32, uint32_t dividend, uint32_t divisor); - FCDECL2(static int64_t, ModInt64, int64_t dividend, int64_t divisor); - FCDECL2(static uint64_t, ModUInt64, uint64_t dividend, uint64_t divisor); + FCDECL2_VV(static int64_t, ModInt64, int64_t dividend, int64_t divisor); + FCDECL2_VV(static uint64_t, ModUInt64, uint64_t dividend, uint64_t divisor); }; #endif // _DIVMODINT_H_ diff --git a/src/coreclr/nativeaot/Runtime/MathHelpers.cpp b/src/coreclr/nativeaot/Runtime/MathHelpers.cpp index 76ac591e85a015..7d5ce5f2e8d79c 100644 --- a/src/coreclr/nativeaot/Runtime/MathHelpers.cpp +++ b/src/coreclr/nativeaot/Runtime/MathHelpers.cpp @@ -56,25 +56,25 @@ FCIMPL1_D(uint32_t, RhpDbl2UInt, double val) FCIMPLEND #ifndef HOST_64BIT -EXTERN_C int64_t F_CALL_CONV InternalDivInt64(int64_t i, int64_t j) +EXTERN_C int64_t QCALLTYPE InternalDivInt64(int64_t i, int64_t j) { ASSERT(j && "Divide by zero!"); return i / j; } -EXTERN_C uint64_t F_CALL_CONV InternalDivUInt64(uint64_t i, uint64_t j) +EXTERN_C uint64_t QCALLTYPE InternalDivUInt64(uint64_t i, uint64_t j) { ASSERT(j && "Divide by zero!"); return i / j; } -EXTERN_C int64_t F_CALL_CONV InternalModInt64(int64_t i, int64_t j) +EXTERN_C int64_t QCALLTYPE InternalModInt64(int64_t i, int64_t j) { ASSERT(j && "Divide by zero!"); return i % j; } -EXTERN_C uint64_t F_CALL_CONV InternalModUInt64(uint64_t i, uint64_t j) +EXTERN_C uint64_t QCALLTYPE InternalModUInt64(uint64_t i, uint64_t j) { ASSERT(j && "Divide by zero!"); return i % j; diff --git a/src/libraries/System.Private.CoreLib/src/System/Math.DivModInt.cs b/src/libraries/System.Private.CoreLib/src/System/Math.DivModInt.cs index 92847247854eac..812aa605d8f121 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Math.DivModInt.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Math.DivModInt.cs @@ -57,7 +57,7 @@ internal static long DivInt64(long dividend, long divisor) if ((int)divisor == -1) { - if ((ulong)dividend == 0x8000000000000000) + if ((ulong)dividend == 0x8000000000000000ul) { ThrowHelper.ThrowOverflowException(); } @@ -136,7 +136,9 @@ internal static long ModInt64(long dividend, long divisor) if ((int)divisor == -1) { - if ((ulong)dividend == 0x8000000000000000) + // TODO, we really should remove this as it lengthens the code path + // and the spec really says that it should not throw an exception. + if ((ulong)dividend == 0x8000000000000000ul) { ThrowHelper.ThrowOverflowException(); } From 3203c739029fbaccb2e4a6f965bcab0816fa961e Mon Sep 17 00:00:00 2001 From: Adeel <3840695+am11@users.noreply.github.com> Date: Thu, 24 Oct 2024 20:06:35 +0300 Subject: [PATCH 04/27] Address CR feedback --- .../CompilerServices/RuntimeHelpers.cs | 2 ++ .../src/System/Math.DivModInt.cs | 26 +++++++++++++++++-- 2 files changed, 26 insertions(+), 2 deletions(-) diff --git a/src/coreclr/nativeaot/Runtime.Base/src/System/Runtime/CompilerServices/RuntimeHelpers.cs b/src/coreclr/nativeaot/Runtime.Base/src/System/Runtime/CompilerServices/RuntimeHelpers.cs index b06f2f3d5eb30c..6a9c7535178c3f 100644 --- a/src/coreclr/nativeaot/Runtime.Base/src/System/Runtime/CompilerServices/RuntimeHelpers.cs +++ b/src/coreclr/nativeaot/Runtime.Base/src/System/Runtime/CompilerServices/RuntimeHelpers.cs @@ -18,5 +18,7 @@ public static int OffsetToStringData [Intrinsic] public static extern void InitializeArray(Array array, RuntimeFieldHandle fldHandle); + + public const string QCall = "*"; } } diff --git a/src/libraries/System.Private.CoreLib/src/System/Math.DivModInt.cs b/src/libraries/System.Private.CoreLib/src/System/Math.DivModInt.cs index 812aa605d8f121..b532ca4fbe6466 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Math.DivModInt.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Math.DivModInt.cs @@ -5,6 +5,10 @@ using System.Numerics; using System.Runtime.CompilerServices; +#if NATIVEAOT +using System.Runtime.InteropServices; +#endif + namespace System { /// @@ -136,8 +140,6 @@ internal static long ModInt64(long dividend, long divisor) if ((int)divisor == -1) { - // TODO, we really should remove this as it lengthens the code path - // and the spec really says that it should not throw an exception. if ((ulong)dividend == 0x8000000000000000ul) { ThrowHelper.ThrowOverflowException(); @@ -189,11 +191,21 @@ private static bool Is32BitSigned(T a) where T : INumber [MethodImpl(MethodImplOptions.InternalCall)] private static extern uint InternalDivUInt32(uint dividend, uint divisor); +#if NATIVEAOT + [LibraryImport(RuntimeHelpers.QCall, EntryPoint = "InternalDivInt64"), SuppressGCTransition] + private static partial long InternalDivInt64(long dividend, long divisor); +#else [MethodImpl(MethodImplOptions.InternalCall)] private static extern long InternalDivInt64(long dividend, long divisor); +#endif +#if NATIVEAOT + [LibraryImport(RuntimeHelpers.QCall, EntryPoint = "InternalDivUInt64"), SuppressGCTransition] + private static partial ulong InternalDivUInt64(ulong dividend, ulong divisor); +#else [MethodImpl(MethodImplOptions.InternalCall)] private static extern ulong InternalDivUInt64(ulong dividend, ulong divisor); +#endif [MethodImpl(MethodImplOptions.InternalCall)] private static extern int InternalModInt32(int dividend, int divisor); @@ -201,10 +213,20 @@ private static bool Is32BitSigned(T a) where T : INumber [MethodImpl(MethodImplOptions.InternalCall)] private static extern uint InternalModUInt32(uint dividend, uint divisor); +#if NATIVEAOT + [LibraryImport(RuntimeHelpers.QCall, EntryPoint = "InternalModInt64"), SuppressGCTransition] + private static partial long InternalModInt64(long dividend, long divisor); +#else [MethodImpl(MethodImplOptions.InternalCall)] private static extern long InternalModInt64(long dividend, long divisor); +#endif +#if NATIVEAOT + [LibraryImport(RuntimeHelpers.QCall, EntryPoint = "InternalModUInt64"), SuppressGCTransition] + private static partial ulong InternalModUInt64(ulong dividend, ulong divisor); +#else [MethodImpl(MethodImplOptions.InternalCall)] private static extern ulong InternalModUInt64(ulong dividend, ulong divisor); +#endif } } From 715b56c90b424ce887dedd34812d548f60c4c9d2 Mon Sep 17 00:00:00 2001 From: Adeel <3840695+am11@users.noreply.github.com> Date: Thu, 24 Oct 2024 21:50:05 +0300 Subject: [PATCH 05/27] Rename native calls to use Internal as suffix --- src/coreclr/nativeaot/Runtime/MathHelpers.cpp | 16 +++---- src/coreclr/vm/ecalllist.h | 16 +++---- .../src/System/Math.DivModInt.cs | 48 +++++++++---------- 3 files changed, 40 insertions(+), 40 deletions(-) diff --git a/src/coreclr/nativeaot/Runtime/MathHelpers.cpp b/src/coreclr/nativeaot/Runtime/MathHelpers.cpp index 7d5ce5f2e8d79c..edefb29ccbd785 100644 --- a/src/coreclr/nativeaot/Runtime/MathHelpers.cpp +++ b/src/coreclr/nativeaot/Runtime/MathHelpers.cpp @@ -56,25 +56,25 @@ FCIMPL1_D(uint32_t, RhpDbl2UInt, double val) FCIMPLEND #ifndef HOST_64BIT -EXTERN_C int64_t QCALLTYPE InternalDivInt64(int64_t i, int64_t j) +EXTERN_C int64_t QCALLTYPE DivInt64Internal(int64_t i, int64_t j) { ASSERT(j && "Divide by zero!"); return i / j; } -EXTERN_C uint64_t QCALLTYPE InternalDivUInt64(uint64_t i, uint64_t j) +EXTERN_C uint64_t QCALLTYPE DivUInt64Internal(uint64_t i, uint64_t j) { ASSERT(j && "Divide by zero!"); return i / j; } -EXTERN_C int64_t QCALLTYPE InternalModInt64(int64_t i, int64_t j) +EXTERN_C int64_t QCALLTYPE ModInt64Internal(int64_t i, int64_t j) { ASSERT(j && "Divide by zero!"); return i % j; } -EXTERN_C uint64_t QCALLTYPE InternalModUInt64(uint64_t i, uint64_t j) +EXTERN_C uint64_t QCALLTYPE ModUInt64Internal(uint64_t i, uint64_t j) { ASSERT(j && "Divide by zero!"); return i % j; @@ -95,25 +95,25 @@ FCIMPLEND #endif #ifdef HOST_ARM -EXTERN_C int32_t F_CALL_CONV InternalDivInt32(int32_t i, int32_t j) +EXTERN_C int32_t F_CALL_CONV DivInt32Internal(int32_t i, int32_t j) { ASSERT(j && "Divide by zero!"); return i / j; } -EXTERN_C uint32_t F_CALL_CONV InternalDivUInt32(uint32_t i, uint32_t j) +EXTERN_C uint32_t F_CALL_CONV DivUInt32Internal(uint32_t i, uint32_t j) { ASSERT(j && "Divide by zero!"); return i / j; } -EXTERN_C int32_t F_CALL_CONV InternalModInt32(int32_t i, int32_t j) +EXTERN_C int32_t F_CALL_CONV ModInt32Internal(int32_t i, int32_t j) { ASSERT(j && "Divide by zero!"); return i % j; } -EXTERN_C uint32_t F_CALL_CONV InternalModUInt32(uint32_t i, uint32_t j) +EXTERN_C uint32_t F_CALL_CONV ModUInt32Internal(uint32_t i, uint32_t j) { ASSERT(j && "Divide by zero!"); return i % j; diff --git a/src/coreclr/vm/ecalllist.h b/src/coreclr/vm/ecalllist.h index a0a0682372e7ae..fd644c3bfc6d1a 100644 --- a/src/coreclr/vm/ecalllist.h +++ b/src/coreclr/vm/ecalllist.h @@ -228,14 +228,14 @@ FCFuncStart(gMathFuncs) FCFuncElement("Tan", COMDouble::Tan) FCFuncElement("Tanh", COMDouble::Tanh) #ifdef TARGET_32BIT - FCFuncElement("InternalDivInt32", COMDivModInt::DivInt32) - FCFuncElement("InternalDivUInt32", COMDivModInt::DivUInt32) - FCFuncElement("InternalDivInt64", COMDivModInt::DivInt64) - FCFuncElement("InternalDivUInt64", COMDivModInt::DivUInt64) - FCFuncElement("InternalModInt32", COMDivModInt::ModInt32) - FCFuncElement("InternalModUInt32", COMDivModInt::ModUInt32) - FCFuncElement("InternalModInt64", COMDivModInt::ModInt64) - FCFuncElement("InternalModUInt64", COMDivModInt::ModUInt64) + FCFuncElement("DivInt32Internal", COMDivModInt::DivInt32) + FCFuncElement("DivUInt32Internal", COMDivModInt::DivUInt32) + FCFuncElement("DivInt64Internal", COMDivModInt::DivInt64) + FCFuncElement("DivUInt64Internal", COMDivModInt::DivUInt64) + FCFuncElement("ModInt32Internal", COMDivModInt::ModInt32) + FCFuncElement("ModUInt32Internal", COMDivModInt::ModUInt32) + FCFuncElement("ModInt64Internal", COMDivModInt::ModInt64) + FCFuncElement("ModUInt64Internal", COMDivModInt::ModUInt64) #endif // TARGET_32BIT FCFuncEnd() diff --git a/src/libraries/System.Private.CoreLib/src/System/Math.DivModInt.cs b/src/libraries/System.Private.CoreLib/src/System/Math.DivModInt.cs index b532ca4fbe6466..9ae6163c0d9dee 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Math.DivModInt.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Math.DivModInt.cs @@ -35,7 +35,7 @@ internal static int DivInt32(int dividend, int divisor) } } - return InternalDivInt32(dividend, divisor); + return DivInt32Internal(dividend, divisor); } [StackTraceHidden] @@ -46,7 +46,7 @@ internal static uint DivUInt32(uint dividend, uint divisor) ThrowHelper.ThrowDivideByZeroException(); } - return InternalDivUInt32(dividend, divisor); + return DivUInt32Internal(dividend, divisor); } [StackTraceHidden] @@ -75,7 +75,7 @@ internal static long DivInt64(long dividend, long divisor) } } - return InternalDivInt64(dividend, divisor); + return DivInt64Internal(dividend, divisor); } [StackTraceHidden] @@ -92,7 +92,7 @@ internal static ulong DivUInt64(ulong dividend, ulong divisor) return (uint)dividend / (uint)divisor; } - return InternalDivUInt64(dividend, divisor); + return DivUInt64Internal(dividend, divisor); } [StackTraceHidden] @@ -114,7 +114,7 @@ internal static int ModInt32(int dividend, int divisor) } } - return InternalModInt32(dividend, divisor); + return ModInt32Internal(dividend, divisor); } [StackTraceHidden] @@ -125,7 +125,7 @@ internal static uint ModUInt32(uint dividend, uint divisor) ThrowHelper.ThrowDivideByZeroException(); } - return InternalModUInt32(dividend, divisor); + return ModUInt32Internal(dividend, divisor); } [StackTraceHidden] @@ -153,7 +153,7 @@ internal static long ModInt64(long dividend, long divisor) } } - return InternalModInt64(dividend, divisor); + return ModInt64Internal(dividend, divisor); } [StackTraceHidden] @@ -170,7 +170,7 @@ internal static ulong ModUInt64(ulong dividend, ulong divisor) return (uint)dividend % (uint)divisor; } - return InternalModUInt64(dividend, divisor); + return ModUInt64Internal(dividend, divisor); } // helper method to get high 32-bit of 64-bit int @@ -186,47 +186,47 @@ private static bool Is32BitSigned(T a) where T : INumber } [MethodImpl(MethodImplOptions.InternalCall)] - private static extern int InternalDivInt32(int dividend, int divisor); + private static extern int DivInt32Internal(int dividend, int divisor); [MethodImpl(MethodImplOptions.InternalCall)] - private static extern uint InternalDivUInt32(uint dividend, uint divisor); + private static extern uint DivUInt32Internal(uint dividend, uint divisor); #if NATIVEAOT - [LibraryImport(RuntimeHelpers.QCall, EntryPoint = "InternalDivInt64"), SuppressGCTransition] - private static partial long InternalDivInt64(long dividend, long divisor); + [LibraryImport(RuntimeHelpers.QCall, EntryPoint = "DivInt64Internal"), SuppressGCTransition] + private static partial long DivInt64Internal(long dividend, long divisor); #else [MethodImpl(MethodImplOptions.InternalCall)] - private static extern long InternalDivInt64(long dividend, long divisor); + private static extern long DivInt64Internal(long dividend, long divisor); #endif #if NATIVEAOT - [LibraryImport(RuntimeHelpers.QCall, EntryPoint = "InternalDivUInt64"), SuppressGCTransition] - private static partial ulong InternalDivUInt64(ulong dividend, ulong divisor); + [LibraryImport(RuntimeHelpers.QCall, EntryPoint = "DivUInt64Internal"), SuppressGCTransition] + private static partial ulong DivUInt64Internal(ulong dividend, ulong divisor); #else [MethodImpl(MethodImplOptions.InternalCall)] - private static extern ulong InternalDivUInt64(ulong dividend, ulong divisor); + private static extern ulong DivUInt64Internal(ulong dividend, ulong divisor); #endif [MethodImpl(MethodImplOptions.InternalCall)] - private static extern int InternalModInt32(int dividend, int divisor); + private static extern int ModInt32Internal(int dividend, int divisor); [MethodImpl(MethodImplOptions.InternalCall)] - private static extern uint InternalModUInt32(uint dividend, uint divisor); + private static extern uint ModUInt32Internal(uint dividend, uint divisor); #if NATIVEAOT - [LibraryImport(RuntimeHelpers.QCall, EntryPoint = "InternalModInt64"), SuppressGCTransition] - private static partial long InternalModInt64(long dividend, long divisor); + [LibraryImport(RuntimeHelpers.QCall, EntryPoint = "ModInt64Internal"), SuppressGCTransition] + private static partial long ModInt64Internal(long dividend, long divisor); #else [MethodImpl(MethodImplOptions.InternalCall)] - private static extern long InternalModInt64(long dividend, long divisor); + private static extern long ModInt64Internal(long dividend, long divisor); #endif #if NATIVEAOT - [LibraryImport(RuntimeHelpers.QCall, EntryPoint = "InternalModUInt64"), SuppressGCTransition] - private static partial ulong InternalModUInt64(ulong dividend, ulong divisor); + [LibraryImport(RuntimeHelpers.QCall, EntryPoint = "ModUInt64Internal"), SuppressGCTransition] + private static partial ulong ModUInt64Internal(ulong dividend, ulong divisor); #else [MethodImpl(MethodImplOptions.InternalCall)] - private static extern ulong InternalModUInt64(ulong dividend, ulong divisor); + private static extern ulong ModUInt64Internal(ulong dividend, ulong divisor); #endif } } From 31f56f6c0bb54137eee1e30e6242844d62774fbe Mon Sep 17 00:00:00 2001 From: Egor Bogatov Date: Thu, 28 Nov 2024 17:45:29 +0100 Subject: [PATCH 06/27] Update Math.DivModInt.cs --- .../System.Private.CoreLib/src/System/Math.DivModInt.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/libraries/System.Private.CoreLib/src/System/Math.DivModInt.cs b/src/libraries/System.Private.CoreLib/src/System/Math.DivModInt.cs index 9ae6163c0d9dee..d85f2ed34c8e07 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Math.DivModInt.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Math.DivModInt.cs @@ -174,12 +174,14 @@ internal static ulong ModUInt64(ulong dividend, ulong divisor) } // helper method to get high 32-bit of 64-bit int + [MethodImpl(MethodImplOptions.AggressiveInlining)] private static uint Hi32Bits(T a) where T : INumber { return (uint)(ulong.CreateTruncating(a) >> 32); } // helper method to check whether 64-bit signed int fits into 32-bit signed (compiles into one 32-bit compare) + [MethodImpl(MethodImplOptions.AggressiveInlining)] private static bool Is32BitSigned(T a) where T : INumber { return Hi32Bits(a) == Hi32Bits(long.CreateTruncating(int.CreateTruncating(a))); From 960dae14629beeded57f55626e08b4831f6c6d64 Mon Sep 17 00:00:00 2001 From: Adeel Mujahid <3840695+am11@users.noreply.github.com> Date: Sat, 30 Nov 2024 01:31:34 +0200 Subject: [PATCH 07/27] Replace CreateTruncating --- .../src/System/Math.DivModInt.cs | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/src/libraries/System.Private.CoreLib/src/System/Math.DivModInt.cs b/src/libraries/System.Private.CoreLib/src/System/Math.DivModInt.cs index d85f2ed34c8e07..59f5e4c1e23404 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Math.DivModInt.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Math.DivModInt.cs @@ -175,17 +175,11 @@ internal static ulong ModUInt64(ulong dividend, ulong divisor) // helper method to get high 32-bit of 64-bit int [MethodImpl(MethodImplOptions.AggressiveInlining)] - private static uint Hi32Bits(T a) where T : INumber - { - return (uint)(ulong.CreateTruncating(a) >> 32); - } + private static uint Hi32Bits(ulong a) => (uint)(int)(a >> 32); // helper method to check whether 64-bit signed int fits into 32-bit signed (compiles into one 32-bit compare) [MethodImpl(MethodImplOptions.AggressiveInlining)] - private static bool Is32BitSigned(T a) where T : INumber - { - return Hi32Bits(a) == Hi32Bits(long.CreateTruncating(int.CreateTruncating(a))); - } + private static bool Is32BitSigned(long a) => (uint)(int)((ulong)a >> 32) == (uint)(int)(((ulong)(int)a) >> 32); [MethodImpl(MethodImplOptions.InternalCall)] private static extern int DivInt32Internal(int dividend, int divisor); From 2f980a2cb8abc05f84444764ef9114a286e8aece Mon Sep 17 00:00:00 2001 From: Adeel Mujahid <3840695+am11@users.noreply.github.com> Date: Sat, 30 Nov 2024 01:32:06 +0200 Subject: [PATCH 08/27] Update src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/JitHelper.cs --- src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/JitHelper.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/JitHelper.cs b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/JitHelper.cs index e3bfed27e42bdf..4627a406636f51 100644 --- a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/JitHelper.cs +++ b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/JitHelper.cs @@ -250,7 +250,7 @@ public static void GetEntryPoint(TypeSystemContext context, ReadyToRunHelper id, methodDesc = context.SystemModule.GetKnownType("System", "Math").GetKnownMethod("ModInt32", null); break; case ReadyToRunHelper.UMod: - methodDesc = context.SystemModule.GetKnownType("System", "Math").GetKnownMethod("ModulUInt32", null); + methodDesc = context.SystemModule.GetKnownType("System", "Math").GetKnownMethod("ModUInt32", null); break; case ReadyToRunHelper.LMod: methodDesc = context.SystemModule.GetKnownType("System", "Math").GetKnownMethod("ModInt64", null); From 40dba4f7613d2bcbfbebd65455dabca9ba74df74 Mon Sep 17 00:00:00 2001 From: Adeel <3840695+am11@users.noreply.github.com> Date: Sat, 30 Nov 2024 03:48:45 +0200 Subject: [PATCH 09/27] Revert "Replace CreateTruncating" This reverts commit 960dae14629beeded57f55626e08b4831f6c6d64. --- .../src/System/Math.DivModInt.cs | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/libraries/System.Private.CoreLib/src/System/Math.DivModInt.cs b/src/libraries/System.Private.CoreLib/src/System/Math.DivModInt.cs index 59f5e4c1e23404..d85f2ed34c8e07 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Math.DivModInt.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Math.DivModInt.cs @@ -175,11 +175,17 @@ internal static ulong ModUInt64(ulong dividend, ulong divisor) // helper method to get high 32-bit of 64-bit int [MethodImpl(MethodImplOptions.AggressiveInlining)] - private static uint Hi32Bits(ulong a) => (uint)(int)(a >> 32); + private static uint Hi32Bits(T a) where T : INumber + { + return (uint)(ulong.CreateTruncating(a) >> 32); + } // helper method to check whether 64-bit signed int fits into 32-bit signed (compiles into one 32-bit compare) [MethodImpl(MethodImplOptions.AggressiveInlining)] - private static bool Is32BitSigned(long a) => (uint)(int)((ulong)a >> 32) == (uint)(int)(((ulong)(int)a) >> 32); + private static bool Is32BitSigned(T a) where T : INumber + { + return Hi32Bits(a) == Hi32Bits(long.CreateTruncating(int.CreateTruncating(a))); + } [MethodImpl(MethodImplOptions.InternalCall)] private static extern int DivInt32Internal(int dividend, int divisor); From d80d2146e7c2a1ad3cb26c244300f476d464670b Mon Sep 17 00:00:00 2001 From: Adeel <3840695+am11@users.noreply.github.com> Date: Sat, 30 Nov 2024 04:02:32 +0200 Subject: [PATCH 10/27] Use AggressiveOptimization as well --- .../System.Private.CoreLib/src/System/Math.DivModInt.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/libraries/System.Private.CoreLib/src/System/Math.DivModInt.cs b/src/libraries/System.Private.CoreLib/src/System/Math.DivModInt.cs index d85f2ed34c8e07..065002a48fb5c6 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Math.DivModInt.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Math.DivModInt.cs @@ -174,14 +174,14 @@ internal static ulong ModUInt64(ulong dividend, ulong divisor) } // helper method to get high 32-bit of 64-bit int - [MethodImpl(MethodImplOptions.AggressiveInlining)] + [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] private static uint Hi32Bits(T a) where T : INumber { return (uint)(ulong.CreateTruncating(a) >> 32); } // helper method to check whether 64-bit signed int fits into 32-bit signed (compiles into one 32-bit compare) - [MethodImpl(MethodImplOptions.AggressiveInlining)] + [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] private static bool Is32BitSigned(T a) where T : INumber { return Hi32Bits(a) == Hi32Bits(long.CreateTruncating(int.CreateTruncating(a))); From e5dcf0b3d4877813ff29fafddffb6b2215f39576 Mon Sep 17 00:00:00 2001 From: Adeel Mujahid <3840695+am11@users.noreply.github.com> Date: Sat, 30 Nov 2024 23:30:55 +0200 Subject: [PATCH 11/27] Remove signed 32 bit helpers and inline conditions --- .../src/System/Math.DivModInt.cs | 30 +++++-------------- 1 file changed, 8 insertions(+), 22 deletions(-) diff --git a/src/libraries/System.Private.CoreLib/src/System/Math.DivModInt.cs b/src/libraries/System.Private.CoreLib/src/System/Math.DivModInt.cs index 065002a48fb5c6..8f40df24ec4d66 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Math.DivModInt.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Math.DivModInt.cs @@ -52,7 +52,7 @@ internal static uint DivUInt32(uint dividend, uint divisor) [StackTraceHidden] internal static long DivInt64(long dividend, long divisor) { - if (Is32BitSigned(divisor)) + if ((uint)(int)((ulong)divisor >> 32) == (uint)(int)(((ulong)(int)divisor) >> 32)) { if ((int)divisor == 0) { @@ -69,7 +69,7 @@ internal static long DivInt64(long dividend, long divisor) } // Check for -ive or +ive numbers in the range -2**31 to 2**31 - if (Is32BitSigned(dividend)) + if ((uint)(int)((ulong)dividend >> 32) == (uint)(int)(((ulong)(int)dividend) >> 32)) { return (int)dividend / (int)divisor; } @@ -81,14 +81,14 @@ internal static long DivInt64(long dividend, long divisor) [StackTraceHidden] internal static ulong DivUInt64(ulong dividend, ulong divisor) { - if (Hi32Bits(divisor) == 0) + if ((uint)(int)(divisor >> 32) == 0) { if ((uint)divisor == 0) { ThrowHelper.ThrowDivideByZeroException(); } - if (Hi32Bits(dividend) == 0) + if ((uint)(int)(dividend >> 32) == 0) return (uint)dividend / (uint)divisor; } @@ -131,7 +131,7 @@ internal static uint ModUInt32(uint dividend, uint divisor) [StackTraceHidden] internal static long ModInt64(long dividend, long divisor) { - if (Is32BitSigned(divisor)) + if ((uint)(int)((ulong)divisor >> 32) == (uint)(int)(((ulong)(int)divisor) >> 32)) { if ((int)divisor == 0) { @@ -147,7 +147,7 @@ internal static long ModInt64(long dividend, long divisor) return 0; } - if (Is32BitSigned(dividend)) + if ((uint)(int)((ulong)dividend >> 32) == (uint)(int)(((ulong)(int)dividend) >> 32)) { return (int)dividend % (int)divisor; } @@ -159,34 +159,20 @@ internal static long ModInt64(long dividend, long divisor) [StackTraceHidden] internal static ulong ModUInt64(ulong dividend, ulong divisor) { - if (Hi32Bits(divisor) == 0) + if ((uint)(int)(divisor >> 32) == 0) { if ((uint)divisor == 0) { ThrowHelper.ThrowDivideByZeroException(); } - if (Hi32Bits(dividend) == 0) + if ((uint)(int)(dividend >> 32) == 0) return (uint)dividend % (uint)divisor; } return ModUInt64Internal(dividend, divisor); } - // helper method to get high 32-bit of 64-bit int - [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] - private static uint Hi32Bits(T a) where T : INumber - { - return (uint)(ulong.CreateTruncating(a) >> 32); - } - - // helper method to check whether 64-bit signed int fits into 32-bit signed (compiles into one 32-bit compare) - [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] - private static bool Is32BitSigned(T a) where T : INumber - { - return Hi32Bits(a) == Hi32Bits(long.CreateTruncating(int.CreateTruncating(a))); - } - [MethodImpl(MethodImplOptions.InternalCall)] private static extern int DivInt32Internal(int dividend, int divisor); From 82aaa96b25aa67edc2498466d996938b86bea654 Mon Sep 17 00:00:00 2001 From: Adeel Mujahid <3840695+am11@users.noreply.github.com> Date: Sat, 30 Nov 2024 23:32:56 +0200 Subject: [PATCH 12/27] Temporarily add AggressiveOptimization on 64b meths --- .../System.Private.CoreLib/src/System/Math.DivModInt.cs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/libraries/System.Private.CoreLib/src/System/Math.DivModInt.cs b/src/libraries/System.Private.CoreLib/src/System/Math.DivModInt.cs index 8f40df24ec4d66..4ac8013cf06bd1 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Math.DivModInt.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Math.DivModInt.cs @@ -50,6 +50,7 @@ internal static uint DivUInt32(uint dividend, uint divisor) } [StackTraceHidden] + [MethodImpl(MethodImplOptions.AggressiveOptimization)] internal static long DivInt64(long dividend, long divisor) { if ((uint)(int)((ulong)divisor >> 32) == (uint)(int)(((ulong)(int)divisor) >> 32)) @@ -79,6 +80,7 @@ internal static long DivInt64(long dividend, long divisor) } [StackTraceHidden] + [MethodImpl(MethodImplOptions.AggressiveOptimization)] internal static ulong DivUInt64(ulong dividend, ulong divisor) { if ((uint)(int)(divisor >> 32) == 0) @@ -129,6 +131,7 @@ internal static uint ModUInt32(uint dividend, uint divisor) } [StackTraceHidden] + [MethodImpl(MethodImplOptions.AggressiveOptimization)] internal static long ModInt64(long dividend, long divisor) { if ((uint)(int)((ulong)divisor >> 32) == (uint)(int)(((ulong)(int)divisor) >> 32)) @@ -157,6 +160,7 @@ internal static long ModInt64(long dividend, long divisor) } [StackTraceHidden] + [MethodImpl(MethodImplOptions.AggressiveOptimization)] internal static ulong ModUInt64(ulong dividend, ulong divisor) { if ((uint)(int)(divisor >> 32) == 0) From 8cb5d4d07f3cc4e2630ed0297da4ce2c21ac5586 Mon Sep 17 00:00:00 2001 From: Adeel Mujahid <3840695+am11@users.noreply.github.com> Date: Sun, 1 Dec 2024 05:00:41 +0200 Subject: [PATCH 13/27] Apply suggestions from code review Co-authored-by: Jan Kotas --- .../System.Private.CoreLib/src/System/Math.DivModInt.cs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/libraries/System.Private.CoreLib/src/System/Math.DivModInt.cs b/src/libraries/System.Private.CoreLib/src/System/Math.DivModInt.cs index 4ac8013cf06bd1..e2d562a28f18fd 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Math.DivModInt.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Math.DivModInt.cs @@ -53,7 +53,7 @@ internal static uint DivUInt32(uint dividend, uint divisor) [MethodImpl(MethodImplOptions.AggressiveOptimization)] internal static long DivInt64(long dividend, long divisor) { - if ((uint)(int)((ulong)divisor >> 32) == (uint)(int)(((ulong)(int)divisor) >> 32)) + if ((int)((ulong)divisor >> 32) == (int)(((ulong)(int)divisor) >> 32)) { if ((int)divisor == 0) { @@ -70,7 +70,7 @@ internal static long DivInt64(long dividend, long divisor) } // Check for -ive or +ive numbers in the range -2**31 to 2**31 - if ((uint)(int)((ulong)dividend >> 32) == (uint)(int)(((ulong)(int)dividend) >> 32)) + if ((int)((ulong)dividend >> 32) == (int)(((ulong)(int)dividend) >> 32)) { return (int)dividend / (int)divisor; } @@ -134,7 +134,7 @@ internal static uint ModUInt32(uint dividend, uint divisor) [MethodImpl(MethodImplOptions.AggressiveOptimization)] internal static long ModInt64(long dividend, long divisor) { - if ((uint)(int)((ulong)divisor >> 32) == (uint)(int)(((ulong)(int)divisor) >> 32)) + if ((int)((ulong)divisor >> 32) == (int)(((ulong)(int)divisor) >> 32)) { if ((int)divisor == 0) { @@ -150,7 +150,7 @@ internal static long ModInt64(long dividend, long divisor) return 0; } - if ((uint)(int)((ulong)dividend >> 32) == (uint)(int)(((ulong)(int)dividend) >> 32)) + if ((int)((ulong)dividend >> 32) == (int)(((ulong)(int)dividend) >> 32)) { return (int)dividend % (int)divisor; } From a9624bb79fe2216b864760be83c8584eef731cf1 Mon Sep 17 00:00:00 2001 From: Adeel Mujahid <3840695+am11@users.noreply.github.com> Date: Sun, 1 Dec 2024 17:49:02 +0200 Subject: [PATCH 14/27] Remove redundant casts and align style --- .../src/System/Math.DivModInt.cs | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/src/libraries/System.Private.CoreLib/src/System/Math.DivModInt.cs b/src/libraries/System.Private.CoreLib/src/System/Math.DivModInt.cs index e2d562a28f18fd..3c691ed2bd2970 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Math.DivModInt.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Math.DivModInt.cs @@ -83,15 +83,17 @@ internal static long DivInt64(long dividend, long divisor) [MethodImpl(MethodImplOptions.AggressiveOptimization)] internal static ulong DivUInt64(ulong dividend, ulong divisor) { - if ((uint)(int)(divisor >> 32) == 0) + if ((int)(divisor >> 32) == 0) { if ((uint)divisor == 0) { ThrowHelper.ThrowDivideByZeroException(); } - if ((uint)(int)(dividend >> 32) == 0) + if ((int)(dividend >> 32) == 0) + { return (uint)dividend / (uint)divisor; + } } return DivUInt64Internal(dividend, divisor); @@ -163,15 +165,17 @@ internal static long ModInt64(long dividend, long divisor) [MethodImpl(MethodImplOptions.AggressiveOptimization)] internal static ulong ModUInt64(ulong dividend, ulong divisor) { - if ((uint)(int)(divisor >> 32) == 0) + if ((int)(divisor >> 32) == 0) { if ((uint)divisor == 0) { ThrowHelper.ThrowDivideByZeroException(); } - if ((uint)(int)(dividend >> 32) == 0) + if ((int)(dividend >> 32) == 0) + { return (uint)dividend % (uint)divisor; + } } return ModUInt64Internal(dividend, divisor); From 2784ba0efddbdc5635ee4b0b02bec7fb6b9ed563 Mon Sep 17 00:00:00 2001 From: Adeel Mujahid <3840695+am11@users.noreply.github.com> Date: Sun, 1 Dec 2024 18:01:03 +0200 Subject: [PATCH 15/27] Use idiomatic long.MinValue --- .../System.Private.CoreLib/src/System/Math.DivModInt.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/libraries/System.Private.CoreLib/src/System/Math.DivModInt.cs b/src/libraries/System.Private.CoreLib/src/System/Math.DivModInt.cs index 3c691ed2bd2970..a03dfb89be5360 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Math.DivModInt.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Math.DivModInt.cs @@ -62,7 +62,7 @@ internal static long DivInt64(long dividend, long divisor) if ((int)divisor == -1) { - if ((ulong)dividend == 0x8000000000000000ul) + if (dividend == long.MinValue) { ThrowHelper.ThrowOverflowException(); } @@ -145,7 +145,7 @@ internal static long ModInt64(long dividend, long divisor) if ((int)divisor == -1) { - if ((ulong)dividend == 0x8000000000000000ul) + if (dividend == long.MinValue) { ThrowHelper.ThrowOverflowException(); } From 1cdbf4d8c603f3027799c24b509a0bd7b9d0145e Mon Sep 17 00:00:00 2001 From: Adeel Mujahid <3840695+am11@users.noreply.github.com> Date: Sun, 1 Dec 2024 23:41:58 +0200 Subject: [PATCH 16/27] Avoid redundant checks in 64bit helpers --- .../System.Private.CoreLib/src/System/Math.DivModInt.cs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/libraries/System.Private.CoreLib/src/System/Math.DivModInt.cs b/src/libraries/System.Private.CoreLib/src/System/Math.DivModInt.cs index a03dfb89be5360..29dd1442494182 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Math.DivModInt.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Math.DivModInt.cs @@ -72,7 +72,7 @@ internal static long DivInt64(long dividend, long divisor) // Check for -ive or +ive numbers in the range -2**31 to 2**31 if ((int)((ulong)dividend >> 32) == (int)(((ulong)(int)dividend) >> 32)) { - return (int)dividend / (int)divisor; + return DivInt32Internal((int)dividend, (int)divisor); } } @@ -92,7 +92,7 @@ internal static ulong DivUInt64(ulong dividend, ulong divisor) if ((int)(dividend >> 32) == 0) { - return (uint)dividend / (uint)divisor; + return DivUInt32Internal((uint)dividend, (uint)divisor); } } @@ -154,7 +154,7 @@ internal static long ModInt64(long dividend, long divisor) if ((int)((ulong)dividend >> 32) == (int)(((ulong)(int)dividend) >> 32)) { - return (int)dividend % (int)divisor; + return ModInt32Internal((int)dividend, (int)divisor); } } @@ -174,7 +174,7 @@ internal static ulong ModUInt64(ulong dividend, ulong divisor) if ((int)(dividend >> 32) == 0) { - return (uint)dividend % (uint)divisor; + return ModUInt32Internal((uint)dividend, (uint)divisor); } } From 5674bc0470417acbcc6098dcb3d3014d0e46d9f1 Mon Sep 17 00:00:00 2001 From: Adeel Mujahid <3840695+am11@users.noreply.github.com> Date: Sun, 1 Dec 2024 23:48:49 +0200 Subject: [PATCH 17/27] actually just remove them.. --- .../src/System/Math.DivModInt.cs | 35 +++---------------- 1 file changed, 4 insertions(+), 31 deletions(-) diff --git a/src/libraries/System.Private.CoreLib/src/System/Math.DivModInt.cs b/src/libraries/System.Private.CoreLib/src/System/Math.DivModInt.cs index 29dd1442494182..7262ccf254ebda 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Math.DivModInt.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Math.DivModInt.cs @@ -68,12 +68,6 @@ internal static long DivInt64(long dividend, long divisor) } return -dividend; } - - // Check for -ive or +ive numbers in the range -2**31 to 2**31 - if ((int)((ulong)dividend >> 32) == (int)(((ulong)(int)dividend) >> 32)) - { - return DivInt32Internal((int)dividend, (int)divisor); - } } return DivInt64Internal(dividend, divisor); @@ -83,17 +77,9 @@ internal static long DivInt64(long dividend, long divisor) [MethodImpl(MethodImplOptions.AggressiveOptimization)] internal static ulong DivUInt64(ulong dividend, ulong divisor) { - if ((int)(divisor >> 32) == 0) + if ((int)(divisor >> 32) == 0 && (uint)divisor == 0) { - if ((uint)divisor == 0) - { - ThrowHelper.ThrowDivideByZeroException(); - } - - if ((int)(dividend >> 32) == 0) - { - return DivUInt32Internal((uint)dividend, (uint)divisor); - } + ThrowHelper.ThrowDivideByZeroException(); } return DivUInt64Internal(dividend, divisor); @@ -151,11 +137,6 @@ internal static long ModInt64(long dividend, long divisor) } return 0; } - - if ((int)((ulong)dividend >> 32) == (int)(((ulong)(int)dividend) >> 32)) - { - return ModInt32Internal((int)dividend, (int)divisor); - } } return ModInt64Internal(dividend, divisor); @@ -165,17 +146,9 @@ internal static long ModInt64(long dividend, long divisor) [MethodImpl(MethodImplOptions.AggressiveOptimization)] internal static ulong ModUInt64(ulong dividend, ulong divisor) { - if ((int)(divisor >> 32) == 0) + if ((int)(divisor >> 32) == 0 && (uint)divisor == 0) { - if ((uint)divisor == 0) - { - ThrowHelper.ThrowDivideByZeroException(); - } - - if ((int)(dividend >> 32) == 0) - { - return ModUInt32Internal((uint)dividend, (uint)divisor); - } + ThrowHelper.ThrowDivideByZeroException(); } return ModUInt64Internal(dividend, divisor); From 228bb4227b51345d027b3ce21bc2980f86faa2a5 Mon Sep 17 00:00:00 2001 From: Adeel Mujahid <3840695+am11@users.noreply.github.com> Date: Mon, 2 Dec 2024 00:13:14 +0200 Subject: [PATCH 18/27] Remove AggressiveOptimization --- .../System.Private.CoreLib/src/System/Math.DivModInt.cs | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/libraries/System.Private.CoreLib/src/System/Math.DivModInt.cs b/src/libraries/System.Private.CoreLib/src/System/Math.DivModInt.cs index 7262ccf254ebda..eee71a570f0b81 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Math.DivModInt.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Math.DivModInt.cs @@ -50,7 +50,6 @@ internal static uint DivUInt32(uint dividend, uint divisor) } [StackTraceHidden] - [MethodImpl(MethodImplOptions.AggressiveOptimization)] internal static long DivInt64(long dividend, long divisor) { if ((int)((ulong)divisor >> 32) == (int)(((ulong)(int)divisor) >> 32)) @@ -74,7 +73,6 @@ internal static long DivInt64(long dividend, long divisor) } [StackTraceHidden] - [MethodImpl(MethodImplOptions.AggressiveOptimization)] internal static ulong DivUInt64(ulong dividend, ulong divisor) { if ((int)(divisor >> 32) == 0 && (uint)divisor == 0) @@ -119,7 +117,6 @@ internal static uint ModUInt32(uint dividend, uint divisor) } [StackTraceHidden] - [MethodImpl(MethodImplOptions.AggressiveOptimization)] internal static long ModInt64(long dividend, long divisor) { if ((int)((ulong)divisor >> 32) == (int)(((ulong)(int)divisor) >> 32)) @@ -143,7 +140,6 @@ internal static long ModInt64(long dividend, long divisor) } [StackTraceHidden] - [MethodImpl(MethodImplOptions.AggressiveOptimization)] internal static ulong ModUInt64(ulong dividend, ulong divisor) { if ((int)(divisor >> 32) == 0 && (uint)divisor == 0) From dda3da9be6eb098fb1434dbb5bd4170e33d9d84d Mon Sep 17 00:00:00 2001 From: Adeel <3840695+am11@users.noreply.github.com> Date: Mon, 2 Dec 2024 01:11:04 +0200 Subject: [PATCH 19/27] Revert "actually just remove them.." This reverts commit 5674bc0470417acbcc6098dcb3d3014d0e46d9f1. --- .../src/System/Math.DivModInt.cs | 35 ++++++++++++++++--- 1 file changed, 31 insertions(+), 4 deletions(-) diff --git a/src/libraries/System.Private.CoreLib/src/System/Math.DivModInt.cs b/src/libraries/System.Private.CoreLib/src/System/Math.DivModInt.cs index eee71a570f0b81..e73203d332b537 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Math.DivModInt.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Math.DivModInt.cs @@ -67,6 +67,12 @@ internal static long DivInt64(long dividend, long divisor) } return -dividend; } + + // Check for -ive or +ive numbers in the range -2**31 to 2**31 + if ((int)((ulong)dividend >> 32) == (int)(((ulong)(int)dividend) >> 32)) + { + return DivInt32Internal((int)dividend, (int)divisor); + } } return DivInt64Internal(dividend, divisor); @@ -75,9 +81,17 @@ internal static long DivInt64(long dividend, long divisor) [StackTraceHidden] internal static ulong DivUInt64(ulong dividend, ulong divisor) { - if ((int)(divisor >> 32) == 0 && (uint)divisor == 0) + if ((int)(divisor >> 32) == 0) { - ThrowHelper.ThrowDivideByZeroException(); + if ((uint)divisor == 0) + { + ThrowHelper.ThrowDivideByZeroException(); + } + + if ((int)(dividend >> 32) == 0) + { + return DivUInt32Internal((uint)dividend, (uint)divisor); + } } return DivUInt64Internal(dividend, divisor); @@ -134,6 +148,11 @@ internal static long ModInt64(long dividend, long divisor) } return 0; } + + if ((int)((ulong)dividend >> 32) == (int)(((ulong)(int)dividend) >> 32)) + { + return ModInt32Internal((int)dividend, (int)divisor); + } } return ModInt64Internal(dividend, divisor); @@ -142,9 +161,17 @@ internal static long ModInt64(long dividend, long divisor) [StackTraceHidden] internal static ulong ModUInt64(ulong dividend, ulong divisor) { - if ((int)(divisor >> 32) == 0 && (uint)divisor == 0) + if ((int)(divisor >> 32) == 0) { - ThrowHelper.ThrowDivideByZeroException(); + if ((uint)divisor == 0) + { + ThrowHelper.ThrowDivideByZeroException(); + } + + if ((int)(dividend >> 32) == 0) + { + return ModUInt32Internal((uint)dividend, (uint)divisor); + } } return ModUInt64Internal(dividend, divisor); From 544f17840484823ff9282abaa2007f54a074384f Mon Sep 17 00:00:00 2001 From: Adeel Mujahid <3840695+am11@users.noreply.github.com> Date: Mon, 2 Dec 2024 12:11:55 +0200 Subject: [PATCH 20/27] Experiment: Try replacing fcalls with software helpers --- .../src/System/Math.DivModInt.cs | 82 ++++++++++++++++--- 1 file changed, 70 insertions(+), 12 deletions(-) diff --git a/src/libraries/System.Private.CoreLib/src/System/Math.DivModInt.cs b/src/libraries/System.Private.CoreLib/src/System/Math.DivModInt.cs index e73203d332b537..ec7bbc0340ea7d 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Math.DivModInt.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Math.DivModInt.cs @@ -35,7 +35,7 @@ internal static int DivInt32(int dividend, int divisor) } } - return DivInt32Internal(dividend, divisor); + return DivModSigned(dividend, divisor).quotient; } [StackTraceHidden] @@ -46,7 +46,7 @@ internal static uint DivUInt32(uint dividend, uint divisor) ThrowHelper.ThrowDivideByZeroException(); } - return DivUInt32Internal(dividend, divisor); + return DivModUnsigned(dividend, divisor).quotient; } [StackTraceHidden] @@ -71,11 +71,11 @@ internal static long DivInt64(long dividend, long divisor) // Check for -ive or +ive numbers in the range -2**31 to 2**31 if ((int)((ulong)dividend >> 32) == (int)(((ulong)(int)dividend) >> 32)) { - return DivInt32Internal((int)dividend, (int)divisor); + return DivModSigned((int)dividend, (int)divisor).quotient; } } - return DivInt64Internal(dividend, divisor); + return DivModSigned(dividend, divisor).quotient; } [StackTraceHidden] @@ -90,11 +90,11 @@ internal static ulong DivUInt64(ulong dividend, ulong divisor) if ((int)(dividend >> 32) == 0) { - return DivUInt32Internal((uint)dividend, (uint)divisor); + return DivModUnsigned((uint)dividend, (uint)divisor).quotient; } } - return DivUInt64Internal(dividend, divisor); + return DivModUnsigned(dividend, divisor).quotient; } [StackTraceHidden] @@ -116,7 +116,7 @@ internal static int ModInt32(int dividend, int divisor) } } - return ModInt32Internal(dividend, divisor); + return DivModSigned(dividend, divisor).remainder; } [StackTraceHidden] @@ -127,7 +127,7 @@ internal static uint ModUInt32(uint dividend, uint divisor) ThrowHelper.ThrowDivideByZeroException(); } - return ModUInt32Internal(dividend, divisor); + return DivModUnsigned(dividend, divisor).remainder; } [StackTraceHidden] @@ -151,11 +151,11 @@ internal static long ModInt64(long dividend, long divisor) if ((int)((ulong)dividend >> 32) == (int)(((ulong)(int)dividend) >> 32)) { - return ModInt32Internal((int)dividend, (int)divisor); + return DivModSigned((int)dividend, (int)divisor).remainder; } } - return ModInt64Internal(dividend, divisor); + return DivModSigned(dividend, divisor).remainder; } [StackTraceHidden] @@ -170,11 +170,69 @@ internal static ulong ModUInt64(ulong dividend, ulong divisor) if ((int)(dividend >> 32) == 0) { - return ModUInt32Internal((uint)dividend, (uint)divisor); + return DivModUnsigned((uint)dividend, (uint)divisor).remainder; } } - return ModUInt64Internal(dividend, divisor); + return DivModUnsigned(dividend, divisor).remainder; + } + + [MethodImpl(MethodImplOptions.AggressiveOptimization)] + private static (T quotient, T remainder) DivModUnsigned(T dividend, T divisor) + where T : INumber, IMinMaxValue, IShiftOperators, IBitwiseOperators + { + T bit = T.One; + T quotient = T.Zero; + int mask = typeof(T) == typeof(int) || typeof(T) == typeof(uint) ? 31 : 63; + + // Align divisor with dividend: align the divisor with the most significant bit of the dividend + while (divisor < dividend && bit != T.Zero && T.IsZero(divisor & (T.One << mask))) + { + divisor <<= 1; + bit <<= 1; + } + + // Perform the division + while (bit > T.Zero) + { + if (dividend >= divisor) + { + dividend -= divisor; + quotient |= bit; + } + bit >>= 1; + divisor >>= 1; + } + + // Return the result as a tuple (quotient, remainder) + return (quotient, dividend); + } + + [MethodImpl(MethodImplOptions.AggressiveOptimization)] + private static (T quotient, T remainder) DivModSigned(T dividend, T divisor) + where T : INumber, IMinMaxValue, IShiftOperators, IBitwiseOperators + where U : INumber, IMinMaxValue, IShiftOperators, IBitwiseOperators + { + bool dividendIsNegative = dividend < T.Zero; + bool divisorIsNegative = divisor < T.Zero; + + dividend = dividendIsNegative ? -dividend : dividend; + divisor = divisorIsNegative ? -divisor : divisor; + + // Use unsigned DivMod method for absolute values + (U quotient, U remainder) = DivModUnsigned(U.CreateTruncating(dividend), U.CreateTruncating(divisor)); + + // Convert the quotient and remainder back to T + T tQuotient = T.CreateTruncating(quotient); + T tRemainder = T.CreateTruncating(remainder); + + // Adjust the signs if necessary + if (dividendIsNegative) + tRemainder = -tRemainder; + if (dividendIsNegative ^ divisorIsNegative) + tQuotient = -tQuotient; + + return (tQuotient, tRemainder); } [MethodImpl(MethodImplOptions.InternalCall)] From e51389e0973e68f7033b7947a8b689a928e55956 Mon Sep 17 00:00:00 2001 From: Adeel <3840695+am11@users.noreply.github.com> Date: Mon, 2 Dec 2024 14:06:07 +0200 Subject: [PATCH 21/27] Reduce a bit --- .../src/System/Math.DivModInt.cs | 113 ++++++++++-------- 1 file changed, 61 insertions(+), 52 deletions(-) diff --git a/src/libraries/System.Private.CoreLib/src/System/Math.DivModInt.cs b/src/libraries/System.Private.CoreLib/src/System/Math.DivModInt.cs index ec7bbc0340ea7d..d1d728b8e11520 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Math.DivModInt.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Math.DivModInt.cs @@ -35,7 +35,7 @@ internal static int DivInt32(int dividend, int divisor) } } - return DivModSigned(dividend, divisor).quotient; + return DivMod(dividend, divisor).quotient; } [StackTraceHidden] @@ -46,7 +46,7 @@ internal static uint DivUInt32(uint dividend, uint divisor) ThrowHelper.ThrowDivideByZeroException(); } - return DivModUnsigned(dividend, divisor).quotient; + return DivMod(dividend, divisor).quotient; } [StackTraceHidden] @@ -71,11 +71,11 @@ internal static long DivInt64(long dividend, long divisor) // Check for -ive or +ive numbers in the range -2**31 to 2**31 if ((int)((ulong)dividend >> 32) == (int)(((ulong)(int)dividend) >> 32)) { - return DivModSigned((int)dividend, (int)divisor).quotient; + return DivMod((int)dividend, (int)divisor).quotient; } } - return DivModSigned(dividend, divisor).quotient; + return DivMod(dividend, divisor).quotient; } [StackTraceHidden] @@ -90,11 +90,11 @@ internal static ulong DivUInt64(ulong dividend, ulong divisor) if ((int)(dividend >> 32) == 0) { - return DivModUnsigned((uint)dividend, (uint)divisor).quotient; + return DivMod((uint)dividend, (uint)divisor).quotient; } } - return DivModUnsigned(dividend, divisor).quotient; + return DivMod(dividend, divisor).quotient; } [StackTraceHidden] @@ -116,7 +116,7 @@ internal static int ModInt32(int dividend, int divisor) } } - return DivModSigned(dividend, divisor).remainder; + return DivMod(dividend, divisor).remainder; } [StackTraceHidden] @@ -127,7 +127,7 @@ internal static uint ModUInt32(uint dividend, uint divisor) ThrowHelper.ThrowDivideByZeroException(); } - return DivModUnsigned(dividend, divisor).remainder; + return DivMod(dividend, divisor).remainder; } [StackTraceHidden] @@ -151,11 +151,11 @@ internal static long ModInt64(long dividend, long divisor) if ((int)((ulong)dividend >> 32) == (int)(((ulong)(int)dividend) >> 32)) { - return DivModSigned((int)dividend, (int)divisor).remainder; + return DivMod((int)dividend, (int)divisor).remainder; } } - return DivModSigned(dividend, divisor).remainder; + return DivMod(dividend, divisor).remainder; } [StackTraceHidden] @@ -170,67 +170,74 @@ internal static ulong ModUInt64(ulong dividend, ulong divisor) if ((int)(dividend >> 32) == 0) { - return DivModUnsigned((uint)dividend, (uint)divisor).remainder; + return DivMod((uint)dividend, (uint)divisor).remainder; } } - return DivModUnsigned(dividend, divisor).remainder; + return DivMod(dividend, divisor).remainder; } - [MethodImpl(MethodImplOptions.AggressiveOptimization)] - private static (T quotient, T remainder) DivModUnsigned(T dividend, T divisor) - where T : INumber, IMinMaxValue, IShiftOperators, IBitwiseOperators + private static (T quotient, T remainder) DivMod(T dividend, T divisor) + where T : INumber, IMinMaxValue + where U : INumber, IMinMaxValue, IShiftOperators, IBitwiseOperators { - T bit = T.One; - T quotient = T.Zero; - int mask = typeof(T) == typeof(int) || typeof(T) == typeof(uint) ? 31 : 63; + bool dividendIsNegative = false; + bool divisorIsNegative = false; + + // Handle signs if T is signed + if (typeof(T) != typeof(U)) + { + if (dividend < T.Zero) + { + dividend = -dividend; + dividendIsNegative = true; + } + if (divisor < T.Zero) + { + divisor = -divisor; + divisorIsNegative = true; + } + } + + // Perform unsigned division using type U + U uDividend = U.CreateTruncating(dividend); + U uDivisor = U.CreateTruncating(divisor); + + U bit = U.One; + U uQuotient = U.Zero; + int mask = typeof(U) == typeof(uint) ? 31 : 63; - // Align divisor with dividend: align the divisor with the most significant bit of the dividend - while (divisor < dividend && bit != T.Zero && T.IsZero(divisor & (T.One << mask))) + // Align divisor with dividend + while (uDivisor < uDividend && bit != U.Zero && U.IsZero(uDivisor & (U.One << mask))) { - divisor <<= 1; + uDivisor <<= 1; bit <<= 1; } // Perform the division - while (bit > T.Zero) + while (bit > U.Zero) { - if (dividend >= divisor) + if (uDividend >= uDivisor) { - dividend -= divisor; - quotient |= bit; + uDividend -= uDivisor; + uQuotient |= bit; } bit >>= 1; - divisor >>= 1; + uDivisor >>= 1; } - // Return the result as a tuple (quotient, remainder) - return (quotient, dividend); - } - - [MethodImpl(MethodImplOptions.AggressiveOptimization)] - private static (T quotient, T remainder) DivModSigned(T dividend, T divisor) - where T : INumber, IMinMaxValue, IShiftOperators, IBitwiseOperators - where U : INumber, IMinMaxValue, IShiftOperators, IBitwiseOperators - { - bool dividendIsNegative = dividend < T.Zero; - bool divisorIsNegative = divisor < T.Zero; - - dividend = dividendIsNegative ? -dividend : dividend; - divisor = divisorIsNegative ? -divisor : divisor; + // Convert results back to type T + T tQuotient = T.CreateTruncating(uQuotient); + T tRemainder = T.CreateTruncating(uDividend); - // Use unsigned DivMod method for absolute values - (U quotient, U remainder) = DivModUnsigned(U.CreateTruncating(dividend), U.CreateTruncating(divisor)); - - // Convert the quotient and remainder back to T - T tQuotient = T.CreateTruncating(quotient); - T tRemainder = T.CreateTruncating(remainder); - - // Adjust the signs if necessary - if (dividendIsNegative) - tRemainder = -tRemainder; - if (dividendIsNegative ^ divisorIsNegative) - tQuotient = -tQuotient; + // Adjust signs if T is signed + if (typeof(T) != typeof(U)) + { + if (dividendIsNegative) + tRemainder = -tRemainder; + if (dividendIsNegative ^ divisorIsNegative) + tQuotient = -tQuotient; + } return (tQuotient, tRemainder); } @@ -241,6 +248,7 @@ private static (T quotient, T remainder) DivModSigned(T dividend, T diviso [MethodImpl(MethodImplOptions.InternalCall)] private static extern uint DivUInt32Internal(uint dividend, uint divisor); +/* #if NATIVEAOT [LibraryImport(RuntimeHelpers.QCall, EntryPoint = "DivInt64Internal"), SuppressGCTransition] private static partial long DivInt64Internal(long dividend, long divisor); @@ -278,5 +286,6 @@ private static (T quotient, T remainder) DivModSigned(T dividend, T diviso [MethodImpl(MethodImplOptions.InternalCall)] private static extern ulong ModUInt64Internal(ulong dividend, ulong divisor); #endif +*/ } } From 48f8f1b28c4ead8af0c67177f926b9e04637d8ea Mon Sep 17 00:00:00 2001 From: Adeel Mujahid <3840695+am11@users.noreply.github.com> Date: Mon, 2 Dec 2024 20:00:58 +0200 Subject: [PATCH 22/27] Revert "Experiment: Try replacing fcalls with software helpers" --- .../src/System/Math.DivModInt.cs | 91 +++---------------- 1 file changed, 12 insertions(+), 79 deletions(-) diff --git a/src/libraries/System.Private.CoreLib/src/System/Math.DivModInt.cs b/src/libraries/System.Private.CoreLib/src/System/Math.DivModInt.cs index d1d728b8e11520..e73203d332b537 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Math.DivModInt.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Math.DivModInt.cs @@ -35,7 +35,7 @@ internal static int DivInt32(int dividend, int divisor) } } - return DivMod(dividend, divisor).quotient; + return DivInt32Internal(dividend, divisor); } [StackTraceHidden] @@ -46,7 +46,7 @@ internal static uint DivUInt32(uint dividend, uint divisor) ThrowHelper.ThrowDivideByZeroException(); } - return DivMod(dividend, divisor).quotient; + return DivUInt32Internal(dividend, divisor); } [StackTraceHidden] @@ -71,11 +71,11 @@ internal static long DivInt64(long dividend, long divisor) // Check for -ive or +ive numbers in the range -2**31 to 2**31 if ((int)((ulong)dividend >> 32) == (int)(((ulong)(int)dividend) >> 32)) { - return DivMod((int)dividend, (int)divisor).quotient; + return DivInt32Internal((int)dividend, (int)divisor); } } - return DivMod(dividend, divisor).quotient; + return DivInt64Internal(dividend, divisor); } [StackTraceHidden] @@ -90,11 +90,11 @@ internal static ulong DivUInt64(ulong dividend, ulong divisor) if ((int)(dividend >> 32) == 0) { - return DivMod((uint)dividend, (uint)divisor).quotient; + return DivUInt32Internal((uint)dividend, (uint)divisor); } } - return DivMod(dividend, divisor).quotient; + return DivUInt64Internal(dividend, divisor); } [StackTraceHidden] @@ -116,7 +116,7 @@ internal static int ModInt32(int dividend, int divisor) } } - return DivMod(dividend, divisor).remainder; + return ModInt32Internal(dividend, divisor); } [StackTraceHidden] @@ -127,7 +127,7 @@ internal static uint ModUInt32(uint dividend, uint divisor) ThrowHelper.ThrowDivideByZeroException(); } - return DivMod(dividend, divisor).remainder; + return ModUInt32Internal(dividend, divisor); } [StackTraceHidden] @@ -151,11 +151,11 @@ internal static long ModInt64(long dividend, long divisor) if ((int)((ulong)dividend >> 32) == (int)(((ulong)(int)dividend) >> 32)) { - return DivMod((int)dividend, (int)divisor).remainder; + return ModInt32Internal((int)dividend, (int)divisor); } } - return DivMod(dividend, divisor).remainder; + return ModInt64Internal(dividend, divisor); } [StackTraceHidden] @@ -170,76 +170,11 @@ internal static ulong ModUInt64(ulong dividend, ulong divisor) if ((int)(dividend >> 32) == 0) { - return DivMod((uint)dividend, (uint)divisor).remainder; + return ModUInt32Internal((uint)dividend, (uint)divisor); } } - return DivMod(dividend, divisor).remainder; - } - - private static (T quotient, T remainder) DivMod(T dividend, T divisor) - where T : INumber, IMinMaxValue - where U : INumber, IMinMaxValue, IShiftOperators, IBitwiseOperators - { - bool dividendIsNegative = false; - bool divisorIsNegative = false; - - // Handle signs if T is signed - if (typeof(T) != typeof(U)) - { - if (dividend < T.Zero) - { - dividend = -dividend; - dividendIsNegative = true; - } - if (divisor < T.Zero) - { - divisor = -divisor; - divisorIsNegative = true; - } - } - - // Perform unsigned division using type U - U uDividend = U.CreateTruncating(dividend); - U uDivisor = U.CreateTruncating(divisor); - - U bit = U.One; - U uQuotient = U.Zero; - int mask = typeof(U) == typeof(uint) ? 31 : 63; - - // Align divisor with dividend - while (uDivisor < uDividend && bit != U.Zero && U.IsZero(uDivisor & (U.One << mask))) - { - uDivisor <<= 1; - bit <<= 1; - } - - // Perform the division - while (bit > U.Zero) - { - if (uDividend >= uDivisor) - { - uDividend -= uDivisor; - uQuotient |= bit; - } - bit >>= 1; - uDivisor >>= 1; - } - - // Convert results back to type T - T tQuotient = T.CreateTruncating(uQuotient); - T tRemainder = T.CreateTruncating(uDividend); - - // Adjust signs if T is signed - if (typeof(T) != typeof(U)) - { - if (dividendIsNegative) - tRemainder = -tRemainder; - if (dividendIsNegative ^ divisorIsNegative) - tQuotient = -tQuotient; - } - - return (tQuotient, tRemainder); + return ModUInt64Internal(dividend, divisor); } [MethodImpl(MethodImplOptions.InternalCall)] @@ -248,7 +183,6 @@ private static (T quotient, T remainder) DivMod(T dividend, T divisor) [MethodImpl(MethodImplOptions.InternalCall)] private static extern uint DivUInt32Internal(uint dividend, uint divisor); -/* #if NATIVEAOT [LibraryImport(RuntimeHelpers.QCall, EntryPoint = "DivInt64Internal"), SuppressGCTransition] private static partial long DivInt64Internal(long dividend, long divisor); @@ -286,6 +220,5 @@ private static (T quotient, T remainder) DivMod(T dividend, T divisor) [MethodImpl(MethodImplOptions.InternalCall)] private static extern ulong ModUInt64Internal(ulong dividend, ulong divisor); #endif -*/ } } From 9dbcf4eb77fb7058c98f48c98b455acab3b78dc9 Mon Sep 17 00:00:00 2001 From: Adeel <3840695+am11@users.noreply.github.com> Date: Thu, 5 Dec 2024 21:53:44 +0200 Subject: [PATCH 23/27] Experiment: Change FCThrow to COMPlusThrowf --- .../System.Private.CoreLib.csproj | 1 + .../src/System/Math.DivMod.cs | 63 ++++ .../classlibnative/float/CMakeLists.txt | 1 - src/coreclr/inc/jithelpers.h | 2 +- .../CompilerServices/RuntimeHelpers.cs | 2 - src/coreclr/nativeaot/Runtime/MathHelpers.cpp | 16 +- .../Runtime/CompilerHelpers/MathHelpers.cs | 128 +++++++ .../src/System.Private.CoreLib.csproj | 1 + .../ILCompiler.Compiler/Compiler/JitHelper.cs | 32 +- src/coreclr/vm/JitQCallHelpers.h | 13 +- src/coreclr/vm/corelib.cpp | 1 - src/coreclr/vm/ecalllist.h | 10 - src/coreclr/vm/jithelpers.cpp | 332 +++++++++++++++++- src/coreclr/vm/qcallentrypoints.cpp | 10 + .../System.Private.CoreLib.Shared.projitems | 1 - 15 files changed, 569 insertions(+), 44 deletions(-) create mode 100644 src/coreclr/System.Private.CoreLib/src/System/Math.DivMod.cs create mode 100644 src/coreclr/nativeaot/System.Private.CoreLib/src/Internal/Runtime/CompilerHelpers/MathHelpers.cs diff --git a/src/coreclr/System.Private.CoreLib/System.Private.CoreLib.csproj b/src/coreclr/System.Private.CoreLib/System.Private.CoreLib.csproj index f4109a290f9206..74f859415f7a86 100644 --- a/src/coreclr/System.Private.CoreLib/System.Private.CoreLib.csproj +++ b/src/coreclr/System.Private.CoreLib/System.Private.CoreLib.csproj @@ -143,6 +143,7 @@ + diff --git a/src/coreclr/System.Private.CoreLib/src/System/Math.DivMod.cs b/src/coreclr/System.Private.CoreLib/src/System/Math.DivMod.cs new file mode 100644 index 00000000000000..e35b469a87faf2 --- /dev/null +++ b/src/coreclr/System.Private.CoreLib/src/System/Math.DivMod.cs @@ -0,0 +1,63 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System.Diagnostics; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +namespace System +{ + /// + /// Provides constants and static methods for trigonometric, logarithmic, and other common mathematical functions. + /// + public static partial class Math + { + [StackTraceHidden] + internal static int DivInt32(int dividend, int divisor) => DivInt32Internal(dividend, divisor); + + [StackTraceHidden] + internal static uint DivUInt32(uint dividend, uint divisor) => DivUInt32Internal(dividend, divisor); + + [StackTraceHidden] + internal static long DivInt64(long dividend, long divisor) => DivInt64Internal(dividend, divisor); + + [StackTraceHidden] + internal static ulong DivUInt64(ulong dividend, ulong divisor) => DivUInt64Internal(dividend, divisor); + + [StackTraceHidden] + internal static int ModInt32(int dividend, int divisor) => ModInt32Internal(dividend, divisor); + + [StackTraceHidden] + internal static uint ModUInt32(uint dividend, uint divisor) => ModUInt32Internal(dividend, divisor); + + [StackTraceHidden] + internal static long ModInt64(long dividend, long divisor) => ModInt64Internal(dividend, divisor); + + [StackTraceHidden] + internal static ulong ModUInt64(ulong dividend, ulong divisor) => ModUInt64Internal(dividend, divisor); + + [LibraryImport(RuntimeHelpers.QCall), SuppressGCTransition] + private static partial int DivInt32Internal(int dividend, int divisor); + + [LibraryImport(RuntimeHelpers.QCall), SuppressGCTransition] + private static partial uint DivUInt32Internal(uint dividend, uint divisor); + + [LibraryImport(RuntimeHelpers.QCall), SuppressGCTransition] + private static partial long DivInt64Internal(long dividend, long divisor); + + [LibraryImport(RuntimeHelpers.QCall), SuppressGCTransition] + private static partial ulong DivUInt64Internal(ulong dividend, ulong divisor); + + [LibraryImport(RuntimeHelpers.QCall), SuppressGCTransition] + private static partial int ModInt32Internal(int dividend, int divisor); + + [LibraryImport(RuntimeHelpers.QCall), SuppressGCTransition] + private static partial uint ModUInt32Internal(uint dividend, uint divisor); + + [LibraryImport(RuntimeHelpers.QCall), SuppressGCTransition] + private static partial long ModInt64Internal(long dividend, long divisor); + + [LibraryImport(RuntimeHelpers.QCall), SuppressGCTransition] + private static partial ulong ModUInt64Internal(ulong dividend, ulong divisor); + } +} diff --git a/src/coreclr/classlibnative/float/CMakeLists.txt b/src/coreclr/classlibnative/float/CMakeLists.txt index c6153d5d34c096..1dbe160248f26e 100644 --- a/src/coreclr/classlibnative/float/CMakeLists.txt +++ b/src/coreclr/classlibnative/float/CMakeLists.txt @@ -3,7 +3,6 @@ include_directories("../inc") set(FLOAT_SOURCES floatdouble.cpp floatsingle.cpp - divmodint.cpp ) add_library_clr(comfloat_wks OBJECT ${FLOAT_SOURCES}) diff --git a/src/coreclr/inc/jithelpers.h b/src/coreclr/inc/jithelpers.h index 3a7f8a27b9b916..172348cb879b01 100644 --- a/src/coreclr/inc/jithelpers.h +++ b/src/coreclr/inc/jithelpers.h @@ -64,7 +64,7 @@ DYNAMICJITHELPER(CORINFO_HELP_LMOD, NULL, METHOD__MATH__MOD_INT64) DYNAMICJITHELPER(CORINFO_HELP_ULDIV, NULL, METHOD__MATH__DIV_UINT64) DYNAMICJITHELPER(CORINFO_HELP_ULMOD, NULL, METHOD__MATH__MOD_UINT64) -#else +#else // TARGET_32BIT DYNAMICJITHELPER(CORINFO_HELP_LMUL_OVF, NULL, METHOD__NIL) DYNAMICJITHELPER(CORINFO_HELP_ULMUL_OVF, NULL, METHOD__NIL) DYNAMICJITHELPER(CORINFO_HELP_LDIV, NULL, METHOD__NIL) diff --git a/src/coreclr/nativeaot/Runtime.Base/src/System/Runtime/CompilerServices/RuntimeHelpers.cs b/src/coreclr/nativeaot/Runtime.Base/src/System/Runtime/CompilerServices/RuntimeHelpers.cs index 6a9c7535178c3f..b06f2f3d5eb30c 100644 --- a/src/coreclr/nativeaot/Runtime.Base/src/System/Runtime/CompilerServices/RuntimeHelpers.cs +++ b/src/coreclr/nativeaot/Runtime.Base/src/System/Runtime/CompilerServices/RuntimeHelpers.cs @@ -18,7 +18,5 @@ public static int OffsetToStringData [Intrinsic] public static extern void InitializeArray(Array array, RuntimeFieldHandle fldHandle); - - public const string QCall = "*"; } } diff --git a/src/coreclr/nativeaot/Runtime/MathHelpers.cpp b/src/coreclr/nativeaot/Runtime/MathHelpers.cpp index edefb29ccbd785..6e3f4d73de8af2 100644 --- a/src/coreclr/nativeaot/Runtime/MathHelpers.cpp +++ b/src/coreclr/nativeaot/Runtime/MathHelpers.cpp @@ -56,25 +56,25 @@ FCIMPL1_D(uint32_t, RhpDbl2UInt, double val) FCIMPLEND #ifndef HOST_64BIT -EXTERN_C int64_t QCALLTYPE DivInt64Internal(int64_t i, int64_t j) +EXTERN_C int64_t QCALLTYPE RhpLDiv(int64_t i, int64_t j) { ASSERT(j && "Divide by zero!"); return i / j; } -EXTERN_C uint64_t QCALLTYPE DivUInt64Internal(uint64_t i, uint64_t j) +EXTERN_C uint64_t QCALLTYPE RhpULDiv(uint64_t i, uint64_t j) { ASSERT(j && "Divide by zero!"); return i / j; } -EXTERN_C int64_t QCALLTYPE ModInt64Internal(int64_t i, int64_t j) +EXTERN_C int64_t QCALLTYPE RhpLMod(int64_t i, int64_t j) { ASSERT(j && "Divide by zero!"); return i % j; } -EXTERN_C uint64_t QCALLTYPE ModUInt64Internal(uint64_t i, uint64_t j) +EXTERN_C uint64_t QCALLTYPE RhpULMod(uint64_t i, uint64_t j) { ASSERT(j && "Divide by zero!"); return i % j; @@ -95,25 +95,25 @@ FCIMPLEND #endif #ifdef HOST_ARM -EXTERN_C int32_t F_CALL_CONV DivInt32Internal(int32_t i, int32_t j) +EXTERN_C int32_t F_CALL_CONV RhpIDiv(int32_t i, int32_t j) { ASSERT(j && "Divide by zero!"); return i / j; } -EXTERN_C uint32_t F_CALL_CONV DivUInt32Internal(uint32_t i, uint32_t j) +EXTERN_C uint32_t F_CALL_CONV RhpUDiv(uint32_t i, uint32_t j) { ASSERT(j && "Divide by zero!"); return i / j; } -EXTERN_C int32_t F_CALL_CONV ModInt32Internal(int32_t i, int32_t j) +EXTERN_C int32_t F_CALL_CONV RhpIMod(int32_t i, int32_t j) { ASSERT(j && "Divide by zero!"); return i % j; } -EXTERN_C uint32_t F_CALL_CONV ModUInt32Internal(uint32_t i, uint32_t j) +EXTERN_C uint32_t F_CALL_CONV RhpUMod(uint32_t i, uint32_t j) { ASSERT(j && "Divide by zero!"); return i % j; diff --git a/src/coreclr/nativeaot/System.Private.CoreLib/src/Internal/Runtime/CompilerHelpers/MathHelpers.cs b/src/coreclr/nativeaot/System.Private.CoreLib/src/Internal/Runtime/CompilerHelpers/MathHelpers.cs new file mode 100644 index 00000000000000..df8c6d407901ff --- /dev/null +++ b/src/coreclr/nativeaot/System.Private.CoreLib/src/Internal/Runtime/CompilerHelpers/MathHelpers.cs @@ -0,0 +1,128 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System; +using System.Diagnostics; +using System.Runtime; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +namespace Internal.Runtime.CompilerHelpers +{ + /// + /// Math helpers for generated code. The helpers here are referenced by the runtime. + /// + [StackTraceHidden] + internal static partial class MathHelpers + { +#if !TARGET_64BIT + private const string RuntimeLibrary = "*"; + + [LibraryImport(RuntimeLibrary)] + [SuppressGCTransition] + private static partial ulong RhpULMod(ulong dividend, ulong divisor); + + public static ulong ULMod(ulong dividend, ulong divisor) + { + if (divisor == 0) + ThrowHelper.ThrowDivideByZeroException(); + + return RhpULMod(dividend, divisor); + } + + [LibraryImport(RuntimeLibrary)] + [SuppressGCTransition] + private static partial long RhpLMod(long dividend, long divisor); + + public static long LMod(long dividend, long divisor) + { + if (divisor == 0) + ThrowHelper.ThrowDivideByZeroException(); + if (divisor == -1 && dividend == long.MinValue) + ThrowHelper.ThrowOverflowException(); + + return RhpLMod(dividend, divisor); + } + + [LibraryImport(RuntimeLibrary)] + [SuppressGCTransition] + private static partial ulong RhpULDiv(ulong dividend, ulong divisor); + + public static ulong ULDiv(ulong dividend, ulong divisor) + { + if (divisor == 0) + ThrowHelper.ThrowDivideByZeroException(); + + return RhpULDiv(dividend, divisor); + } + + [LibraryImport(RuntimeLibrary)] + [SuppressGCTransition] + private static partial long RhpLDiv(long dividend, long divisor); + + public static long LDiv(long dividend, long divisor) + { + if (divisor == 0) + ThrowHelper.ThrowDivideByZeroException(); + if (divisor == -1 && dividend == long.MinValue) + ThrowHelper.ThrowOverflowException(); + + return RhpLDiv(dividend, divisor); + } + +#if TARGET_ARM + [RuntimeImport(RuntimeLibrary, "RhpIDiv")] + [MethodImpl(MethodImplOptions.InternalCall)] + private static extern int RhpIDiv(int dividend, int divisor); + + public static int IDiv(int dividend, int divisor) + { + if (divisor == 0) + ThrowHelper.ThrowDivideByZeroException(); + if (divisor == -1 && dividend == int.MinValue) + ThrowHelper.ThrowOverflowException(); + + return RhpIDiv(dividend, divisor); + } + + [RuntimeImport(RuntimeLibrary, "RhpUDiv")] + [MethodImpl(MethodImplOptions.InternalCall)] + private static extern uint RhpUDiv(uint dividend, uint divisor); + + public static long UDiv(uint dividend, uint divisor) + { + if (divisor == 0) + ThrowHelper.ThrowDivideByZeroException(); + + return RhpUDiv(dividend, divisor); + } + + [RuntimeImport(RuntimeLibrary, "RhpIMod")] + [MethodImpl(MethodImplOptions.InternalCall)] + private static extern int RhpIMod(int dividend, int divisor); + + public static int IMod(int dividend, int divisor) + { + if (divisor == 0) + ThrowHelper.ThrowDivideByZeroException(); + if (divisor == -1 && dividend == int.MinValue) + ThrowHelper.ThrowOverflowException(); + + return RhpIMod(dividend, divisor); + } + + [RuntimeImport(RuntimeLibrary, "RhpUMod")] + [MethodImpl(MethodImplOptions.InternalCall)] + private static extern uint RhpUMod(uint dividend, uint divisor); + + public static long UMod(uint dividend, uint divisor) + { + if (divisor == 0) + ThrowHelper.ThrowDivideByZeroException(); + + return RhpUMod(dividend, divisor); + } +#endif // TARGET_ARM +#endif // TARGET_64BIT + } +} diff --git a/src/coreclr/nativeaot/System.Private.CoreLib/src/System.Private.CoreLib.csproj b/src/coreclr/nativeaot/System.Private.CoreLib/src/System.Private.CoreLib.csproj index 90f5a4fdfa91aa..a37ba28ad85f15 100644 --- a/src/coreclr/nativeaot/System.Private.CoreLib/src/System.Private.CoreLib.csproj +++ b/src/coreclr/nativeaot/System.Private.CoreLib/src/System.Private.CoreLib.csproj @@ -116,6 +116,7 @@ + diff --git a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/JitHelper.cs b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/JitHelper.cs index 4627a406636f51..8861535467c8ca 100644 --- a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/JitHelper.cs +++ b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/JitHelper.cs @@ -233,30 +233,30 @@ public static void GetEntryPoint(TypeSystemContext context, ReadyToRunHelper id, } break; - case ReadyToRunHelper.Div: - methodDesc = context.SystemModule.GetKnownType("System", "Math").GetKnownMethod("DivInt32", null); + case ReadyToRunHelper.Mod: + methodDesc = context.GetHelperEntryPoint("MathHelpers", "IMod"); break; - case ReadyToRunHelper.UDiv: - methodDesc = context.SystemModule.GetKnownType("System", "Math").GetKnownMethod("DivUInt32", null); + case ReadyToRunHelper.UMod: + methodDesc = context.GetHelperEntryPoint("MathHelpers", "UMod"); break; - case ReadyToRunHelper.LDiv: - methodDesc = context.SystemModule.GetKnownType("System", "Math").GetKnownMethod("DivInt64", null); + case ReadyToRunHelper.ULMod: + methodDesc = context.GetHelperEntryPoint("MathHelpers", "ULMod"); break; - case ReadyToRunHelper.ULDiv: - methodDesc = context.SystemModule.GetKnownType("System", "Math").GetKnownMethod("DivUInt64", null); + case ReadyToRunHelper.LMod: + methodDesc = context.GetHelperEntryPoint("MathHelpers", "LMod"); break; - case ReadyToRunHelper.Mod: - methodDesc = context.SystemModule.GetKnownType("System", "Math").GetKnownMethod("ModInt32", null); + case ReadyToRunHelper.Div: + methodDesc = context.GetHelperEntryPoint("MathHelpers", "IDiv"); break; - case ReadyToRunHelper.UMod: - methodDesc = context.SystemModule.GetKnownType("System", "Math").GetKnownMethod("ModUInt32", null); + case ReadyToRunHelper.UDiv: + methodDesc = context.GetHelperEntryPoint("MathHelpers", "UDiv"); break; - case ReadyToRunHelper.LMod: - methodDesc = context.SystemModule.GetKnownType("System", "Math").GetKnownMethod("ModInt64", null); + case ReadyToRunHelper.ULDiv: + methodDesc = context.GetHelperEntryPoint("MathHelpers", "ULDiv"); break; - case ReadyToRunHelper.ULMod: - methodDesc = context.SystemModule.GetKnownType("System", "Math").GetKnownMethod("ModUInt64", null); + case ReadyToRunHelper.LDiv: + methodDesc = context.GetHelperEntryPoint("MathHelpers", "LDiv"); break; case ReadyToRunHelper.LRsz: diff --git a/src/coreclr/vm/JitQCallHelpers.h b/src/coreclr/vm/JitQCallHelpers.h index ff3bfa97981f3e..c19f009d20dc57 100644 --- a/src/coreclr/vm/JitQCallHelpers.h +++ b/src/coreclr/vm/JitQCallHelpers.h @@ -25,4 +25,15 @@ extern "C" void QCALLTYPE ThrowInvalidCastException(CORINFO_CLASS_HANDLE pTarget extern "C" void QCALLTYPE GetThreadStaticsByMethodTable(QCall::ByteRefOnStack refHandle, MethodTable* pMT, bool gcStatic); extern "C" void QCALLTYPE GetThreadStaticsByIndex(QCall::ByteRefOnStack refHandle, uint32_t staticBlockIndex, bool gcStatic); -#endif //_JITQCALLHELPERS_H +#if defined(TARGET_32BIT) +extern "C" INT32 QCALLTYPE DivInt32Internal(INT32 dividend, INT32 divisor); +extern "C" UINT32 QCALLTYPE DivUInt32Internal(UINT32 dividend, UINT32 divisor); +extern "C" INT64 QCALLTYPE DivInt64Internal(INT64 dividend, INT64 divisor); +extern "C" UINT64 QCALLTYPE DivUInt64Internal(UINT64 dividend, UINT64 divisor); +extern "C" INT32 QCALLTYPE ModInt32Internal(INT32 dividend, INT32 divisor); +extern "C" UINT32 QCALLTYPE ModUInt32Internal(UINT32 dividend, UINT32 divisor); +extern "C" INT64 QCALLTYPE ModInt64Internal(INT64 dividend, INT64 divisor); +extern "C" UINT64 QCALLTYPE ModUInt64Internal(UINT64 dividend, UINT64 divisor); +#endif // TARGET_32BIT + +#endif // _JITQCALLHELPERS_H diff --git a/src/coreclr/vm/corelib.cpp b/src/coreclr/vm/corelib.cpp index 22c1c983b49003..4c3f7438a559ab 100644 --- a/src/coreclr/vm/corelib.cpp +++ b/src/coreclr/vm/corelib.cpp @@ -28,7 +28,6 @@ #include "comsynchronizable.h" #include "floatdouble.h" #include "floatsingle.h" -#include "divmodint.h" #include "comdatetime.h" #include "debugdebugger.h" #include "assemblynative.hpp" diff --git a/src/coreclr/vm/ecalllist.h b/src/coreclr/vm/ecalllist.h index 9321f7e66b8467..5aff25d5caa72c 100644 --- a/src/coreclr/vm/ecalllist.h +++ b/src/coreclr/vm/ecalllist.h @@ -216,16 +216,6 @@ FCFuncStart(gMathFuncs) FCFuncElement("Sqrt", COMDouble::Sqrt) FCFuncElement("Tan", COMDouble::Tan) FCFuncElement("Tanh", COMDouble::Tanh) -#ifdef TARGET_32BIT - FCFuncElement("DivInt32Internal", COMDivModInt::DivInt32) - FCFuncElement("DivUInt32Internal", COMDivModInt::DivUInt32) - FCFuncElement("DivInt64Internal", COMDivModInt::DivInt64) - FCFuncElement("DivUInt64Internal", COMDivModInt::DivUInt64) - FCFuncElement("ModInt32Internal", COMDivModInt::ModInt32) - FCFuncElement("ModUInt32Internal", COMDivModInt::ModUInt32) - FCFuncElement("ModInt64Internal", COMDivModInt::ModInt64) - FCFuncElement("ModUInt64Internal", COMDivModInt::ModUInt64) -#endif // TARGET_32BIT FCFuncEnd() FCFuncStart(gMathFFuncs) diff --git a/src/coreclr/vm/jithelpers.cpp b/src/coreclr/vm/jithelpers.cpp index f2d32e5567fcef..42aa41726a59ee 100644 --- a/src/coreclr/vm/jithelpers.cpp +++ b/src/coreclr/vm/jithelpers.cpp @@ -85,8 +85,6 @@ using std::isnan; // //======================================================================== - - //======================================================================== // // INTEGER ARITHMETIC HELPERS @@ -127,6 +125,334 @@ HCIMPL2_VV(INT64, JIT_LMul, INT64 val1, INT64 val2) HCIMPLEND #endif // !TARGET_X86 || TARGET_UNIX +#ifdef TARGET_32BIT + +/*********************************************************************/ +extern "C" INT32 QCALLTYPE DivInt32Internal(INT32 dividend, INT32 divisor) +{ + CONTRACTL + { + THROWS; + GC_TRIGGERS; + MODE_COOPERATIVE; + } + CONTRACTL_END; + + INT32 result = 0; + + BEGIN_QCALL; + + if (((UINT32) (divisor + 1)) <= 1) // Unsigned test for divisor in [-1 .. 0] + { + if (divisor == 0) + { + COMPlusThrow(kDivideByZeroException); + goto END; + } + else if (divisor == -1) + { + if (dividend == INT32_MIN) + { + COMPlusThrow(kOverflowException); + goto END; + } + + result = -dividend; + goto END; + } + } + + result = dividend / divisor; + + END_QCALL; + +END: + return result; +} + +/*********************************************************************/ +extern "C" UINT32 QCALLTYPE DivUInt32Internal(UINT32 dividend, UINT32 divisor) +{ + CONTRACTL + { + THROWS; + GC_TRIGGERS; + MODE_COOPERATIVE; + } + CONTRACTL_END; + + UINT32 result = 0; + + BEGIN_QCALL; + + if (divisor == 0) + { + COMPlusThrow(kDivideByZeroException); + goto END; + } + + result = dividend / divisor; + + END_QCALL; + +END: + return result; +} + +/*********************************************************************/ +extern "C" INT64 QCALLTYPE DivInt64Internal(INT64 dividend, INT64 divisor) +{ + CONTRACTL + { + THROWS; + GC_TRIGGERS; + MODE_COOPERATIVE; + } + CONTRACTL_END; + + INT64 result = 0; + + BEGIN_QCALL; + + if (Is32BitSigned(divisor)) + { + if ((INT32)divisor == 0) + { + COMPlusThrow(kDivideByZeroException); + goto END; + } + + if ((INT32)divisor == -1) + { + if ((UINT64) dividend == UI64(0x8000000000000000)) + { + COMPlusThrow(kOverflowException); + goto END; + } + + result = -dividend; + goto END; + } + + // Check for -ive or +ive numbers in the range -2**31 to 2**31 + if (Is32BitSigned(dividend)) + { + result = (INT32)dividend / (INT32)divisor; + goto END; + } + } + + // For all other combinations fallback to int64 div. + result = dividend / divisor; + + END_QCALL; + +END: + return result; +} + + +/*********************************************************************/ +extern "C" UINT64 QCALLTYPE DivUInt64Internal(UINT64 dividend, UINT64 divisor) +{ + CONTRACTL + { + THROWS; + GC_TRIGGERS; + MODE_COOPERATIVE; + } + CONTRACTL_END; + + UINT64 result = 0; + + BEGIN_QCALL; + + if (Hi32Bits(divisor) == 0) + { + if ((UINT32)(divisor) == 0) + { + COMPlusThrow(kDivideByZeroException); + goto END; + } + + if (Hi32Bits(dividend) == 0) + { + result = (UINT32)dividend / (UINT32)divisor; + goto END; + } + } + + result = dividend / divisor; + + END_QCALL; + +END: + return result; +} + +/*********************************************************************/ +extern "C" INT32 QCALLTYPE ModInt32Internal(INT32 dividend, INT32 divisor) +{ + CONTRACTL + { + THROWS; + GC_TRIGGERS; + MODE_COOPERATIVE; + } + CONTRACTL_END; + + INT32 result = 0; + + BEGIN_QCALL; + + if (((UINT32) (divisor + 1)) <= 1) // Unsigned test for divisor in [-1 .. 0] + { + if (divisor == 0) + { + COMPlusThrow(kDivideByZeroException); + goto END; + } + else if (divisor == -1) + { + if (dividend == INT32_MIN) + { + COMPlusThrow(kOverflowException); + goto END; + } + + result = 0; + goto END; + } + } + + result = dividend % divisor; + + END_QCALL; + +END: + return result; +} + +/*********************************************************************/ +extern "C" UINT32 QCALLTYPE ModUInt32Internal(UINT32 dividend, UINT32 divisor) +{ + CONTRACTL + { + THROWS; + GC_TRIGGERS; + MODE_COOPERATIVE; + } + CONTRACTL_END; + + UINT32 result = 0; + + BEGIN_QCALL; + + if (divisor == 0) + { + COMPlusThrow(kDivideByZeroException); + goto END; + } + + result = dividend % divisor; + + END_QCALL; + +END: + return result; +} + +/*********************************************************************/ +extern "C" INT64 QCALLTYPE ModInt64Internal(INT64 dividend, INT64 divisor) +{ + CONTRACTL + { + THROWS; + GC_TRIGGERS; + MODE_COOPERATIVE; + } + CONTRACTL_END; + + INT64 result = 0; + + BEGIN_QCALL; + + if (Is32BitSigned(divisor)) + { + if ((INT32)divisor == 0) + { + COMPlusThrow(kDivideByZeroException); + goto END; + } + + if ((INT32)divisor == -1) + { + // TODO, we really should remove this as it lengthens the code path + // and the spec really says that it should not throw an exception. + if ((UINT64) dividend == UI64(0x8000000000000000)) + { + COMPlusThrow(kOverflowException); + } + + goto END; + } + + // Check for -ive or +ive numbers in the range -2**31 to 2**31 + if (Is32BitSigned(dividend)) + { + result = (INT32)dividend % (INT32)divisor; + goto END; + } + } + + result = dividend % divisor; + + END_QCALL; + +END: + return result; +} + +/*********************************************************************/ +extern "C" UINT64 QCALLTYPE ModUInt64Internal(UINT64 dividend, UINT64 divisor) +{ + CONTRACTL + { + THROWS; + GC_TRIGGERS; + MODE_COOPERATIVE; + } + CONTRACTL_END; + + UINT64 result = 0; + + BEGIN_QCALL; + + if (Hi32Bits(divisor) == 0) + { + if ((UINT32)(divisor) == 0) + { + COMPlusThrow(kDivideByZeroException); + goto END; + } + + if (Hi32Bits(dividend) == 0) + { + result = (UINT32)dividend % (UINT32)divisor; + goto END; + } + } + + result = dividend % divisor; + + END_QCALL; + +END: + return result; +} + +#endif // TARGET_32BIT + #if !defined(HOST_64BIT) && !defined(TARGET_X86) /*********************************************************************/ HCIMPL2_VV(UINT64, JIT_LLsh, UINT64 num, int shift) @@ -3876,7 +4202,7 @@ bool IndirectionAllowedForJitHelper(CorInfoHelpFunc ftnNum) { return false; } - + return true; } diff --git a/src/coreclr/vm/qcallentrypoints.cpp b/src/coreclr/vm/qcallentrypoints.cpp index a60d16dfb22218..08cc1dba261a65 100644 --- a/src/coreclr/vm/qcallentrypoints.cpp +++ b/src/coreclr/vm/qcallentrypoints.cpp @@ -471,6 +471,16 @@ static const Entry s_QCall[] = #endif #if defined(TARGET_X86) || defined(TARGET_AMD64) DllImportEntry(X86BaseCpuId) +#endif +#if defined(TARGET_32BIT) + DllImportEntry(DivInt32Internal) + DllImportEntry(DivUInt32Internal) + DllImportEntry(DivInt64Internal) + DllImportEntry(DivUInt64Internal) + DllImportEntry(ModInt32Internal) + DllImportEntry(ModUInt32Internal) + DllImportEntry(ModInt64Internal) + DllImportEntry(ModUInt64Internal) #endif DllImportEntry(StubHelpers_CreateCustomMarshaler) DllImportEntry(StubHelpers_SetStringTrailByte) diff --git a/src/libraries/System.Private.CoreLib/src/System.Private.CoreLib.Shared.projitems b/src/libraries/System.Private.CoreLib/src/System.Private.CoreLib.Shared.projitems index 0842c6756752f1..51e003bae50afc 100644 --- a/src/libraries/System.Private.CoreLib/src/System.Private.CoreLib.Shared.projitems +++ b/src/libraries/System.Private.CoreLib/src/System.Private.CoreLib.Shared.projitems @@ -570,7 +570,6 @@ - From f0cd1110b195a8dd6bce6bfb08ad967f8c55aa01 Mon Sep 17 00:00:00 2001 From: Adeel <3840695+am11@users.noreply.github.com> Date: Thu, 5 Dec 2024 22:17:49 +0200 Subject: [PATCH 24/27] Revert "Experiment: Change FCThrow to COMPlusThrowf" This reverts commit 9dbcf4eb77fb7058c98f48c98b455acab3b78dc9. --- .../System.Private.CoreLib.csproj | 1 - .../src/System/Math.DivMod.cs | 63 ---- .../classlibnative/float/CMakeLists.txt | 1 + src/coreclr/inc/jithelpers.h | 2 +- .../CompilerServices/RuntimeHelpers.cs | 2 + src/coreclr/nativeaot/Runtime/MathHelpers.cpp | 16 +- .../Runtime/CompilerHelpers/MathHelpers.cs | 128 ------- .../src/System.Private.CoreLib.csproj | 1 - .../ILCompiler.Compiler/Compiler/JitHelper.cs | 32 +- src/coreclr/vm/JitQCallHelpers.h | 13 +- src/coreclr/vm/corelib.cpp | 1 + src/coreclr/vm/ecalllist.h | 10 + src/coreclr/vm/jithelpers.cpp | 332 +----------------- src/coreclr/vm/qcallentrypoints.cpp | 10 - .../System.Private.CoreLib.Shared.projitems | 1 + 15 files changed, 44 insertions(+), 569 deletions(-) delete mode 100644 src/coreclr/System.Private.CoreLib/src/System/Math.DivMod.cs delete mode 100644 src/coreclr/nativeaot/System.Private.CoreLib/src/Internal/Runtime/CompilerHelpers/MathHelpers.cs diff --git a/src/coreclr/System.Private.CoreLib/System.Private.CoreLib.csproj b/src/coreclr/System.Private.CoreLib/System.Private.CoreLib.csproj index 74f859415f7a86..f4109a290f9206 100644 --- a/src/coreclr/System.Private.CoreLib/System.Private.CoreLib.csproj +++ b/src/coreclr/System.Private.CoreLib/System.Private.CoreLib.csproj @@ -143,7 +143,6 @@ - diff --git a/src/coreclr/System.Private.CoreLib/src/System/Math.DivMod.cs b/src/coreclr/System.Private.CoreLib/src/System/Math.DivMod.cs deleted file mode 100644 index e35b469a87faf2..00000000000000 --- a/src/coreclr/System.Private.CoreLib/src/System/Math.DivMod.cs +++ /dev/null @@ -1,63 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System.Diagnostics; -using System.Runtime.CompilerServices; -using System.Runtime.InteropServices; - -namespace System -{ - /// - /// Provides constants and static methods for trigonometric, logarithmic, and other common mathematical functions. - /// - public static partial class Math - { - [StackTraceHidden] - internal static int DivInt32(int dividend, int divisor) => DivInt32Internal(dividend, divisor); - - [StackTraceHidden] - internal static uint DivUInt32(uint dividend, uint divisor) => DivUInt32Internal(dividend, divisor); - - [StackTraceHidden] - internal static long DivInt64(long dividend, long divisor) => DivInt64Internal(dividend, divisor); - - [StackTraceHidden] - internal static ulong DivUInt64(ulong dividend, ulong divisor) => DivUInt64Internal(dividend, divisor); - - [StackTraceHidden] - internal static int ModInt32(int dividend, int divisor) => ModInt32Internal(dividend, divisor); - - [StackTraceHidden] - internal static uint ModUInt32(uint dividend, uint divisor) => ModUInt32Internal(dividend, divisor); - - [StackTraceHidden] - internal static long ModInt64(long dividend, long divisor) => ModInt64Internal(dividend, divisor); - - [StackTraceHidden] - internal static ulong ModUInt64(ulong dividend, ulong divisor) => ModUInt64Internal(dividend, divisor); - - [LibraryImport(RuntimeHelpers.QCall), SuppressGCTransition] - private static partial int DivInt32Internal(int dividend, int divisor); - - [LibraryImport(RuntimeHelpers.QCall), SuppressGCTransition] - private static partial uint DivUInt32Internal(uint dividend, uint divisor); - - [LibraryImport(RuntimeHelpers.QCall), SuppressGCTransition] - private static partial long DivInt64Internal(long dividend, long divisor); - - [LibraryImport(RuntimeHelpers.QCall), SuppressGCTransition] - private static partial ulong DivUInt64Internal(ulong dividend, ulong divisor); - - [LibraryImport(RuntimeHelpers.QCall), SuppressGCTransition] - private static partial int ModInt32Internal(int dividend, int divisor); - - [LibraryImport(RuntimeHelpers.QCall), SuppressGCTransition] - private static partial uint ModUInt32Internal(uint dividend, uint divisor); - - [LibraryImport(RuntimeHelpers.QCall), SuppressGCTransition] - private static partial long ModInt64Internal(long dividend, long divisor); - - [LibraryImport(RuntimeHelpers.QCall), SuppressGCTransition] - private static partial ulong ModUInt64Internal(ulong dividend, ulong divisor); - } -} diff --git a/src/coreclr/classlibnative/float/CMakeLists.txt b/src/coreclr/classlibnative/float/CMakeLists.txt index 1dbe160248f26e..c6153d5d34c096 100644 --- a/src/coreclr/classlibnative/float/CMakeLists.txt +++ b/src/coreclr/classlibnative/float/CMakeLists.txt @@ -3,6 +3,7 @@ include_directories("../inc") set(FLOAT_SOURCES floatdouble.cpp floatsingle.cpp + divmodint.cpp ) add_library_clr(comfloat_wks OBJECT ${FLOAT_SOURCES}) diff --git a/src/coreclr/inc/jithelpers.h b/src/coreclr/inc/jithelpers.h index 172348cb879b01..3a7f8a27b9b916 100644 --- a/src/coreclr/inc/jithelpers.h +++ b/src/coreclr/inc/jithelpers.h @@ -64,7 +64,7 @@ DYNAMICJITHELPER(CORINFO_HELP_LMOD, NULL, METHOD__MATH__MOD_INT64) DYNAMICJITHELPER(CORINFO_HELP_ULDIV, NULL, METHOD__MATH__DIV_UINT64) DYNAMICJITHELPER(CORINFO_HELP_ULMOD, NULL, METHOD__MATH__MOD_UINT64) -#else // TARGET_32BIT +#else DYNAMICJITHELPER(CORINFO_HELP_LMUL_OVF, NULL, METHOD__NIL) DYNAMICJITHELPER(CORINFO_HELP_ULMUL_OVF, NULL, METHOD__NIL) DYNAMICJITHELPER(CORINFO_HELP_LDIV, NULL, METHOD__NIL) diff --git a/src/coreclr/nativeaot/Runtime.Base/src/System/Runtime/CompilerServices/RuntimeHelpers.cs b/src/coreclr/nativeaot/Runtime.Base/src/System/Runtime/CompilerServices/RuntimeHelpers.cs index b06f2f3d5eb30c..6a9c7535178c3f 100644 --- a/src/coreclr/nativeaot/Runtime.Base/src/System/Runtime/CompilerServices/RuntimeHelpers.cs +++ b/src/coreclr/nativeaot/Runtime.Base/src/System/Runtime/CompilerServices/RuntimeHelpers.cs @@ -18,5 +18,7 @@ public static int OffsetToStringData [Intrinsic] public static extern void InitializeArray(Array array, RuntimeFieldHandle fldHandle); + + public const string QCall = "*"; } } diff --git a/src/coreclr/nativeaot/Runtime/MathHelpers.cpp b/src/coreclr/nativeaot/Runtime/MathHelpers.cpp index 6e3f4d73de8af2..edefb29ccbd785 100644 --- a/src/coreclr/nativeaot/Runtime/MathHelpers.cpp +++ b/src/coreclr/nativeaot/Runtime/MathHelpers.cpp @@ -56,25 +56,25 @@ FCIMPL1_D(uint32_t, RhpDbl2UInt, double val) FCIMPLEND #ifndef HOST_64BIT -EXTERN_C int64_t QCALLTYPE RhpLDiv(int64_t i, int64_t j) +EXTERN_C int64_t QCALLTYPE DivInt64Internal(int64_t i, int64_t j) { ASSERT(j && "Divide by zero!"); return i / j; } -EXTERN_C uint64_t QCALLTYPE RhpULDiv(uint64_t i, uint64_t j) +EXTERN_C uint64_t QCALLTYPE DivUInt64Internal(uint64_t i, uint64_t j) { ASSERT(j && "Divide by zero!"); return i / j; } -EXTERN_C int64_t QCALLTYPE RhpLMod(int64_t i, int64_t j) +EXTERN_C int64_t QCALLTYPE ModInt64Internal(int64_t i, int64_t j) { ASSERT(j && "Divide by zero!"); return i % j; } -EXTERN_C uint64_t QCALLTYPE RhpULMod(uint64_t i, uint64_t j) +EXTERN_C uint64_t QCALLTYPE ModUInt64Internal(uint64_t i, uint64_t j) { ASSERT(j && "Divide by zero!"); return i % j; @@ -95,25 +95,25 @@ FCIMPLEND #endif #ifdef HOST_ARM -EXTERN_C int32_t F_CALL_CONV RhpIDiv(int32_t i, int32_t j) +EXTERN_C int32_t F_CALL_CONV DivInt32Internal(int32_t i, int32_t j) { ASSERT(j && "Divide by zero!"); return i / j; } -EXTERN_C uint32_t F_CALL_CONV RhpUDiv(uint32_t i, uint32_t j) +EXTERN_C uint32_t F_CALL_CONV DivUInt32Internal(uint32_t i, uint32_t j) { ASSERT(j && "Divide by zero!"); return i / j; } -EXTERN_C int32_t F_CALL_CONV RhpIMod(int32_t i, int32_t j) +EXTERN_C int32_t F_CALL_CONV ModInt32Internal(int32_t i, int32_t j) { ASSERT(j && "Divide by zero!"); return i % j; } -EXTERN_C uint32_t F_CALL_CONV RhpUMod(uint32_t i, uint32_t j) +EXTERN_C uint32_t F_CALL_CONV ModUInt32Internal(uint32_t i, uint32_t j) { ASSERT(j && "Divide by zero!"); return i % j; diff --git a/src/coreclr/nativeaot/System.Private.CoreLib/src/Internal/Runtime/CompilerHelpers/MathHelpers.cs b/src/coreclr/nativeaot/System.Private.CoreLib/src/Internal/Runtime/CompilerHelpers/MathHelpers.cs deleted file mode 100644 index df8c6d407901ff..00000000000000 --- a/src/coreclr/nativeaot/System.Private.CoreLib/src/Internal/Runtime/CompilerHelpers/MathHelpers.cs +++ /dev/null @@ -1,128 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System; -using System.Diagnostics; -using System.Runtime; -using System.Runtime.CompilerServices; -using System.Runtime.InteropServices; - -namespace Internal.Runtime.CompilerHelpers -{ - /// - /// Math helpers for generated code. The helpers here are referenced by the runtime. - /// - [StackTraceHidden] - internal static partial class MathHelpers - { -#if !TARGET_64BIT - private const string RuntimeLibrary = "*"; - - [LibraryImport(RuntimeLibrary)] - [SuppressGCTransition] - private static partial ulong RhpULMod(ulong dividend, ulong divisor); - - public static ulong ULMod(ulong dividend, ulong divisor) - { - if (divisor == 0) - ThrowHelper.ThrowDivideByZeroException(); - - return RhpULMod(dividend, divisor); - } - - [LibraryImport(RuntimeLibrary)] - [SuppressGCTransition] - private static partial long RhpLMod(long dividend, long divisor); - - public static long LMod(long dividend, long divisor) - { - if (divisor == 0) - ThrowHelper.ThrowDivideByZeroException(); - if (divisor == -1 && dividend == long.MinValue) - ThrowHelper.ThrowOverflowException(); - - return RhpLMod(dividend, divisor); - } - - [LibraryImport(RuntimeLibrary)] - [SuppressGCTransition] - private static partial ulong RhpULDiv(ulong dividend, ulong divisor); - - public static ulong ULDiv(ulong dividend, ulong divisor) - { - if (divisor == 0) - ThrowHelper.ThrowDivideByZeroException(); - - return RhpULDiv(dividend, divisor); - } - - [LibraryImport(RuntimeLibrary)] - [SuppressGCTransition] - private static partial long RhpLDiv(long dividend, long divisor); - - public static long LDiv(long dividend, long divisor) - { - if (divisor == 0) - ThrowHelper.ThrowDivideByZeroException(); - if (divisor == -1 && dividend == long.MinValue) - ThrowHelper.ThrowOverflowException(); - - return RhpLDiv(dividend, divisor); - } - -#if TARGET_ARM - [RuntimeImport(RuntimeLibrary, "RhpIDiv")] - [MethodImpl(MethodImplOptions.InternalCall)] - private static extern int RhpIDiv(int dividend, int divisor); - - public static int IDiv(int dividend, int divisor) - { - if (divisor == 0) - ThrowHelper.ThrowDivideByZeroException(); - if (divisor == -1 && dividend == int.MinValue) - ThrowHelper.ThrowOverflowException(); - - return RhpIDiv(dividend, divisor); - } - - [RuntimeImport(RuntimeLibrary, "RhpUDiv")] - [MethodImpl(MethodImplOptions.InternalCall)] - private static extern uint RhpUDiv(uint dividend, uint divisor); - - public static long UDiv(uint dividend, uint divisor) - { - if (divisor == 0) - ThrowHelper.ThrowDivideByZeroException(); - - return RhpUDiv(dividend, divisor); - } - - [RuntimeImport(RuntimeLibrary, "RhpIMod")] - [MethodImpl(MethodImplOptions.InternalCall)] - private static extern int RhpIMod(int dividend, int divisor); - - public static int IMod(int dividend, int divisor) - { - if (divisor == 0) - ThrowHelper.ThrowDivideByZeroException(); - if (divisor == -1 && dividend == int.MinValue) - ThrowHelper.ThrowOverflowException(); - - return RhpIMod(dividend, divisor); - } - - [RuntimeImport(RuntimeLibrary, "RhpUMod")] - [MethodImpl(MethodImplOptions.InternalCall)] - private static extern uint RhpUMod(uint dividend, uint divisor); - - public static long UMod(uint dividend, uint divisor) - { - if (divisor == 0) - ThrowHelper.ThrowDivideByZeroException(); - - return RhpUMod(dividend, divisor); - } -#endif // TARGET_ARM -#endif // TARGET_64BIT - } -} diff --git a/src/coreclr/nativeaot/System.Private.CoreLib/src/System.Private.CoreLib.csproj b/src/coreclr/nativeaot/System.Private.CoreLib/src/System.Private.CoreLib.csproj index a37ba28ad85f15..90f5a4fdfa91aa 100644 --- a/src/coreclr/nativeaot/System.Private.CoreLib/src/System.Private.CoreLib.csproj +++ b/src/coreclr/nativeaot/System.Private.CoreLib/src/System.Private.CoreLib.csproj @@ -116,7 +116,6 @@ - diff --git a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/JitHelper.cs b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/JitHelper.cs index 8861535467c8ca..4627a406636f51 100644 --- a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/JitHelper.cs +++ b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/JitHelper.cs @@ -233,30 +233,30 @@ public static void GetEntryPoint(TypeSystemContext context, ReadyToRunHelper id, } break; - case ReadyToRunHelper.Mod: - methodDesc = context.GetHelperEntryPoint("MathHelpers", "IMod"); + case ReadyToRunHelper.Div: + methodDesc = context.SystemModule.GetKnownType("System", "Math").GetKnownMethod("DivInt32", null); break; - case ReadyToRunHelper.UMod: - methodDesc = context.GetHelperEntryPoint("MathHelpers", "UMod"); + case ReadyToRunHelper.UDiv: + methodDesc = context.SystemModule.GetKnownType("System", "Math").GetKnownMethod("DivUInt32", null); break; - case ReadyToRunHelper.ULMod: - methodDesc = context.GetHelperEntryPoint("MathHelpers", "ULMod"); + case ReadyToRunHelper.LDiv: + methodDesc = context.SystemModule.GetKnownType("System", "Math").GetKnownMethod("DivInt64", null); break; - case ReadyToRunHelper.LMod: - methodDesc = context.GetHelperEntryPoint("MathHelpers", "LMod"); + case ReadyToRunHelper.ULDiv: + methodDesc = context.SystemModule.GetKnownType("System", "Math").GetKnownMethod("DivUInt64", null); break; - case ReadyToRunHelper.Div: - methodDesc = context.GetHelperEntryPoint("MathHelpers", "IDiv"); + case ReadyToRunHelper.Mod: + methodDesc = context.SystemModule.GetKnownType("System", "Math").GetKnownMethod("ModInt32", null); break; - case ReadyToRunHelper.UDiv: - methodDesc = context.GetHelperEntryPoint("MathHelpers", "UDiv"); + case ReadyToRunHelper.UMod: + methodDesc = context.SystemModule.GetKnownType("System", "Math").GetKnownMethod("ModUInt32", null); break; - case ReadyToRunHelper.ULDiv: - methodDesc = context.GetHelperEntryPoint("MathHelpers", "ULDiv"); + case ReadyToRunHelper.LMod: + methodDesc = context.SystemModule.GetKnownType("System", "Math").GetKnownMethod("ModInt64", null); break; - case ReadyToRunHelper.LDiv: - methodDesc = context.GetHelperEntryPoint("MathHelpers", "LDiv"); + case ReadyToRunHelper.ULMod: + methodDesc = context.SystemModule.GetKnownType("System", "Math").GetKnownMethod("ModUInt64", null); break; case ReadyToRunHelper.LRsz: diff --git a/src/coreclr/vm/JitQCallHelpers.h b/src/coreclr/vm/JitQCallHelpers.h index c19f009d20dc57..ff3bfa97981f3e 100644 --- a/src/coreclr/vm/JitQCallHelpers.h +++ b/src/coreclr/vm/JitQCallHelpers.h @@ -25,15 +25,4 @@ extern "C" void QCALLTYPE ThrowInvalidCastException(CORINFO_CLASS_HANDLE pTarget extern "C" void QCALLTYPE GetThreadStaticsByMethodTable(QCall::ByteRefOnStack refHandle, MethodTable* pMT, bool gcStatic); extern "C" void QCALLTYPE GetThreadStaticsByIndex(QCall::ByteRefOnStack refHandle, uint32_t staticBlockIndex, bool gcStatic); -#if defined(TARGET_32BIT) -extern "C" INT32 QCALLTYPE DivInt32Internal(INT32 dividend, INT32 divisor); -extern "C" UINT32 QCALLTYPE DivUInt32Internal(UINT32 dividend, UINT32 divisor); -extern "C" INT64 QCALLTYPE DivInt64Internal(INT64 dividend, INT64 divisor); -extern "C" UINT64 QCALLTYPE DivUInt64Internal(UINT64 dividend, UINT64 divisor); -extern "C" INT32 QCALLTYPE ModInt32Internal(INT32 dividend, INT32 divisor); -extern "C" UINT32 QCALLTYPE ModUInt32Internal(UINT32 dividend, UINT32 divisor); -extern "C" INT64 QCALLTYPE ModInt64Internal(INT64 dividend, INT64 divisor); -extern "C" UINT64 QCALLTYPE ModUInt64Internal(UINT64 dividend, UINT64 divisor); -#endif // TARGET_32BIT - -#endif // _JITQCALLHELPERS_H +#endif //_JITQCALLHELPERS_H diff --git a/src/coreclr/vm/corelib.cpp b/src/coreclr/vm/corelib.cpp index 4c3f7438a559ab..22c1c983b49003 100644 --- a/src/coreclr/vm/corelib.cpp +++ b/src/coreclr/vm/corelib.cpp @@ -28,6 +28,7 @@ #include "comsynchronizable.h" #include "floatdouble.h" #include "floatsingle.h" +#include "divmodint.h" #include "comdatetime.h" #include "debugdebugger.h" #include "assemblynative.hpp" diff --git a/src/coreclr/vm/ecalllist.h b/src/coreclr/vm/ecalllist.h index 5aff25d5caa72c..9321f7e66b8467 100644 --- a/src/coreclr/vm/ecalllist.h +++ b/src/coreclr/vm/ecalllist.h @@ -216,6 +216,16 @@ FCFuncStart(gMathFuncs) FCFuncElement("Sqrt", COMDouble::Sqrt) FCFuncElement("Tan", COMDouble::Tan) FCFuncElement("Tanh", COMDouble::Tanh) +#ifdef TARGET_32BIT + FCFuncElement("DivInt32Internal", COMDivModInt::DivInt32) + FCFuncElement("DivUInt32Internal", COMDivModInt::DivUInt32) + FCFuncElement("DivInt64Internal", COMDivModInt::DivInt64) + FCFuncElement("DivUInt64Internal", COMDivModInt::DivUInt64) + FCFuncElement("ModInt32Internal", COMDivModInt::ModInt32) + FCFuncElement("ModUInt32Internal", COMDivModInt::ModUInt32) + FCFuncElement("ModInt64Internal", COMDivModInt::ModInt64) + FCFuncElement("ModUInt64Internal", COMDivModInt::ModUInt64) +#endif // TARGET_32BIT FCFuncEnd() FCFuncStart(gMathFFuncs) diff --git a/src/coreclr/vm/jithelpers.cpp b/src/coreclr/vm/jithelpers.cpp index 42aa41726a59ee..f2d32e5567fcef 100644 --- a/src/coreclr/vm/jithelpers.cpp +++ b/src/coreclr/vm/jithelpers.cpp @@ -85,6 +85,8 @@ using std::isnan; // //======================================================================== + + //======================================================================== // // INTEGER ARITHMETIC HELPERS @@ -125,334 +127,6 @@ HCIMPL2_VV(INT64, JIT_LMul, INT64 val1, INT64 val2) HCIMPLEND #endif // !TARGET_X86 || TARGET_UNIX -#ifdef TARGET_32BIT - -/*********************************************************************/ -extern "C" INT32 QCALLTYPE DivInt32Internal(INT32 dividend, INT32 divisor) -{ - CONTRACTL - { - THROWS; - GC_TRIGGERS; - MODE_COOPERATIVE; - } - CONTRACTL_END; - - INT32 result = 0; - - BEGIN_QCALL; - - if (((UINT32) (divisor + 1)) <= 1) // Unsigned test for divisor in [-1 .. 0] - { - if (divisor == 0) - { - COMPlusThrow(kDivideByZeroException); - goto END; - } - else if (divisor == -1) - { - if (dividend == INT32_MIN) - { - COMPlusThrow(kOverflowException); - goto END; - } - - result = -dividend; - goto END; - } - } - - result = dividend / divisor; - - END_QCALL; - -END: - return result; -} - -/*********************************************************************/ -extern "C" UINT32 QCALLTYPE DivUInt32Internal(UINT32 dividend, UINT32 divisor) -{ - CONTRACTL - { - THROWS; - GC_TRIGGERS; - MODE_COOPERATIVE; - } - CONTRACTL_END; - - UINT32 result = 0; - - BEGIN_QCALL; - - if (divisor == 0) - { - COMPlusThrow(kDivideByZeroException); - goto END; - } - - result = dividend / divisor; - - END_QCALL; - -END: - return result; -} - -/*********************************************************************/ -extern "C" INT64 QCALLTYPE DivInt64Internal(INT64 dividend, INT64 divisor) -{ - CONTRACTL - { - THROWS; - GC_TRIGGERS; - MODE_COOPERATIVE; - } - CONTRACTL_END; - - INT64 result = 0; - - BEGIN_QCALL; - - if (Is32BitSigned(divisor)) - { - if ((INT32)divisor == 0) - { - COMPlusThrow(kDivideByZeroException); - goto END; - } - - if ((INT32)divisor == -1) - { - if ((UINT64) dividend == UI64(0x8000000000000000)) - { - COMPlusThrow(kOverflowException); - goto END; - } - - result = -dividend; - goto END; - } - - // Check for -ive or +ive numbers in the range -2**31 to 2**31 - if (Is32BitSigned(dividend)) - { - result = (INT32)dividend / (INT32)divisor; - goto END; - } - } - - // For all other combinations fallback to int64 div. - result = dividend / divisor; - - END_QCALL; - -END: - return result; -} - - -/*********************************************************************/ -extern "C" UINT64 QCALLTYPE DivUInt64Internal(UINT64 dividend, UINT64 divisor) -{ - CONTRACTL - { - THROWS; - GC_TRIGGERS; - MODE_COOPERATIVE; - } - CONTRACTL_END; - - UINT64 result = 0; - - BEGIN_QCALL; - - if (Hi32Bits(divisor) == 0) - { - if ((UINT32)(divisor) == 0) - { - COMPlusThrow(kDivideByZeroException); - goto END; - } - - if (Hi32Bits(dividend) == 0) - { - result = (UINT32)dividend / (UINT32)divisor; - goto END; - } - } - - result = dividend / divisor; - - END_QCALL; - -END: - return result; -} - -/*********************************************************************/ -extern "C" INT32 QCALLTYPE ModInt32Internal(INT32 dividend, INT32 divisor) -{ - CONTRACTL - { - THROWS; - GC_TRIGGERS; - MODE_COOPERATIVE; - } - CONTRACTL_END; - - INT32 result = 0; - - BEGIN_QCALL; - - if (((UINT32) (divisor + 1)) <= 1) // Unsigned test for divisor in [-1 .. 0] - { - if (divisor == 0) - { - COMPlusThrow(kDivideByZeroException); - goto END; - } - else if (divisor == -1) - { - if (dividend == INT32_MIN) - { - COMPlusThrow(kOverflowException); - goto END; - } - - result = 0; - goto END; - } - } - - result = dividend % divisor; - - END_QCALL; - -END: - return result; -} - -/*********************************************************************/ -extern "C" UINT32 QCALLTYPE ModUInt32Internal(UINT32 dividend, UINT32 divisor) -{ - CONTRACTL - { - THROWS; - GC_TRIGGERS; - MODE_COOPERATIVE; - } - CONTRACTL_END; - - UINT32 result = 0; - - BEGIN_QCALL; - - if (divisor == 0) - { - COMPlusThrow(kDivideByZeroException); - goto END; - } - - result = dividend % divisor; - - END_QCALL; - -END: - return result; -} - -/*********************************************************************/ -extern "C" INT64 QCALLTYPE ModInt64Internal(INT64 dividend, INT64 divisor) -{ - CONTRACTL - { - THROWS; - GC_TRIGGERS; - MODE_COOPERATIVE; - } - CONTRACTL_END; - - INT64 result = 0; - - BEGIN_QCALL; - - if (Is32BitSigned(divisor)) - { - if ((INT32)divisor == 0) - { - COMPlusThrow(kDivideByZeroException); - goto END; - } - - if ((INT32)divisor == -1) - { - // TODO, we really should remove this as it lengthens the code path - // and the spec really says that it should not throw an exception. - if ((UINT64) dividend == UI64(0x8000000000000000)) - { - COMPlusThrow(kOverflowException); - } - - goto END; - } - - // Check for -ive or +ive numbers in the range -2**31 to 2**31 - if (Is32BitSigned(dividend)) - { - result = (INT32)dividend % (INT32)divisor; - goto END; - } - } - - result = dividend % divisor; - - END_QCALL; - -END: - return result; -} - -/*********************************************************************/ -extern "C" UINT64 QCALLTYPE ModUInt64Internal(UINT64 dividend, UINT64 divisor) -{ - CONTRACTL - { - THROWS; - GC_TRIGGERS; - MODE_COOPERATIVE; - } - CONTRACTL_END; - - UINT64 result = 0; - - BEGIN_QCALL; - - if (Hi32Bits(divisor) == 0) - { - if ((UINT32)(divisor) == 0) - { - COMPlusThrow(kDivideByZeroException); - goto END; - } - - if (Hi32Bits(dividend) == 0) - { - result = (UINT32)dividend % (UINT32)divisor; - goto END; - } - } - - result = dividend % divisor; - - END_QCALL; - -END: - return result; -} - -#endif // TARGET_32BIT - #if !defined(HOST_64BIT) && !defined(TARGET_X86) /*********************************************************************/ HCIMPL2_VV(UINT64, JIT_LLsh, UINT64 num, int shift) @@ -4202,7 +3876,7 @@ bool IndirectionAllowedForJitHelper(CorInfoHelpFunc ftnNum) { return false; } - + return true; } diff --git a/src/coreclr/vm/qcallentrypoints.cpp b/src/coreclr/vm/qcallentrypoints.cpp index 08cc1dba261a65..a60d16dfb22218 100644 --- a/src/coreclr/vm/qcallentrypoints.cpp +++ b/src/coreclr/vm/qcallentrypoints.cpp @@ -471,16 +471,6 @@ static const Entry s_QCall[] = #endif #if defined(TARGET_X86) || defined(TARGET_AMD64) DllImportEntry(X86BaseCpuId) -#endif -#if defined(TARGET_32BIT) - DllImportEntry(DivInt32Internal) - DllImportEntry(DivUInt32Internal) - DllImportEntry(DivInt64Internal) - DllImportEntry(DivUInt64Internal) - DllImportEntry(ModInt32Internal) - DllImportEntry(ModUInt32Internal) - DllImportEntry(ModInt64Internal) - DllImportEntry(ModUInt64Internal) #endif DllImportEntry(StubHelpers_CreateCustomMarshaler) DllImportEntry(StubHelpers_SetStringTrailByte) diff --git a/src/libraries/System.Private.CoreLib/src/System.Private.CoreLib.Shared.projitems b/src/libraries/System.Private.CoreLib/src/System.Private.CoreLib.Shared.projitems index 51e003bae50afc..0842c6756752f1 100644 --- a/src/libraries/System.Private.CoreLib/src/System.Private.CoreLib.Shared.projitems +++ b/src/libraries/System.Private.CoreLib/src/System.Private.CoreLib.Shared.projitems @@ -570,6 +570,7 @@ + From 22fdedd2243e81a81764b8ce61c2ffecf3f4fb36 Mon Sep 17 00:00:00 2001 From: Adeel <3840695+am11@users.noreply.github.com> Date: Thu, 12 Dec 2024 15:30:19 +0200 Subject: [PATCH 25/27] Remove COM prefix --- src/coreclr/classlibnative/float/divmodint.cpp | 16 ++++++++-------- src/coreclr/classlibnative/inc/divmodint.h | 2 +- src/coreclr/vm/ecalllist.h | 16 ++++++++-------- 3 files changed, 17 insertions(+), 17 deletions(-) diff --git a/src/coreclr/classlibnative/float/divmodint.cpp b/src/coreclr/classlibnative/float/divmodint.cpp index 1b2b9f563ce9a4..d7b194c5587dc7 100644 --- a/src/coreclr/classlibnative/float/divmodint.cpp +++ b/src/coreclr/classlibnative/float/divmodint.cpp @@ -9,49 +9,49 @@ #include -FCIMPL2(int32_t, COMDivModInt::DivInt32, int32_t dividend, int32_t divisor) +FCIMPL2(int32_t, DivModInt::DivInt32, int32_t dividend, int32_t divisor) FCALL_CONTRACT; return dividend / divisor; FCIMPLEND -FCIMPL2(uint32_t, COMDivModInt::DivUInt32, uint32_t dividend, uint32_t divisor) +FCIMPL2(uint32_t, DivModInt::DivUInt32, uint32_t dividend, uint32_t divisor) FCALL_CONTRACT; return dividend / divisor; FCIMPLEND -FCIMPL2_VV(int64_t, COMDivModInt::DivInt64, int64_t dividend, int64_t divisor) +FCIMPL2_VV(int64_t, DivModInt::DivInt64, int64_t dividend, int64_t divisor) FCALL_CONTRACT; return dividend / divisor; FCIMPLEND -FCIMPL2_VV(uint64_t, COMDivModInt::DivUInt64, uint64_t dividend, uint64_t divisor) +FCIMPL2_VV(uint64_t, DivModInt::DivUInt64, uint64_t dividend, uint64_t divisor) FCALL_CONTRACT; return dividend / divisor; FCIMPLEND -FCIMPL2(int32_t, COMDivModInt::ModInt32, int32_t dividend, int32_t divisor) +FCIMPL2(int32_t, DivModInt::ModInt32, int32_t dividend, int32_t divisor) FCALL_CONTRACT; return dividend % divisor; FCIMPLEND -FCIMPL2(uint32_t, COMDivModInt::ModUInt32, uint32_t dividend, uint32_t divisor) +FCIMPL2(uint32_t, DivModInt::ModUInt32, uint32_t dividend, uint32_t divisor) FCALL_CONTRACT; return dividend % divisor; FCIMPLEND -FCIMPL2_VV(int64_t, COMDivModInt::ModInt64, int64_t dividend, int64_t divisor) +FCIMPL2_VV(int64_t, DivModInt::ModInt64, int64_t dividend, int64_t divisor) FCALL_CONTRACT; return dividend % divisor; FCIMPLEND -FCIMPL2_VV(uint64_t, COMDivModInt::ModUInt64, uint64_t dividend, uint64_t divisor) +FCIMPL2_VV(uint64_t, DivModInt::ModUInt64, uint64_t dividend, uint64_t divisor) FCALL_CONTRACT; return dividend % divisor; diff --git a/src/coreclr/classlibnative/inc/divmodint.h b/src/coreclr/classlibnative/inc/divmodint.h index 31a03a7f51c06b..bb196b5ef2d50e 100644 --- a/src/coreclr/classlibnative/inc/divmodint.h +++ b/src/coreclr/classlibnative/inc/divmodint.h @@ -7,7 +7,7 @@ #include #include -class COMDivModInt { +class DivModInt { public: FCDECL2(static int32_t, DivInt32, int32_t dividend, int32_t divisor); FCDECL2(static uint32_t, DivUInt32, uint32_t dividend, uint32_t divisor); diff --git a/src/coreclr/vm/ecalllist.h b/src/coreclr/vm/ecalllist.h index 9321f7e66b8467..678ed8dc64be2e 100644 --- a/src/coreclr/vm/ecalllist.h +++ b/src/coreclr/vm/ecalllist.h @@ -217,14 +217,14 @@ FCFuncStart(gMathFuncs) FCFuncElement("Tan", COMDouble::Tan) FCFuncElement("Tanh", COMDouble::Tanh) #ifdef TARGET_32BIT - FCFuncElement("DivInt32Internal", COMDivModInt::DivInt32) - FCFuncElement("DivUInt32Internal", COMDivModInt::DivUInt32) - FCFuncElement("DivInt64Internal", COMDivModInt::DivInt64) - FCFuncElement("DivUInt64Internal", COMDivModInt::DivUInt64) - FCFuncElement("ModInt32Internal", COMDivModInt::ModInt32) - FCFuncElement("ModUInt32Internal", COMDivModInt::ModUInt32) - FCFuncElement("ModInt64Internal", COMDivModInt::ModInt64) - FCFuncElement("ModUInt64Internal", COMDivModInt::ModUInt64) + FCFuncElement("DivInt32Internal", DivModInt::DivInt32) + FCFuncElement("DivUInt32Internal", DivModInt::DivUInt32) + FCFuncElement("DivInt64Internal", DivModInt::DivInt64) + FCFuncElement("DivUInt64Internal", DivModInt::DivUInt64) + FCFuncElement("ModInt32Internal", DivModInt::ModInt32) + FCFuncElement("ModUInt32Internal", DivModInt::ModUInt32) + FCFuncElement("ModInt64Internal", DivModInt::ModInt64) + FCFuncElement("ModUInt64Internal", DivModInt::ModUInt64) #endif // TARGET_32BIT FCFuncEnd() From ed9193e41daff8d4026ad08bd432edd9676b54ad Mon Sep 17 00:00:00 2001 From: Adeel <3840695+am11@users.noreply.github.com> Date: Thu, 12 Dec 2024 15:33:28 +0200 Subject: [PATCH 26/27] Update header guard to preferred naming convention --- src/coreclr/classlibnative/inc/divmodint.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/coreclr/classlibnative/inc/divmodint.h b/src/coreclr/classlibnative/inc/divmodint.h index bb196b5ef2d50e..a6aefdbdb78aed 100644 --- a/src/coreclr/classlibnative/inc/divmodint.h +++ b/src/coreclr/classlibnative/inc/divmodint.h @@ -1,8 +1,8 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -#ifndef _DIVMODINT_H_ -#define _DIVMODINT_H_ +#ifndef HAVE_DIVMODINT_H +#define HAVE_DIVMODINT_H #include #include @@ -19,4 +19,4 @@ class DivModInt { FCDECL2_VV(static uint64_t, ModUInt64, uint64_t dividend, uint64_t divisor); }; -#endif // _DIVMODINT_H_ +#endif // HAVE_DIVMODINT_H From 4f1f4755360abfabce1cdbae8d4f186ec34d9d2b Mon Sep 17 00:00:00 2001 From: Adeel Mujahid <3840695+am11@users.noreply.github.com> Date: Fri, 17 Jan 2025 18:11:04 +0200 Subject: [PATCH 27/27] Update Math.DivModInt.cs --- .../System.Private.CoreLib/src/System/Math.DivModInt.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libraries/System.Private.CoreLib/src/System/Math.DivModInt.cs b/src/libraries/System.Private.CoreLib/src/System/Math.DivModInt.cs index e73203d332b537..ef6c219482f8de 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Math.DivModInt.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Math.DivModInt.cs @@ -12,7 +12,7 @@ namespace System { /// - /// Provides constants and static methods for trigonometric, logarithmic, and other common mathematical functions. + /// Math helpers for generated code. The helpers here are referenced by the runtime. /// public static partial class Math {