00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 
00010 
00011 
00012 
00013 
00014 
00015 
00016 
00017 
00018 
00019 
00020 
00021 
00022 
00023 
00024 
00025 
00026 
00027 
00028 
00029 
00030 
00031 
00032 
00033 
00034 
00035 
00036 
00037 
00038 
00039 
00040 
00041 
00042 
00043 
00044 
00045 
00046 
00047 
00048 
00049 
00050 
00051 
00052 
00053 
00054 
00055 
00056 
00057 
00058 
00059 
00060 
00061 
00062 
00063 
00064 #ifndef lint
00065 static const char libbu_htond_RCSid[] = "@(#)$Header: /cvsroot/brlcad/brlcad/src/libbu/htond.c,v 14.13 2006/09/03 15:14:07 lbutler Exp $ (BRL)";
00066 #endif
00067 
00068 #include "common.h"
00069 
00070 
00071 #include <stdio.h>
00072 #include "machine.h"
00073 #include "bu.h"
00074 
00075 #ifdef HAVE_MEMORY_H
00076 #  include <memory.h>
00077 #endif
00078 #include <stdio.h>
00079 
00080 #define OUT_IEEE_ZERO   { \
00081         *out++ = 0; \
00082         *out++ = 0; \
00083         *out++ = 0; \
00084         *out++ = 0; \
00085         *out++ = 0; \
00086         *out++ = 0; \
00087         *out++ = 0; \
00088         *out++ = 0; \
00089         continue; } \
00090 
00091 #define OUT_IEEE_NAN    {  \
00092         *out++ = 0xFF; \
00093         *out++ = 0xF0; \
00094         *out++ = 0x0B; \
00095         *out++ = 0xAD; \
00096         *out++ = 0x0B; \
00097         *out++ = 0xAD; \
00098         *out++ = 0x0B; \
00099         *out++ = 0xAD; \
00100         continue; } \
00101 
00102 
00103 
00104 
00105 
00106 
00107 void
00108 htond(register unsigned char *out, register const unsigned char *in, int count)
00109 {
00110 #if     defined(NATURAL_IEEE)
00111         
00112 
00113 
00114 
00115 
00116 #       ifdef HAVE_MEMORY_H
00117                 memcpy( out, in, count*8 );
00118 #       else
00119                 bcopy( in, out, count*8 );
00120 #       endif
00121         return;
00122 #       define  HTOND   yes1
00123 #endif
00124 #if     defined(REVERSE_IEEE)
00125         
00126         register int    i;
00127         for( i=count-1; i >= 0; i-- )  {
00128                 *out++ = in[7];
00129                 *out++ = in[6];
00130                 *out++ = in[5];
00131                 *out++ = in[4];
00132                 *out++ = in[3];
00133                 *out++ = in[2];
00134                 *out++ = in[1];
00135                 *out++ = in[0];
00136                 in += SIZEOF_NETWORK_DOUBLE;
00137         }
00138         return;
00139 #       define  HTOND   yes2
00140 
00141         
00142 
00143 #endif
00144 #if     defined(sgi) && !defined(mips)
00145         
00146 
00147 
00148 
00149 
00150 
00151 
00152         register int    i;
00153         for( i=count-1; i >= 0; i-- )  {
00154                 
00155                 float small;
00156                 long float big;
00157                 register unsigned char *fp = (unsigned char *)&small;
00158 
00159                 *fp++ = *in++;
00160                 *fp++ = *in++;
00161                 *fp++ = *in++;
00162                 *fp++ = *in++;
00163                 big = small;            
00164 
00165                 fp = (unsigned char *)&big;
00166                 *out++ = *fp++;
00167                 *out++ = *fp++;
00168                 *out++ = *fp++;
00169                 *out++ = *fp++;
00170                 *out++ = *fp++;
00171                 *out++ = *fp++;
00172                 *out++ = *fp++;
00173                 *out++ = *fp++;
00174         }
00175         return;
00176 #       define  HTOND   yes3
00177 #endif
00178 #if     defined(vax)
00179         
00180 
00181 
00182 
00183 
00184         register int    i;
00185         for( i=count-1; i >= 0; i-- )  {
00186                 register unsigned long left, right, signbit;
00187                 register int exp;
00188 
00189                 left  = (in[1]<<24) | (in[0]<<16) | (in[3]<<8) | in[2];
00190                 right = (in[5]<<24) | (in[4]<<16) | (in[7]<<8) | in[6];
00191                 in += 8;
00192 
00193                 exp = (left >> 23) & 0xFF;
00194                 signbit = left & 0x80000000;
00195                 if( exp == 0 )  {
00196                         if( signbit )  {
00197                                 OUT_IEEE_NAN;
00198                         } else {
00199                                 OUT_IEEE_ZERO;
00200                         }
00201                 }
00202                 exp += 1023 - 129;
00203                 
00204 #               ifdef ROUNDING
00205                         right = (left<<(32-3)) | ((right+4)>>3);
00206 #               else
00207                         right = (left<<(32-3)) | (right>>3);
00208 #               endif
00209                 left =  ((left & 0x007FFFFF)>>3) | signbit | (exp<<20);
00210                 *out++ = left>>24;
00211                 *out++ = left>>16;
00212                 *out++ = left>>8;
00213                 *out++ = left;
00214                 *out++ = right>>24;
00215                 *out++ = right>>16;
00216                 *out++ = right>>8;
00217                 *out++ = right;
00218         }
00219         return;
00220 #       define  HTOND   yes4
00221 #endif
00222 #if     defined(ibm) || defined(gould)
00223         
00224 
00225 
00226 
00227 
00228         register int    i;
00229         for( i=count-1; i >= 0; i-- )  {
00230                 register unsigned long left, right, signbit;
00231                 register int exp;
00232 
00233                 left  = (in[0]<<24) | (in[1]<<16) | (in[2]<<8) | in[3];
00234                 right = (in[4]<<24) | (in[5]<<16) | (in[6]<<8) | in[7];
00235                 in += 8;
00236 
00237                 exp = (left>>24) & 0x7F;        
00238                 if( left == 0 && right == 0 )
00239                         OUT_IEEE_ZERO;
00240 
00241                 signbit = left & 0x80000000;
00242                 left &= 0x00FFFFFF;
00243                 if( signbit )  {
00244                         
00245 
00246 
00247                         left  ^= 0xFFFFFFFF;
00248                         right ^= 0xFFFFFFFF;
00249                         if( right & 0x80000000 )  {
00250                                 
00251                                 right += 1;
00252                                 if( (right & 0x80000000) == 0 )  {
00253                                         
00254                                         left += 1;
00255                                 }
00256                         } else {
00257                                 
00258                                 right += 1;
00259                         }
00260                         left &= 0x00FFFFFF;
00261                         exp = (~exp) & 0x7F;
00262                 }
00263                 exp -= (64-32+1);               
00264                 exp *= 4;                       
00265 ibm_normalized:
00266                 if( left & 0x00800000 )  {
00267                         
00268                         exp += 1023-129+1+ 3-0;
00269                 } else if( left & 0x00400000 ) {
00270                         
00271                         exp += 1023-129+1+ 3-1;
00272                         left = (left<<1) |
00273                                 ( (right>>(32-1)) & (0x7FFFFFFF>>(31-1)) );
00274                         right <<= 1;
00275                 } else if( left & 0x00200000 ) {
00276                         
00277                         exp += 1023-129+1+ 3-2;
00278                         left = (left<<2) |
00279                                 ( (right>>(32-2)) & (0x7FFFFFFF>>(31-2)) );
00280                         right <<= 2;
00281                 } else if( left & 0x00100000 ){
00282                         
00283                         exp += 1023-129+1+ 3-3;
00284                         left = (left<<3) |
00285                                 ( (right>>(32-3)) & (0x7FFFFFFF>>(31-3)) );
00286                         right <<= 3;
00287                 } else {
00288                         
00289 
00290 
00291 
00292 
00293                         exp -= 4;
00294                         left = (left<<4) | (right>>(32-4));
00295                         right <<= 4;
00296                         goto ibm_normalized;
00297                 }
00298 
00299                 
00300                 if( (left & 0x00800000) == 0 )  {
00301                         fprintf(stderr,"ibm->ieee missing 1, left=x%x\n", left);
00302                         left = (left<<1) | (right>>31);
00303                         right <<= 1;
00304                         goto ibm_normalized;
00305                 }
00306 
00307                 
00308 #               ifdef ROUNDING
00309                         right = (left<<(32-3)) | ((right+4)>>3);
00310 #               else
00311                         right = (left<<(32-3)) | (right>>3);
00312 #               endif
00313                 left =  ((left & 0x007FFFFF)>>3) | signbit | (exp<<20);
00314 
00315                 *out++ = left>>24;
00316                 *out++ = left>>16;
00317                 *out++ = left>>8;
00318                 *out++ = left;
00319                 *out++ = right>>24;
00320                 *out++ = right>>16;
00321                 *out++ = right>>8;
00322                 *out++ = right;
00323         }
00324         return;
00325 #       define  HTOND   yes5
00326 #endif
00327 #if     defined(CRAY1) || defined(CRAY2) || defined(eta10)
00328         
00329 
00330 
00331 
00332 
00333         register int    i;
00334         for( i=count-1; i >= 0; i-- )  {
00335                 register unsigned long word, signbit;
00336                 register int exp;
00337 
00338 #ifdef never
00339                 if( (((int)in) & 07) == 0 )
00340                         word = *((unsigned long *)in);
00341                 else
00342 #endif
00343                         word  = (((long)in[0])<<56) | (((long)in[1])<<48) |
00344                                 (((long)in[2])<<40) | (((long)in[3])<<32) |
00345                                 (((long)in[4])<<24) | (((long)in[5])<<16) |
00346                                 (((long)in[6])<<8) | ((long)in[7]);
00347                 in += 8;
00348 
00349                 if( word == 0 )
00350                         OUT_IEEE_ZERO;
00351                 exp = (word >> 48) & 0x7FFF;
00352                 signbit = word & 0x8000000000000000L;
00353 #ifdef redundant
00354                 if( exp <= 020001 || exp >= 060000 )
00355                         OUT_IEEE_NAN;
00356 #endif
00357                 exp += 1023 - 040000 - 1;
00358                 if( (exp & ~0x7FF) != 0 )  {
00359                         fprintf(stderr,"htond:  Cray exponent too large on x%x\n", word);
00360                         OUT_IEEE_NAN;
00361                 }
00362 
00363 #if defined(CRAY2) && defined(ROUNDING)
00364                 
00365                 word += 1;
00366 #endif
00367                 word = ((word & 0x00007FFFFFFFFFFFL) << (15-11+1)) |
00368                         signbit | (((long)exp)<<(64-12));
00369 
00370                 *out++ = word>>56;
00371                 *out++ = word>>48;
00372                 *out++ = word>>40;
00373                 *out++ = word>>32;
00374                 *out++ = word>>24;
00375                 *out++ = word>>16;
00376                 *out++ = word>>8;
00377                 *out++ = word;
00378         }
00379         return;
00380 #       define  HTOND   yes6
00381 #endif
00382 #if defined(convex_NATIVE) || defined(__convex__NATIVE)
00383         
00384 
00385 
00386 
00387 
00388 
00389 
00390         register int    i;
00391         for( i=count-1; i >= 0; i-- )  {
00392                 register unsigned long long     word;
00393                 register int exp;
00394 
00395 
00396                 word = *((unsigned long long *)in);
00397                 in += 8;
00398 
00399                 if( word == 0 )
00400                         OUT_IEEE_ZERO;
00401                 exp = (word >> 52) & 0x7FF;
00402                 
00403                 exp += 1023 - 1024 - 1;
00404                 if( (exp & ~0x7FF) != 0 )  {
00405                         fprintf(stderr,"htond:  Convex exponent too large on x%lx\n", word);
00406                         OUT_IEEE_NAN;
00407                 }
00408 
00409                 word = ((word & 0x800FFFFFFFFFFFFFLL) |
00410                         ((long long)exp)<<52);
00411 
00412                 *((unsigned long long *)out) = word;
00413                 out += 8;
00414         }
00415         return;
00416 #       define  HTOND   yes7
00417 #endif
00418 
00419 #ifndef HTOND
00420 # include "htond.c:  ERROR, no HtoND conversion for this machine type"
00421 #endif
00422 }
00423 
00424 
00425 
00426 
00427 
00428 
00429 void
00430 ntohd(register unsigned char *out, register const unsigned char *in, int count)
00431 {
00432 #ifdef NATURAL_IEEE
00433         
00434 
00435 
00436 
00437 
00438         if( sizeof(double) != SIZEOF_NETWORK_DOUBLE )
00439                 bu_bomb("ntohd:  sizeof(double) != SIZEOF_NETWORK_DOUBLE\n");
00440 #       ifdef HAVE_MEMORY_H
00441                 memcpy( out, in, count*SIZEOF_NETWORK_DOUBLE );
00442 #       else
00443                 bcopy( in, out, count*SIZEOF_NETWORK_DOUBLE );
00444 #       endif
00445         return;
00446 #       define  NTOHD   yes1
00447 #endif
00448 #if     defined(REVERSE_IEEE)
00449         
00450         register int    i;
00451         for( i=count-1; i >= 0; i-- )  {
00452                 *out++ = in[7];
00453                 *out++ = in[6];
00454                 *out++ = in[5];
00455                 *out++ = in[4];
00456                 *out++ = in[3];
00457                 *out++ = in[2];
00458                 *out++ = in[1];
00459                 *out++ = in[0];
00460                 in += SIZEOF_NETWORK_DOUBLE;
00461         }
00462         return;
00463 #       define  NTOHD   yes2
00464 #endif
00465 #if     defined(sgi) && !defined(mips)
00466         
00467 
00468 
00469 
00470         register int    i;
00471         for( i=count-1; i >= 0; i-- )  {
00472                 
00473                 float small;
00474                 long float big;
00475                 register unsigned char *fp = (unsigned char *)&big;
00476                 *fp++ = *in++;
00477                 *fp++ = *in++;
00478                 *fp++ = *in++;
00479                 *fp++ = *in++;
00480                 *fp++ = *in++;
00481                 *fp++ = *in++;
00482                 *fp++ = *in++;
00483                 *fp++ = *in++;
00484                 small = big;            
00485                 fp = (unsigned char *)&small;
00486                 *out++ = *fp++;
00487                 *out++ = *fp++;
00488                 *out++ = *fp++;
00489                 *out++ = *fp++;
00490         }
00491         return;
00492 #       define  NTOHD   yes3
00493 #endif
00494 #if     defined(vax)
00495         
00496 
00497 
00498 
00499 
00500         register int    i;
00501         for( i=count-1; i >= 0; i-- )  {
00502                 register unsigned long left, right, signbit;
00503                 register int fix, exp;
00504 
00505                 left  = (in[0]<<24) | (in[1]<<16) | (in[2]<<8) | in[3];
00506                 right = (in[4]<<24) | (in[5]<<16) | (in[6]<<8) | in[7];
00507                 in += 8;
00508 
00509                 exp = (left >> 20) & 0x7FF;
00510                 signbit = left & 0x80000000;
00511                 if( exp == 0 )  {
00512                         *out++ = 0;             
00513                         *out++ = 0;
00514                         *out++ = 0;
00515                         *out++ = 0;
00516                         *out++ = 0;
00517                         *out++ = 0;
00518                         *out++ = 0;
00519                         *out++ = 0;
00520                         continue;
00521                 } else if( exp == 0x7FF )  {
00522 vax_undef:              *out++ = 0x80;          
00523                         *out++ = 0;
00524                         *out++ = 0;
00525                         *out++ = 0;
00526                         *out++ = 0;
00527                         *out++ = 0;
00528                         *out++ = 0;
00529                         *out++ = 0;
00530                         continue;
00531                 }
00532                 exp += 129 - 1023;
00533                 
00534                 if( (exp & ~0xFF) != 0 )  {
00535                         fprintf(stderr,"ntohd: VAX exponent overflow\n");
00536                         goto vax_undef;
00537                 }
00538                 left = ((left & 0x000FFFFF)<<3) | signbit | (exp<<23) |
00539                         (right >> (32-3));
00540                 right <<= 3;
00541                 out[1] = left>>24;
00542                 out[0] = left>>16;
00543                 out[3] = left>>8;
00544                 out[2] = left;
00545                 out[5] = right>>24;
00546                 out[4] = right>>16;
00547                 out[7] = right>>8;
00548                 out[6] = right;
00549                 out += 8;
00550         }
00551         return;
00552 #       define  NTOHD   yes4
00553 #endif
00554 #if     defined(ibm) || defined(gould)
00555         
00556 
00557 
00558 
00559 
00560         register int    i;
00561         for( i=count-1; i >= 0; i-- )  {
00562                 register unsigned long left, right;
00563                 register int fix, exp, signbit;
00564 
00565                 left  = (in[0]<<24) | (in[1]<<16) | (in[2]<<8) | in[3];
00566                 right = (in[4]<<24) | (in[5]<<16) | (in[6]<<8) | in[7];
00567                 in += 8;
00568 
00569                 exp = ((left >> 20) & 0x7FF);
00570                 signbit = (left & 0x80000000) >> 24;
00571                 if( exp == 0 || exp == 0x7FF )  {
00572 ibm_undef:              *out++ = 0;             
00573                         *out++ = 0;
00574                         *out++ = 0;
00575                         *out++ = 0;
00576                         *out++ = 0;
00577                         *out++ = 0;
00578                         *out++ = 0;
00579                         *out++ = 0;
00580                         continue;
00581                 }
00582 
00583                 left = (left & 0x000FFFFF) | 0x00100000;
00584 
00585                 exp += 129 - 1023 -1;   
00586                 fix = exp % 4;          
00587                 exp /= 4;               
00588                 exp += (64-32+1);       
00589                 if( (exp & ~0xFF) != 0 )  {
00590                         fprintf(stderr,"ntohd:  IBM exponent overflow\n");
00591                         goto ibm_undef;
00592                 }
00593 
00594                 if( fix )  {
00595                         left = (left<<fix) | (right >> (32-fix));
00596                         right <<= fix;
00597                 }
00598 
00599                 if( signbit )  {
00600                         
00601 
00602 
00603                         left  ^= 0xFFFFFFFF;
00604                         right ^= 0xFFFFFFFF;
00605                         if( right & 0x80000000 )  {
00606                                 
00607                                 right += 1;
00608                                 if( (right & 0x80000000) == 0 )  {
00609                                         
00610                                         left += 1;
00611                                 }
00612                         } else {
00613                                 
00614                                 right += 1;
00615                         }
00616                         left &= 0x00FFFFFF;
00617                         exp = (~exp) & 0x7F;
00618                 }
00619 
00620 
00621                 
00622 
00623 
00624                 while( (left & 0x00F00000) == 0 && left != 0 )  {
00625                         if( signbit && exp <= 0x41 )  break;
00626 
00627                         left = (left << 4) | (right >> (32-4));
00628                         right <<= 4;
00629                         if(signbit)  exp--;
00630                         else exp++;
00631                 }
00632 
00633                 *out++ = signbit | exp;
00634                 *out++ = left>>16;
00635                 *out++ = left>>8;
00636                 *out++ = left;
00637                 *out++ = right>>24;
00638                 *out++ = right>>16;
00639                 *out++ = right>>8;
00640                 *out++ = right;
00641         }
00642         return;
00643 #       define  NTOHD   yes5
00644 #endif
00645 #if     defined(CRAY1) || defined(CRAY2) || defined(eta10)
00646         
00647 
00648 
00649 
00650 
00651         register int    i;
00652         for( i=count-1; i >= 0; i-- )  {
00653                 register unsigned long word, signbit;
00654                 register int exp;
00655 
00656 #ifdef never
00657                 if( (((int)in) & 07) == 0 )
00658                         word = *((unsigned long *)in);
00659                 else
00660 #endif
00661                         word  = (((long)in[0])<<56) | (((long)in[1])<<48) |
00662                                 (((long)in[2])<<40) | (((long)in[3])<<32) |
00663                                 (((long)in[4])<<24) | (((long)in[5])<<16) |
00664                                 (((long)in[6])<<8) | ((long)in[7]);
00665                 in += 8;
00666 
00667                 exp = (word>>(64-12)) & 0x7FF;
00668                 signbit = word & 0x8000000000000000L;
00669                 if( exp == 0 )  {
00670                         word = 0;
00671                         goto cray_out;
00672                 }
00673                 if( exp == 0x7FF )  {
00674                         word = 067777L<<48;     
00675                         goto cray_out;
00676                 }
00677                 exp += 040000 - 1023 + 1;
00678                 word = ((word & 0x000FFFFFFFFFFFFFL) >> (15-11+1)) |
00679                         0x0000800000000000L | signbit |
00680                         (((long)exp)<<(64-16));
00681 
00682 cray_out:
00683                 *out++ = word>>56;
00684                 *out++ = word>>48;
00685                 *out++ = word>>40;
00686                 *out++ = word>>32;
00687                 *out++ = word>>24;
00688                 *out++ = word>>16;
00689                 *out++ = word>>8;
00690                 *out++ = word;
00691         }
00692         return;
00693 #       define  NTOHD   yes6
00694 #endif
00695 #if defined(convex_NATIVE) || defined(__convex__NATIVE)
00696         
00697 
00698 
00699         register int    i;
00700         for( i=count-1; i >= 0; i-- )  {
00701                 register unsigned long long     word;
00702                 register int exp;
00703 
00704                 word = *((unsigned long long *)in);
00705                 in += 8;
00706 
00707                 exp = (word >> 52) & 0x7FF;
00708                 if( exp == 0 )  {
00709                         word = 0;
00710                         goto convex_out;
00711                 }
00712                 if( exp == 0x7FF )  {
00713                         
00714                         fprintf(stderr,"ntohd: Convex NaN unimplemented\n");
00715                         word = 0;
00716                         goto convex_out;
00717                 }
00718                 exp += 1024 - 1023 + 1;
00719                 word = (word & 0x800FFFFFFFFFFFFFLL) |
00720                         (((long long)exp)<<52);
00721 
00722 convex_out:
00723                 *((unsigned long long *)out) = word;
00724                 out += 8;
00725         }
00726         return;
00727 #       define  NTOHD   yes7
00728 #endif
00729 
00730 #ifndef NTOHD
00731 # include "ntohd.c:  ERROR, no NtoHD conversion for this machine type"
00732 #endif
00733 }
00734 
00735 
00736 
00737 
00738 
00739 
00740 
00741 
00742 
00743