Skip to content
This repository was archived by the owner on Jan 23, 2023. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
217 changes: 217 additions & 0 deletions src/classlibnative/float/floatsingle.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,11 @@

#define IS_FLT_INFINITY(x) (((*((INT32*)((void*)&x))) & 0x7FFFFFFF) == 0x7F800000)

// Windows x86 and Windows ARM don't define _isnanf() but they do define a generic macro isnan()
#if (defined(_TARGET_X86_) || defined(_TARGET_ARM_)) && !defined(FEATURE_PAL) && !defined(_isnanf)
#define _isnanf isnan
#endif

// The default compilation mode is /fp:precise, which disables floating-point intrinsics. This
// default compilation mode has previously caused performance regressions in floating-point code.
// We enable /fp:fast semantics for the majority of the math functions, as it will speed up performance
Expand Down Expand Up @@ -39,6 +44,218 @@ FCIMPL1(float, COMSingle::Abs, float x)
return (float)fabsf(x);
FCIMPLEND

/*=====================================Acos=====================================
**
==============================================================================*/
FCIMPL1(float, COMSingle::Acos, float x)
FCALL_CONTRACT;

return (float)acosf(x);
FCIMPLEND

/*=====================================Asin=====================================
**
==============================================================================*/
FCIMPL1(float, COMSingle::Asin, float x)
FCALL_CONTRACT;

return (float)asinf(x);
FCIMPLEND

/*=====================================Atan=====================================
**
==============================================================================*/
FCIMPL1(float, COMSingle::Atan, float x)
FCALL_CONTRACT;

return (float)atanf(x);
FCIMPLEND

/*=====================================Atan2====================================
**
==============================================================================*/
FCIMPL2(float, COMSingle::Atan2, float y, float x)
FCALL_CONTRACT;

// atan2f(+/-INFINITY, +/-INFINITY) produces +/-0.785398163f (x is +INFINITY) and
// +/-2.35619449f (x is -INFINITY) instead of the expected value of NaN. We handle
// that case here ourselves.
if (IS_FLT_INFINITY(y) && IS_FLT_INFINITY(x)) {
return (float)(y / x);
}

return (float)atan2f(y, x);
FCIMPLEND

/*====================================Ceil======================================
**
==============================================================================*/
FCIMPL1(float, COMSingle::Ceil, float x)
FCALL_CONTRACT;

return (float)ceilf(x);
FCIMPLEND

/*=====================================Cos======================================
**
==============================================================================*/
FCIMPL1(float, COMSingle::Cos, float x)
FCALL_CONTRACT;

return (float)cosf(x);
FCIMPLEND

/*=====================================Cosh=====================================
**
==============================================================================*/
FCIMPL1(float, COMSingle::Cosh, float x)
FCALL_CONTRACT;

return (float)coshf(x);
FCIMPLEND

/*=====================================Exp======================================
**
==============================================================================*/
FCIMPL1(float, COMSingle::Exp, float x)
FCALL_CONTRACT;

return (float)expf(x);
FCIMPLEND

/*====================================Floor=====================================
**
==============================================================================*/
FCIMPL1(float, COMSingle::Floor, float x)
FCALL_CONTRACT;

return (float)floorf(x);
FCIMPLEND

/*=====================================Log======================================
**
==============================================================================*/
FCIMPL1(float, COMSingle::Log, float x)
FCALL_CONTRACT;

return (float)logf(x);
FCIMPLEND

/*====================================Log10=====================================
**
==============================================================================*/
FCIMPL1(float, COMSingle::Log10, float x)
FCALL_CONTRACT;

return (float)log10f(x);
FCIMPLEND

/*=====================================ModF=====================================
**
==============================================================================*/
FCIMPL1(float, COMSingle::ModF, float* iptr)
FCALL_CONTRACT;

return (float)modff(*iptr, iptr);
FCIMPLEND

