OLD | NEW |
1 /* | 1 /* |
2 * Copyright 2014 Google Inc. | 2 * Copyright 2014 Google Inc. |
3 * | 3 * |
4 * Use of this source code is governed by a BSD-style license that can be | 4 * Use of this source code is governed by a BSD-style license that can be |
5 * found in the LICENSE file. | 5 * found in the LICENSE file. |
6 */ | 6 */ |
7 | 7 |
8 #ifndef SkHalf_DEFINED | 8 #ifndef SkHalf_DEFINED |
9 #define SkHalf_DEFINED | 9 #define SkHalf_DEFINED |
10 | 10 |
| 11 #include "SkCpu.h" |
11 #include "SkNx.h" | 12 #include "SkNx.h" |
12 #include "SkTypes.h" | 13 #include "SkTypes.h" |
13 | 14 |
14 // 16-bit floating point value | 15 // 16-bit floating point value |
15 // format is 1 bit sign, 5 bits exponent, 10 bits mantissa | 16 // format is 1 bit sign, 5 bits exponent, 10 bits mantissa |
16 // only used for storage | 17 // only used for storage |
17 typedef uint16_t SkHalf; | 18 typedef uint16_t SkHalf; |
18 | 19 |
19 #define SK_HalfMin 0x0400 // 2^-24 (minimum positive normal value) | 20 #define SK_HalfMin 0x0400 // 2^-24 (minimum positive normal value) |
20 #define SK_HalfMax 0x7bff // 65504 | 21 #define SK_HalfMax 0x7bff // 65504 |
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
115 } | 116 } |
116 r = (uint64_t)hs[3] << 48 | 117 r = (uint64_t)hs[3] << 48 |
117 | (uint64_t)hs[2] << 32 | 118 | (uint64_t)hs[2] << 32 |
118 | (uint64_t)hs[1] << 16 | 119 | (uint64_t)hs[1] << 16 |
119 | (uint64_t)hs[0] << 0; | 120 | (uint64_t)hs[0] << 0; |
120 #endif | 121 #endif |
121 return r; | 122 return r; |
122 } | 123 } |
123 | 124 |
124 #endif | 125 #endif |
| 126 |
| 127 static inline Sk4f SkHalfToFloat_01(const uint64_t* hs) { |
| 128 #if !defined(SKNX_NO_SIMD) && SK_CPU_SSE_LEVEL >= SK_CPU_SSE_LEVEL_SSE2 |
| 129 if (SkCpu::Supports(SkCpu::F16C)) { |
| 130 __m128 fs; |
| 131 #if defined(__GNUC__) || defined(__clang__) |
| 132 asm("vcvtph2ps %[hs], %[fs]" : [fs]"=x"(fs) : [hs]"m"(*hs)); |
| 133 #else |
| 134 fs = _mm_cvtph_ps(_mm_loadl_epi64((const __m128i*)hs)); |
| 135 #endif |
| 136 return fs; |
| 137 } |
| 138 #endif |
| 139 return SkHalfToFloat_01(*hs); |
| 140 } |
| 141 |
| 142 static inline void SkFloatToHalf_01(const Sk4f& fs, uint64_t* hs) { |
| 143 #if !defined(SKNX_NO_SIMD) && SK_CPU_SSE_LEVEL >= SK_CPU_SSE_LEVEL_SSE2 |
| 144 if (SkCpu::Supports(SkCpu::F16C)) { |
| 145 #if defined(__GNUC__) || defined(__clang__) |
| 146 asm("vcvtps2ph $0, %[fs], %[hs]" : [hs]"=m"(*hs) : [fs]"x"(fs.fVec)); |
| 147 #else |
| 148 _mm_storel_epi64((__m128i*)hs, _mm_cvtps_ph(fs.fVec, 0)); |
| 149 #endif |
| 150 return; |
| 151 } |
| 152 #endif |
| 153 *hs = SkFloatToHalf_01(fs); |
| 154 } |
OLD | NEW |