#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
#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;
udwords u;
double f;
} double_bits;
+#endif
typedef struct {
#if _YUGA_LITTLE_ENDIAN
#define HAS_80_BIT_LONG_DOUBLE 0
#endif
+#if CRT_HAS_FLOATING_POINT
typedef union {
uqwords u;
long double f;
#define COMPLEX_REAL(x) (x).real
#define COMPLEX_IMAGINARY(x) (x).imaginary
#endif
+#endif
#endif // INT_TYPES_H