/*=====================================Pow======================================
**
==============================================================================*/
FCIMPL2(float, COMSingle::Pow, float x, float y)
FCALL_CONTRACT;

// The CRT version of pow preserves the NaN payload of x over the NaN payload of y.

if(_isnanf(y)) {
return y; // IEEE 754-2008: NaN payload must be preserved
}

if(_isnanf(x)) {
return x; // IEEE 754-2008: NaN payload must be preserved
}

// The CRT version of powf does not return NaN for powf(-1.0f, +/-INFINITY) and
// instead returns +1.0f.

if(IS_FLT_INFINITY(y) && (x == -1.0f)) {
INT32 result = CLR_NAN_32;
return (*((float*)((INT32*)&result)));
}

return (float)powf(x, y);
FCIMPLEND

/*====================================Round=====================================
**
==============================================================================*/
FCIMPL1(float, COMSingle::Round, float x)
FCALL_CONTRACT;

// If the number has no fractional part do nothing
// This shortcut is necessary to workaround precision loss in borderline cases on some platforms
if (x == (float)((INT32)x)) {
return x;
}

// We had a number that was equally close to 2 integers.
// We need to return the even one.

float tempVal = (x + 0.5f);
float flrTempVal = floorf(tempVal);

if ((flrTempVal == tempVal) && (fmodf(tempVal, 2.0f) != 0)) {
flrTempVal -= 1.0f;
}

return _copysignf(flrTempVal, x);
FCIMPLEND

/*=====================================Sin======================================
**
==============================================================================*/
FCIMPL1(float, COMSingle::Sin, float x)
FCALL_CONTRACT;

return (float)sinf(x);
FCIMPLEND

/*=====================================Sinh=====================================
**
==============================================================================*/
FCIMPL1(float, COMSingle::Sinh, float x)
FCALL_CONTRACT;

return (float)sinhf(x);
FCIMPLEND

/*=====================================Sqrt=====================================
**
==============================================================================*/
FCIMPL1(float, COMSingle::Sqrt, float x)
FCALL_CONTRACT;

return (float)sqrtf(x);
FCIMPLEND

/*=====================================Tan======================================
**
==============================================================================*/
FCIMPL1(float, COMSingle::Tan, float x)
FCALL_CONTRACT;

return (float)tanf(x);
FCIMPLEND

/*=====================================Tanh=====================================
**
==============================================================================*/
FCIMPL1(float, COMSingle::Tanh, float x)
FCALL_CONTRACT;

return (float)tanhf(x);
FCIMPLEND

#ifdef _MSC_VER
#pragma float_control(precise, on )
#endif
Expand Down
19 changes: 19 additions & 0 deletions src/classlibnative/inc/floatsingle.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,25 @@
class COMSingle {
public:
FCDECL1(static float, Abs, float x);
FCDECL1(static float, Acos, float x);
FCDECL1(static float, Asin, float x);
FCDECL1(static float, Atan, float x);
FCDECL2(static float, Atan2, float y, float x);
FCDECL1(static float, Ceil, float x);
FCDECL1(static float, Cos, float x);
FCDECL1(static float, Cosh, float x);
FCDECL1(static float, Exp, float x);
FCDECL1(static float, Floor, float x);
FCDECL1(static float, Log, float x);
FCDECL1(static float, Log10, float x);
FCDECL1(static float, ModF, float* iptr);
FCDECL2(static float, Pow, float x, float y);
FCDECL1(static float, Round, float x);
FCDECL1(static float, Sin, float x);
FCDECL1(static float, Sinh, float x);
FCDECL1(static float, Sqrt, float x);
FCDECL1(static float, Tan, float x);
FCDECL1(static float, Tanh, float x);
};

