#ifndef U_HALF_H
#define U_HALF_H
#include "pipe/p_compiler.h"
#include "util/u_math.h"
#include "util/half_float.h"
#ifdef __cplusplus
extern "C" {
#endif
static inline uint16_t
util_float_to_half(float f)
{
return _mesa_float_to_half(f);
}
static inline uint16_t
util_float_to_half_rtz(float f)
{
uint32_t sign_mask = 0x80000000;
uint32_t round_mask = ~0xfff;
uint32_t f32inf = 0xff << 23;
uint32_t f16inf = 0x1f << 23;
uint32_t sign;
union fi magic;
union fi f32;
uint16_t f16;
magic.ui = 0xf << 23;
f32.f = f;
sign = f32.ui & sign_mask;
f32.ui ^= sign;
if (f32.ui == f32inf) {
f16 = 0x7c00;
} else if (f32.ui > f32inf) {
f16 = 0x7e00;
} else {
f32.ui &= round_mask;
f32.f *= magic.f;
f32.ui -= round_mask;
if (f32.ui > f16inf)
f32.ui = f16inf - 1;
f16 = f32.ui >> 13;
}
f16 |= sign >> 16;
return f16;
}
static inline float
util_half_to_float(uint16_t f16)
{
union fi infnan;
union fi magic;
union fi f32;
infnan.ui = 0x8f << 23;
infnan.f = 65536.0f;
magic.ui = 0xef << 23;
f32.ui = (f16 & 0x7fff) << 13;
f32.f *= magic.f;
if (f32.f >= infnan.f)
f32.ui |= 0xff << 23;
f32.ui |= (uint32_t)(f16 & 0x8000) << 16;
return f32.f;
}
#ifdef __cplusplus
}
#endif
#endif