diff options
Diffstat (limited to 'src/gallium/auxiliary/util')
-rw-r--r-- | src/gallium/auxiliary/util/u_half.c | 195 | ||||
-rw-r--r-- | src/gallium/auxiliary/util/u_half.h | 24 |
2 files changed, 112 insertions, 107 deletions
diff --git a/src/gallium/auxiliary/util/u_half.c b/src/gallium/auxiliary/util/u_half.c index 4611b201b95..96b83e5ac00 100644 --- a/src/gallium/auxiliary/util/u_half.c +++ b/src/gallium/auxiliary/util/u_half.c @@ -1,3 +1,4 @@ + /* * Copyright 2010 Luca Barbieri * @@ -58,101 +59,107 @@ uint32_t util_half_to_float_offset_table[64]; 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); diff --git a/src/gallium/auxiliary/util/u_half.h b/src/gallium/auxiliary/util/u_half.h index 5afdd925a62..4b80d45b919 100644 --- a/src/gallium/auxiliary/util/u_half.h +++ b/src/gallium/auxiliary/util/u_half.h @@ -8,7 +8,6 @@ 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]; @@ -29,33 +28,31 @@ extern uint8_t util_float_to_half_shift_table[512]; 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 @@ -63,3 +60,4 @@ util_float_to_half(float f) #endif #endif /* U_HALF_H */ + |