Gets rid of unnecessary delays on startup and compiler-specific hax.tags/mesa-7.9-rc1
*/ | */ | ||||
#include "util/u_half.h" | #include "util/u_half.h" | ||||
#include "util/u_init.h" | |||||
uint32_t util_half_to_float_mantissa_table[2048]; | uint32_t util_half_to_float_mantissa_table[2048]; | ||||
uint32_t util_half_to_float_exponent_table[64]; | uint32_t util_half_to_float_exponent_table[64]; | ||||
uint16_t util_float_to_half_base_table[512]; | uint16_t util_float_to_half_base_table[512]; | ||||
uint8_t util_float_to_half_shift_table[512]; | uint8_t util_float_to_half_shift_table[512]; | ||||
static void util_half_init_tables(void) | |||||
void util_half_init_tables(void) | |||||
{ | { | ||||
static boolean inited = FALSE; | |||||
int i; | int i; | ||||
if (inited) { | |||||
return; | |||||
} | |||||
/* zero */ | /* zero */ | ||||
util_half_to_float_mantissa_table[0] = 0; | util_half_to_float_mantissa_table[0] = 0; | ||||
util_float_to_half_base_table[256 + i] = util_float_to_half_base_table[i] | 0x8000; | 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_float_to_half_shift_table[256 + i] = util_float_to_half_shift_table[i]; | ||||
} | } | ||||
} | |||||
UTIL_INIT(util_half_init_tables); | |||||
inited = TRUE; | |||||
} |
extern "C" { | extern "C" { | ||||
#endif | #endif | ||||
extern uint32_t util_half_to_float_mantissa_table[2048]; | 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_exponent_table[64]; | ||||
extern uint32_t util_half_to_float_offset_table[64]; | extern uint32_t util_half_to_float_offset_table[64]; | ||||
extern uint16_t util_float_to_half_base_table[512]; | extern uint16_t util_float_to_half_base_table[512]; | ||||
extern uint8_t util_float_to_half_shift_table[512]; | extern uint8_t util_float_to_half_shift_table[512]; | ||||
void util_half_init_tables(void); | |||||
/* | /* | ||||
* Note that if the half float is a signaling NaN, the x87 FPU will turn | * Note that if the half float is a signaling NaN, the x87 FPU will turn | ||||
* it into a quiet NaN immediately upon loading into a float. | * it into a quiet NaN immediately upon loading into a float. | ||||
util_half_to_floatui(half h) | util_half_to_floatui(half h) | ||||
{ | { | ||||
unsigned exp = h >> 10; | unsigned exp = h >> 10; | ||||
util_half_init_tables(); | |||||
return util_half_to_float_mantissa_table[util_half_to_float_offset_table[exp] + (h & 0x3ff)] | return util_half_to_float_mantissa_table[util_half_to_float_offset_table[exp] + (h & 0x3ff)] | ||||
+ util_half_to_float_exponent_table[exp]; | + util_half_to_float_exponent_table[exp]; | ||||
} | } | ||||
util_half_to_float(half h) | util_half_to_float(half h) | ||||
{ | { | ||||
union fi r; | union fi r; | ||||
util_half_init_tables(); | |||||
r.ui = util_half_to_floatui(h); | r.ui = util_half_to_floatui(h); | ||||
return r.f; | return r.f; | ||||
} | } | ||||
util_floatui_to_half(uint32_t v) | util_floatui_to_half(uint32_t v) | ||||
{ | { | ||||
unsigned signexp = v >> 23; | unsigned signexp = v >> 23; | ||||
util_half_init_tables(); | |||||
return util_float_to_half_base_table[signexp] | return util_float_to_half_base_table[signexp] | ||||
+ ((v & 0x007fffff) >> util_float_to_half_shift_table[signexp]); | + ((v & 0x007fffff) >> util_float_to_half_shift_table[signexp]); | ||||
} | } | ||||
util_float_to_half(float f) | util_float_to_half(float f) | ||||
{ | { | ||||
union fi i; | union fi i; | ||||
util_half_init_tables(); | |||||
i.f = f; | i.f = f; | ||||
return util_floatui_to_half(i.ui); | return util_floatui_to_half(i.ui); | ||||
} | } |
/* | |||||
* Copyright 2010 Luca Barbieri | |||||
* | |||||
* Permission is hereby granted, free of charge, to any person obtaining | |||||
* a copy of this software and associated documentation files (the | |||||
* "Software"), to deal in the Software without restriction, including | |||||
* without limitation the rights to use, copy, modify, merge, publish, | |||||
* distribute, sublicense, and/or sell copies of the Software, and to | |||||
* permit persons to whom the Software is furnished to do so, subject to | |||||
* the following conditions: | |||||
* | |||||
* The above copyright notice and this permission notice (including the | |||||
* next paragraph) shall be included in all copies or substantial | |||||
* portions of the Software. | |||||
* | |||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | |||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | |||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. | |||||
* IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE | |||||
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION | |||||
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION | |||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | |||||
* | |||||
**************************************************************************/ | |||||
#ifndef U_INIT_H | |||||
#define U_INIT_H | |||||
/* Use UTIL_INIT(f) to have f called at program initialization. | |||||
Note that it is only guaranteed to be called if any symbol in the | |||||
.c file it is in sis referenced by the program. | |||||
UTIL_INIT functions are called in arbitrary order. | |||||
*/ | |||||
#ifdef __cplusplus | |||||
/* use a C++ global constructor */ | |||||
#define UTIL_INIT(f) struct f##__gctor_t {f##__gctor_t() {x();}} f##__gctor; | |||||
#elif defined(_MSC_VER) | |||||
/* add a pointer to the section where MSVC stores global constructor pointers */ | |||||
/* see http://blogs.msdn.com/vcblog/archive/2006/10/20/crt-initialization.aspx and | |||||
http://stackoverflow.com/questions/1113409/attribute-constructor-equivalent-in-vc */ | |||||
#pragma data_seg(".CRT$XCU") | |||||
#define UTIL_INIT(f) static void __cdecl f##__init(void) {f();}; __declspec(allocate(".CRT$XCU")) void (__cdecl* f##__xcu)(void) = f##__init; | |||||
#elif defined(__GNUC__) | |||||
#define UTIL_INIT(f) static void f##__init(void) __attribute__((constructor)); static void f##__init(void) {f();} | |||||
#else | |||||
#error Unsupported compiler: please find out how to implement global initializers in C on it | |||||
#endif | |||||
#endif | |||||