| 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" | |
| 12 #include "SkNx.h" | 11 #include "SkNx.h" |
| 13 #include "SkTypes.h" | 12 #include "SkTypes.h" |
| 14 | 13 |
| 15 // 16-bit floating point value | 14 // 16-bit floating point value |
| 16 // format is 1 bit sign, 5 bits exponent, 10 bits mantissa | 15 // format is 1 bit sign, 5 bits exponent, 10 bits mantissa |
| 17 // only used for storage | 16 // only used for storage |
| 18 typedef uint16_t SkHalf; | 17 typedef uint16_t SkHalf; |
| 19 | 18 |
| 20 #define SK_HalfMin 0x0400 // 2^-24 (minimum positive normal value) | 19 #define SK_HalfMin 0x0400 // 2^-24 (minimum positive normal value) |
| 21 #define SK_HalfMax 0x7bff // 65504 | 20 #define SK_HalfMax 0x7bff // 65504 |
| (...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 116 } | 115 } |
| 117 r = (uint64_t)hs[3] << 48 | 116 r = (uint64_t)hs[3] << 48 |
| 118 | (uint64_t)hs[2] << 32 | 117 | (uint64_t)hs[2] << 32 |
| 119 | (uint64_t)hs[1] << 16 | 118 | (uint64_t)hs[1] << 16 |
| 120 | (uint64_t)hs[0] << 0; | 119 | (uint64_t)hs[0] << 0; |
| 121 #endif | 120 #endif |
| 122 return r; | 121 return r; |
| 123 } | 122 } |
| 124 | 123 |
| 125 #endif | 124 #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 |