@@ -13,37 +13,55 @@ HRESULT Library_nf_native_system_math_System_Math::Max___STATIC__R8__R8__R8(CLR_
1313 NATIVE_PROFILE_CLR_CORE ();
1414 NANOCLR_HEADER ();
1515
16+ // This matches the IEEE 754:2019 `maximum` function
17+ //
18+ // It propagates NaN inputs back to the caller and
19+ // otherwise returns the greater of the inputs. It
20+ // treats +0 as greater than -0 as per the specification.
21+
1622#if (DP_FLOATINGPOINT == TRUE)
1723
18- double x = stack.Arg0 ().NumericByRefConst ().r8 ;
19- double y = stack.Arg1 ().NumericByRefConst ().r8 ;
24+ double val1 = stack.Arg0 ().NumericByRefConst ().r8 ;
25+ double val2 = stack.Arg1 ().NumericByRefConst ().r8 ;
2026
21- // from .NET spec: If val1, val2, or both val1 and val2 are equal to NaN, NaN is returned.
22- if (System::Double::IsNaN (x) || System::Double::IsNaN (y))
27+ if (val1 != val2)
2328 {
24- stack.SetResult_R8 (NAN);
29+ if (!__isnand (val1))
30+ {
31+ double res = val2 < val1 ? val1 : val2;
32+ stack.SetResult_R8 (res);
33+ }
34+ else
35+ {
36+ stack.SetResult_R8 (val1);
37+ }
2538 }
2639 else
2740 {
28- double res = x >= y ? x : y;
29-
41+ double res = (__signbitd (val2) != 0 ) ? val1 : val2;
3042 stack.SetResult_R8 (res);
3143 }
3244
3345#else
3446
35- float x = (float )stack.Arg0 ().NumericByRefConst ().r8 ;
36- float y = (float )stack.Arg1 ().NumericByRefConst ().r8 ;
47+ float val1 = (float )stack.Arg0 ().NumericByRefConst ().r8 ;
48+ float val2 = (float )stack.Arg1 ().NumericByRefConst ().r8 ;
3749
38- // from .NET spec: If val1, val2, or both val1 and val2 are equal to NaN, NaN is returned.
39- if (System::Double::IsNaN (x) || System::Double::IsNaN (y))
50+ if (val1 != val2)
4051 {
41- stack.SetResult_R8 (NAN);
52+ if (!__isnand (val1))
53+ {
54+ float res = val2 < val1 ? val1 : val2;
55+ stack.SetResult_R8 (res);
56+ }
57+ else
58+ {
59+ stack.SetResult_R8 (val1);
60+ }
4261 }
4362 else
4463 {
45- float res = x >= y ? x : y;
46-
64+ float res = (__signbitd (val2) != 0 ) ? val1 : val2;
4765 stack.SetResult_R8 (res);
4866 }
4967
@@ -52,32 +70,138 @@ HRESULT Library_nf_native_system_math_System_Math::Max___STATIC__R8__R8__R8(CLR_
5270 NANOCLR_NOCLEANUP_NOLABEL ();
5371}
5472
73+ HRESULT Library_nf_native_system_math_System_Math::Max___STATIC__R4__R4__R4 (CLR_RT_StackFrame &stack)
74+ {
75+ NATIVE_PROFILE_CLR_CORE ();
76+ NANOCLR_HEADER ();
77+
78+ // This matches the IEEE 754:2019 `maximum` function
79+ //
80+ // It propagates NaN inputs back to the caller and
81+ // otherwise returns the greater of the inputs. It
82+ // treats +0 as greater than -0 as per the specification.
83+
84+ float val1 = (float )stack.Arg0 ().NumericByRefConst ().r4 ;
85+ float val2 = (float )stack.Arg1 ().NumericByRefConst ().r4 ;
86+
87+ if (val1 != val2)
88+ {
89+ if (!__isnand (val1))
90+ {
91+ float res = val2 < val1 ? val1 : val2;
92+ stack.SetResult_R4 (res);
93+ }
94+ else
95+ {
96+ stack.SetResult_R4 (val1);
97+ }
98+ }
99+ else
100+ {
101+ float res = (__signbitd (val2) != 0 ) ? val1 : val2;
102+ stack.SetResult_R4 (res);
103+ }
104+
105+ NANOCLR_NOCLEANUP_NOLABEL ();
106+ }
107+
55108HRESULT Library_nf_native_system_math_System_Math::Min___STATIC__R8__R8__R8 (CLR_RT_StackFrame &stack)
56109{
57110 NATIVE_PROFILE_CLR_CORE ();
58111 NANOCLR_HEADER ();
59112
113+ // This matches the IEEE 754:2019 `minimum` function
114+ //
115+ // It propagates NaN inputs back to the caller and
116+ // otherwise returns the lesser of the inputs. It
117+ // treats +0 as lesser than -0 as per the specification.
118+
60119#if (DP_FLOATINGPOINT == TRUE)
61120
62- double x = stack.Arg0 ().NumericByRefConst ().r8 ;
63- double y = stack.Arg1 ().NumericByRefConst ().r8 ;
64- double res = x <= y ? x : y;
121+ double val1 = stack.Arg0 ().NumericByRefConst ().r8 ;
122+ double val2 = stack.Arg1 ().NumericByRefConst ().r8 ;
65123
66- stack.SetResult_R8 (res);
124+ if (val1 != val2)
125+ {
126+ if (!__isnand (val1))
127+ {
128+ double res = val1 < val2 ? val1 : val2;
129+ stack.SetResult_R8 (res);
130+ }
131+ else
132+ {
133+ stack.SetResult_R8 (val1);
134+ }
135+ }
136+ else
137+ {
138+ double res = (__signbitd (val2) != 0 ) ? val1 : val2;
139+ stack.SetResult_R8 (res);
140+ }
67141
68142#else
69143
70- float x = (float )stack.Arg0 ().NumericByRefConst ().r8 ;
71- float y = (float )stack.Arg1 ().NumericByRefConst ().r8 ;
72- float res = x <= y ? x : y;
144+ float val1 = (float )stack.Arg0 ().NumericByRefConst ().r8 ;
145+ float val2 = (float )stack.Arg1 ().NumericByRefConst ().r8 ;
73146
74- stack.SetResult_R8 (res);
147+ if (val1 != val2)
148+ {
149+ if (!__isnand (val1))
150+ {
151+ float res = val1 < val2 ? val1 : val2;
152+ stack.SetResult_R8 (res);
153+ }
154+ else
155+ {
156+ stack.SetResult_R8 ((float )val1);
157+ }
158+ }
159+ else
160+ {
161+ float res = (__signbitd (val2) != 0 ) ? val1 : val2;
162+ stack.SetResult_R8 (res);
163+ }
75164
76165#endif
77166
78167 NANOCLR_NOCLEANUP_NOLABEL ();
79168}
80169
170+ HRESULT Library_nf_native_system_math_System_Math::Min___STATIC__R4__R4__R4 (CLR_RT_StackFrame &stack)
171+ {
172+ NATIVE_PROFILE_CLR_CORE ();
173+ NANOCLR_HEADER ();
174+
175+ // This matches the IEEE 754:2019 `minimum` function
176+ //
177+ // It propagates NaN inputs back to the caller and
178+ // otherwise returns the lesser of the inputs. It
179+ // treats +0 as lesser than -0 as per the specification.
180+
181+ float val1 = (float )stack.Arg0 ().NumericByRefConst ().r4 ;
182+ float val2 = (float )stack.Arg1 ().NumericByRefConst ().r4 ;
183+
184+ if (val1 != val2)
185+ {
186+ if (!__isnand (val1))
187+ {
188+ float res = val1 < val2 ? val1 : val2;
189+ stack.SetResult_R4 (res);
190+ }
191+ else
192+ {
193+ stack.SetResult_R4 (val1);
194+ }
195+ }
196+ else
197+ {
198+ float res = (__signbitd (val2) != 0 ) ? val1 : val2;
199+ stack.SetResult_R8 (res);
200+ }
201+
202+ NANOCLR_NOCLEANUP_NOLABEL ();
203+ }
204+
81205HRESULT Library_nf_native_system_math_System_Math::Abs___STATIC__R8__R8 (CLR_RT_StackFrame &stack)
82206{
83207 NATIVE_PROFILE_CLR_CORE ();
@@ -820,6 +944,16 @@ HRESULT Library_nf_native_system_math_System_Math::Max___STATIC__R8__R8__R8(CLR_
820944 NANOCLR_NOCLEANUP ();
821945}
822946
947+ HRESULT Library_nf_native_system_math_System_Math::Max___STATIC__R4__R4__R4 (CLR_RT_StackFrame &stack)
948+ {
949+ NATIVE_PROFILE_CLR_CORE ();
950+ NANOCLR_HEADER ();
951+
952+ NANOCLR_SET_AND_LEAVE (stack.NotImplementedStub ());
953+
954+ NANOCLR_NOCLEANUP ();
955+ }
956+
823957HRESULT Library_nf_native_system_math_System_Math::Min___STATIC__R8__R8__R8 (CLR_RT_StackFrame &stack)
824958{
825959 NATIVE_PROFILE_CLR_CORE ();
@@ -830,6 +964,16 @@ HRESULT Library_nf_native_system_math_System_Math::Min___STATIC__R8__R8__R8(CLR_
830964 NANOCLR_NOCLEANUP ();
831965}
832966
967+ HRESULT Library_nf_native_system_math_System_Math::Min___STATIC__R4__R4__R4 (CLR_RT_StackFrame &stack)
968+ {
969+ NATIVE_PROFILE_CLR_CORE ();
970+ NANOCLR_HEADER ();
971+
972+ NANOCLR_SET_AND_LEAVE (stack.NotImplementedStub ());
973+
974+ NANOCLR_NOCLEANUP ();
975+ }
976+
833977HRESULT Library_nf_native_system_math_System_Math::Abs___STATIC__R8__R8 (CLR_RT_StackFrame &stack)
834978{
835979 NATIVE_PROFILE_CLR_CORE ();
0 commit comments