|
|
1.1.1.2 ! root 1: /* $Id: ieee754-misc.c,v 1.3 2006/11/16 01:05:56 fredette Exp $ */ 1.1 root 2: 3: /* ic/ieee754/ieee754-misc.c - IEEE 754 miscellaneous: */ 4: 5: /* 6: * Copyright (c) 2004 Matt Fredette 7: * All rights reserved. 8: * 9: * Redistribution and use in source and binary forms, with or without 10: * modification, are permitted provided that the following conditions 11: * are met: 12: * 1. Redistributions of source code must retain the above copyright 13: * notice, this list of conditions and the following disclaimer. 14: * 2. Redistributions in binary form must reproduce the above copyright 15: * notice, this list of conditions and the following disclaimer in the 16: * documentation and/or other materials provided with the distribution. 17: * 3. All advertising materials mentioning features or use of this software 18: * must display the following acknowledgement: 19: * This product includes software developed by Matt Fredette. 20: * 4. The name of the author may not be used to endorse or promote products 21: * derived from this software without specific prior written permission. 22: * 23: * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 24: * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 25: * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 26: * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, 27: * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 28: * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 29: * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 30: * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 31: * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 32: * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 33: * POSSIBILITY OF SUCH DAMAGE. 34: */ 35: 36: #include <tme/common.h> 1.1.1.2 ! root 37: _TME_RCSID("$Id: ieee754-misc.c,v 1.3 2006/11/16 01:05:56 fredette Exp $"); 1.1 root 38: 39: /* includes: */ 40: #include <tme/ic/ieee754.h> 41: 42: /* constants: */ 43: 44: const tme_uint32_t tme_ieee754_single_constant_pi = 0x40490fdb; 45: const tme_uint32_t tme_ieee754_single_constant_log10_2 = 0x3e9a209b; 46: const tme_uint32_t tme_ieee754_single_constant_e = 0x402df854; 47: const tme_uint32_t tme_ieee754_single_constant_log2_e = 0x3fb8aa3b; 48: const tme_uint32_t tme_ieee754_single_constant_log10_e = 0x3ede5bd9; 49: const tme_uint32_t tme_ieee754_single_constant_zero = 0x00000000; 50: const tme_uint32_t tme_ieee754_single_constant_ln_2 = 0x3f317218; 51: const tme_uint32_t tme_ieee754_single_constant_ln_10 = 0x40135d8e; 52: const tme_uint32_t tme_ieee754_single_constant_one = 0x3f800000; 53: const struct tme_ieee754_double_constant tme_ieee754_double_constant_pi = { 0x400921fb, 0x5421d100 }; 54: const struct tme_ieee754_double_constant tme_ieee754_double_constant_log10_2 = { 0x3fd34413, 0x509f79ff }; 55: const struct tme_ieee754_double_constant tme_ieee754_double_constant_e = { 0x4005bf0a, 0x8b145769 }; 56: const struct tme_ieee754_double_constant tme_ieee754_double_constant_log2_e = { 0x3ff71547, 0x652b82fe }; 57: const struct tme_ieee754_double_constant tme_ieee754_double_constant_log10_e = { 0x3fdbcb7b, 0x1526e50e }; 58: const struct tme_ieee754_double_constant tme_ieee754_double_constant_zero = { 0x00000000, 0x00000000 }; 59: const struct tme_ieee754_double_constant tme_ieee754_double_constant_ln_2 = { 0x3fe62e42, 0xfefa39ef }; 60: const struct tme_ieee754_double_constant tme_ieee754_double_constant_ln_10 = { 0x40026bb1, 0xbbb55516 }; 61: const struct tme_ieee754_double_constant tme_ieee754_double_constant_one = { 0x3ff00000, 0x00000000 }; 62: const struct tme_ieee754_extended80_constant tme_ieee754_extended80_constant_pi = { 0x4000, 0xc90fdaa2, 0x2168c000 }; 63: const struct tme_ieee754_extended80_constant tme_ieee754_extended80_constant_log10_2 = { 0x3ffd, 0x9a209a84, 0xfbcff800 }; 64: const struct tme_ieee754_extended80_constant tme_ieee754_extended80_constant_e = { 0x4000, 0xadf85458, 0xa2bb4800 }; 65: const struct tme_ieee754_extended80_constant tme_ieee754_extended80_constant_log2_e = { 0x3fff, 0xb8aa3b29, 0x5c17f000 }; 66: const struct tme_ieee754_extended80_constant tme_ieee754_extended80_constant_log10_e = { 0x3ffd, 0xde5bd8a9, 0x37287000 }; 67: const struct tme_ieee754_extended80_constant tme_ieee754_extended80_constant_zero = { 0x0000, 0x00000000, 0x00000000 }; 68: const struct tme_ieee754_extended80_constant tme_ieee754_extended80_constant_ln_2 = { 0x3ffe, 0xb17217f7, 0xd1cf7800 }; 69: const struct tme_ieee754_extended80_constant tme_ieee754_extended80_constant_ln_10 = { 0x4000, 0x935d8ddd, 0xaaa8b000 }; 70: const struct tme_ieee754_extended80_constant tme_ieee754_extended80_constant_one = { 0x3fff, 0x80000000, 0x00000000 }; 71: 72: /* IEEE 754 single precision values of the form 2^x, where x is a power of two: */ 73: const tme_uint32_t tme_ieee754_single_constant_2e2ex[] = { 74: 75: /* 2^1: */ 76: 0x40000000, 77: 78: /* 2^2: */ 79: 0x40800000, 80: 81: /* 2^4: */ 82: 0x41800000, 83: 84: /* 2^8: */ 85: 0x43800000, 86: 87: /* 2^16: */ 88: 0x47800000, 89: 90: /* 2^32: */ 91: 0x4f800000, 92: 93: /* 2^64: */ 94: 0x5f800000 95: }; 96: 97: /* IEEE 754 single precision values of the form 2^-x, where x is a power of two: */ 98: const tme_uint32_t tme_ieee754_single_constant_2e_minus_2ex[] = { 99: 100: /* 2^-1: */ 101: 0x3f000000, 102: 103: /* 2^-2: */ 104: 0x3e800000, 105: 106: /* 2^-4: */ 107: 0x3d800000, 108: 109: /* 2^-8: */ 110: 0x3b800000, 111: 112: /* 2^-16: */ 113: 0x37800000, 114: 115: /* 2^-32: */ 116: 0x2f800000, 117: 118: /* 2^-64: */ 119: 0x1f800000 120: }; 121: 122: /* IEEE 754 single precision values of the form 10^x, where x is a power of two: */ 123: const tme_uint32_t tme_ieee754_single_constant_10e2ex[] = { 124: 125: /* 10^1: */ 126: 0x41200000, 127: 128: /* 10^2: */ 129: 0x42c80000, 130: 131: /* 10^4: */ 132: 0x461c4000, 133: 134: /* 10^8: */ 135: 0x4cbebc20, 136: 137: /* 10^16: */ 138: 0x5a0e1bca, 139: 140: /* 10^32: */ 141: 0x749dc5ae 142: }; 143: 144: /* IEEE 754 single precision values of the form 10^-x, where x is a power of two: */ 145: const tme_uint32_t tme_ieee754_single_constant_10e_minus_2ex[] = { 146: 147: /* 10^-1: */ 148: 0x3dcccccd, 149: 150: /* 10^-2: */ 151: 0x3c23d70b, 152: 153: /* 10^-4: */ 154: 0x38d1b719, 155: 156: /* 10^-8: */ 157: 0x322bcc7a, 158: 159: /* 10^-16: */ 160: 0x24e6959d, 161: 162: /* 10^-32: */ 163: 0x0a4fb12e 164: }; 165: 166: /* IEEE 754 double precision values of the form 2^x, where x is a power of two: */ 167: const struct tme_ieee754_double_constant tme_ieee754_double_constant_2e2ex[] = { 168: 169: /* 2^1: */ 170: { 0x40000000, 0x00000000 }, 171: 172: /* 2^2: */ 173: { 0x40100000, 0x00000000 }, 174: 175: /* 2^4: */ 176: { 0x40300000, 0x00000000 }, 177: 178: /* 2^8: */ 179: { 0x40700000, 0x00000000 }, 180: 181: /* 2^16: */ 182: { 0x40f00000, 0x00000000 }, 183: 184: /* 2^32: */ 185: { 0x41f00000, 0x00000000 }, 186: 187: /* 2^64: */ 188: { 0x43f00000, 0x00000000 }, 189: 190: /* 2^128: */ 191: { 0x47f00000, 0x00000000 }, 192: 193: /* 2^256: */ 194: { 0x4ff00000, 0x00000000 }, 195: 196: /* 2^512: */ 197: { 0x5ff00000, 0x00000000 } 198: }; 199: 200: /* IEEE 754 double precision values of the form 2^-x, where x is a power of two: */ 201: const struct tme_ieee754_double_constant tme_ieee754_double_constant_2e_minus_2ex[] = { 202: 203: /* 2^-1: */ 204: { 0x3fe00000, 0x00000000 }, 205: 206: /* 2^-2: */ 207: { 0x3fd00000, 0x00000000 }, 208: 209: /* 2^-4: */ 210: { 0x3fb00000, 0x00000000 }, 211: 212: /* 2^-8: */ 213: { 0x3f700000, 0x00000000 }, 214: 215: /* 2^-16: */ 216: { 0x3ef00000, 0x00000000 }, 217: 218: /* 2^-32: */ 219: { 0x3df00000, 0x00000000 }, 220: 221: /* 2^-64: */ 222: { 0x3bf00000, 0x00000000 }, 223: 224: /* 2^-128: */ 225: { 0x37f00000, 0x00000000 }, 226: 227: /* 2^-256: */ 228: { 0x2ff00000, 0x00000000 }, 229: 230: /* 2^-512: */ 231: { 0x1ff00000, 0x00000000 } 232: }; 233: 234: /* IEEE 754 double precision values of the form 10^x, where x is a power of two: */ 235: const struct tme_ieee754_double_constant tme_ieee754_double_constant_10e2ex[] = { 236: 237: /* 10^1: */ 238: { 0x40240000, 0x00000000 }, 239: 240: /* 10^2: */ 241: { 0x40590000, 0x00000000 }, 242: 243: /* 10^4: */ 244: { 0x40c38800, 0x00000000 }, 245: 246: /* 10^8: */ 247: { 0x4197d784, 0x00000000 }, 248: 249: /* 10^16: */ 250: { 0x4341c379, 0x37e08000 }, 251: 252: /* 10^32: */ 253: { 0x4693b8b5, 0xb5056e17 }, 254: 255: /* 10^64: */ 256: { 0x4d384f03, 0xe93ff9f6 }, 257: 258: /* 10^128: */ 259: { 0x5a827748, 0xf9301d33 }, 260: 261: /* 10^256: */ 262: { 0x75154fdd, 0x7f73bf3f } 263: }; 264: 265: /* IEEE 754 double precision values of the form 10^-x, where x is a power of two: */ 266: const struct tme_ieee754_double_constant tme_ieee754_double_constant_10e_minus_2ex[] = { 267: 268: /* 10^-1: */ 269: { 0x3fb99999, 0x9999999a }, 270: 271: /* 10^-2: */ 272: { 0x3f847ae1, 0x47ae147c }, 273: 274: /* 10^-4: */ 275: { 0x3f1a36e2, 0xeb1c4330 }, 276: 277: /* 10^-8: */ 278: { 0x3e45798e, 0xe2308c3f }, 279: 280: /* 10^-16: */ 281: { 0x3c9cd2b2, 0x97d889ca }, 282: 283: /* 10^-32: */ 284: { 0x3949f623, 0xd5a8a74c }, 285: 286: /* 10^-64: */ 287: { 0x32a50ffd, 0x44f4a766 }, 288: 289: /* 10^-128: */ 290: { 0x255bba08, 0xcf8c9808 }, 291: 292: /* 10^-256: */ 293: { 0x0ac80628, 0x64ac6ffd } 294: }; 295: 296: /* IEEE 754 extended80 precision values of the form 2^x, where x is a power of two: */ 297: const struct tme_ieee754_extended80_constant tme_ieee754_extended80_constant_2e2ex[] = { 298: 299: /* 2^1: */ 300: { 0x4000, 0x80000000, 0x00000000 }, 301: 302: /* 2^2: */ 303: { 0x4001, 0x80000000, 0x00000000 }, 304: 305: /* 2^4: */ 306: { 0x4003, 0x80000000, 0x00000000 }, 307: 308: /* 2^8: */ 309: { 0x4007, 0x80000000, 0x00000000 }, 310: 311: /* 2^16: */ 312: { 0x400f, 0x80000000, 0x00000000 }, 313: 314: /* 2^32: */ 315: { 0x401f, 0x80000000, 0x00000000 }, 316: 317: /* 2^64: */ 318: { 0x403f, 0x80000000, 0x00000000 }, 319: 320: /* 2^128: */ 321: { 0x407f, 0x80000000, 0x00000000 }, 322: 323: /* 2^256: */ 324: { 0x40ff, 0x80000000, 0x00000000 }, 325: 326: /* 2^512: */ 327: { 0x41ff, 0x80000000, 0x00000000 }, 328: 329: /* 2^1024: */ 330: { 0x43ff, 0x80000000, 0x00000000 }, 331: 332: /* 2^2048: */ 333: { 0x47ff, 0x80000000, 0x00000000 }, 334: 335: /* 2^4096: */ 336: { 0x4fff, 0x80000000, 0x00000000 }, 337: 338: /* 2^8192: */ 339: { 0x5fff, 0x80000000, 0x00000000 } 340: }; 341: 342: /* IEEE 754 extended80 precision values of the form 2^-x, where x is a power of two: */ 343: const struct tme_ieee754_extended80_constant tme_ieee754_extended80_constant_2e_minus_2ex[] = { 344: 345: /* 2^-1: */ 346: { 0x3ffe, 0x80000000, 0x00000000 }, 347: 348: /* 2^-2: */ 349: { 0x3ffd, 0x80000000, 0x00000000 }, 350: 351: /* 2^-4: */ 352: { 0x3ffb, 0x80000000, 0x00000000 }, 353: 354: /* 2^-8: */ 355: { 0x3ff7, 0x80000000, 0x00000000 }, 356: 357: /* 2^-16: */ 358: { 0x3fef, 0x80000000, 0x00000000 }, 359: 360: /* 2^-32: */ 361: { 0x3fdf, 0x80000000, 0x00000000 }, 362: 363: /* 2^-64: */ 364: { 0x3fbf, 0x80000000, 0x00000000 }, 365: 366: /* 2^-128: */ 367: { 0x3f7f, 0x80000000, 0x00000000 }, 368: 369: /* 2^-256: */ 370: { 0x3eff, 0x80000000, 0x00000000 }, 371: 372: /* 2^-512: */ 373: { 0x3dff, 0x80000000, 0x00000000 }, 374: 375: /* 2^-1024: */ 376: { 0x3bff, 0x80000000, 0x00000000 }, 377: 378: /* 2^-2048: */ 379: { 0x37ff, 0x80000000, 0x00000000 }, 380: 381: /* 2^-4096: */ 382: { 0x2fff, 0x80000000, 0x00000000 }, 383: 384: /* 2^-8192: */ 385: { 0x1fff, 0x80000000, 0x00000000 } 386: }; 387: 388: /* IEEE 754 extended80 precision values of the form 10^x, where x is a power of two: */ 389: const struct tme_ieee754_extended80_constant tme_ieee754_extended80_constant_10e2ex[] = { 390: 391: /* 10^1: */ 392: { 0x4002, 0xa0000000, 0x00000000 }, 393: 394: /* 10^2: */ 395: { 0x4005, 0xc8000000, 0x00000000 }, 396: 397: /* 10^4: */ 398: { 0x400c, 0x9c400000, 0x00000000 }, 399: 400: /* 10^8: */ 401: { 0x4019, 0xbebc2000, 0x00000000 }, 402: 403: /* 10^16: */ 404: { 0x4034, 0x8e1bc9bf, 0x04000000 }, 405: 406: /* 10^32: */ 407: { 0x4069, 0x9dc5ada8, 0x2b70b800 }, 408: 409: /* 10^64: */ 410: { 0x40d3, 0xc2781f49, 0xffcfb000 }, 411: 412: /* 10^128: */ 413: { 0x41a8, 0x93ba47c9, 0x80e99800 }, 414: 415: /* 10^256: */ 416: { 0x4351, 0xaa7eebfb, 0x9df9f800 }, 417: 418: /* 10^512: */ 419: { 0x46a3, 0xe319a0ae, 0xa60ed800 }, 420: 421: /* 10^1024: */ 422: { 0x4d48, 0xc9767586, 0x81758800 }, 423: 424: /* 10^2048: */ 425: { 0x5a92, 0x9e8b3b5d, 0xc53e2000 }, 426: 427: /* 10^4096: */ 428: { 0x7525, 0xc4605202, 0x8a227800 } 429: }; 430: 431: /* IEEE 754 extended80 precision values of the form 10^-x, where x is a power of two: */ 432: const struct tme_ieee754_extended80_constant tme_ieee754_extended80_constant_10e_minus_2ex[] = { 433: 434: /* 10^-1: */ 435: { 0x3ffb, 0xcccccccc, 0xccccd000 }, 436: 437: /* 10^-2: */ 438: { 0x3ff8, 0xa3d70a3d, 0x70a3e000 }, 439: 440: /* 10^-4: */ 441: { 0x3ff1, 0xd1b71758, 0xe2198000 }, 442: 443: /* 10^-8: */ 444: { 0x3fe4, 0xabcc7711, 0x8461f800 }, 445: 446: /* 10^-16: */ 447: { 0x3fc9, 0xe69594be, 0xc44e5000 }, 448: 449: /* 10^-32: */ 450: { 0x3f94, 0xcfb11ead, 0x453a6000 }, 451: 452: /* 10^-64: */ 453: { 0x3f2a, 0xa87fea27, 0xa53b3000 }, 454: 455: /* 10^-128: */ 456: { 0x3e55, 0xddd0467c, 0x64c04000 }, 457: 458: /* 10^-256: */ 459: { 0x3cac, 0xc0314325, 0x637fe800 }, 460: 461: /* 10^-512: */ 462: { 0x395a, 0x9049ee32, 0xdb2c8800 }, 463: 464: /* 10^-1024: */ 465: { 0x32b5, 0xa2a682a5, 0xda6b6800 }, 466: 467: /* 10^-2048: */ 468: { 0x256b, 0xceae534f, 0x34682000 }, 469: 470: /* 10^-4096: */ 471: { 0x0ad8, 0xa6dd04c8, 0xd31f4800 } 472: }; 473: 474: /* the native floating-point exception function: */ 475: void 476: tme_ieee754_exception_float(int exceptions, void *_ieee754_ctl) 477: { 478: struct tme_ieee754_ctl *ieee754_ctl; 479: 480: /* recover our global control: */ 481: ieee754_ctl = (struct tme_ieee754_ctl *) _ieee754_ctl; 482: 483: /* signal the exception: */ 484: (*ieee754_ctl->tme_ieee754_ctl_exception)(ieee754_ctl, exceptions); 485: } 486: 487: /* the softfloat unlock function: */ 488: int 489: tme_ieee754_unlock_softfloat(void) 490: { 491: int exceptions; 492: 493: tme_ieee754_global_ctl = NULL; 494: exceptions = tme_ieee754_global_exceptions; 495: tme_mutex_unlock(&tme_ieee754_global_mutex); 496: return (exceptions); 497: } 498: 1.1.1.2 ! root 499: /* for processors that manage a fundamentally single-precision ! 500: floating-point register file, but that allow size-aligned sets of ! 501: registers to combine into double- and quad-precision registers, ! 502: this manages the register set and converts register contents ! 503: between formats: */ ! 504: void ! 505: tme_ieee754_fpreg_format(struct tme_float *fpregs, ! 506: unsigned int *fpreg_sizes, ! 507: unsigned int fpreg_number, ! 508: unsigned int fpreg_size_new) ! 509: { ! 510: unsigned int flags; ! 511: unsigned int fpreg_size_old; ! 512: unsigned int format_new_ieee754; ! 513: const unsigned int formats_ieee754[] = ! 514: { 0, ! 515: TME_FLOAT_FORMAT_IEEE754_SINGLE, ! 516: TME_FLOAT_FORMAT_IEEE754_DOUBLE, ! 517: 0, ! 518: TME_FLOAT_FORMAT_IEEE754_QUAD }; ! 519: unsigned int fpreg_i; ! 520: unsigned int fpreg_j; ! 521: unsigned int single_word_i; ! 522: unsigned int single_word_i_mask; ! 523: tme_uint32_t value_single_buffer; ! 524: const union tme_value64 *value_double; ! 525: union tme_value64 value_double_buffer; ! 526: const struct tme_float_ieee754_quad *value_quad; ! 527: struct tme_float_ieee754_quad value_quad_buffer; ! 528: tme_uint32_t single_words[sizeof(struct tme_float_ieee754_quad) / sizeof(tme_uint32_t)]; ! 529: ! 530: /* remove the flags from the size: */ ! 531: flags = (fpreg_size_new & (TME_IEEE754_FPREG_FORMAT_BUILTIN | TME_IEEE754_FPREG_FORMAT_ENDIAN_BIG)); ! 532: fpreg_size_new ^= flags; ! 533: ! 534: /* the size of the new IEEE754 format must be a power of two: */ ! 535: assert (fpreg_size_new > 0 ! 536: && fpreg_size_new < TME_ARRAY_ELS(single_words) ! 537: && (fpreg_size_new & (fpreg_size_new - 1)) == 0); ! 538: ! 539: /* the register number must be aligned: */ ! 540: assert ((fpreg_number & (fpreg_size_new - 1)) == 0); ! 541: ! 542: /* if this register is not already the right size: */ ! 543: fpreg_size_old = fpreg_sizes[fpreg_number]; ! 544: if (__tme_predict_false(fpreg_size_old != fpreg_size_new)) { ! 545: ! 546: /* convert all of the registers that contain any part of this ! 547: register's value into single-precision format: */ ! 548: fpreg_j = TME_MAX(fpreg_size_old, fpreg_size_new); ! 549: fpreg_i = fpreg_number & (0 - fpreg_j); ! 550: fpreg_j += fpreg_i; ! 551: do { ! 552: ! 553: /* get the current size of this register and its ! 554: single-precision words: */ ! 555: fpreg_size_old = fpreg_sizes[fpreg_i]; ! 556: switch (fpreg_size_old) { ! 557: ! 558: default: assert(FALSE); ! 559: ! 560: /* a single-precision register: */ ! 561: case (sizeof(tme_uint32_t) / sizeof(tme_uint32_t)): ! 562: single_words[0] = *tme_ieee754_single_value_get(&fpregs[fpreg_i], &value_single_buffer); ! 563: break; ! 564: ! 565: /* a double-precision register: */ ! 566: case (sizeof(union tme_value64) / sizeof(tme_uint32_t)): ! 567: value_double = tme_ieee754_double_value_get(&fpregs[fpreg_i], &value_double_buffer); ! 568: single_words[0] = value_double->tme_value64_uint32_lo; ! 569: single_words[1] = value_double->tme_value64_uint32_hi; ! 570: break; ! 571: ! 572: /* a quad-precision register: */ ! 573: case (sizeof(struct tme_float_ieee754_quad) / sizeof(tme_uint32_t)): ! 574: value_quad = tme_ieee754_quad_value_get(&fpregs[fpreg_i], &value_quad_buffer); ! 575: single_words[0] = value_quad->tme_float_ieee754_quad_lo.tme_value64_uint32_lo; ! 576: single_words[1] = value_quad->tme_float_ieee754_quad_lo.tme_value64_uint32_hi; ! 577: single_words[2] = value_quad->tme_float_ieee754_quad_hi.tme_value64_uint32_lo; ! 578: single_words[3] = value_quad->tme_float_ieee754_quad_hi.tme_value64_uint32_hi; ! 579: break; ! 580: } ! 581: ! 582: /* if this floating-point register file is organized in ! 583: little-endian fashion, the least significant single-precision ! 584: word goes with the first register, else the most significant ! 585: single-precision word goes with the first register: */ ! 586: single_word_i_mask ! 587: = (((flags & TME_IEEE754_FPREG_FORMAT_ENDIAN_BIG) == 0) ! 588: ? 0 ! 589: : (fpreg_size_old - 1)); ! 590: ! 591: /* make all of the covered floating-point registers single ! 592: precision: */ ! 593: single_word_i = 0; ! 594: do { ! 595: fpregs[fpreg_i].tme_float_format = TME_FLOAT_FORMAT_IEEE754_SINGLE; ! 596: fpregs[fpreg_i].tme_float_value_ieee754_single = single_words[single_word_i ^ single_word_i_mask]; ! 597: fpreg_sizes[fpreg_i] = sizeof(tme_uint32_t) / sizeof(tme_uint32_t); ! 598: single_word_i++; ! 599: fpreg_i++; ! 600: } while (--fpreg_size_old > 0); ! 601: } while (fpreg_i < fpreg_j); ! 602: ! 603: /* if the desired format isn't single-precision: */ ! 604: if (fpreg_size_new != (sizeof(tme_uint32_t) / sizeof(tme_uint32_t))) { ! 605: ! 606: /* collect the single-precision words from the covered ! 607: floating-point registers, and mark all of them as now ! 608: belonging to this larger register: */ ! 609: fpreg_i = fpreg_number; ! 610: fpreg_j = fpreg_i + fpreg_size_new; ! 611: do { ! 612: single_words[fpreg_i - fpreg_number] ! 613: = *tme_ieee754_single_value_get(&fpregs[fpreg_i], &value_single_buffer); ! 614: fpreg_sizes[fpreg_i] = fpreg_size_new; ! 615: fpreg_i++; ! 616: } while (fpreg_i < fpreg_j); ! 617: ! 618: /* if this floating-point register file is organized in ! 619: little-endian fashion, the first single-precision register ! 620: provides the least significant word, else the first ! 621: single-precision register provides the most significant word: */ ! 622: single_word_i_mask ! 623: = (((flags & TME_IEEE754_FPREG_FORMAT_ENDIAN_BIG) == 0) ! 624: ? 0 ! 625: : (fpreg_size_new - 1)); ! 626: ! 627: switch (fpreg_size_new) { ! 628: ! 629: default: assert(FALSE); ! 630: ! 631: /* a double-precision register: */ ! 632: case (sizeof(union tme_value64) / sizeof(tme_uint32_t)): ! 633: fpregs[fpreg_number].tme_float_format = TME_FLOAT_FORMAT_IEEE754_DOUBLE; ! 634: fpregs[fpreg_number].tme_float_value_ieee754_double.tme_value64_uint32_lo ! 635: = single_words[0 ^ single_word_i_mask]; ! 636: fpregs[fpreg_number].tme_float_value_ieee754_double.tme_value64_uint32_hi ! 637: = single_words[1 ^ single_word_i_mask]; ! 638: break; ! 639: ! 640: /* a quad-precision register: */ ! 641: case (sizeof(struct tme_float_ieee754_quad) / sizeof(tme_uint32_t)): ! 642: fpregs[fpreg_number].tme_float_format = TME_FLOAT_FORMAT_IEEE754_QUAD; ! 643: fpregs[fpreg_number].tme_float_value_ieee754_quad.tme_float_ieee754_quad_lo.tme_value64_uint32_lo ! 644: = single_words[0 ^ single_word_i_mask]; ! 645: fpregs[fpreg_number].tme_float_value_ieee754_quad.tme_float_ieee754_quad_lo.tme_value64_uint32_hi ! 646: = single_words[1 ^ single_word_i_mask]; ! 647: fpregs[fpreg_number].tme_float_value_ieee754_quad.tme_float_ieee754_quad_hi.tme_value64_uint32_lo ! 648: = single_words[2 ^ single_word_i_mask]; ! 649: fpregs[fpreg_number].tme_float_value_ieee754_quad.tme_float_ieee754_quad_hi.tme_value64_uint32_hi ! 650: = single_words[3 ^ single_word_i_mask]; ! 651: break; ! 652: } ! 653: } ! 654: } ! 655: ! 656: /* if the register must be in the exact IEEE754 format (as opposed ! 657: to the best-match, but different, builtin type), and it isn't in ! 658: that format: */ ! 659: format_new_ieee754 = formats_ieee754[fpreg_size_new]; ! 660: if (__tme_predict_false((flags & TME_IEEE754_FPREG_FORMAT_BUILTIN) == 0 ! 661: && fpregs[fpreg_number].tme_float_format != format_new_ieee754)) { ! 662: ! 663: /* convert from the builtin type to the IEEE754 format: */ ! 664: switch (format_new_ieee754) { ! 665: default: assert(FALSE); ! 666: case TME_FLOAT_FORMAT_IEEE754_SINGLE: ! 667: fpregs[fpreg_number].tme_float_value_ieee754_single ! 668: = *tme_ieee754_single_value_get(&fpregs[fpreg_number], &value_single_buffer); ! 669: break; ! 670: case TME_FLOAT_FORMAT_IEEE754_DOUBLE: ! 671: fpregs[fpreg_number].tme_float_value_ieee754_double ! 672: = *tme_ieee754_double_value_get(&fpregs[fpreg_number], &value_double_buffer); ! 673: break; ! 674: case TME_FLOAT_FORMAT_IEEE754_QUAD: ! 675: fpregs[fpreg_number].tme_float_value_ieee754_quad ! 676: = *tme_ieee754_quad_value_get(&fpregs[fpreg_number], &value_quad_buffer); ! 677: break; ! 678: } ! 679: fpregs[fpreg_number].tme_float_format = format_new_ieee754; ! 680: } ! 681: } ! 682: 1.1 root 683: #include "ieee754-misc-auto.c"
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.