aboutsummaryrefslogtreecommitdiff
path: root/src/util.hpp
diff options
context:
space:
mode:
authorAndrea Orru <andrea@orru.io>2018-08-06 01:43:19 -0400
committerAndrea Orru <andrea@orru.io>2018-08-06 01:43:19 -0400
commitd2f5e57b68da0b16e5789ca19045ccbcb4ecfa8d (patch)
treee9fa3caec533a0d1e2b434868b2fde1f9240e5c8 /src/util.hpp
parent06614b3fa09954464c2e2f32756cacedc178a282 (diff)
parent63a23e848a62d5f167f8d5478de9766cb24aa6eb (diff)
downloadzig-d2f5e57b68da0b16e5789ca19045ccbcb4ecfa8d.tar.gz
zig-d2f5e57b68da0b16e5789ca19045ccbcb4ecfa8d.zip
Merge branch 'master' into zen_stdlib
Diffstat (limited to 'src/util.hpp')
-rw-r--r--src/util.hpp48
1 files changed, 40 insertions, 8 deletions
diff --git a/src/util.hpp b/src/util.hpp
index ae33cb84af..b0402137bd 100644
--- a/src/util.hpp
+++ b/src/util.hpp
@@ -31,6 +31,8 @@
#endif
+#include "softfloat.hpp"
+
#define BREAKPOINT __asm("int $0x03")
ATTRIBUTE_COLD
@@ -38,11 +40,11 @@ ATTRIBUTE_NORETURN
ATTRIBUTE_PRINTF(1, 2)
void zig_panic(const char *format, ...);
-ATTRIBUTE_COLD
-ATTRIBUTE_NORETURN
-static inline void zig_unreachable(void) {
- zig_panic("unreachable");
-}
+#ifdef WIN32
+#define __func__ __FUNCTION__
+#endif
+
+#define zig_unreachable() zig_panic("unreachable: %s:%s:%d", __FILE__, __func__, __LINE__)
#if defined(_MSC_VER)
static inline int clzll(unsigned long long mask) {
@@ -65,6 +67,11 @@ static inline int clzll(unsigned long long mask) {
template<typename T>
ATTRIBUTE_RETURNS_NOALIAS static inline T *allocate_nonzero(size_t count) {
+#ifndef NDEBUG
+ // make behavior when size == 0 portable
+ if (count == 0)
+ return nullptr;
+#endif
T *ptr = reinterpret_cast<T*>(malloc(count * sizeof(T)));
if (!ptr)
zig_panic("allocation failed");
@@ -73,6 +80,11 @@ ATTRIBUTE_RETURNS_NOALIAS static inline T *allocate_nonzero(size_t count) {
template<typename T>
ATTRIBUTE_RETURNS_NOALIAS static inline T *allocate(size_t count) {
+#ifndef NDEBUG
+ // make behavior when size == 0 portable
+ if (count == 0)
+ return nullptr;
+#endif
T *ptr = reinterpret_cast<T*>(calloc(count, sizeof(T)));
if (!ptr)
zig_panic("allocation failed");
@@ -93,9 +105,7 @@ static inline void safe_memcpy(T *dest, const T *src, size_t count) {
template<typename T>
static inline T *reallocate(T *old, size_t old_count, size_t new_count) {
- T *ptr = reinterpret_cast<T*>(realloc(old, new_count * sizeof(T)));
- if (!ptr)
- zig_panic("allocation failed");
+ T *ptr = reallocate_nonzero(old, old_count, new_count);
if (new_count > old_count) {
memset(&ptr[old_count], 0, (new_count - old_count) * sizeof(T));
}
@@ -104,6 +114,11 @@ static inline T *reallocate(T *old, size_t old_count, size_t new_count) {
template<typename T>
static inline T *reallocate_nonzero(T *old, size_t old_count, size_t new_count) {
+#ifndef NDEBUG
+ // make behavior when size == 0 portable
+ if (new_count == 0 && old == nullptr)
+ return nullptr;
+#endif
T *ptr = reinterpret_cast<T*>(realloc(old, new_count * sizeof(T)));
if (!ptr)
zig_panic("allocation failed");
@@ -152,4 +167,21 @@ static inline uint8_t log2_u64(uint64_t x) {
return (63 - clzll(x));
}
+static inline float16_t zig_double_to_f16(double x) {
+ float64_t y;
+ static_assert(sizeof(x) == sizeof(y), "");
+ memcpy(&y, &x, sizeof(x));
+ return f64_to_f16(y);
+}
+
+
+// Return value is safe to coerce to float even when |x| is NaN or Infinity.
+static inline double zig_f16_to_double(float16_t x) {
+ float64_t y = f16_to_f64(x);
+ double z;
+ static_assert(sizeof(y) == sizeof(z), "");
+ memcpy(&z, &y, sizeof(y));
+ return z;
+}
+
#endif