+
/*
* Copyright 2010 Luca Barbieri
*
uint16_t util_float_to_half_base_table[512];
uint8_t util_float_to_half_shift_table[512];
-static void util_half_init_tables(void)
+static void
+util_half_init_tables(void)
{
- int i;
-
- /* zero */
- util_half_to_float_mantissa_table[0] = 0;
-
- /* denormals */
- for(i = 1; i < 1024; ++i) {
- unsigned int m = i << 13;
- unsigned int e = 0;
-
- /* Normalize number */
- while(!(m & 0x00800000)) {
- e -= 0x00800000;
- m<<=1;
- }
- m &= ~0x00800000;
- e+= 0x38800000;
- util_half_to_float_mantissa_table[i] = m | e;
- }
-
- /* normals */
- for(i = 1024; i < 2048; ++i)
- util_half_to_float_mantissa_table[i] = ((i-1024)<<13);
-
- /* positive zero or denormals */
- util_half_to_float_exponent_table[0] = 0;
-
- /* positive numbers */
- for(i = 1; i <= 30; ++i)
- util_half_to_float_exponent_table[i] = 0x38000000 + (i << 23);
-
- /* positive infinity/NaN */
- util_half_to_float_exponent_table[31] = 0x7f800000;
-
- /* negative zero or denormals */
- util_half_to_float_exponent_table[32] = 0x80000000;
-
- /* negative numbers */
- for(i = 33; i <= 62; ++i)
- util_half_to_float_exponent_table[i] = 0xb8000000 + ((i - 32) << 23);
-
- /* negative infinity/NaN */
- util_half_to_float_exponent_table[63] = 0xff800000;
-
- /* positive zero or denormals */
- util_half_to_float_offset_table[0] = 0;
-
- /* positive normals */
- for(i = 1; i < 32; ++i)
- util_half_to_float_offset_table[i] = 1024;
-
- /* negative zero or denormals */
- util_half_to_float_offset_table[32] = 0;
-
- /* negative normals */
- for(i = 33; i < 64; ++i)
- util_half_to_float_offset_table[i] = 1024;
-
-
-
- /* very small numbers mapping to zero */
- for(i = -127; i < -24; ++i) {
- util_float_to_half_base_table[127 + i] = 0;
- util_float_to_half_shift_table[127 + i] = 24;
- }
-
- /* small numbers mapping to denormals */
- for(i = -24; i < -14; ++i) {
- util_float_to_half_base_table[127 + i] = 0x0400 >> (-14 - i);
- util_float_to_half_shift_table[127 + i] = -i - 1;
- }
-
- /* normal numbers */
- for(i = -14; i < 16; ++i) {
- util_float_to_half_base_table[127 + i] = (i + 15) << 10;
- util_float_to_half_shift_table[127 + i] = 13;
- }
-
- /* large numbers mapping to infinity */
- for(i = 16; i < 128; ++i) {
- util_float_to_half_base_table[127 + i] = 0x7c00;
- util_float_to_half_shift_table[127 + i] = 24;
- }
-
- /* infinity and NaNs */
- util_float_to_half_base_table[255] = 0x7c00;
- util_float_to_half_shift_table[255] = 13;
-
- /* negative numbers */
- for(i = 0; i < 256; ++i) {
- util_float_to_half_base_table[256 + i] = util_float_to_half_base_table[i] | 0x8000;
- util_float_to_half_shift_table[256 + i] = util_float_to_half_shift_table[i];
- }
+ int i;
+
+ /* zero */
+ util_half_to_float_mantissa_table[0] = 0;
+
+ /* denormals */
+ for(i = 1; i < 1024; ++i)
+ {
+ unsigned int m = i << 13;
+ unsigned int e = 0;
+
+ /* Normalize number */
+ while(!(m & 0x00800000))
+ {
+ e -= 0x00800000;
+ m <<= 1;
+ }
+ m &= ~0x00800000;
+ e += 0x38800000;
+ util_half_to_float_mantissa_table[i] = m | e;
+ }
+
+ /* normals */
+ for(i = 1024; i < 2048; ++i)
+ util_half_to_float_mantissa_table[i] = ((i - 1024) << 13);
+
+ /* positive zero or denormals */
+ util_half_to_float_exponent_table[0] = 0;
+
+ /* positive numbers */
+ for(i = 1; i <= 30; ++i)
+ util_half_to_float_exponent_table[i] = 0x38000000 + (i << 23);
+
+ /* positive infinity/NaN */
+ util_half_to_float_exponent_table[31] = 0x7f800000;
+
+ /* negative zero or denormals */
+ util_half_to_float_exponent_table[32] = 0x80000000;
+
+ /* negative numbers */
+ for(i = 33; i <= 62; ++i)
+ util_half_to_float_exponent_table[i] = 0xb8000000 + ((i - 32) << 23);
+
+ /* negative infinity/NaN */
+ util_half_to_float_exponent_table[63] = 0xff800000;
+
+ /* positive zero or denormals */
+ util_half_to_float_offset_table[0] = 0;
+
+ /* positive normals */
+ for(i = 1; i < 32; ++i)
+ util_half_to_float_offset_table[i] = 1024;
+
+ /* negative zero or denormals */
+ util_half_to_float_offset_table[32] = 0;
+
+ /* negative normals */
+ for(i = 33; i < 64; ++i)
+ util_half_to_float_offset_table[i] = 1024;
+
+ /* very small numbers mapping to zero */
+ for(i = -127; i < -24; ++i)
+ {
+ util_float_to_half_base_table[127 + i] = 0;
+ util_float_to_half_shift_table[127 + i] = 24;
+ }
+
+ /* small numbers mapping to denormals */
+ for(i = -24; i < -14; ++i)
+ {
+ util_float_to_half_base_table[127 + i] = 0x0400 >> (-14 - i);
+ util_float_to_half_shift_table[127 + i] = -i - 1;
+ }
+
+ /* normal numbers */
+ for(i = -14; i < 16; ++i)
+ {
+ util_float_to_half_base_table[127 + i] = (i + 15) << 10;
+ util_float_to_half_shift_table[127 + i] = 13;
+ }
+
+ /* large numbers mapping to infinity */
+ for(i = 16; i < 128; ++i)
+ {
+ util_float_to_half_base_table[127 + i] = 0x7c00;
+ util_float_to_half_shift_table[127 + i] = 24;
+ }
+
+ /* infinity and NaNs */
+ util_float_to_half_base_table[255] = 0x7c00;
+ util_float_to_half_shift_table[255] = 13;
+
+ /* negative numbers */
+ for(i = 0; i < 256; ++i)
+ {
+ util_float_to_half_base_table[256 + i] = util_float_to_half_base_table[i] | 0x8000;
+ util_float_to_half_shift_table[256 + i] = util_float_to_half_shift_table[i];
+ }
}
UTIL_INIT(util_half_init_tables);
extern "C" {
#endif
-
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];
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];
+ 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 fi r;
- r.ui = util_half_to_floatui(h);
- return r.f;
+ union fi r;
+ r.ui = 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]);
+ 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 fi i;
- i.f = f;
- return util_floatui_to_half(i.ui);
+ union fi i;
+ i.f = f;
+ return util_floatui_to_half(i.ui);
}
#ifdef __cplusplus
#endif
#endif /* U_HALF_H */
+