1783e94243a46e5d11d9db51924839a1c64a281bcJosé Fonseca/************************************************************************** 2783e94243a46e5d11d9db51924839a1c64a281bcJosé Fonseca * 3783e94243a46e5d11d9db51924839a1c64a281bcJosé Fonseca * Copyright 2010 Luca Barbieri 4783e94243a46e5d11d9db51924839a1c64a281bcJosé Fonseca * 5783e94243a46e5d11d9db51924839a1c64a281bcJosé Fonseca * Permission is hereby granted, free of charge, to any person obtaining 6783e94243a46e5d11d9db51924839a1c64a281bcJosé Fonseca * a copy of this software and associated documentation files (the 7783e94243a46e5d11d9db51924839a1c64a281bcJosé Fonseca * "Software"), to deal in the Software without restriction, including 8783e94243a46e5d11d9db51924839a1c64a281bcJosé Fonseca * without limitation the rights to use, copy, modify, merge, publish, 9783e94243a46e5d11d9db51924839a1c64a281bcJosé Fonseca * distribute, sublicense, and/or sell copies of the Software, and to 10783e94243a46e5d11d9db51924839a1c64a281bcJosé Fonseca * permit persons to whom the Software is furnished to do so, subject to 11783e94243a46e5d11d9db51924839a1c64a281bcJosé Fonseca * the following conditions: 12783e94243a46e5d11d9db51924839a1c64a281bcJosé Fonseca * 13783e94243a46e5d11d9db51924839a1c64a281bcJosé Fonseca * The above copyright notice and this permission notice (including the 14783e94243a46e5d11d9db51924839a1c64a281bcJosé Fonseca * next paragraph) shall be included in all copies or substantial 15783e94243a46e5d11d9db51924839a1c64a281bcJosé Fonseca * portions of the Software. 16783e94243a46e5d11d9db51924839a1c64a281bcJosé Fonseca * 17783e94243a46e5d11d9db51924839a1c64a281bcJosé Fonseca * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 18783e94243a46e5d11d9db51924839a1c64a281bcJosé Fonseca * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 19783e94243a46e5d11d9db51924839a1c64a281bcJosé Fonseca * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 20783e94243a46e5d11d9db51924839a1c64a281bcJosé Fonseca * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE 21783e94243a46e5d11d9db51924839a1c64a281bcJosé Fonseca * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 22783e94243a46e5d11d9db51924839a1c64a281bcJosé Fonseca * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 23783e94243a46e5d11d9db51924839a1c64a281bcJosé Fonseca * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 24783e94243a46e5d11d9db51924839a1c64a281bcJosé Fonseca * 25783e94243a46e5d11d9db51924839a1c64a281bcJosé Fonseca **************************************************************************/ 26783e94243a46e5d11d9db51924839a1c64a281bcJosé Fonseca 27783e94243a46e5d11d9db51924839a1c64a281bcJosé Fonseca 283ff175d6de89ad92d167362355501f99d06f0f97Luca Barbieri#ifndef U_HALF_H 293ff175d6de89ad92d167362355501f99d06f0f97Luca Barbieri#define U_HALF_H 303ff175d6de89ad92d167362355501f99d06f0f97Luca Barbieri 313ff175d6de89ad92d167362355501f99d06f0f97Luca Barbieri#include "pipe/p_compiler.h" 32aee5bb5b8ad80d4aed849519a80b1d696991e866Luca Barbieri#include "util/u_math.h" 333ff175d6de89ad92d167362355501f99d06f0f97Luca Barbieri 3489034b8ae71ca12f9a12935807a33caa686ede00José Fonseca#ifdef __cplusplus 3589034b8ae71ca12f9a12935807a33caa686ede00José Fonsecaextern "C" { 3689034b8ae71ca12f9a12935807a33caa686ede00José Fonseca#endif 3789034b8ae71ca12f9a12935807a33caa686ede00José Fonseca 383ff175d6de89ad92d167362355501f99d06f0f97Luca Barbieri/* 396dd8e6f9cbca63b222fe4a1c2c49ddb53e75999eJames Benton * References for float <-> half conversions 403ff175d6de89ad92d167362355501f99d06f0f97Luca Barbieri * 416dd8e6f9cbca63b222fe4a1c2c49ddb53e75999eJames Benton * http://fgiesen.wordpress.com/2012/03/28/half-to-float-done-quic/ 426dd8e6f9cbca63b222fe4a1c2c49ddb53e75999eJames Benton * https://gist.github.com/2156668 436dd8e6f9cbca63b222fe4a1c2c49ddb53e75999eJames Benton * https://gist.github.com/2144712 443ff175d6de89ad92d167362355501f99d06f0f97Luca Barbieri */ 453ff175d6de89ad92d167362355501f99d06f0f97Luca Barbieri 466dd8e6f9cbca63b222fe4a1c2c49ddb53e75999eJames Bentonstatic INLINE uint16_t 476dd8e6f9cbca63b222fe4a1c2c49ddb53e75999eJames Bentonutil_float_to_half(float f) 483ff175d6de89ad92d167362355501f99d06f0f97Luca Barbieri{ 496dd8e6f9cbca63b222fe4a1c2c49ddb53e75999eJames Benton uint32_t sign_mask = 0x80000000; 506dd8e6f9cbca63b222fe4a1c2c49ddb53e75999eJames Benton uint32_t round_mask = ~0xfff; 516dd8e6f9cbca63b222fe4a1c2c49ddb53e75999eJames Benton uint32_t f32inf = 0xff << 23; 526dd8e6f9cbca63b222fe4a1c2c49ddb53e75999eJames Benton uint32_t f16inf = 0x1f << 23; 536dd8e6f9cbca63b222fe4a1c2c49ddb53e75999eJames Benton uint32_t sign; 546dd8e6f9cbca63b222fe4a1c2c49ddb53e75999eJames Benton union fi magic; 556dd8e6f9cbca63b222fe4a1c2c49ddb53e75999eJames Benton union fi f32; 566dd8e6f9cbca63b222fe4a1c2c49ddb53e75999eJames Benton uint16_t f16; 576dd8e6f9cbca63b222fe4a1c2c49ddb53e75999eJames Benton 586dd8e6f9cbca63b222fe4a1c2c49ddb53e75999eJames Benton magic.ui = 0xf << 23; 596dd8e6f9cbca63b222fe4a1c2c49ddb53e75999eJames Benton 606dd8e6f9cbca63b222fe4a1c2c49ddb53e75999eJames Benton f32.f = f; 616dd8e6f9cbca63b222fe4a1c2c49ddb53e75999eJames Benton 626dd8e6f9cbca63b222fe4a1c2c49ddb53e75999eJames Benton /* Sign */ 636dd8e6f9cbca63b222fe4a1c2c49ddb53e75999eJames Benton sign = f32.ui & sign_mask; 646dd8e6f9cbca63b222fe4a1c2c49ddb53e75999eJames Benton f32.ui ^= sign; 656dd8e6f9cbca63b222fe4a1c2c49ddb53e75999eJames Benton 666dd8e6f9cbca63b222fe4a1c2c49ddb53e75999eJames Benton if (f32.ui == f32inf) { 676dd8e6f9cbca63b222fe4a1c2c49ddb53e75999eJames Benton /* Inf */ 686dd8e6f9cbca63b222fe4a1c2c49ddb53e75999eJames Benton f16 = 0x7c00; 696dd8e6f9cbca63b222fe4a1c2c49ddb53e75999eJames Benton } else if (f32.ui > f32inf) { 706dd8e6f9cbca63b222fe4a1c2c49ddb53e75999eJames Benton /* NaN */ 716dd8e6f9cbca63b222fe4a1c2c49ddb53e75999eJames Benton f16 = 0x7e00; 726dd8e6f9cbca63b222fe4a1c2c49ddb53e75999eJames Benton } else { 736dd8e6f9cbca63b222fe4a1c2c49ddb53e75999eJames Benton /* Number */ 746dd8e6f9cbca63b222fe4a1c2c49ddb53e75999eJames Benton f32.ui &= round_mask; 756dd8e6f9cbca63b222fe4a1c2c49ddb53e75999eJames Benton f32.f *= magic.f; 766dd8e6f9cbca63b222fe4a1c2c49ddb53e75999eJames Benton f32.ui -= round_mask; 776dd8e6f9cbca63b222fe4a1c2c49ddb53e75999eJames Benton 786dd8e6f9cbca63b222fe4a1c2c49ddb53e75999eJames Benton /* Clamp to infinity if overflowed */ 796dd8e6f9cbca63b222fe4a1c2c49ddb53e75999eJames Benton if (f32.ui > f16inf) 806dd8e6f9cbca63b222fe4a1c2c49ddb53e75999eJames Benton f32.ui = f16inf; 816dd8e6f9cbca63b222fe4a1c2c49ddb53e75999eJames Benton 826dd8e6f9cbca63b222fe4a1c2c49ddb53e75999eJames Benton f16 = f32.ui >> 13; 836dd8e6f9cbca63b222fe4a1c2c49ddb53e75999eJames Benton } 846dd8e6f9cbca63b222fe4a1c2c49ddb53e75999eJames Benton 856dd8e6f9cbca63b222fe4a1c2c49ddb53e75999eJames Benton /* Sign */ 866dd8e6f9cbca63b222fe4a1c2c49ddb53e75999eJames Benton f16 |= sign >> 16; 876dd8e6f9cbca63b222fe4a1c2c49ddb53e75999eJames Benton 886dd8e6f9cbca63b222fe4a1c2c49ddb53e75999eJames Benton return f16; 893ff175d6de89ad92d167362355501f99d06f0f97Luca Barbieri} 903ff175d6de89ad92d167362355501f99d06f0f97Luca Barbieri 913ff175d6de89ad92d167362355501f99d06f0f97Luca Barbieristatic INLINE float 926dd8e6f9cbca63b222fe4a1c2c49ddb53e75999eJames Bentonutil_half_to_float(uint16_t f16) 933ff175d6de89ad92d167362355501f99d06f0f97Luca Barbieri{ 946dd8e6f9cbca63b222fe4a1c2c49ddb53e75999eJames Benton union fi infnan; 956dd8e6f9cbca63b222fe4a1c2c49ddb53e75999eJames Benton union fi magic; 966dd8e6f9cbca63b222fe4a1c2c49ddb53e75999eJames Benton union fi f32; 973ff175d6de89ad92d167362355501f99d06f0f97Luca Barbieri 986dd8e6f9cbca63b222fe4a1c2c49ddb53e75999eJames Benton infnan.ui = 0x8f << 23; 996dd8e6f9cbca63b222fe4a1c2c49ddb53e75999eJames Benton infnan.f = 65536.0f; 1006dd8e6f9cbca63b222fe4a1c2c49ddb53e75999eJames Benton magic.ui = 0xef << 23; 1013ff175d6de89ad92d167362355501f99d06f0f97Luca Barbieri 1026dd8e6f9cbca63b222fe4a1c2c49ddb53e75999eJames Benton /* Exponent / Mantissa */ 1036dd8e6f9cbca63b222fe4a1c2c49ddb53e75999eJames Benton f32.ui = (f16 & 0x7fff) << 13; 1046dd8e6f9cbca63b222fe4a1c2c49ddb53e75999eJames Benton 1056dd8e6f9cbca63b222fe4a1c2c49ddb53e75999eJames Benton /* Adjust */ 1066dd8e6f9cbca63b222fe4a1c2c49ddb53e75999eJames Benton f32.f *= magic.f; 1076dd8e6f9cbca63b222fe4a1c2c49ddb53e75999eJames Benton 1086dd8e6f9cbca63b222fe4a1c2c49ddb53e75999eJames Benton /* Inf / NaN */ 1096dd8e6f9cbca63b222fe4a1c2c49ddb53e75999eJames Benton if (f32.f >= infnan.f) 1106dd8e6f9cbca63b222fe4a1c2c49ddb53e75999eJames Benton f32.ui |= 0xff << 23; 1116dd8e6f9cbca63b222fe4a1c2c49ddb53e75999eJames Benton 1126dd8e6f9cbca63b222fe4a1c2c49ddb53e75999eJames Benton /* Sign */ 1136dd8e6f9cbca63b222fe4a1c2c49ddb53e75999eJames Benton f32.ui |= (f16 & 0x8000) << 16; 1146dd8e6f9cbca63b222fe4a1c2c49ddb53e75999eJames Benton 1156dd8e6f9cbca63b222fe4a1c2c49ddb53e75999eJames Benton return f32.f; 1163ff175d6de89ad92d167362355501f99d06f0f97Luca Barbieri} 1173ff175d6de89ad92d167362355501f99d06f0f97Luca Barbieri 11889034b8ae71ca12f9a12935807a33caa686ede00José Fonseca#ifdef __cplusplus 11989034b8ae71ca12f9a12935807a33caa686ede00José Fonseca} 12089034b8ae71ca12f9a12935807a33caa686ede00José Fonseca#endif 12189034b8ae71ca12f9a12935807a33caa686ede00José Fonseca 1223ff175d6de89ad92d167362355501f99d06f0f97Luca Barbieri#endif /* U_HALF_H */ 1236c5f444f596984778a786b49058d3cf2a4fd2c2cLuca Barbieri 124