summaryrefslogtreecommitdiff
path: root/src/jit/utils.cpp
diff options
context:
space:
mode:
authorTanner Gooding <tagoo@outlook.com>2017-02-06 06:44:14 +0000
committerTanner Gooding <tagoo@outlook.com>2017-02-22 06:03:39 -0800
commit43ea736713dd1bf83957c8685a2f8a8a6d2ff88d (patch)
tree8052756f14de15c32de5580bdf40c032fe3420e8 /src/jit/utils.cpp
parent0b4e58ac7a455640a5410b6f647ca3044426ea56 (diff)
downloadcoreclr-43ea736713dd1bf83957c8685a2f8a8a6d2ff88d.tar.gz
coreclr-43ea736713dd1bf83957c8685a2f8a8a6d2ff88d.tar.bz2
coreclr-43ea736713dd1bf83957c8685a2f8a8a6d2ff88d.zip
Updating jit/valuenum to properly handle the single-precision versions of the math intrinsics.
Diffstat (limited to 'src/jit/utils.cpp')
-rw-r--r--src/jit/utils.cpp42
1 files changed, 41 insertions, 1 deletions
diff --git a/src/jit/utils.cpp b/src/jit/utils.cpp
index df5bd2bea6..bb76a730d9 100644
--- a/src/jit/utils.cpp
+++ b/src/jit/utils.cpp
@@ -1748,7 +1748,7 @@ double FloatingPointUtils::round(double x)
{
// 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 == ((double)((__int64)x)))
+ if (x == (double)((INT64)x))
{
return x;
}
@@ -1766,3 +1766,43 @@ double FloatingPointUtils::round(double x)
return _copysign(flrTempVal, x);
}
+
+// Windows x86 and Windows ARM/ARM64 may not define _copysignf() but they do define _copysign().
+// We will redirect the macro to this other functions if the macro is not defined for the platform.
+// This has the side effect of a possible implicit upcasting for arguments passed in and an explicit
+// downcasting for the _copysign() call.
+#if (defined(_TARGET_X86_) || defined(_TARGET_ARM_) || defined(_TARGET_ARM64_)) && !defined(FEATURE_PAL)
+
+#if !defined(_copysignf)
+#define _copysignf (float)_copysign
+#endif
+
+#endif
+
+// Rounds a single-precision floating-point value to the nearest integer,
+// and rounds midpoint values to the nearest even number.
+// Note this should align with classlib in floatsingle.cpp
+// Specializing for x86 using a x87 instruction is optional since
+// this outcome is identical across targets.
+float FloatingPointUtils::round(float x)
+{
+ // 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);
+}