[compiler-rt] Support FreeBSD standalone (boot) environment

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

GitOrigin-RevId: add98b2462906a8b81f425cc820c0d165bf6ceca
diff --git a/lib/builtins/int_lib.h b/lib/builtins/int_lib.h
index 991c4a9..a371589 100644
--- a/lib/builtins/int_lib.h
+++ b/lib/builtins/int_lib.h
@@ -70,12 +70,21 @@
 #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
diff --git a/lib/builtins/int_types.h b/lib/builtins/int_types.h
index 705355a..7a72de4 100644
--- a/lib/builtins/int_types.h
+++ b/lib/builtins/int_types.h
@@ -121,6 +121,15 @@
 
 #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 @@
   udwords u;
   double f;
 } double_bits;
+#endif
 
 typedef struct {
 #if _YUGA_LITTLE_ENDIAN
@@ -155,6 +165,7 @@
 #define HAS_80_BIT_LONG_DOUBLE 0
 #endif
 
+#if CRT_HAS_FLOATING_POINT
 typedef union {
   uqwords u;
   long double f;
@@ -183,4 +194,5 @@
 #define COMPLEX_REAL(x) (x).real
 #define COMPLEX_IMAGINARY(x) (x).imaginary
 #endif
+#endif
 #endif // INT_TYPES_H