gallium/util: rewrite global constructor system for half floats (GCC/MSVC only!)
[mesa.git] / src / gallium / auxiliary / util / u_half.h
1 #ifndef U_HALF_H
2 #define U_HALF_H
3
4 #include "pipe/p_compiler.h"
5 #include "u_math.h"
6
7 #ifdef __cplusplus
8 extern "C" {
9 #endif
10
11
12 extern uint32_t util_half_to_float_mantissa_table[2048];
13 extern uint32_t util_half_to_float_exponent_table[64];
14 extern uint32_t util_half_to_float_offset_table[64];
15 extern uint16_t util_float_to_half_base_table[512];
16 extern uint8_t util_float_to_half_shift_table[512];
17
18 /*
19 * Note that if the half float is a signaling NaN, the x87 FPU will turn
20 * it into a quiet NaN immediately upon loading into a float.
21 *
22 * Additionally, denormals may be flushed to zero.
23 *
24 * To avoid this, use the floatui functions instead of the float ones
25 * when just doing conversion rather than computation on the resulting
26 * floats.
27 */
28
29 static INLINE uint32_t
30 util_half_to_floatui(half h)
31 {
32 unsigned exp = h >> 10;
33 return util_half_to_float_mantissa_table[util_half_to_float_offset_table[exp] + (h & 0x3ff)]
34 + util_half_to_float_exponent_table[exp];
35 }
36
37 static INLINE float
38 util_half_to_float(half h)
39 {
40 union fi r;
41 r.ui = util_half_to_floatui(h);
42 return r.f;
43 }
44
45 static INLINE half
46 util_floatui_to_half(uint32_t v)
47 {
48 unsigned signexp = v >> 23;
49 return util_float_to_half_base_table[signexp]
50 + ((v & 0x007fffff) >> util_float_to_half_shift_table[signexp]);
51 }
52
53 static INLINE half
54 util_float_to_half(float f)
55 {
56 union fi i;
57 i.f = f;
58 return util_floatui_to_half(i.ui);
59 }
60
61 #ifdef __cplusplus
62 }
63 #endif
64
65 #endif /* U_HALF_H */