1// Licensed to the .NET Foundation under one or more agreements.
2// The .NET Foundation licenses this file to you under the MIT license.
3// See the LICENSE file in the project root for more information.
4//
5// File: FloatDouble.cpp
6//
7
8#include <common.h>
9
10#include "floatdouble.h"
11
12// The default compilation mode is /fp:precise, which disables floating-point intrinsics. This
13// default compilation mode has previously caused performance regressions in floating-point code.
14// We enable /fp:fast semantics for the majority of the math functions, as it will speed up performance
15// and is really unlikely to cause any other code regressions.
16
17// Sin, Cos, and Tan on AMD64 Windows were previously implemented in vm\amd64\JitHelpers_Fast.asm
18// by calling x87 floating point code (fsin, fcos, fptan) because the CRT helpers were too slow. This
19// is no longer the case and the CRT call is used on all platforms.
20
21// Log, Log10 and Exp were previously slower with /fp:fast on SSE2 enabled hardware (see #500373).
22// This is no longer the case and they now consume use the /fp:fast versions.
23
24// Exp(+/-INFINITY) did not previously return the expected results of +0.0 (for -INFINITY)
25// and +INFINITY (for +INFINITY) so these cases were handled specially. As this is no longer
26// the case and the expected results are now returned, the special handling has been removed.
27
28// Previously there was more special handling for the x86 Windows version of Pow.
29// This additional handling was unnecessary and has since been removed.
30
31////////////////////////////////////////////////////////////////////////////////////
32////////////////////////////////////////////////////////////////////////////////////
33////////////////////////////////////////////////////////////////////////////////////
34///
35/// beginning of /fp:fast scope
36///
37////////////////////////////////////////////////////////////////////////////////////
38////////////////////////////////////////////////////////////////////////////////////
39////////////////////////////////////////////////////////////////////////////////////
40
41#ifdef _MSC_VER
42#pragma float_control(push)
43#pragma float_control(precise, off)
44#endif
45
46/*=====================================Abs======================================
47**
48==============================================================================*/
49FCIMPL1_V(double, COMDouble::Abs, double x)
50 FCALL_CONTRACT;
51
52 return (double)fabs(x);
53FCIMPLEND
54
55/*=====================================Acos=====================================
56**
57==============================================================================*/
58FCIMPL1_V(double, COMDouble::Acos, double x)
59 FCALL_CONTRACT;
60
61 return (double)acos(x);
62FCIMPLEND
63
64/*=====================================Acosh====================================
65**
66==============================================================================*/
67FCIMPL1_V(double, COMDouble::Acosh, double x)
68 FCALL_CONTRACT;
69
70 return (double)acosh(x);
71FCIMPLEND
72
73/*=====================================Asin=====================================
74**
75==============================================================================*/
76FCIMPL1_V(double, COMDouble::Asin, double x)
77 FCALL_CONTRACT;
78
79 return (double)asin(x);
80FCIMPLEND
81
82/*=====================================Asinh====================================
83**
84==============================================================================*/
85FCIMPL1_V(double, COMDouble::Asinh, double x)
86 FCALL_CONTRACT;
87
88 return (double)asinh(x);
89FCIMPLEND
90
91/*=====================================Atan=====================================
92**
93==============================================================================*/
94FCIMPL1_V(double, COMDouble::Atan, double x)
95 FCALL_CONTRACT;
96
97 return (double)atan(x);
98FCIMPLEND
99
100/*=====================================Atanh====================================
101**
102==============================================================================*/
103FCIMPL1_V(double, COMDouble::Atanh, double x)
104 FCALL_CONTRACT;
105
106 return (double)atanh(x);
107FCIMPLEND
108
109/*=====================================Atan2====================================
110**
111==============================================================================*/
112FCIMPL2_VV(double, COMDouble::Atan2, double y, double x)
113 FCALL_CONTRACT;
114
115 return (double)atan2(y, x);
116FCIMPLEND
117
118/*====================================Cbrt======================================
119**
120==============================================================================*/
121FCIMPL1_V(double, COMDouble::Cbrt, double x)
122 FCALL_CONTRACT;
123
124 return (double)cbrt(x);
125FCIMPLEND
126
127#if defined(_MSC_VER) && defined(_TARGET_AMD64_)
128// The /fp:fast form of `ceil` for AMD64 does not correctly handle: `-1.0 < value <= -0.0`
129// https://github.com/dotnet/coreclr/issues/19739
130#pragma float_control(push)
131#pragma float_control(precise, on)
132#endif
133
134/*====================================Ceil======================================
135**
136==============================================================================*/
137FCIMPL1_V(double, COMDouble::Ceil, double x)
138 FCALL_CONTRACT;
139
140 return (double)ceil(x);
141FCIMPLEND
142
143#if defined(_MSC_VER) && defined(_TARGET_AMD64_)
144#pragma float_control(pop)
145#endif
146
147/*=====================================Cos======================================
148**
149==============================================================================*/
150FCIMPL1_V(double, COMDouble::Cos, double x)
151 FCALL_CONTRACT;
152
153 return (double)cos(x);
154FCIMPLEND
155
156/*=====================================Cosh=====================================
157**
158==============================================================================*/
159FCIMPL1_V(double, COMDouble::Cosh, double x)
160 FCALL_CONTRACT;
161
162 return (double)cosh(x);
163FCIMPLEND
164
165/*=====================================Exp======================================
166**
167==============================================================================*/
168FCIMPL1_V(double, COMDouble::Exp, double x)
169 FCALL_CONTRACT;
170
171 return (double)exp(x);
172FCIMPLEND
173
174#if defined(_MSC_VER) && defined(_TARGET_X86_)
175// The /fp:fast form of `floor` for x86 does not correctly handle: `-0.0`
176// https://github.com/dotnet/coreclr/issues/19739
177#pragma float_control(push)
178#pragma float_control(precise, on)
179#endif
180
181/*====================================Floor=====================================
182**
183==============================================================================*/
184FCIMPL1_V(double, COMDouble::Floor, double x)
185 FCALL_CONTRACT;
186
187 return (double)floor(x);
188FCIMPLEND
189
190#if defined(_MSC_VER) && defined(_TARGET_X86_)
191#pragma float_control(pop)
192#endif
193
194/*=====================================FMod=====================================
195**
196==============================================================================*/
197FCIMPL2_VV(double, COMDouble::FMod, double x, double y)
198 FCALL_CONTRACT;
199
200 return (double)fmod(x, y);
201FCIMPLEND
202
203/*=====================================FusedMultiplyAdd==========================
204**
205==============================================================================*/
206FCIMPL3_VVV(double, COMDouble::FusedMultiplyAdd, double x, double y, double z)
207 FCALL_CONTRACT;
208
209 return (double)fma(x, y, z);
210FCIMPLEND
211
212/*=====================================Ilog2====================================
213**
214==============================================================================*/
215FCIMPL1_V(int, COMDouble::ILogB, double x)
216 FCALL_CONTRACT;
217
218 return (int)ilogb(x);
219FCIMPLEND
220
221/*=====================================Log======================================
222**
223==============================================================================*/
224FCIMPL1_V(double, COMDouble::Log, double x)
225 FCALL_CONTRACT;
226
227 return (double)log(x);
228FCIMPLEND
229
230/*=====================================Log2=====================================
231**
232==============================================================================*/
233FCIMPL1_V(double, COMDouble::Log2, double x)
234 FCALL_CONTRACT;
235
236 return (double)log2(x);
237FCIMPLEND
238
239/*====================================Log10=====================================
240**
241==============================================================================*/
242FCIMPL1_V(double, COMDouble::Log10, double x)
243 FCALL_CONTRACT;
244
245 return (double)log10(x);
246FCIMPLEND
247
248/*=====================================ModF=====================================
249**
250==============================================================================*/
251FCIMPL2_VI(double, COMDouble::ModF, double x, double* intptr)
252 FCALL_CONTRACT;
253
254 return (double)modf(x, intptr);
255FCIMPLEND
256
257/*=====================================Pow======================================
258**
259==============================================================================*/
260FCIMPL2_VV(double, COMDouble::Pow, double x, double y)
261 FCALL_CONTRACT;
262
263 return (double)pow(x, y);
264FCIMPLEND
265
266/*=====================================ScaleB===================================
267**
268==============================================================================*/
269FCIMPL2_VI(double, COMDouble::ScaleB, double x, int n)
270 FCALL_CONTRACT;
271
272 return (double)scalbn(x, n);
273FCIMPLEND
274
275/*=====================================Sin======================================
276**
277==============================================================================*/
278FCIMPL1_V(double, COMDouble::Sin, double x)
279 FCALL_CONTRACT;
280
281 return (double)sin(x);
282FCIMPLEND
283
284/*=====================================Sinh=====================================
285**
286==============================================================================*/
287FCIMPL1_V(double, COMDouble::Sinh, double x)
288 FCALL_CONTRACT;
289
290 return (double)sinh(x);
291FCIMPLEND
292
293/*=====================================Sqrt=====================================
294**
295==============================================================================*/
296FCIMPL1_V(double, COMDouble::Sqrt, double x)
297 FCALL_CONTRACT;
298
299 return (double)sqrt(x);
300FCIMPLEND
301
302/*=====================================Tan======================================
303**
304==============================================================================*/
305FCIMPL1_V(double, COMDouble::Tan, double x)
306 FCALL_CONTRACT;
307
308 return (double)tan(x);
309FCIMPLEND
310
311/*=====================================Tanh=====================================
312**
313==============================================================================*/
314FCIMPL1_V(double, COMDouble::Tanh, double x)
315 FCALL_CONTRACT;
316
317 return (double)tanh(x);
318FCIMPLEND
319
320#ifdef _MSC_VER
321#pragma float_control(pop)
322#endif
323
324////////////////////////////////////////////////////////////////////////////////////
325////////////////////////////////////////////////////////////////////////////////////
326////////////////////////////////////////////////////////////////////////////////////
327///
328/// End of /fp:fast scope
329///
330////////////////////////////////////////////////////////////////////////////////////
331////////////////////////////////////////////////////////////////////////////////////
332////////////////////////////////////////////////////////////////////////////////////
333