Max 5 API Reference
00001 /* 00002 * Copyright 2001-2005 - Cycling '74 00003 * Derek Gerstmann - derek@cycling74.com 00004 * 00005 * Support for 16 bit floating point evaluation. Based on the OpenEXR 00006 * C++ half datatype. License information follows. 00007 * 00008 */ 00009 00010 #include "jit.common.h" 00011 #include "jit.half.h" 00012 00013 00014 /////////////////////////////////////////////////////////////////////////// 00015 // 00016 // Copyright (c) 2002, Industrial Light & Magic, a division of Lucas 00017 // Digital Ltd. LLC 00018 // 00019 // All rights reserved. 00020 // 00021 // Redistribution and use in source and binary forms, with or without 00022 // modification, are permitted provided that the following conditions are 00023 // met: 00024 // * Redistributions of source code must retain the above copyright 00025 // notice, this list of conditions and the following disclaimer. 00026 // * Redistributions in binary form must reproduce the above 00027 // copyright notice, this list of conditions and the following disclaimer 00028 // in the documentation and/or other materials provided with the 00029 // distribution. 00030 // * Neither the name of Industrial Light & Magic nor the names of 00031 // its contributors may be used to endorse or promote products derived 00032 // from this software without specific prior written permission. 00033 // 00034 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 00035 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 00036 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 00037 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 00038 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 00039 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 00040 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 00041 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 00042 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 00043 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 00044 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 00045 // 00046 /////////////////////////////////////////////////////////////////////////// 00047 00048 // -------------------------------------------------------------------------- 00049 00050 // combined unsigned int & float union 00051 typedef union _uif 00052 { 00053 unsigned int i; 00054 float f; 00055 } uif; 00056 00057 // -------------------------------------------------------------------------- 00058 00059 static long jit_half_flut_ok = FALSE; // init flag for half-to-float lut 00060 static long jit_half_elut_ok = FALSE; // init flag for float-to-half lut 00061 static uif jit_half_flut[1 << 16]; // half-to-float lookup table 00062 static half jit_half_elut[1 << 9]; // float-to-half exponent lookup table 00063 00064 // -------------------------------------------------------------------------- 00065 00066 static void jit_half_elut_init(); 00067 static void jit_half_flut_init(); 00068 static half jit_bits_to_half(int i); 00069 static unsigned int jit_half_to_bits(half y); 00070 static float jit_half_overflow(); 00071 00072 //--------------------------------------------------------------------------- 00073 // 00074 // Implementation -- 00075 // 00076 // Representation of a float: 00077 // 00078 // We assume that a float, f, is an IEEE 754 single-precision 00079 // floating point number, whose bits are arranged as follows: 00080 // 00081 // 31 (msb) 00082 // | 00083 // | 30 23 00084 // | | | 00085 // | | | 22 0 (lsb) 00086 // | | | | | 00087 // X XXXXXXXX XXXXXXXXXXXXXXXXXXXXXXX 00088 // 00089 // s e m 00090 // 00091 // S is the sign-bit, e is the exponent and m is the significand. 00092 // 00093 // If e is between 1 and 254, f is a normalized number: 00094 // 00095 // s e-127 00096 // f = (-1) * 2 * 1.m 00097 // 00098 // If e is 0, and m is not zero, f is a denormalized number: 00099 // 00100 // s -126 00101 // f = (-1) * 2 * 0.m 00102 // 00103 // If e and m are both zero, f is zero: 00104 // 00105 // f = 0.0 00106 // 00107 // If e is 255, f is an "infinity" or "not a number" (NAN), 00108 // depending on whether m is zero or not. 00109 // 00110 // Examples: 00111 // 00112 // 0 00000000 00000000000000000000000 = 0.0 00113 // 0 01111110 00000000000000000000000 = 0.5 00114 // 0 01111111 00000000000000000000000 = 1.0 00115 // 0 10000000 00000000000000000000000 = 2.0 00116 // 0 10000000 10000000000000000000000 = 3.0 00117 // 1 10000101 11110000010000000000000 = -124.0625 00118 // 0 11111111 00000000000000000000000 = +infinity 00119 // 1 11111111 00000000000000000000000 = -infinity 00120 // 0 11111111 10000000000000000000000 = NAN 00121 // 1 11111111 11111111111111111111111 = NAN 00122 // 00123 // Representation of a half: 00124 // 00125 // Here is the bit-layout for a half number, h: 00126 // 00127 // 15 (msb) 00128 // | 00129 // | 14 10 00130 // | | | 00131 // | | | 9 0 (lsb) 00132 // | | | | | 00133 // X XXXXX XXXXXXXXXX 00134 // 00135 // s e m 00136 // 00137 // S is the sign-bit, e is the exponent and m is the significand. 00138 // 00139 // If e is between 1 and 30, h is a normalized number: 00140 // 00141 // s e-15 00142 // h = (-1) * 2 * 1.m 00143 // 00144 // If e is 0, and m is not zero, h is a denormalized number: 00145 // 00146 // S -14 00147 // h = (-1) * 2 * 0.m 00148 // 00149 // If e and m are both zero, h is zero: 00150 // 00151 // h = 0.0 00152 // 00153 // If e is 31, h is an "infinity" or "not a number" (NAN), 00154 // depending on whether m is zero or not. 00155 // 00156 // Examples: 00157 // 00158 // 0 00000 0000000000 = 0.0 00159 // 0 01110 0000000000 = 0.5 00160 // 0 01111 0000000000 = 1.0 00161 // 0 10000 0000000000 = 2.0 00162 // 0 10000 1000000000 = 3.0 00163 // 1 10101 1111000001 = -124.0625 00164 // 0 11111 0000000000 = +infinity 00165 // 1 11111 0000000000 = -infinity 00166 // 0 11111 1000000000 = NAN 00167 // 1 11111 1111111111 = NAN 00168 // 00169 // Conversion: 00170 // 00171 // Converting from a float to a half requires some non-trivial bit 00172 // manipulations. In some cases, this makes conversion relatively 00173 // slow, but the most common case is accelerated via table lookups. 00174 // 00175 // Converting back from a half to a float is easier because we don't 00176 // have to do any rounding. In addition, there are only 65536 00177 // different half numbers; we can convert each of those numbers once 00178 // and store the results in a table. Later, all conversions can be 00179 // done using only simple table lookups. 00180 // 00181 //--------------------------------------------------------------------------- 00182 00183 // -------------------------------------------------------------------------- 00184 // Convert a float to half 00185 // -------------------------------------------------------------------------- 00186 half jit_float_to_half(float f) 00187 { 00188 uif x; 00189 half h; 00190 register int e; 00191 if (f == 0) 00192 { 00193 // common special case - zero. 00194 // for speed, we don't preserve the zero's sign. 00195 h = 0; 00196 } 00197 else 00198 { 00199 // We extract the combined sign and exponent, e, from our 00200 // floating-point number, f. Then we convert e to the sign 00201 // and exponent of the half number via a table lookup. 00202 // 00203 // For the most common case, where a normalized half is produced, 00204 // the table lookup returns a non-zero value; in this case, all 00205 // we have to do, is round f's significand to 10 bits and combine 00206 // the result with e. 00207 // 00208 // For all other cases (overflow, zeroes, denormalized numbers 00209 // resulting from underflow, infinities and NANs), the table 00210 // lookup returns zero, and we call a longer, non-inline function 00211 // to do the float-to-half conversion. 00212 x.f = f; 00213 e = (x.i >> 23) & 0x000001ff; 00214 e = jit_half_elut[e]; 00215 00216 if (e) 00217 { 00218 // Simple case - round the significand and 00219 // combine it with the sign and exponent. 00220 h = e + (((x.i & 0x007fffff) + 0x00001000) >> 13); 00221 } 00222 else 00223 { 00224 // Difficult case - call a function. 00225 h = jit_bits_to_half(x.i); 00226 } 00227 } 00228 return h; 00229 } 00230 00231 // -------------------------------------------------------------------------- 00232 // Round to n-bit precision 00233 // -------------------------------------------------------------------------- 00234 half jit_half_round(half h, unsigned int n) 00235 { 00236 00237 unsigned short s, e; 00238 00239 // Parameter check. 00240 if (n >= 10) 00241 return h; 00242 00243 // Disassemble h into the sign, s, 00244 // and the combined exponent and significand, e. 00245 s = h & 0x8000; 00246 e = h & 0x7fff; 00247 00248 // Round the exponent and significand to the nearest value 00249 // where ones occur only in the (10-n) most significant bits. 00250 // Note that the exponent adjusts automatically if rounding 00251 // up causes the significand to overflow. 00252 e >>= 9 - n; 00253 e += e & 1; 00254 e <<= 9 - n; 00255 00256 // Check for exponent overflow. 00257 if (e >= 0x7c00) 00258 { 00259 // Overflow occurred -- truncate instead of rounding. 00260 e = h; 00261 e >>= 10 - n; 00262 e <<= 10 - n; 00263 } 00264 00265 // Put the original sign bit back. 00266 h = s | e; 00267 return h; 00268 } 00269 00270 // -------------------------------------------------------------------------- 00271 // Convert a half-to-float 00272 // -------------------------------------------------------------------------- 00273 float jit_half_to_float(half y) 00274 { 00275 return jit_half_flut[y].f; 00276 /* 00277 // use the following without a lookup table 00278 unsigned int r = jit_half_to_bits(y); 00279 return *(float*)(&r); 00280 */ 00281 } 00282 00283 // -------------------------------------------------------------------------- 00284 // Arithmetic operations 00285 // -------------------------------------------------------------------------- 00286 half jit_half_negate(half h) 00287 { 00288 return h ^ 0x8000; 00289 } 00290 00291 half jit_half_add(half h, half a) 00292 { 00293 return jit_half_to_float(jit_half_to_float(h) + jit_half_to_float (a)); 00294 } 00295 00296 half jit_half_add_float(half h, float a) 00297 { 00298 return jit_half_to_float(jit_half_to_float(h) + a); 00299 } 00300 00301 half jit_half_sub(half h, half a) 00302 { 00303 return jit_float_to_half(jit_half_to_float(h) - jit_half_to_float(a)); 00304 } 00305 00306 half jit_half_sub_float(half h, float a) 00307 { 00308 return jit_float_to_half(jit_half_to_float(h) - a); 00309 } 00310 00311 half jit_half_mul(half h, half a) 00312 { 00313 return jit_float_to_half(jit_half_to_float(h) * jit_half_to_float(a)); 00314 } 00315 00316 half jit_half_mul_float(half h, float a) 00317 { 00318 return jit_float_to_half(jit_half_to_float(h) * a); 00319 } 00320 00321 half jit_half_div(half h, half a) 00322 { 00323 return jit_float_to_half(jit_half_to_float(h) / jit_half_to_float(a)); 00324 } 00325 00326 half jit_half_div_float(half h, float a) 00327 { 00328 return jit_float_to_half(jit_half_to_float(h) / a); 00329 } 00330 00331 long jit_half_is_finite(half h) 00332 { 00333 unsigned short e = (h >> 10) & 0x001f; 00334 return e < 31; 00335 } 00336 00337 long jit_half_is_normalized(half h) 00338 { 00339 unsigned short e = (h >> 10) & 0x001f; 00340 return e > 0 && e < 31; 00341 } 00342 00343 long jit_half_is_denormalized(half h) 00344 { 00345 unsigned short e = (h >> 10) & 0x001f; 00346 unsigned short m = h & 0x3ff; 00347 return e == 0 && m != 0; 00348 } 00349 00350 long jit_half_is_zero(half h) 00351 { 00352 return (h & 0x7fff) == 0; 00353 } 00354 00355 long jit_half_is_negative(half h) 00356 { 00357 return (h & 0x8000) != 0; 00358 } 00359 00360 00361 long jit_half_is_nan(half h) 00362 { 00363 unsigned short e = (h >> 10) & 0x001f; 00364 unsigned short m = h & 0x3ff; 00365 return e == 31 && m != 0; 00366 } 00367 00368 long jit_half_is_inf(half h) 00369 { 00370 unsigned short e = (h >> 10) & 0x001f; 00371 unsigned short m = h & 0x3ff; 00372 return e == 31 && m == 0; 00373 } 00374 00375 // -------------------------------------------------------------------------- 00376 // Initialize the lookup tables for half/float conversion 00377 // -------------------------------------------------------------------------- 00378 void jit_half_init() 00379 { 00380 if(!jit_half_elut_ok) 00381 jit_half_elut_init(); 00382 jit_half_elut_ok = TRUE; 00383 00384 if(!jit_half_flut_ok) 00385 jit_half_flut_init(); 00386 jit_half_flut_ok = TRUE; 00387 } 00388 00389 // -------------------------------------------------------------------------- 00390 // Compute a lookup table for float-to-half conversion. 00391 // 00392 // When indexed with the combined sign and exponent of 00393 // a float, the table either returns the combined sign 00394 // and exponent of the corresponding half, or zero if 00395 // the corresponding half may not be normalized (zero, 00396 // denormalized, overflow). 00397 // -------------------------------------------------------------------------- 00398 static void jit_half_elut_init() 00399 { 00400 int i, e; 00401 for (i = 0; i < 0x100; i++) 00402 { 00403 e = (i & 0x0ff) - (127 - 15); 00404 00405 if (e <= 0 || e >= 30) 00406 { 00407 // special case 00408 jit_half_elut[i] = 0; 00409 jit_half_elut[i | 0x100] = 0; 00410 } 00411 else 00412 { 00413 // common case - normalized half, no exponent overflow possible 00414 jit_half_elut[i] = (e << 10); 00415 jit_half_elut[i | 0x100] = ((e << 10) | 0x8000); 00416 } 00417 } 00418 } 00419 00420 // -------------------------------------------------------------------------- 00421 // Compute a lookup table for half-to-float conversion. 00422 // -------------------------------------------------------------------------- 00423 static void jit_half_flut_init() 00424 { 00425 int i; 00426 uif x; 00427 unsigned int ui; 00428 for(i = 0; i < (1 << 16); i++) 00429 { 00430 ui = jit_half_to_bits(i); 00431 x.i = ui; 00432 jit_half_flut[i] = x; 00433 } 00434 } 00435 00436 // -------------------------------------------------------------------------- 00437 // Compose a half from a bitwise representation 00438 // -------------------------------------------------------------------------- 00439 static half jit_bits_to_half(int i) 00440 { 00441 // Our floating point number, f, is represented by the bit 00442 // pattern in integer i. Disassemble that bit pattern into 00443 // the sign, s, the exponent, e, and the significand, m. 00444 // Shift s into the position where it will go in in the 00445 // resulting half number. 00446 // Adjust e, accounting for the different exponent bias 00447 // of float and half (127 versus 15). 00448 00449 register int s = (i >> 16) & 0x00008000; 00450 register int e = ((i >> 23) & 0x000000ff) - (127 - 15); 00451 register int m = i & 0x007fffff; 00452 00453 // Now reassemble s, e and m into a half: 00454 if (e <= 0) 00455 { 00456 if (e < -10) 00457 { 00458 // E is less than -10. The absolute value of f is 00459 // less than HALF_MIN (f may be a small normalized 00460 // float, a denormalized float or a zero). 00461 // 00462 // We convert f to a half zero. 00463 return 0; 00464 } 00465 00466 // E is between -10 and 0. F is a normalized float, 00467 // whose magnitude is less than HALF_NRM_MIN. 00468 // 00469 // We convert f to a denormalized half. 00470 m = (m | 0x00800000) >> (1 - e); 00471 00472 // Round to nearest, round "0.5" up. 00473 // 00474 // Rounding may cause the significand to overflow and make 00475 // our number normalized. Because of the way a half's bits 00476 // are laid out, we don't have to treat this case separately; 00477 // the code below will handle it correctly. 00478 if (m & 0x00001000) 00479 m += 0x00002000; 00480 00481 // Assemble the half from s, e (zero) and m. 00482 return s | (m >> 13); 00483 } 00484 else if (e == 0xff - (127 - 15)) 00485 { 00486 if (m == 0) 00487 { 00488 // F is an infinity; convert f to a half 00489 // infinity with the same sign as f. 00490 return s | 0x7c00; 00491 } 00492 else 00493 { 00494 // F is a NAN; we produce a half NAN that preserves 00495 // the sign bit and the 10 leftmost bits of the 00496 // significand of f, with one exception: If the 10 00497 // leftmost bits are all zero, the NAN would turn 00498 // into an infinity, so we have to set at least one 00499 // bit in the significand. 00500 m >>= 13; 00501 return s | 0x7c00 | m | (m == 0); 00502 } 00503 } 00504 else 00505 { 00506 // E is greater than zero. F is a normalized float. 00507 // We try to convert f to a normalized half. 00508 00509 // Round to nearest, round "0.5" up 00510 if (m & 0x00001000) 00511 { 00512 m += 0x00002000; 00513 00514 if (m & 0x00800000) 00515 { 00516 m = 0; // overflow in significand, 00517 e += 1; // adjust exponent 00518 } 00519 } 00520 00521 // Handle exponent overflow 00522 if (e > 30) 00523 { 00524 // cause a hardware floating point overflow 00525 jit_half_overflow(); 00526 00527 00528 // if this returns, the half becomes an 00529 // infinity with the same sign as f. 00530 return s | 0x7c00; 00531 00532 } 00533 00534 // Assemble the half from s, e and m. 00535 return s | (e << 10) | (m >> 13); 00536 } 00537 } 00538 00539 // -------------------------------------------------------------------------- 00540 // Decompose a half to a bitwise representation 00541 // -------------------------------------------------------------------------- 00542 static unsigned int jit_half_to_bits(half y) 00543 { 00544 register int s = (y >> 15) & 0x00000001; 00545 register int e = (y >> 10) & 0x0000001f; 00546 register int m = y & 0x000003ff; 00547 00548 if (e == 0) 00549 { 00550 if (m == 0) // Plus or minus zero 00551 { 00552 return s << 31; 00553 } 00554 else // Denormalized number -- renormalize it 00555 { 00556 while (!(m & 0x00000400)) 00557 { 00558 m <<= 1; 00559 e -= 1; 00560 } 00561 00562 e += 1; 00563 m &= ~0x00000400; 00564 } 00565 } 00566 else if (e == 31) 00567 { 00568 if (m == 0) // Inf 00569 { 00570 return (s << 31) | 0x7f800000; 00571 } 00572 else // NaN 00573 { 00574 return (s << 31) | 0x7f800000 | (m << 13); 00575 } 00576 } 00577 00578 e = e + (127 - 15); 00579 m = m << 13; 00580 00581 return (s << 31) | (e << 23) | m; 00582 } 00583 00584 // -------------------------------------------------------------------------- 00585 // Overflow handler for float-to-half conversion which generates a 00586 // hardware floating-point overflow, which may be trapped by the OS. 00587 // -------------------------------------------------------------------------- 00588 static float jit_half_overflow() 00589 { 00590 int i; 00591 volatile float f = 1e10; 00592 00593 for (i = 0; i < 10; i++) 00594 f *= f; // this will overflow before 00595 // the for�loop terminates 00596 return f; 00597 } 00598 00599 // --------------------------------------------------------------------------
Copyright © 2008, Cycling '74