pvmgetdsig.c

Go to the documentation of this file.
00001 
00007 /* $Id: pvmgetdsig.c,v 1.5 2004/08/17 21:15:42 seymour Exp $ */
00008 /* $UTK_Copyright: $ */
00009 
00010 /*
00011  *         PVM version 3.4:  Parallel Virtual Machine System
00012  *               University of Tennessee, Knoxville TN.
00013  *           Oak Ridge National Laboratory, Oak Ridge TN.
00014  *                   Emory University, Atlanta GA.
00015  *      Authors:  J. J. Dongarra, G. E. Fagg, M. Fischer
00016  *          G. A. Geist, J. A. Kohl, R. J. Manchek, P. Mucci,
00017  *         P. M. Papadopoulos, S. L. Scott, and V. S. Sunderam
00018  *                   (C) 1997 All Rights Reserved
00019  *
00020  *                              NOTICE
00021  *
00022  * Permission to use, copy, modify, and distribute this software and
00023  * its documentation for any purpose and without fee is hereby granted
00024  * provided that the above copyright notice appear in all copies and
00025  * that both the copyright notice and this permission notice appear in
00026  * supporting documentation.
00027  *
00028  * Neither the Institutions (Emory University, Oak Ridge National
00029  * Laboratory, and University of Tennessee) nor the Authors make any
00030  * representations about the suitability of this software for any
00031  * purpose.  This software is provided ``as is'' without express or
00032  * implied warranty.
00033  *
00034  * PVM version 3 was funded in part by the U.S. Department of Energy,
00035  * the National Science Foundation and the State of Tennessee.
00036  */
00037 
00038 #include <stdio.h>
00039 #include <stdlib.h>
00040 #include "utility.h"
00041 
00042 #ifdef NEEDMENDIAN
00043 #include <machine/endian.h>
00044 #endif
00045 #ifdef NEEDENDIAN
00046 #include <endian.h>
00047 #endif
00048 #ifdef NEEDSENDIAN
00049 #include <sys/endian.h>
00050 #endif
00051 
00052 void
00053 printbits(int x)
00054 {
00055   int i;
00056 
00057   for(i=31;i>=0;i--) {
00058     printf("%d", (x>>i)&0x1);
00059     if(i%4==0) printf(" ");
00060   }
00061 }
00062 
00063 /****************************
00064 *  Generate data signature  *
00065 *                           *
00066 ****************************/
00067 
00068 /* #ifdef   NEEDSFFS */
00069 int
00070 ffs(x)
00071     int x;
00072 {
00073     int n = 1, m = 1;
00074 
00075     if (!x)
00076         return 0;
00077     while (!(x & m)) {
00078         m += m;
00079         n++;
00080     }
00081     return n;
00082 }
00083 /* #endif */
00084 
00085 
00086 static int
00087 ibol(o, p, n)
00088     int o;
00089     char *p;
00090     int n;
00091 {
00092     int i, j;
00093 
00094     if (p[0] == 0) {
00095         i = 0;  /* ll */
00096     } else if (p[0] == n - 1) {
00097         i = 3;  /* hh */
00098     } else if (p[0] == n / 2) {
00099         i = 2;  /* hl */
00100     } else if (p[0] == n / 2 - 1) {
00101         i = 1;  /* lh */
00102     } else {
00103         fprintf(stderr, "can't generate signature for my integer byte order\n");
00104         abort();
00105     }
00106 
00107     j = ffs(n) - 1;
00108 /*
00109     printf(".%d%d.%d%d%d", (i & 2) ? 1 : 0, (i & 1) ? 1 : 0
00110             (j & 4) ? 1 : 0, (j & 2) ? 1 : 0, (j & 1) ? 1 : 0);
00111 */
00112     return ((i << 3) | j) << o;
00113 }
00114 
00115 
00116 /*
00117 *  (float)1.0 =
00118 *  IEEE single ll   00 00 80 3f
00119 *  IEEE double ll   00 00 00 00 00 00 f0 3f
00120 *  IEEE single hh   3f 80 00 00
00121 *  IEEE double hh   3f f0 00 00 00 00 00 00
00122 *  CRAY       (hh)  40 01 80 00 00 00 00 00
00123 *  Convex s   (hh)  40 80 00 00
00124 *  Convex d   (hh)  40 10 00 00 00 00 00 00
00125 *  IBM370 s
00126 *  IBM370 d
00127 *  VAX xxxx?
00128 */
00129 
00130 /*
00131 * signatures for float = 1.0 in hh byte order, all formats
00132 */
00133 
00134 unsigned char fs1[] = { 0x3f, 0x80, 0x00, 0x00 };
00135 unsigned char fs2[] = { 0x3f, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
00136 unsigned char fs4[] = { 0x40, 0x01, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00 };
00137 unsigned char fs5[] = { 0x40, 0x80, 0x00, 0x00 };
00138 unsigned char fs6[] = { 0x40, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
00139 
00140 struct floatsig thesigs[] = {
00141     { 0, 0, "UNKNOWN" },
00142     { 4, fs1, "IEEE_single" },
00143     { 8, fs2, "IEEE_double" },
00144     { 0, 0, "UNDEFINED" },
00145     { 8, fs4, "Cray" },
00146     { 4, fs5, "Convex_single" },
00147     { 8, fs6, "Convex_double" },
00148     { 0, 0, "UNDEFINED" },
00149     { 0, 0, "UNDEFINED" },
00150     { 0, 0, "UNDEFINED" },
00151     { 0, 0, "UNDEFINED" },
00152     { 0, 0, "UNDEFINED" },
00153     { 0, 0, "UNDEFINED" },
00154     { 0, 0, "UNDEFINED" },
00155     { 0, 0, "UNDEFINED" },
00156     { 0, 0, "UNDEFINED" },
00157 };
00158 
00159 
00160 static int
00161 fbol(o, p, n)
00162     int o;
00163     unsigned char *p;
00164     int n;
00165 {
00166     int i, j;
00167 
00168     for (i = 0; i < 16; i++) {
00169         if (thesigs[i].length == n) {
00170             for (j = 0; j < n; j++)
00171                 if (p[j] != thesigs[i].bytes[j])
00172                     break;
00173             if (j == n)
00174                 return ((3 << 4) | i) << o;
00175 
00176             for (j = 0; j < n; j++)
00177                 if (p[n - 1 - j] != thesigs[i].bytes[j])
00178                     break;
00179             if (j == n)
00180                 return i << o;
00181         }
00182     }
00183     fprintf(stderr, "can't generate signature for my integer byte order\n");
00184     abort();
00185     return 0;
00186 }
00187 
00188 
00189 /*  pvm_getdsig()
00190 *
00191 *   Return data signature for executable, describing representations
00192 *   of integers and floats.
00193 *
00194 *   Bits:
00195 *    0:2  short int size
00196 *    3:4  short int byte order
00197 *    5:7  int size
00198 *    8:9  int byte order
00199 *   10:12  long int size
00200 *   13:14  long int byte order
00201 *   15:18  float format
00202 *   19:20  float byte order
00203 *   21:24  double float format
00204 *   25:26  double float byte order
00205 *   27:31  0
00206 *
00207 *   Sizes are 2 ** (0..7) bytes
00208 *   Byte order specifies overall order and half-folding:
00209 *       00  Little endian (e.g. 0 1 2 3)
00210 *       01  Little, but half-swapped (1 0 3 2 or 3 2 1 0 7 6 5 4)
00211 *       10  Big, but half swapped (2 3 0 1 or 4 5 6 7 0 1 2 3)
00212 *       11  Big endian (3 2 1 0)
00213 */
00214 
00215 int
00216 pvmgetdsig()
00217 {
00218     static int myfmt = -1;
00219 
00220     short i0;
00221     int i1;
00222     long i2;
00223     float f0;
00224     double f1;
00225     int i;
00226     int fmt;
00227 
00228     if (myfmt != -1)
00229         return myfmt;
00230 
00231     fmt = 0;
00232 
00233     i0 = 0;
00234     for (i = 0; i < sizeof(i0); i++)
00235         i0 += (short)i << (i * 8);
00236     fmt |= ibol(0, (char *) &i0, (int) sizeof(i0));
00237 
00238     i1 = 0;
00239     for (i = 0; i < sizeof(i1); i++)
00240         i1 += (int)i << (i * 8);
00241     fmt |= ibol(5, (char *) &i1, (int) sizeof(i1));
00242 
00243     i2 = 0;
00244     for (i = 0; i < sizeof(i2); i++)
00245         i2 += (long)i << (i * 8);
00246     fmt |= ibol(10, (char *) &i2, (int) sizeof(i2));
00247 
00248     f0 = 1.0;
00249     fmt |= fbol(15, (unsigned char *) &f0, (int) sizeof(f0));
00250 
00251     f1 = 1.0;
00252     fmt |= fbol(21, (unsigned char *) &f1, (int) sizeof(f1));
00253 
00254     myfmt = fmt;
00255     return fmt;
00256 }
00257 
00258