diff options
| author | Andrea Orru <andrea@orru.io> | 2018-08-06 01:43:19 -0400 |
|---|---|---|
| committer | Andrea Orru <andrea@orru.io> | 2018-08-06 01:43:19 -0400 |
| commit | d2f5e57b68da0b16e5789ca19045ccbcb4ecfa8d (patch) | |
| tree | e9fa3caec533a0d1e2b434868b2fde1f9240e5c8 /src/util.hpp | |
| parent | 06614b3fa09954464c2e2f32756cacedc178a282 (diff) | |
| parent | 63a23e848a62d5f167f8d5478de9766cb24aa6eb (diff) | |
| download | zig-d2f5e57b68da0b16e5789ca19045ccbcb4ecfa8d.tar.gz zig-d2f5e57b68da0b16e5789ca19045ccbcb4ecfa8d.zip | |
Merge branch 'master' into zen_stdlib
Diffstat (limited to 'src/util.hpp')
| -rw-r--r-- | src/util.hpp | 48 |
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 |
