Open64 (mfef90, whirl2f, and IR tools)
TAG: version-openad; SVN changeset: 916
|
00001 /* 00002 00003 Copyright (C) 2000, 2001 Silicon Graphics, Inc. All Rights Reserved. 00004 00005 This program is free software; you can redistribute it and/or modify it 00006 under the terms of version 2 of the GNU General Public License as 00007 published by the Free Software Foundation. 00008 00009 This program is distributed in the hope that it would be useful, but 00010 WITHOUT ANY WARRANTY; without even the implied warranty of 00011 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 00012 00013 Further, this software is distributed without any warranty that it is 00014 free of the rightful claim of any third person regarding infringement 00015 or the like. Any license provided herein, whether implied or 00016 otherwise, applies only to this software file. Patent licenses, if 00017 any, provided herein do not apply to combinations of this program with 00018 other software, or any other product whatsoever. 00019 00020 You should have received a copy of the GNU General Public License along 00021 with this program; if not, write the Free Software Foundation, Inc., 59 00022 Temple Place - Suite 330, Boston MA 02111-1307, USA. 00023 00024 Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pky, 00025 Mountain View, CA 94043, or: 00026 00027 http://www.sgi.com 00028 00029 For further information regarding this notice, see: 00030 00031 http://oss.sgi.com/projects/GenInfo/NoticeExplan 00032 00033 */ 00034 00035 00036 /* ==================================================================== 00037 * ==================================================================== 00038 * 00039 * 00040 * Revision history: 00041 * 28-jun-93 - Original Version 00042 * 00043 * Description: Convert a decimal number to a quad precision binary. 00044 * 00045 * ==================================================================== 00046 * ==================================================================== 00047 */ 00048 00049 static char *source_file = __FILE__; 00050 00051 /* Macros to pull apart parts of single and double precision 00052 * floating point numbers in IEEE format 00053 */ 00054 00055 /* double precision */ 00056 00057 typedef union { 00058 struct { 00059 unsigned sign :1; 00060 unsigned exp :11; 00061 unsigned hi :20; 00062 unsigned lo :32; 00063 } fparts; 00064 struct { 00065 unsigned sign :1; 00066 unsigned exp :11; 00067 unsigned qnan_bit :1; 00068 unsigned hi :19; 00069 unsigned lo :32; 00070 } nparts; 00071 struct { 00072 unsigned hi; 00073 unsigned lo; 00074 } fwords; 00075 double d; 00076 } _dval; 00077 00078 /* quad precision */ 00079 00080 typedef union { 00081 struct { 00082 _dval hi; 00083 _dval lo; 00084 } qparts; 00085 struct { 00086 unsigned long long hi; 00087 unsigned long long lo; 00088 } fwords; 00089 } _ldblval; 00090 00091 /* parts of a double precision floating point number */ 00092 00093 #define SIGNBIT(X) (((_dval *)&(X))->fparts.sign) 00094 #define EXPONENT(X) (((_dval *)&(X))->fparts.exp) 00095 #define MAXCOUNT 34 00096 00097 00098 #include <math.h> 00099 #include "defs.h" 00100 #include "quad.h" 00101 00102 00103 extern void c_qtenscale( _ldblval *, INT32, INT32 *); 00104 extern QUAD c_a_to_q(char *str, INT *p_err ); 00105 static QUAD c_atoq(char *buffer, INT32 ndigit, INT32 exp); 00106 00107 /* ascii to quad */ 00108 00109 #pragma weak c_a_to_q = __c_a_to_q 00110 #define c_a_to_q __c_a_to_q 00111 00112 #define MAXDIGITS 34 00113 00114 00115 /* ==================================================================== 00116 * 00117 * FunctionName: c_a_to_q 00118 * 00119 * Description: Convert a decimal number to quad precision 00120 * Except for minor changes, this routine is the same as atold() 00121 * in libc. Included here, so we can do cross compilations on 00122 * machines not supporting quad precision. 00123 * 00124 * 00125 * ==================================================================== 00126 */ 00127 00128 QUAD 00129 c_a_to_q(char *s, INT *p_err ) 00130 { 00131 register UINT32 c; 00132 register UINT32 negate, decimal_point; 00133 register char *d; 00134 register INT32 exp; 00135 QUAD x; 00136 register INT32 dpchar; 00137 char digits[MAXDIGITS]; 00138 00139 *p_err = 0; 00140 00141 while ( (c = *s++) == ' ' ) 00142 ; 00143 00144 /* process sign */ 00145 negate = 0; 00146 if (c == '+') { 00147 c = *s++; 00148 } 00149 else if (c == '-') { 00150 negate = 1; 00151 c = *s++; 00152 } 00153 d = digits; 00154 dpchar = '.' - '0'; 00155 decimal_point = 0; 00156 exp = 0; 00157 while (1) { 00158 c -= '0'; 00159 if (c < 10) { 00160 if (d == digits+MAXDIGITS) { 00161 /* ignore more than 34 digits, but adjust exponent */ 00162 exp += (decimal_point ^ 1); 00163 } 00164 else { 00165 if (c == 0 && d == digits) { 00166 /* ignore leading zeros */ 00167 ; 00168 } 00169 else { 00170 *d++ = c; 00171 } 00172 exp -= decimal_point; 00173 } 00174 } 00175 else if (c == dpchar && !decimal_point) { /* INTERNATIONAL */ 00176 decimal_point = 1; 00177 } 00178 else { 00179 break; 00180 } 00181 c = *s++; 00182 } 00183 if (d == digits) { 00184 x.hi = 0.0; 00185 x.lo = 0.0; 00186 return x; 00187 } 00188 if (c == 'e'-'0' || c == 'E'-'0') { 00189 register UINT32 negate_exp = 0; 00190 register INT32 e = 0; 00191 c = *s++; 00192 if (c == '+' || c == ' ') { 00193 c = *s++; 00194 } 00195 else if (c == '-') { 00196 negate_exp = 1; 00197 c = *s++; 00198 } 00199 if (c -= '0', c < 10) { 00200 do { 00201 if (e <= 340) 00202 e = e * 10 + c; 00203 else break; 00204 c = *s++; 00205 } 00206 while (c -= '0', c < 10); 00207 if (negate_exp) { 00208 e = -e; 00209 } 00210 if (e < -(323+MAXDIGITS) || e > 308) 00211 exp = e; 00212 else 00213 exp += e; 00214 } 00215 } 00216 00217 if (exp < -(324+MAXDIGITS)) { 00218 x.hi = 0.0; 00219 x.lo = 0.0; 00220 } 00221 else if (exp > 308) { 00222 x.hi = HUGE_VAL; 00223 x.lo = 0.0; 00224 } 00225 else { 00226 /* let c_atoq diagnose under- and over-flows */ 00227 /* if the input was == 0.0, we have already returned, 00228 so retval of +-Inf signals OVERFLOW, 0.0 UNDERFLOW 00229 */ 00230 00231 x = c_atoq (digits, d - digits, exp); 00232 } 00233 if (negate) { 00234 x.hi = -x.hi; 00235 x.lo = -x.lo; 00236 } 00237 return x; 00238 } 00239 00240 /* ==================================================================== 00241 * 00242 * FunctionName: c_atoq 00243 * 00244 * Description: Convert a decimal number to a quad precision binary. 00245 * 00246 * Except for minor changes, this routine is the same as _atoq() 00247 * in libc. Included here, so we can do cross compilations on 00248 * machines not supporting quad precision. 00249 * 00250 * ==================================================================== 00251 */ 00252 00253 static 00254 QUAD 00255 c_atoq(buffer,ndigit,exp) 00256 char *buffer; /* Values from 0 to 9, NOT ascii. 00257 * Leading zeros have been discarded, 00258 * except for the case of zero in which 00259 * case there is a single 0 digit. 00260 */ 00261 00262 INT32 ndigit; /* 1 <= ndigit <= 37. 00263 * Log2(1e37) = 122.9 bits, so the 00264 * number can be converted to a 128 bit 00265 * integer with room left over. 00266 */ 00267 00268 INT32 exp; /* The minimum quad numbers are 00269 * 00270 * 4.9406564584124654e-324 (denorm) and 00271 * 2.2250738585072014e-308 (norm). 00272 * 00273 * The maximum value is 00274 * 00275 * 1.7976931348623157e+308, 00276 * 00277 * therefore 00278 * -324-ndigit = -361 <= exp <= 308. 00279 */ 00280 { 00281 _ldblval value; /* the result */ 00282 #define HI (value.fwords.hi) /* top 64b of 124b integer */ 00283 #define LO (value.fwords.lo) /* bottom 60b of 124b integer */ 00284 /* later converted to 128b fraction */ 00285 00286 QUAD result; 00287 UINT32 guard; /* First guard bit */ 00288 UINT32 rest; /* Remaining 21 guard bits */ 00289 UINT64 lolo; /* lower 60b of LO */ 00290 UINT32 lohi; /* upper 4b of LO */ 00291 double z; /* canonical HI */ 00292 00293 INT32 exphi, explo; /* binary exponent */ 00294 INT32 nzero; /* number of non-zeros */ 00295 INT32 i; /* loop index */ 00296 INT32 x; /* temporary */ 00297 INT32 losign=0; /* sign of LO */ 00298 00299 char *bufferend; /* pointer to char after last digit */ 00300 00301 HI = 0; 00302 00303 /* Check for zero and treat it as a special case */ 00304 00305 if ((INT32) *buffer == 0){ 00306 result.hi = result.lo = 0.0; 00307 return ( result ); 00308 } 00309 00310 /* Convert the decimal digits to a binary integer. */ 00311 00312 bufferend = buffer + ndigit; 00313 HI = 0; 00314 LO = *buffer++; 00315 00316 /* the first batch of digits fits in LO */ 00317 for( i=1 ; buffer < bufferend && i<19; buffer++, i++ ){ 00318 LO *= 10; 00319 LO += *buffer; 00320 } 00321 00322 #if QUAD_DEBUG 00323 printf("halfway thru conversion: HI=0x%016llx\n",HI); 00324 printf(" LO=0x%016llx\n",LO); 00325 printf(" i=%d\n",i); 00326 #endif 00327 00328 if( buffer < bufferend ) { 00329 /* The second batch of digits affects both HI and LO */ 00330 00331 lolo = LO & (1Ull<<60)-1; /* Split LO into 60b */ 00332 lohi = LO >> 60; /* and 4b pieces */ 00333 00334 #if QUAD_DEBUG 00335 printf("After LO split: lohi=0x%x\n",lohi); 00336 printf(" lolo=0x%016llx\n",lolo); 00337 #endif 00338 00339 for( ; buffer < bufferend; buffer++ ){ 00340 lolo = 10*lolo + *buffer; /* Multiply by 10 and add digit */ 00341 #if QUAD_DEBUG 00342 printf("After 10*: lolo=0x%016llx\n",lolo); 00343 #endif 00344 lohi = 10*lohi + (lolo>>60); 00345 HI = 10*HI + (lohi>>4); 00346 lolo &= (1Ull<<60)-1; /* discard carries already propagated */ 00347 #if QUAD_DEBUG 00348 printf("After carry discard: lolo=0x%016llx\n",lolo); 00349 #endif 00350 lohi &= (1U << 4)-1; /* Are these two statements needed??? */ 00351 00352 #if QUAD_DEBUG 00353 printf("After iteration: lohi=0x%x\n",lohi); 00354 printf(" lolo=0x%016llx\n",lolo); 00355 #endif 00356 00357 } 00358 /* Reconstitute LO from its pieces. */ 00359 LO = lolo | ((UINT64) lohi)<<60; 00360 00361 #if QUAD_DEBUG 00362 printf("After reconstitution: HI=0x%016llx\n",HI); 00363 printf(" LO=0x%016llx\n",LO); 00364 #endif 00365 00366 } 00367 00368 #if QUAD_DEBUG 00369 printf("after conversion: HI=0x%016llx\n",HI); 00370 printf(" LO=0x%016llx\n",LO); 00371 #endif 00372 00373 /* Normalize HI-LO */ 00374 00375 exphi = 128; /* convert from 128b int to fraction */ 00376 if (HI == 0){ /* 64 bit shift */ 00377 HI = LO; 00378 LO = 0; 00379 exphi -= 64; 00380 } 00381 00382 /* Count number of non-zeroes in HI */ 00383 nzero = 0; 00384 if ( HI >> (32 ) ){ nzero = 32; } 00385 if ( HI >> (16 + nzero) ){ nzero += 16; } 00386 if ( HI >> ( 8 + nzero) ){ nzero += 8; } 00387 if ( HI >> ( 4 + nzero) ){ nzero += 4; } 00388 if ( HI >> ( 2 + nzero) ){ nzero += 2; } 00389 if ( HI >> ( 1 + nzero) ){ nzero += 1; } 00390 if ( HI >> ( nzero) ){ nzero += 1; } 00391 00392 /* Normalize */ 00393 HI = (HI << (64-nzero)) | (LO >> (nzero)); 00394 LO <<= 64-nzero; 00395 exphi -= 64-nzero; 00396 00397 /* At this point we have a 128b fraction and a binary exponent 00398 * but have yet to incorporate the decimal exponent. 00399 */ 00400 00401 #if QUAD_DEBUG 00402 printf("after normalization: HI=0x%016llx\n",HI); 00403 printf(" LO=0x%016llx\n",LO); 00404 printf(" nzero=%d\n",nzero); 00405 printf(" exphi=%d\n",exphi); 00406 #endif 00407 00408 /* multiply by 10^exp */ 00409 00410 c_qtenscale(&value,exp,&x); 00411 exphi += x; 00412 00413 #if QUAD_DEBUG 00414 printf("after multiplication: HI=0x%016llx\n",HI); 00415 printf(" LO=0x%016llx\n",LO); 00416 printf(" exphi=%d\n",exphi); 00417 #endif 00418 /* Round to 107 bits */ 00419 /* Take the 128 bits of HI and LO and divide them as follows 00420 * 00421 * before HI LO guard rest 00422 * 64b 64b 00423 * after 53b 54b 1b 20b 00424 * =11 of HI 00425 * +43 of LO 00426 */ 00427 00428 rest = LO & (1ULL<<20)-1; 00429 LO >>= 20; 00430 00431 #if QUAD_DEBUG 00432 printf("during split: LO=0x%016llx\n",LO); 00433 #endif 00434 00435 guard = LO & 1; 00436 LO >>= 1; 00437 00438 #if QUAD_DEBUG 00439 printf("during split: LO=0x%016llx\n",LO); 00440 #endif 00441 00442 LO |= (HI & (1ULL<<11)-1) << 43; 00443 HI >>= 11; 00444 00445 #if QUAD_DEBUG 00446 printf("after split: HI=0x%016llx\n",HI); 00447 printf(" LO=0x%016llx\n",LO); 00448 printf(" guard=%d\n",guard); 00449 printf(" rest=%lx\n",rest); 00450 #endif 00451 00452 /* LO&1 guard rest Action 00453 * 00454 * dc 0 dc none 00455 * 1 1 dc round 00456 * 0 1 0 none 00457 * 0 1 !=0 round 00458 */ 00459 00460 if(guard) { 00461 if(LO&1 || rest) { 00462 LO++; /* round */ 00463 HI += LO>>54; 00464 LO &= (1ULL<<54)-1; 00465 if(HI>>53) { /* carry all the way across */ 00466 HI >>= 1; /* renormalize */ 00467 exphi ++; 00468 } 00469 } 00470 } 00471 00472 explo = exphi-53; 00473 00474 #if QUAD_DEBUG 00475 printf("after rounding: HI=0x%016llx\n",HI); 00476 printf(" LO=0x%016llx\n",LO); 00477 printf(" exphi=%d\n",exphi); 00478 printf(" explo=%d\n",explo); 00479 #endif 00480 00481 /* Apply Dekker's algorithm */ 00482 /* Determine whether HI <- (double) HI+LO would change HI */ 00483 if( LO & (1ULL<<53) ) { /* high bit of LO on */ 00484 if(HI & 1 || LO & ((1ULL<<53)-1)) { 00485 HI++; /* round */ 00486 if(HI & (1ULL<<53)) { /* ripple carry */ 00487 HI >>= 1; 00488 exphi++; 00489 } 00490 LO = (1ULL<<54) - LO; /* complement LO */ 00491 losign = 1; 00492 00493 #if QUAD_DEBUG 00494 printf("after dekker: HI=0x%016llx\n",HI); 00495 printf(" LO=0x%016llx\n",LO); 00496 printf(" exphi=%d\n",exphi); 00497 printf(" explo=%d\n",explo); 00498 printf(" losign=%d\n",losign); 00499 #endif 00500 00501 } 00502 } 00503 if( LO ) { 00504 /* normalize LO */ 00505 if(LO & (1ULL<<53)) { /* LO = 0x0020000000000000 */ 00506 explo++; /* in all other cases this bit's zero */ 00507 LO >>=1; 00508 00509 #if QUAD_DEBUG 00510 printf("after right shift: LO=0x%016llx\n",LO); 00511 printf(" explo=%d\n",explo); 00512 #endif 00513 00514 } 00515 else { 00516 while( ! (LO & 0x0010000000000000ULL) ){ 00517 00518 #if QUAD_DEBUG 00519 printf("before left shift: LO=0x%016llx\n",LO); 00520 printf(" explo=%d\n",explo); 00521 #endif 00522 00523 explo--; 00524 LO <<= 1; 00525 } 00526 } 00527 explo--; /* we now have only 53 bits */ 00528 } 00529 00530 #if QUAD_DEBUG 00531 printf("after LO normalize: LO=0x%016llx\n",LO); 00532 printf(" explo=%d\n",explo); 00533 #endif 00534 00535 /* 00536 * Check for overflow and denorm...... 00537 * IEEE Double Precision Format 00538 * (From Table 7-8 of Kane and Heinrich) 00539 * 00540 * Fraction bits 52 00541 * Emax +1023 00542 * Emin -1022 00543 * Exponent bias +1023 00544 * Exponent bits 11 00545 * Integer bit hidden 00546 * Total width in bits 64 00547 */ 00548 00549 if (exphi > 1024) { /* overflow */ 00550 value.qparts.hi.d = value.qparts.lo.d = HUGE_VAL; 00551 00552 #if QUAD_DEBUG 00553 printf("Overflow: value.qparts.hi.d=0x%016llx\n",value.qparts.hi.d); 00554 printf(" value.qparts.lo.d=0x%016llx\n",value.qparts.lo.d); 00555 #endif 00556 00557 result.hi = value.qparts.hi.d; 00558 result.lo = value.qparts.lo.d; 00559 return ( result ); 00560 } 00561 if (exphi <= -1022) { /* HI denorm or underflow */ 00562 00563 value.qparts.lo.d = 0; /* therefore LO is zero */ 00564 exphi += 1022; 00565 if( exphi < -52 ) { /* underflow */ 00566 value.qparts.hi.d = 0; 00567 00568 #if QUAD_DEBUG 00569 printf("HI underflow: HI=0x%016llx\n",HI); 00570 printf(" exphi=%d\n",exphi); 00571 #endif 00572 00573 } 00574 else { /* denorm */ 00575 rest = HI & (1UL << exphi-1)-1; 00576 guard = (HI & (1UL << exphi)) >> exphi; 00577 HI >>= 1-exphi; /* exponent is zero */ 00578 00579 #if QUAD_DEBUG 00580 printf("HI denorm: HI=0x%016llx\n",HI); 00581 printf(" rest=0x%016llx\n",rest); 00582 printf(" guard=%d\n",guard); 00583 printf(" exphi=%d\n",exphi); 00584 #endif 00585 00586 /* Round */ 00587 if( guard ) { 00588 if( HI&1 || rest ) { 00589 HI++; 00590 if( HI == (1ULL << 52) ) { /* carry created a normal number */ 00591 HI = 0; 00592 EXPONENT(HI) = 1; 00593 } 00594 00595 #if QUAD_DEBUG 00596 printf("Round denorm: HI=0x%016llx\n",HI); 00597 #endif 00598 00599 } 00600 } 00601 } 00602 } 00603 else { /* HI is normal */ 00604 HI &= ~(1ULL << 52); /* hide hidden bit */ 00605 EXPONENT(HI) = exphi + 1022; /* add bias */ 00606 00607 #if QUAD_DEBUG 00608 printf("Normal HI: HI=0x%016llx\n",HI); 00609 #endif 00610 00611 } 00612 00613 if( explo <= -1022 ) { /* LO denorm or underflow */ 00614 explo += 1022; 00615 if( explo < -52 ) { /* underflow */ 00616 value.qparts.lo.d = 0; 00617 00618 #if QUAD_DEBUG 00619 printf("LO underflow: LO=0x%016llx\n",LO); 00620 printf(" explo=%d\n",explo); 00621 #endif 00622 00623 } 00624 else { /* denorm */ 00625 rest = LO & (1UL << explo-1)-1; 00626 guard = (LO & (1UL << explo)) >> explo; 00627 LO >>= 1-explo; /* exponent is zero */ 00628 00629 #if QUAD_DEBUG 00630 printf("LO denorm: LO=0x%016llx\n",LO); 00631 printf(" explo=%d\n",explo); 00632 printf(" guard=%d\n",guard); 00633 printf(" rest=0x%016llx\n",rest); 00634 #endif 00635 00636 /* Round */ 00637 if( guard ) { 00638 if( LO&1 || rest ) { 00639 LO++; 00640 if( LO == (1ULL << 52) ) { /* carry created normal number */ 00641 LO = 0; 00642 EXPONENT(LO) = 1; 00643 } 00644 00645 #if QUAD_DEBUG 00646 printf("After LO round: LO=0x%016llx\n",LO); 00647 #endif 00648 00649 } 00650 } 00651 } 00652 } 00653 else { /* LO is normal */ 00654 if(LO) { 00655 LO &= ~(1ULL << 52); /* hide hidden bit */ 00656 EXPONENT(LO) = explo + 1022; /* add bias */ 00657 } 00658 #if QUAD_DEBUG 00659 printf("Normal LO before making canonical: LO=0x%016llx\n",LO); 00660 #endif 00661 /* Make representation canonical */ 00662 z = value.qparts.lo.d + value.qparts.hi.d; 00663 value.qparts.lo.d -= (z - value.qparts.hi.d); 00664 value.qparts.hi.d = z; 00665 #if QUAD_DEBUG 00666 printf("After making canonical: HI=0x%016llx\n",HI); 00667 printf(" : LO=0x%016llx\n",LO); 00668 #endif 00669 00670 } 00671 00672 SIGNBIT(LO) = losign; 00673 result.hi = value.qparts.hi.d; 00674 result.lo = value.qparts.lo.d; 00675 return ( result ); 00676 } 00677