aboutsummaryrefslogtreecommitdiff
path: root/src/stage1/softfloat.hpp
blob: 57e60a5fc07b75c24c008aec16425c1bea7c861b (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
/*
 * Copyright (c) 2017 Andrew Kelley
 *
 * This file is part of zig, which is MIT licensed.
 * See http://opensource.org/licenses/MIT
 */

#ifndef ZIG_SOFTFLOAT_HPP
#define ZIG_SOFTFLOAT_HPP

extern "C" {
#include "softfloat.h"
}

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;
}

static inline bool zig_f16_isNaN(float16_t a) {
    union { uint16_t ui; float16_t f; } uA;
    uA.f = a;
    return 0x7C00 < (uA.ui & 0x7FFF);
}

static inline bool zig_f128_isNaN(float128_t *aPtr) {
    uint64_t absA64 = aPtr->v[1] & UINT64_C(0x7FFFFFFFFFFFFFFF);
    return
        (UINT64_C(0x7FFF000000000000) < absA64)
            || ((absA64 == UINT64_C(0x7FFF000000000000)) && aPtr->v[0]);
}

#endif