1 /*------------------------------------------------------------------------- 2 * drawElements Base Portability Library 3 * ------------------------------------- 4 * 5 * Copyright 2014 The Android Open Source Project 6 * 7 * Licensed under the Apache License, Version 2.0 (the "License"); 8 * you may not use this file except in compliance with the License. 9 * You may obtain a copy of the License at 10 * 11 * http://www.apache.org/licenses/LICENSE-2.0 12 * 13 * Unless required by applicable law or agreed to in writing, software 14 * distributed under the License is distributed on an "AS IS" BASIS, 15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 * See the License for the specific language governing permissions and 17 * limitations under the License. 18 * 19 *//*! 20 * \file 21 * \brief 16-bit floating-point math. 22 *//*--------------------------------------------------------------------*/ 23 24 #include "deFloat16.h" 25 26 DE_BEGIN_EXTERN_C 27 deFloat32To16(float val32)28deFloat16 deFloat32To16 (float val32) 29 { 30 deUint32 sign; 31 int expotent; 32 deUint32 mantissa; 33 union 34 { 35 float f; 36 deUint32 u; 37 } x; 38 39 x.f = val32; 40 sign = (x.u >> 16u) & 0x00008000u; 41 expotent = (int)((x.u >> 23u) & 0x000000ffu) - (127 - 15); 42 mantissa = x.u & 0x007fffffu; 43 44 if (expotent <= 0) 45 { 46 if (expotent < -10) 47 { 48 /* Rounds to zero. */ 49 return (deFloat16) sign; 50 } 51 52 /* Converted to denormalized half, add leading 1 to significand. */ 53 mantissa = mantissa | 0x00800000u; 54 55 /* Round mantissa to nearest (10+e) */ 56 { 57 deUint32 t = 14u - expotent; 58 deUint32 a = (1u << (t - 1u)) - 1u; 59 deUint32 b = (mantissa >> t) & 1u; 60 61 mantissa = (mantissa + a + b) >> t; 62 } 63 64 return (deFloat16) (sign | mantissa); 65 } 66 else if (expotent == 0xff - (127 - 15)) 67 { 68 if (mantissa == 0u) 69 { 70 /* InF */ 71 return (deFloat16) (sign | 0x7c00u); 72 } 73 else 74 { 75 /* NaN */ 76 mantissa >>= 13u; 77 return (deFloat16) (sign | 0x7c00u | mantissa | (mantissa == 0u)); 78 } 79 } 80 else 81 { 82 /* Normalized float. */ 83 mantissa = mantissa + 0x00000fffu + ((mantissa >> 13u) & 1u); 84 85 if (mantissa & 0x00800000u) 86 { 87 /* Overflow in mantissa. */ 88 mantissa = 0u; 89 expotent += 1; 90 } 91 92 if (expotent > 30) 93 { 94 /* \todo [pyry] Cause hw fp overflow */ 95 return (deFloat16) (sign | 0x7c00u); 96 } 97 98 return (deFloat16) (sign | ((deUint32)expotent << 10u) | (mantissa >> 13u)); 99 } 100 } 101 deFloat16To32(deFloat16 val16)102float deFloat16To32 (deFloat16 val16) 103 { 104 deUint32 sign; 105 deUint32 expotent; 106 deUint32 mantissa; 107 union 108 { 109 float f; 110 deUint32 u; 111 } x; 112 113 x.u = 0u; 114 115 sign = ((deUint32)val16 >> 15u) & 0x00000001u; 116 expotent = ((deUint32)val16 >> 10u) & 0x0000001fu; 117 mantissa = (deUint32)val16 & 0x000003ffu; 118 119 if (expotent == 0u) 120 { 121 if (mantissa == 0u) 122 { 123 /* +/- 0 */ 124 x.u = sign << 31u; 125 return x.f; 126 } 127 else 128 { 129 /* Denormalized, normalize it. */ 130 131 while (!(mantissa & 0x00000400u)) 132 { 133 mantissa <<= 1u; 134 expotent -= 1u; 135 } 136 137 expotent += 1u; 138 mantissa &= ~0x00000400u; 139 } 140 } 141 else if (expotent == 31u) 142 { 143 if (mantissa == 0u) 144 { 145 /* +/- InF */ 146 x.u = (sign << 31u) | 0x7f800000u; 147 return x.f; 148 } 149 else 150 { 151 /* +/- NaN */ 152 x.u = (sign << 31u) | 0x7f800000u | (mantissa << 13u); 153 return x.f; 154 } 155 } 156 157 expotent = expotent + (127u - 15u); 158 mantissa = mantissa << 13u; 159 160 x.u = (sign << 31u) | (expotent << 23u) | mantissa; 161 return x.f; 162 } 163 164 DE_END_EXTERN_C 165