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