u_half.h revision c476305cdeb1ca9d755983e2058cb44f5b9109f0
17935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert#ifndef U_HALF_H 27935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert#define U_HALF_H 37935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 47935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert#include "pipe/p_compiler.h" 57935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert#include "util/u_math.h" 67935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 77935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert#ifdef __cplusplus 87935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubertextern "C" { 97935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert#endif 107935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 117935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubertextern uint32_t util_half_to_float_mantissa_table[2048]; 127935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubertextern uint32_t util_half_to_float_exponent_table[64]; 137935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubertextern uint32_t util_half_to_float_offset_table[64]; 147935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubertextern uint16_t util_float_to_half_base_table[512]; 157935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubertextern uint8_t util_float_to_half_shift_table[512]; 167935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 177935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert/* 187935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * Note that if the half float is a signaling NaN, the x87 FPU will turn 197935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * it into a quiet NaN immediately upon loading into a float. 207935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * 217935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * Additionally, denormals may be flushed to zero. 227935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * 237935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * To avoid this, use the floatui functions instead of the float ones 247935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * when just doing conversion rather than computation on the resulting 257935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * floats. 267935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert */ 277935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 287935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubertstatic INLINE uint32_t 297935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubertutil_half_to_floatui(half h) 307935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert{ 317935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert unsigned exp = h >> 10; 327935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert return util_half_to_float_mantissa_table[util_half_to_float_offset_table[exp] + (h & 0x3ff)] + util_half_to_float_exponent_table[exp]; 337935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert} 347935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 357935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubertstatic INLINE float 367935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubertutil_half_to_float(half h) 377935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert{ 387935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert union fi r; 397935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert r.ui = util_half_to_floatui(h); 407935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert return r.f; 417935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert} 427935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 437935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubertstatic INLINE half 447935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubertutil_floatui_to_half(uint32_t v) 457935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert{ 467935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert unsigned signexp = v >> 23; 477935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert return util_float_to_half_base_table[signexp] + ((v & 0x007fffff) >> util_float_to_half_shift_table[signexp]); 487935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert} 497935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 507935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubertstatic INLINE half 517935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubertutil_float_to_half(float f) 527935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert{ 537935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert union fi i; 547935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert i.f = f; 557935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert return util_floatui_to_half(i.ui); 567935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert} 577935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 587935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert#ifdef __cplusplus 597935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert} 607935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert#endif 617935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 627935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert#endif /* U_HALF_H */ 637935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 647935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert