summaryrefslogtreecommitdiff
path: root/zephyr/fpu.cmake
diff options
context:
space:
mode:
authorYuval Peress <peress@chromium.org>2021-09-01 20:55:45 -0600
committerCommit Bot <commit-bot@chromium.org>2021-09-03 19:52:46 +0000
commit0c0ba0a2b1297fa9bb1c47da95c220ae1df3b9e2 (patch)
tree6870edf030f696d8a61053c4cc1aee6ff263b51d /zephyr/fpu.cmake
parenta42b82561483d046b08bb177b02393104ce88c0b (diff)
downloadchrome-ec-0c0ba0a2b1297fa9bb1c47da95c220ae1df3b9e2.tar.gz
test: accel_cal: fix for gitlab
Fix a rounding error. See documentation for details. It is important to include the detailed documentation as it provides strong details for why these flags are necessary. It will avoid confusion in the future. BRANCH=none BUG=b:178731498 TEST=zmake configure --test zephyr/test/accel_cal (both in chroot and in gitlab docker). Change-Id: Ie040f49dfaacb84dc10b76481a16213be6a2f09e Signed-off-by: Yuval Peress <peress@chromium.org> Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/3139254 Reviewed-by: Jeremy Bettis <jbettis@chromium.org> Reviewed-by: Paul Fagerburg <pfagerburg@chromium.org>
Diffstat (limited to 'zephyr/fpu.cmake')
-rw-r--r--zephyr/fpu.cmake42
1 files changed, 42 insertions, 0 deletions
diff --git a/zephyr/fpu.cmake b/zephyr/fpu.cmake
new file mode 100644
index 0000000000..ddf782e5c8
--- /dev/null
+++ b/zephyr/fpu.cmake
@@ -0,0 +1,42 @@
+# Copyright 2021 The Chromium OS Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+#[[
+Disclaimer: the following example is pieced together from
+https://lemire.me/blog/2020/06/26/gcc-not-nearest/ along with other information
+found in GCC documentation.
+
+The following flags are needed to to ensure consistent FPU rounding in unit
+tests. For example using GNU GCC 7.5 rounds down. Note that at the time of
+writing, Clang 13.0.0 passes all the FPU unit tests without these flags.
+
+Some of the sensor logic which requires FPU support is susceptible to rounding
+errors. In GCC 7.5, as an example:
+
+ double x = 50178230318.0;
+ double y = 100000000000.0;
+ double ratio = x/y;
+
+In this example, we would expect ratio to be 0.50178230318. Instead, using a
+64-bit float, it falls between:
+* The floating-point number 0.501782303179999944 == 4519653187245114 * 2 ** -53
+* The floating-point number 0.501782303180000055 == 4519653187245115 * 2 ** -53
+
+The real mantissa using the same logic should be:
+0.50178230318 = 4519653187245114.50011795456 * 2 ** -53
+
+Since the mantissa's decimal is just over 0.5, it should stand to reason that
+the correct solution is 0.501782303180000055. To force GCC to round correctly
+we must set the following modes:
+1. 'sse' - Generate SSE instructions.
+2. 'fpmath=sse' - Use scalar floating-point instructions present in the SSE
+ instruction set.
+3. 'arch=pentium4' - Choose the Pentium4 because it's a stable choice that
+ supports SSE and is known to work (there may be other good choices).
+]]
+if(DEFINED CONFIG_SOC_POSIX)
+ set(FLOAT_FLAGS "-msse -mfpmath=sse -march=pentium4")
+ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${FLOAT_FLAGS}")
+ set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${FLOAT_FLAGS}")
+endif()