#endif // _FLOATSINGLE_H_
34 changes: 34 additions & 0 deletions src/mscorlib/model.xml
Original file line number Diff line number Diff line change
Expand Up @@ -447,6 +447,7 @@
</Type>
<Type Name="System.BitConverter">
<Member Name="DoubleToInt64Bits(System.Double)" />
<Member Name="Int32BitsToSingle(System.Int32)" />
<Member Name="Int64BitsToDouble(System.Int64)" />
<Member MemberType="Field" Name="IsLittleEndian" />
<Member Name="GetBytes(System.Boolean)" />
Expand All @@ -459,6 +460,7 @@
<Member Name="GetBytes(System.UInt32)" />
<Member Name="GetBytes(System.UInt64)" />
<Member Name="GetBytes(System.UInt16)" />
<Member Name="SingleToInt32Bits(System.Single)" />
<Member Name="ToBoolean(System.Byte[],System.Int32)" />
<Member Name="ToChar(System.Byte[],System.Int32)" />
<Member Name="ToDouble(System.Byte[],System.Int32)" />
Expand Down Expand Up @@ -3660,6 +3662,38 @@
<Member Name="Truncate(System.Decimal)" />
<Member Name="Truncate(System.Double)" />
</Type>
<Type Name="System.MathF">
<Member MemberType="Field" Name="E" />
<Member MemberType="Field" Name="PI" />
<Member Name="Abs(System.Single)" />
<Member Name="Acos(System.Single)" />
<Member Name="Asin(System.Single)" />
<Member Name="Atan(System.Single)" />
<Member Name="Atan2(System.Single,System.Single)" />
<Member Name="Ceiling(System.Single)"/>
<Member Name="Cos(System.Single)" />
<Member Name="Cosh(System.Single)" />
<Member Name="Exp(System.Single)" />
<Member Name="Floor(System.Single)" />
<Member Name="IEEERemainder(System.Single,System.Single)" />
<Member Name="Log(System.Single)" />
<Member Name="Log(System.Single,System.Single)" />
<Member Name="Log10(System.Single)" />
<Member Name="Max(System.Single,System.Single)" />
<Member Name="Min(System.Single,System.Single)" />
<Member Name="Pow(System.Single,System.Single)" />
<Member Name="Round(System.Single)" />
<Member Name="Round(System.Single,System.Int32)" />
<Member Name="Round(System.Single,System.Int32,System.MidpointRounding)" />
<Member Name="Round(System.Single,System.MidpointRounding)" />
<Member Name="Sign(System.Single)" />
<Member Name="Sin(System.Single)" />
<Member Name="Sinh(System.Single)" />
<Member Name="Sqrt(System.Single)" />
<Member Name="Tan(System.Single)" />
<Member Name="Tanh(System.Single)" />
<Member Name="Truncate(System.Single)" />
</Type>
<Type Name="System.MemberAccessException">
<Member Name="#ctor" />
<Member Name="#ctor(System.String)" />
Expand Down
1 change: 1 addition & 0 deletions src/mscorlib/mscorlib.shared.sources.props
Original file line number Diff line number Diff line change
Expand Up @@ -369,6 +369,7 @@
<SystemSources Include="$(BclSourcesRoot)\System\_LocalDataStoreMgr.cs" />
<SystemSources Include="$(BclSourcesRoot)\System\MarshalByRefObject.cs" />
<SystemSources Include="$(BclSourcesRoot)\System\Math.cs" />
<SystemSources Include="$(BclSourcesRoot)\System\MathF.cs" />
<SystemSources Include="$(BclSourcesRoot)\System\mda.cs" />
<SystemSources Include="$(BclSourcesRoot)\System\MethodAccessException.cs" />
<SystemSources Include="$(BclSourcesRoot)\System\MidpointRounding.cs" />
Expand Down
57 changes: 57 additions & 0 deletions src/mscorlib/ref/mscorlib.cs
Original file line number Diff line number Diff line change
Expand Up @@ -603,7 +603,11 @@ public static partial class BitConverter
[System.CLSCompliantAttribute(false)]
public static byte[] GetBytes(ulong value) { throw null; }
[System.Security.SecuritySafeCriticalAttribute]
public static float Int32BitsToSingle(int value) { throw null; }
[System.Security.SecuritySafeCriticalAttribute]
public static double Int64BitsToDouble(long value) { throw null; }
[System.Security.SecuritySafeCriticalAttribute]
public static int SingleToInt32Bits(float value) { throw null; }
public static bool ToBoolean(byte[] value, int startIndex) { throw null; }
public static char ToChar(byte[] value, int startIndex) { throw null; }
[System.Security.SecuritySafeCriticalAttribute]
Expand Down Expand Up @@ -2622,6 +2626,59 @@ public static partial class Math
public static decimal Truncate(decimal d) { throw null; }
public static double Truncate(double d) { throw null; }
}
public static partial class MathF
{
public const float E = 2.71828183f;
public const float PI = 3.14159265f;
[System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.InternalCall)][System.Security.SecuritySafeCriticalAttribute]
public static float Abs(float x) { return default(float); }
[System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.InternalCall)][System.Security.SecuritySafeCriticalAttribute]
public static float Acos(float x) { return default(float); }
[System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.InternalCall)][System.Security.SecuritySafeCriticalAttribute]
public static float Asin(float x) { return default(float); }
[System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.InternalCall)][System.Security.SecuritySafeCriticalAttribute]
public static float Atan(float x) { return default(float); }
[System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.InternalCall)][System.Security.SecuritySafeCriticalAttribute]
public static float Atan2(float y, float x) { return default(float); }
[System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.InternalCall)][System.Security.SecuritySafeCriticalAttribute]
public static float Ceiling(float x) { return default(float); }
[System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.InternalCall)][System.Security.SecuritySafeCriticalAttribute]
public static float Cos(float x) { return default(float); }
[System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.InternalCall)][System.Security.SecuritySafeCriticalAttribute]
public static float Cosh(float x) { return default(float); }
[System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.InternalCall)][System.Security.SecuritySafeCriticalAttribute]
public static float Exp(float x) { return default(float); }
[System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.InternalCall)][System.Security.SecuritySafeCriticalAttribute]
public static float Floor(float x) { return default(float); }
public static float IEEERemainder(float x, float y) { return default(float); }
[System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.InternalCall)][System.Security.SecuritySafeCriticalAttribute]
public static float Log(float x) { return default(float); }
public static float Log(float x, float y) { return default(float); }
[System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.InternalCall)][System.Security.SecuritySafeCriticalAttribute]
public static float Log10(float x) { return default(float); }
public static float Max(float x, float y) { return default(float); }
public static float Min(float x, float y) { return default(float); }
[System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.InternalCall)][System.Security.SecuritySafeCriticalAttribute]
public static float Pow(float x, float y) { return default(float); }
[System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.InternalCall)][System.Security.SecuritySafeCriticalAttribute]
public static float Round(float x) { return default(float); }
public static float Round(float x, int digits) { return default(float); }
public static float Round(float x, int digits, System.MidpointRounding mode) { return default(float); }
public static float Round(float x, System.MidpointRounding mode) { return default(float); }
public static int Sign(float x) { return default(int); }
[System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.InternalCall)][System.Security.SecuritySafeCriticalAttribute]
public static float Sin(float x) { return default(float); }
[System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.InternalCall)][System.Security.SecuritySafeCriticalAttribute]
public static float Sinh(float x) { return default(float); }
[System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.InternalCall)]
[System.Security.SecuritySafeCriticalAttribute]
public static float Sqrt(float x) { return default(float); }
[System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.InternalCall)][System.Security.SecuritySafeCriticalAttribute]
public static float Tan(float x) { return default(float); }
[System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.InternalCall)][System.Security.SecuritySafeCriticalAttribute]
public static float Tanh(float x) { return default(float); }
public static float Truncate(float x) { return default(float); }
}
[System.Runtime.InteropServices.ComVisibleAttribute(true)]
public partial class MemberAccessException : System.SystemException
{
Expand Down
Loading