[compiler-rt] Support FreeBSD standalone (boot) environment
authorJessica Clarke <jrtc27@jrtc27.com>
Wed, 27 Jan 2021 15:28:59 +0000 (15:28 +0000)
committerJessica Clarke <jrtc27@jrtc27.com>
Wed, 27 Jan 2021 15:29:39 +0000 (15:29 +0000)
FreeBSD uses -Ddouble=jagged-little-pill -Dfloat=floaty-mcfloatface to
poison uses of floating point in its standalone environment. It also
deprecates machine/limits.h in favour of sys/limits.h and does not even
provide the former on newer architectures.

This is a cleaner reimplementation of equivalent patches in FreeBSD's
vendored copy of compiler-rt.

Reviewed By: dim

Differential Revision: https://reviews.llvm.org/D95264

compiler-rt/lib/builtins/int_lib.h
compiler-rt/lib/builtins/int_types.h

index 991c4a9..a371589 100644 (file)
 #error Unsupported target
 #endif
 
-#if defined(__NetBSD__) && (defined(_KERNEL) || defined(_STANDALONE))
+#if (defined(__FreeBSD__) || defined(__NetBSD__)) &&                           \
+    (defined(_KERNEL) || defined(_STANDALONE))
 //
 // Kernel and boot environment can't use normal headers,
 // so use the equivalent system headers.
+// NB: FreeBSD (and OpenBSD) deprecate machine/limits.h in
+// favour of sys/limits.h, so prefer the former, but fall
+// back on the latter if not available since NetBSD only has
+// the latter.
 //
+#if defined(__has_include) && __has_include(<sys/limits.h>)
+#include <sys/limits.h>
+#else
 #include <machine/limits.h>
+#endif
 #include <sys/stdint.h>
 #include <sys/types.h>
 #else
index 705355a..7a72de4 100644 (file)
@@ -121,6 +121,15 @@ static __inline tu_int make_tu(du_int h, du_int l) {
 
 #endif // CRT_HAS_128BIT
 
+// FreeBSD's boot environment does not support using floating-point and poisons
+// the float and double keywords.
+#if defined(__FreeBSD__) && defined(_STANDALONE)
+#define CRT_HAS_FLOATING_POINT 0
+#else
+#define CRT_HAS_FLOATING_POINT 1
+#endif
+
+#if CRT_HAS_FLOATING_POINT
 typedef union {
   su_int u;
   float f;
@@ -130,6 +139,7 @@ typedef union {
   udwords u;
   double f;
 } double_bits;
+#endif
 
 typedef struct {
 #if _YUGA_LITTLE_ENDIAN
@@ -155,6 +165,7 @@ typedef struct {
 #define HAS_80_BIT_LONG_DOUBLE 0
 #endif
 
+#if CRT_HAS_FLOATING_POINT
 typedef union {
   uqwords u;
   long double f;
@@ -183,4 +194,5 @@ typedef struct {
 #define COMPLEX_REAL(x) (x).real
 #define COMPLEX_IMAGINARY(x) (x).imaginary
 #endif
+#endif
 #endif // INT_TYPES_H