summaryrefslogtreecommitdiffstats
path: root/src/gallium/auxiliary/util/u_half.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/gallium/auxiliary/util/u_half.h')
-rw-r--r--src/gallium/auxiliary/util/u_half.h55
1 files changed, 55 insertions, 0 deletions
diff --git a/src/gallium/auxiliary/util/u_half.h b/src/gallium/auxiliary/util/u_half.h
new file mode 100644
index 00000000000..464d43df8a0
--- /dev/null
+++ b/src/gallium/auxiliary/util/u_half.h
@@ -0,0 +1,55 @@
+#ifndef U_HALF_H
+#define U_HALF_H
+
+#include "pipe/p_compiler.h"
+
+extern uint32_t util_half_to_float_mantissa_table[2048];
+extern uint32_t util_half_to_float_exponent_table[64];
+extern uint32_t util_half_to_float_offset_table[64];
+extern uint16_t util_float_to_half_base_table[512];
+extern uint8_t util_float_to_half_shift_table[512];
+
+/*
+ * Note that if the half float is a signaling NaN, the x87 FPU will turn
+ * it into a quiet NaN immediately upon loading into a float.
+ *
+ * Additionally, denormals may be flushed to zero.
+ *
+ * To avoid this, use the floatui functions instead of the float ones
+ * when just doing conversion rather than computation on the resulting
+ * floats.
+ */
+
+static INLINE uint32_t
+util_half_to_floatui(half h)
+{
+ unsigned exp = h >> 10;
+ return util_half_to_float_mantissa_table[util_half_to_float_offset_table[exp] + (h & 0x3ff)]
+ + util_half_to_float_exponent_table[exp];
+}
+
+static INLINE float
+util_half_to_float(half h)
+{
+ union {float f; uint32_t v;} r;
+ r.v = util_half_to_floatui(h);
+ return r.f;
+}
+
+static INLINE half
+util_floatui_to_half(uint32_t v)
+{
+ unsigned signexp = v >> 23;
+ return util_float_to_half_base_table[signexp]
+ + ((v & 0x007fffff) >> util_float_to_half_shift_table[signexp]);
+}
+
+static INLINE half
+util_float_to_half(float f)
+{
+ union {float f; uint32_t v;} i;
+ i.f = f;
+ return util_floatui_to_half(i.v);
+}
+
+#endif /* U_HALF_H */