|
|
@@ -111,61 +111,16 @@ static inline uint16_t float_to_half_branch(uint32_t x) |
|
|
|
return bits; |
|
|
|
} |
|
|
|
|
|
|
|
#if 0 |
|
|
|
static inline void float_to_half_vector(half *dst, float const *src) |
|
|
|
{ |
|
|
|
vector unsigned int const v7 = vec_splat_u32(7); |
|
|
|
vector unsigned short const v6 = vec_splat_u16(6); |
|
|
|
#if _XBOX |
|
|
|
vector signed short const v9 = vec_splat_u16(9); |
|
|
|
vector unsigned short const v10 = vec_splat_u16(10); |
|
|
|
#else |
|
|
|
vector signed short const v0x0040 = { |
|
|
|
0x0040, 0x0040, 0x0040, 0x0040, 0x0040, 0x0040, 0x0040, 0x0040}; |
|
|
|
vector unsigned short const v0x0400 = { |
|
|
|
0x0400, 0x0400, 0x0400, 0x0400, 0x0400, 0x0400, 0x0400, 0x0400}; |
|
|
|
#endif |
|
|
|
vector unsigned char const shuffle_high = { |
|
|
|
0, 1, 4, 5, 8, 9, 12, 13, 16, 17, 20, 21, 24, 25, 28, 29}; |
|
|
|
vector unsigned char const shuffle_low = { |
|
|
|
2, 3, 6, 7, 10, 11, 14, 15, 18, 19, 22, 23, 26, 27, 30, 31}; |
|
|
|
vector unsigned char const v0xbf70 = { |
|
|
|
0xbf, 0x70, 0xbf, 0x70, 0xbf, 0x70, 0xbf, 0x70, |
|
|
|
0xbf, 0x70, 0xbf, 0x70, 0xbf, 0x70, 0xbf, 0x70}; |
|
|
|
|
|
|
|
vector unsigned short v_mant, v_ret; |
|
|
|
vector signed short v_exp; |
|
|
|
vector unsigned int in0 = (vector unsigned int)vec_ld(0, src); |
|
|
|
vector unsigned int in1 = (vector unsigned int)vec_ld(16, src); |
|
|
|
|
|
|
|
in0 = vec_sra(in0, v7); |
|
|
|
in1 = vec_sra(in1, v7); |
|
|
|
v_exp = (vector signed short)vec_perm(in0, in1, shuffle_high); |
|
|
|
v_mant = (vector unsigned short)vec_perm(in0, in1, shuffle_low); |
|
|
|
v_exp = (vector signed short)vec_subs((vector unsigned char)v_exp, v0xbf70); |
|
|
|
#if _XBOX |
|
|
|
v_ret = (vector unsigned short)vec_or(v_exp, vec_sr(v_exp, v9)); |
|
|
|
#else |
|
|
|
v_ret = (vector unsigned short)vec_madds(v_exp, v0x0040, v_exp); |
|
|
|
#endif |
|
|
|
v_mant = vec_sr(v_mant, v6); |
|
|
|
#if _XBOX |
|
|
|
v_ret = vec_or(v_mant, vec_sl(v_ret, v10)); |
|
|
|
#else |
|
|
|
v_ret = vec_mladd(v_ret, v0x0400, v_mant); |
|
|
|
#endif |
|
|
|
vec_st(v_ret, 0, (uint16_t *)dst); |
|
|
|
} |
|
|
|
#endif |
|
|
|
|
|
|
|
/* We use this magic table, inspired by De Bruijn sequences, to compute a |
|
|
|
* branchless integer log2. The actual value fetched is 24-log2(x+1) for x |
|
|
|
* in 1, 3, 7, f, 1f, 3f, 7f, ff, 1fe, 1ff, 3fc, 3fd, 3fe, 3ff. */ |
|
|
|
* in 1, 3, 7, f, 1f, 3f, 7f, ff, 1fe, 1ff, 3fc, 3fd, 3fe, 3ff. See |
|
|
|
* http://lol.zoy.org/blog/2012/4/3/beyond-de-bruijn for an explanation |
|
|
|
* of how the value 0x5a1a1a2u was obtained. */ |
|
|
|
static int const shifttable[16] = |
|
|
|
{ |
|
|
|
23, 22, 21, 15, -1, 20, 18, 14, 14, 16, 19, -1, 17, -1, -1, -1, |
|
|
|
}; |
|
|
|
static uint32_t const shiftmagic = 0x05a1a1a2u; |
|
|
|
static uint32_t const shiftmagic = 0x5a1a1a2u; |
|
|
|
|
|
|
|
/* Lookup table-based algorithm from “Fast Half Float Conversions” |
|
|
|
* by Jeroen van der Zijp, November 2008. Tables are generated using |
|
|
@@ -285,13 +240,6 @@ size_t half::convert(half *dst, float const *src, size_t nelem) |
|
|
|
union { float f; uint32_t x; } u; |
|
|
|
u.f = *src++; |
|
|
|
*dst++ = makebits(float_to_half_nobranch(u.x)); |
|
|
|
#if 0 |
|
|
|
/* AltiVec code. Will work one day. */ |
|
|
|
float_to_half_vector(dst, src); |
|
|
|
src += 8; |
|
|
|
dst += 8; |
|
|
|
i += 7; |
|
|
|
#endif |
|
|
|
} |
|
|
|
|
|
|
|
return nelem; |
|
|
|