diff --git a/src/coreclr/System.Private.CoreLib/src/System/Math.CoreCLR.cs b/src/coreclr/System.Private.CoreLib/src/System/Math.CoreCLR.cs index ef37d9d1ce83..c86aa1b2e62b 100644 --- a/src/coreclr/System.Private.CoreLib/src/System/Math.CoreCLR.cs +++ b/src/coreclr/System.Private.CoreLib/src/System/Math.CoreCLR.cs @@ -80,10 +80,6 @@ public static partial class Math [MethodImpl(MethodImplOptions.InternalCall)] public static extern double FusedMultiplyAdd(double x, double y, double z); - [Intrinsic] - [MethodImpl(MethodImplOptions.InternalCall)] - public static extern int ILogB(double x); - [Intrinsic] [MethodImpl(MethodImplOptions.InternalCall)] public static extern double Log(double d); diff --git a/src/coreclr/System.Private.CoreLib/src/System/MathF.CoreCLR.cs b/src/coreclr/System.Private.CoreLib/src/System/MathF.CoreCLR.cs index 5398f9537c0a..855a1b1e7ef1 100644 --- a/src/coreclr/System.Private.CoreLib/src/System/MathF.CoreCLR.cs +++ b/src/coreclr/System.Private.CoreLib/src/System/MathF.CoreCLR.cs @@ -69,10 +69,6 @@ public static partial class MathF [MethodImpl(MethodImplOptions.InternalCall)] public static extern float FusedMultiplyAdd(float x, float y, float z); - [Intrinsic] - [MethodImpl(MethodImplOptions.InternalCall)] - public static extern int ILogB(float x); - [Intrinsic] [MethodImpl(MethodImplOptions.InternalCall)] public static extern float Log(float x); diff --git a/src/coreclr/classlibnative/float/floatdouble.cpp b/src/coreclr/classlibnative/float/floatdouble.cpp index 4b4b2a267c57..67aceb60ea13 100644 --- a/src/coreclr/classlibnative/float/floatdouble.cpp +++ b/src/coreclr/classlibnative/float/floatdouble.cpp @@ -208,15 +208,6 @@ FCIMPL3_VVV(double, COMDouble::FusedMultiplyAdd, double x, double y, double z) return fma(x, y, z); FCIMPLEND -/*=====================================Ilog2==================================== -** -==============================================================================*/ -FCIMPL1_V(int, COMDouble::ILogB, double x) - FCALL_CONTRACT; - - return ilogb(x); -FCIMPLEND - /*=====================================Log====================================== ** ==============================================================================*/ diff --git a/src/coreclr/classlibnative/float/floatsingle.cpp b/src/coreclr/classlibnative/float/floatsingle.cpp index e2e7d8f638da..965998fbaa2b 100644 --- a/src/coreclr/classlibnative/float/floatsingle.cpp +++ b/src/coreclr/classlibnative/float/floatsingle.cpp @@ -195,15 +195,6 @@ FCIMPL3_VVV(float, COMSingle::FusedMultiplyAdd, float x, float y, float z) return fmaf(x, y, z); FCIMPLEND -/*=====================================Ilog2==================================== -** -==============================================================================*/ -FCIMPL1_V(int, COMSingle::ILogB, float x) - FCALL_CONTRACT; - - return ilogbf(x); -FCIMPLEND - /*=====================================Log====================================== ** ==============================================================================*/ diff --git a/src/coreclr/classlibnative/inc/floatdouble.h b/src/coreclr/classlibnative/inc/floatdouble.h index 80e49c0bd7ee..9163349127ca 100644 --- a/src/coreclr/classlibnative/inc/floatdouble.h +++ b/src/coreclr/classlibnative/inc/floatdouble.h @@ -25,7 +25,6 @@ class COMDouble { FCDECL1_V(static double, Floor, double x); FCDECL2_VV(static double, FMod, double x, double y); FCDECL3_VVV(static double, FusedMultiplyAdd, double x, double y, double z); - FCDECL1_V(static int, ILogB, double x); FCDECL1_V(static double, Log, double x); FCDECL1_V(static double, Log2, double x); FCDECL1_V(static double, Log10, double x); diff --git a/src/coreclr/classlibnative/inc/floatsingle.h b/src/coreclr/classlibnative/inc/floatsingle.h index e14bebb3867b..09a0512b230d 100644 --- a/src/coreclr/classlibnative/inc/floatsingle.h +++ b/src/coreclr/classlibnative/inc/floatsingle.h @@ -25,7 +25,6 @@ class COMSingle { FCDECL1_V(static float, Floor, float x); FCDECL2_VV(static float, FMod, float x, float y); FCDECL3_VVV(static float, FusedMultiplyAdd, float x, float y, float z); - FCDECL1_V(static int, ILogB, float x); FCDECL1_V(static float, Log, float x); FCDECL1_V(static float, Log2, float x); FCDECL1_V(static float, Log10, float x); diff --git a/src/coreclr/vm/ecalllist.h b/src/coreclr/vm/ecalllist.h index 5abf6c7d87c9..a8c054d5b23c 100644 --- a/src/coreclr/vm/ecalllist.h +++ b/src/coreclr/vm/ecalllist.h @@ -512,7 +512,6 @@ FCFuncStart(gMathFuncs) FCFuncElement("Floor", COMDouble::Floor) FCFuncElement("FMod", COMDouble::FMod) FCFuncElement("FusedMultiplyAdd", COMDouble::FusedMultiplyAdd) - FCFuncElement("ILogB", COMDouble::ILogB) FCFuncElement("Log", COMDouble::Log) FCFuncElement("Log2", COMDouble::Log2) FCFuncElement("Log10", COMDouble::Log10) @@ -542,7 +541,6 @@ FCFuncStart(gMathFFuncs) FCFuncElement("Floor", COMSingle::Floor) FCFuncElement("FMod", COMSingle::FMod) FCFuncElement("FusedMultiplyAdd", COMSingle::FusedMultiplyAdd) - FCFuncElement("ILogB", COMSingle::ILogB) FCFuncElement("Log", COMSingle::Log) FCFuncElement("Log2", COMSingle::Log2) FCFuncElement("Log10", COMSingle::Log10) diff --git a/src/libraries/System.Private.CoreLib/src/System/Math.cs b/src/libraries/System.Private.CoreLib/src/System/Math.cs index bb7fa0d4d3c8..f242b825fb17 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Math.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Math.cs @@ -49,6 +49,10 @@ public static partial class Math private const double SCALEB_C3 = 9007199254740992; // 0x1p53 + private const int ILogB_NaN = 0x7fffffff; + + private const int ILogB_Zero = (-1 - 0x7fffffff); + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static short Abs(short value) { @@ -788,6 +792,38 @@ public static double IEEERemainder(double x, double y) } } + public static int ILogB(double x) + { + // Implementation based on https://git.musl-libc.org/cgit/musl/tree/src/math/ilogb.c + + if (double.IsNaN(x)) + { + return ILogB_NaN; + } + + ulong i = BitConverter.DoubleToUInt64Bits(x); + int e = (int)((i >> 52) & 0x7FF); + + if (e == 0) + { + i <<= 12; + if (i == 0) + { + return ILogB_Zero; + } + + for (e = -0x3FF; (i >> 63) == 0; e--, i <<= 1) ; + return e; + } + + if (e == 0x7FF) + { + return (i << 12) != 0 ? ILogB_Zero : int.MaxValue; + } + + return e - 0x3FF; + } + public static double Log(double a, double newBase) { if (double.IsNaN(a)) diff --git a/src/libraries/System.Private.CoreLib/src/System/MathF.cs b/src/libraries/System.Private.CoreLib/src/System/MathF.cs index 9d1b75c8b161..2c4d7dce969d 100644 --- a/src/libraries/System.Private.CoreLib/src/System/MathF.cs +++ b/src/libraries/System.Private.CoreLib/src/System/MathF.cs @@ -43,6 +43,10 @@ public static partial class MathF private const float SCALEB_C3 = 16777216f; // 0x1p24f + private const int ILogB_NaN = 0x7fffffff; + + private const int ILogB_Zero = (-1 - 0x7fffffff); + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static float Abs(float x) { @@ -180,6 +184,38 @@ public static float IEEERemainder(float x, float y) } } + public static int ILogB(float x) + { + // Implementation based on https://git.musl-libc.org/cgit/musl/tree/src/math/ilogbf.c + + if (float.IsNaN(x)) + { + return ILogB_NaN; + } + + uint i = BitConverter.SingleToUInt32Bits(x); + int e = (int)((i >> 23) & 0xFF); + + if (e == 0) + { + i <<= 9; + if (i == 0) + { + return ILogB_Zero; + } + + for (e = -0x7F; (i >> 31) == 0; e--, i <<= 1) ; + return e; + } + + if (e == 0xFF) + { + return i << 9 != 0 ? ILogB_Zero : int.MaxValue; + } + + return e - 0x7F; + } + public static float Log(float x, float y) { if (float.IsNaN(x)) diff --git a/src/libraries/System.Runtime.Extensions/tests/System/Math.cs b/src/libraries/System.Runtime.Extensions/tests/System/Math.cs index 44f4bf6d282e..ad98ff3ea714 100644 --- a/src/libraries/System.Runtime.Extensions/tests/System/Math.cs +++ b/src/libraries/System.Runtime.Extensions/tests/System/Math.cs @@ -2796,6 +2796,16 @@ public static void FusedMultiplyAdd(double x, double y, double z, double expecte [InlineData( 6.5808859910179210, 2)] [InlineData( 8.8249778270762876, 3)] [InlineData( double.PositiveInfinity, unchecked((int)(0x7FFFFFFF)))] + [InlineData( -8.066848, 3)] + [InlineData( 4.345240, 2)] + [InlineData( -8.381433, 3)] + [InlineData( -6.531674, 2)] + [InlineData( 9.267057, 3)] + [InlineData( 0.661986, -1)] + [InlineData( -0.406604, -2)] + [InlineData( 0.561760, -1)] + [InlineData( 0.774152, -1)] + [InlineData( -0.678764, -1)] public static void ILogB(double value, int expectedResult) { Assert.Equal(expectedResult, Math.ILogB(value)); diff --git a/src/libraries/System.Runtime.Extensions/tests/System/MathF.cs b/src/libraries/System.Runtime.Extensions/tests/System/MathF.cs index 562d101b1b1b..6d834e6ef554 100644 --- a/src/libraries/System.Runtime.Extensions/tests/System/MathF.cs +++ b/src/libraries/System.Runtime.Extensions/tests/System/MathF.cs @@ -1063,6 +1063,16 @@ public static void IEEERemainder() [InlineData(6.58088599f, 2)] [InlineData(8.82497783f, 3)] [InlineData(float.PositiveInfinity, unchecked((int)(0x7FFFFFFF)))] + [InlineData(-8.066849f, 3)] + [InlineData(4.345240f, 2)] + [InlineData(-8.381433f, 3)] + [InlineData(-6.531673f, 2)] + [InlineData(9.267057f, 3)] + [InlineData(0.661986f, -1)] + [InlineData(-0.406604f, -2)] + [InlineData(0.561760f, -1)] + [InlineData(0.774152f, -1)] + [InlineData(-0.678764f, -1)] public static void ILogB(float value, int expectedResult) { Assert.Equal(expectedResult, MathF.ILogB(value)); diff --git a/src/mono/System.Private.CoreLib/src/System/Math.Mono.cs b/src/mono/System.Private.CoreLib/src/System/Math.Mono.cs index 5b626e36ad02..b2bf6baadd57 100644 --- a/src/mono/System.Private.CoreLib/src/System/Math.Mono.cs +++ b/src/mono/System.Private.CoreLib/src/System/Math.Mono.cs @@ -82,9 +82,6 @@ public partial class Math [MethodImpl(MethodImplOptions.InternalCall)] public static extern double FusedMultiplyAdd(double x, double y, double z); - [MethodImpl(MethodImplOptions.InternalCall)] - public static extern int ILogB(double x); - [MethodImpl(MethodImplOptions.InternalCall)] public static extern double Log2(double x); diff --git a/src/mono/System.Private.CoreLib/src/System/MathF.Mono.cs b/src/mono/System.Private.CoreLib/src/System/MathF.Mono.cs index da8f1603a7ad..4fd4dc614458 100644 --- a/src/mono/System.Private.CoreLib/src/System/MathF.Mono.cs +++ b/src/mono/System.Private.CoreLib/src/System/MathF.Mono.cs @@ -76,9 +76,6 @@ public partial class MathF [MethodImpl(MethodImplOptions.InternalCall)] public static extern float FusedMultiplyAdd(float x, float y, float z); - [MethodImpl(MethodImplOptions.InternalCall)] - public static extern int ILogB(float x); - [MethodImpl(MethodImplOptions.InternalCall)] public static extern float Log2(float x); diff --git a/src/mono/mono/metadata/icall-decl.h b/src/mono/mono/metadata/icall-decl.h index c145332ed493..20cbe2723c97 100644 --- a/src/mono/mono/metadata/icall-decl.h +++ b/src/mono/mono/metadata/icall-decl.h @@ -118,10 +118,8 @@ ICALL_EXPORT float ves_icall_System_MathF_Sqrt (float); ICALL_EXPORT float ves_icall_System_MathF_Tan (float); ICALL_EXPORT float ves_icall_System_MathF_Tanh (float); ICALL_EXPORT float ves_icall_System_Math_Abs_single (float); -ICALL_EXPORT gint32 ves_icall_System_Math_ILogB (double); ICALL_EXPORT double ves_icall_System_Math_Log2 (double); ICALL_EXPORT double ves_icall_System_Math_FusedMultiplyAdd (double, double, double); -ICALL_EXPORT gint32 ves_icall_System_MathF_ILogB (float); ICALL_EXPORT float ves_icall_System_MathF_Log2 (float); ICALL_EXPORT float ves_icall_System_MathF_FusedMultiplyAdd (float, float, float); ICALL_EXPORT gint32 ves_icall_System_Environment_get_ProcessorCount (void); diff --git a/src/mono/mono/metadata/icall-def-netcore.h b/src/mono/mono/metadata/icall-def-netcore.h index 983cc5330f0c..1f0a400008e5 100644 --- a/src/mono/mono/metadata/icall-def-netcore.h +++ b/src/mono/mono/metadata/icall-def-netcore.h @@ -126,7 +126,6 @@ NOHANDLES(ICALL(MATH_7, "Exp", ves_icall_System_Math_Exp)) NOHANDLES(ICALL(MATH_7a, "FMod", ves_icall_System_Math_FMod)) NOHANDLES(ICALL(MATH_8, "Floor", ves_icall_System_Math_Floor)) NOHANDLES(ICALL(MATH_22, "FusedMultiplyAdd", ves_icall_System_Math_FusedMultiplyAdd)) -NOHANDLES(ICALL(MATH_23, "ILogB", ves_icall_System_Math_ILogB)) NOHANDLES(ICALL(MATH_9, "Log", ves_icall_System_Math_Log)) NOHANDLES(ICALL(MATH_10, "Log10", ves_icall_System_Math_Log10)) NOHANDLES(ICALL(MATH_24, "Log2", ves_icall_System_Math_Log2)) @@ -155,7 +154,6 @@ NOHANDLES(ICALL(MATHF_12, "Exp", ves_icall_System_MathF_Exp)) NOHANDLES(ICALL(MATHF_22, "FMod", ves_icall_System_MathF_FMod)) NOHANDLES(ICALL(MATHF_13, "Floor", ves_icall_System_MathF_Floor)) NOHANDLES(ICALL(MATHF_24, "FusedMultiplyAdd", ves_icall_System_MathF_FusedMultiplyAdd)) -NOHANDLES(ICALL(MATHF_25, "ILogB", ves_icall_System_MathF_ILogB)) NOHANDLES(ICALL(MATHF_14, "Log", ves_icall_System_MathF_Log)) NOHANDLES(ICALL(MATHF_15, "Log10", ves_icall_System_MathF_Log10)) NOHANDLES(ICALL(MATHF_26, "Log2", ves_icall_System_MathF_Log2)) diff --git a/src/mono/mono/metadata/sysmath.c b/src/mono/mono/metadata/sysmath.c index 5c0d4ae85fe5..e8fef9f8e08e 100644 --- a/src/mono/mono/metadata/sysmath.c +++ b/src/mono/mono/metadata/sysmath.c @@ -187,17 +187,6 @@ ves_icall_System_Math_Ceiling (gdouble v) return ceil (v); } -gint32 -ves_icall_System_Math_ILogB (gdouble x) -{ - if (FP_ILOGB0 != INT_MIN && x == 0.0) - return INT_MIN; - if (FP_ILOGBNAN != INT_MAX && isnan(x)) - return INT_MAX; - - return ilogb(x); -} - gdouble ves_icall_System_Math_Log2 (gdouble x) { @@ -348,17 +337,6 @@ ves_icall_System_MathF_ModF (float x, float *d) return modff (x, d); } -gint32 -ves_icall_System_MathF_ILogB (float x) -{ - if (FP_ILOGB0 != INT_MIN && x == 0.0) - return INT_MIN; - if (FP_ILOGBNAN != INT_MAX && isnan(x)) - return INT_MAX; - - return ilogbf(x); -} - float ves_icall_System_MathF_Log2 (float x) { diff --git a/src/mono/mono/mini/interp/interp.c b/src/mono/mono/mini/interp/interp.c index 7ea1e598dec1..368e23a66b3c 100644 --- a/src/mono/mono/mini/interp/interp.c +++ b/src/mono/mono/mini/interp/interp.c @@ -6781,19 +6781,6 @@ MINT_IN_CASE(MINT_BRTRUE_I8_SP) ZEROP_SP(gint64, !=); MINT_IN_BREAK; LOCAL_VAR (ip [1], double) = scalbn (LOCAL_VAR (ip [2], double), LOCAL_VAR (ip [3], gint32)); ip += 4; MINT_IN_BREAK; - MINT_IN_CASE(MINT_ILOGB) { - int result; - double x = LOCAL_VAR (ip [2], double); - if (FP_ILOGB0 != INT_MIN && x == 0.0) - result = INT_MIN; - else if (FP_ILOGBNAN != INT_MAX && isnan(x)) - result = INT_MAX; - else - result = ilogb (x); - LOCAL_VAR (ip [1], gint32) = result; - ip += 3; - MINT_IN_BREAK; - } #define MATH_UNOPF(mathfunc) \ LOCAL_VAR (ip [1], float) = mathfunc (LOCAL_VAR (ip [2], float)); \ @@ -6834,19 +6821,6 @@ MINT_IN_CASE(MINT_BRTRUE_I8_SP) ZEROP_SP(gint64, !=); MINT_IN_BREAK; LOCAL_VAR (ip [1], float) = scalbnf (LOCAL_VAR (ip [2], float), LOCAL_VAR (ip [3], gint32)); ip += 4; MINT_IN_BREAK; - MINT_IN_CASE(MINT_ILOGBF) { - int result; - float x = LOCAL_VAR (ip [2], float); - if (FP_ILOGB0 != INT_MIN && x == 0.0) - result = INT_MIN; - else if (FP_ILOGBNAN != INT_MAX && isnan(x)) - result = INT_MAX; - else - result = ilogbf (x); - LOCAL_VAR (ip [1], gint32) = result; - ip += 3; - MINT_IN_BREAK; - } MINT_IN_CASE(MINT_INTRINS_ENUM_HASFLAG) { MonoClass *klass = (MonoClass*)frame->imethod->data_items [ip [4]]; diff --git a/src/mono/mono/mini/interp/mintops.def b/src/mono/mono/mini/interp/mintops.def index 3f5586965954..e464902f8168 100644 --- a/src/mono/mono/mini/interp/mintops.def +++ b/src/mono/mono/mini/interp/mintops.def @@ -721,7 +721,6 @@ OPDEF(MINT_COSH, "cosh", 3, 1, 1, MintOpNoArgs) OPDEF(MINT_EXP, "exp", 3, 1, 1, MintOpNoArgs) OPDEF(MINT_FMA, "fma", 5, 1, 3, MintOpNoArgs) OPDEF(MINT_FLOOR, "floor", 3, 1, 1, MintOpNoArgs) -OPDEF(MINT_ILOGB, "ilogb", 3, 1, 1, MintOpNoArgs) OPDEF(MINT_LOG, "log", 3, 1, 1, MintOpNoArgs) OPDEF(MINT_LOG2, "log2", 3, 1, 1, MintOpNoArgs) OPDEF(MINT_LOG10, "log10", 3, 1, 1, MintOpNoArgs) @@ -749,7 +748,6 @@ OPDEF(MINT_COSHF, "coshf", 3, 1, 1, MintOpNoArgs) OPDEF(MINT_EXPF, "expf", 3, 1, 1, MintOpNoArgs) OPDEF(MINT_FMAF, "fmaf", 5, 1, 3, MintOpNoArgs) OPDEF(MINT_FLOORF, "floorf", 3, 1, 1, MintOpNoArgs) -OPDEF(MINT_ILOGBF, "ilogbf", 3, 1, 1, MintOpNoArgs) OPDEF(MINT_LOGF, "logf", 3, 1, 1, MintOpNoArgs) OPDEF(MINT_LOG2F, "log2f", 3, 1, 1, MintOpNoArgs) OPDEF(MINT_LOG10F, "log10f", 3, 1, 1, MintOpNoArgs) diff --git a/src/mono/mono/mini/interp/transform.c b/src/mono/mono/mini/interp/transform.c index 979f7a1b7ffe..fd5138dafdc9 100644 --- a/src/mono/mono/mini/interp/transform.c +++ b/src/mono/mono/mini/interp/transform.c @@ -2238,8 +2238,6 @@ interp_handle_intrinsics (TransformData *td, MonoMethod *target_method, MonoClas *op = MINT_EXP; } else if (strcmp (tm, "Floor") == 0) { *op = MINT_FLOOR; - } else if (strcmp (tm, "ILogB") == 0) { - *op = MINT_ILOGB; } else if (tm [0] == 'L') { if (strcmp (tm, "Log") == 0) { *op = MINT_LOG;