-
Notifications
You must be signed in to change notification settings - Fork 58
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
sw/math: Add safe FP <--> INT conversions
- Loading branch information
Showing
2 changed files
with
128 additions
and
4 deletions.
There are no files selected for viewing
81 changes: 81 additions & 0 deletions
81
sw/deps/patches/musl/0003-sw-math-Add-safe-FP-INT-conversions.patch
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,81 @@ | ||
From eb96f4d7454a07498f571eb1ed18aa1db2413551 Mon Sep 17 00:00:00 2001 | ||
From: Luca Colagrande <[email protected]> | ||
Date: Mon, 23 Oct 2023 16:45:17 +0200 | ||
Subject: [PATCH] `sw/math`: Add safe FP <--> INT conversions | ||
|
||
--- | ||
src/internal/libm.h | 51 +++++++++++++++++++++++++++++++++++++++++---- | ||
1 file changed, 47 insertions(+), 4 deletions(-) | ||
|
||
diff --git a/src/internal/libm.h b/src/internal/libm.h | ||
index 72ad17d..60b9866 100644 | ||
--- a/src/internal/libm.h | ||
+++ b/src/internal/libm.h | ||
@@ -96,6 +96,47 @@ static int32_t converttoint(double_t); | ||
#define predict_false(x) (x) | ||
#endif | ||
|
||
+/* FPU fence to synchronize the FPU and integer core in Snitch. */ | ||
+inline void snrt_fpu_fence() { | ||
+ unsigned tmp; | ||
+ __asm__ volatile( | ||
+ "fmv.x.w %0, fa0\n" | ||
+ "mv %0, %0\n" | ||
+ : "+r"(tmp)::"memory"); | ||
+} | ||
+ | ||
+/* Synch-secure double to uint64 conversion functions. */ | ||
+static inline uint64_t asuint64(double f) { | ||
+ uint64_t result; | ||
+ snrt_fpu_fence(); | ||
+ result = *(uint64_t *)&f; | ||
+ return result; | ||
+} | ||
+ | ||
+/* Synch-secure float to uint conversion functions. */ | ||
+static inline uint64_t asuint(float f) { | ||
+ uint32_t result; | ||
+ snrt_fpu_fence(); | ||
+ result = *(uint32_t *)&f; | ||
+ return result; | ||
+} | ||
+ | ||
+/* Synch-secure uint64 to double conversion functions. */ | ||
+static inline double asdouble(uint64_t i) { | ||
+ double result; | ||
+ snrt_fpu_fence(); | ||
+ result = *(double *)&i; | ||
+ return result; | ||
+} | ||
+ | ||
+/* Synch-secure uint to float conversion functions. */ | ||
+static inline float asfloat(uint32_t i) { | ||
+ float result; | ||
+ snrt_fpu_fence(); | ||
+ result = *(float *)&i; | ||
+ return result; | ||
+} | ||
+ | ||
/* Evaluate an expression as the specified type. With standard excess | ||
precision handling a type cast or assignment is enough (with | ||
-ffloat-store an assignment is required, in old compilers argument | ||
@@ -187,10 +228,12 @@ static inline void fp_force_evall(long double x) | ||
} \ | ||
} while(0) | ||
|
||
-#define asuint(f) ((union{float _f; uint32_t _i;}){f})._i | ||
-#define asfloat(i) ((union{uint32_t _i; float _f;}){i})._f | ||
-#define asuint64(f) ((union{double _f; uint64_t _i;}){f})._i | ||
-#define asdouble(i) ((union{uint64_t _i; double _f;}){i})._f | ||
+// Unsafe in Snitch due to the decoupled FPU and integer | ||
+// arithmetic units. Use at your own risk. | ||
+#define asuint_unsafe(f) ((union{float _f; uint32_t _i;}){f})._i | ||
+#define asfloat_unsafe(i) ((union{uint32_t _i; float _f;}){i})._f | ||
+#define asuint64_unsafe(f) ((union{double _f; uint64_t _i;}){f})._i | ||
+#define asdouble_unsafe(i) ((union{uint64_t _i; double _f;}){i})._f | ||
|
||
#define EXTRACT_WORDS(hi,lo,d) \ | ||
do { \ | ||
-- | ||
2.28.0 | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters