-:    0:Source:/home/MPI/testing/mpich2/mpich2/src/mpid/common/datatype/mpid_ext32_segment.h
        -:    0:Graph:mpid_ext32_segment.gcno
        -:    0:Data:-
        -:    0:Runs:0
        -:    0:Programs:0
        -:    1:/* -*- Mode: C; c-basic-offset:4 ; -*- */
        -:    2:/*
        -:    3: *  (C) 2001 by Argonne National Laboratory.
        -:    4: *      See COPYRIGHT in top-level directory.
        -:    5: */
        -:    6:
        -:    7:#ifndef MPIDEXT32SEGMENT_H
        -:    8:#define MPIDEXT32SEGMENT_H
        -:    9:
        -:   10:#include "mpichconf.h"
        -:   11:
        -:   12:/* FIXME!!!  TODO!!!  FOO!!!  DO THIS!!!  DETECT ME!!!
        -:   13: *
        -:   14: * Include mpiimpl.h up here too, taking it out of mpid_ext32_segment.c
        -:   15: *
        -:   16: * Consider using MPIU_INT64_T etc. types instead of the
        -:   17: * EIGHT_BYTE_BASIC_TYPE stuff, or put #defines at the top of this file
        -:   18: * assigning them in a simple manner.
        -:   19: *
        -:   20: * Doing that might require that we create MPIU_UINT64_T types (etc),
        -:   21: * because it looks like we really want to have unsigned types for the
        -:   22: * various convert functions below.
        -:   23: */
        -:   24:
        -:   25:#ifdef HAVE_INTTYPES_H
        -:   26:#include <inttypes.h>
        -:   27:#endif
        -:   28:#ifdef HAVE_LIMITS_H
        -:   29:#include <limits.h>
        -:   30:#endif
        -:   31:#ifdef HAVE_ENDIAN_H
        -:   32:#include <endian.h>
        -:   33:#endif
        -:   34:
        -:   35:#ifdef HAVE_INT64
        -:   36:#define uint64_t __int64
        -:   37:#define uint32_t __int32
        -:   38:#elif defined(MPIU_INT64_T)
        -:   39:/* FIXME: This is necessary with some compilers or compiler settings */
        -:   40:#define uint64_t unsigned MPIU_INT64_T
        -:   41:#endif
        -:   42:
        -:   43:/* FIXME: Who defines __BYTE_ORDER or __BIG_ENDIAN?  They aren't part of C */
        -:   44:/* FIXME: The else test assumes that the byte order is little endian, whereas
        -:   45:   it may simply have been undetermined.  This should instead use either 
        -:   46:   a configure-time test (for which there are macros) or a runtime test
        -:   47:   and not use this non-portable check */
        -:   48:#if defined(WORDS_BIGENDIAN)
        -:   49:#define BLENDIAN 0
        -:   50:#elif defined(WORDS_LITTLEENDIAN)
        -:   51:#define BLENDIAN 1
        -:   52:#else
        -:   53:#if !defined(__BYTE_ORDER) || !defined(__BIG_ENDIAN)
        -:   54:#error This code assumes that __BYTE_ORDER and __BIG_ENDIAN are defined
        -:   55:#endif
        -:   56:/* FIXME: "BLENDIAN" is a non-conforming name - it could conflict with some
        -:   57:   other definition in a non-mpich2 header file */
        -:   58:#if ((defined(_BIG_ENDIAN) && !defined(ntohl)) || (__BYTE_ORDER == __BIG_ENDIAN))
        -:   59:#define BLENDIAN 0 /* detected host arch byte order is big endian */
        -:   60:#else
        -:   61:#define BLENDIAN 1 /* detected host arch byte order is little endian */
        -:   62:#endif
        -:   63:#endif
        -:   64:
        -:   65:#if 0
        -:   66:#if !defined(__FLOAT_WORD_ORDER) || !defined(__LITTLE_ENDIAN)
        -:   67:#error This code assumes that __FLOAT_WORD_ORDER and __LITTLE_ENDIAN are defined
        -:   68:#endif
        -:   69:#define FLENDIAN (__FLOAT_WORD_ORDER == __LITTLE_ENDIAN)
        -:   70:#endif
        -:   71:
        -:   72:/*
        -:   73:  set to 1: uses manual swapping routines
        -:   74:            for 16/32 bit data types
        -:   75:  set to 0: uses system provided swapping routines
        -:   76:            for 16/32 bit data types
        -:   77:*/
        -:   78:#define MANUAL_BYTESWAPS 1
        -:   79:
        -:   80:/*
        -:   81:  NOTE:
        -:   82:
        -:   83:  There are two 'public' calls here:
        -:   84:
        -:   85:  FLOAT_convert(src, dest) -- converts floating point src into
        -:   86:  external32 floating point format and stores the result in dest.
        -:   87:
        -:   88:  BASIC_convert(src, dest) -- converts integral type src into
        -:   89:  external32 integral type and stores the result in dest.
        -:   90:
        -:   91:  These two macros compile to assignments on big-endian architectures.
        -:   92:*/
        -:   93:
        -:   94:#if (MANUAL_BYTESWAPS == 0)
        -:   95:#include <netinet/in.h>
        -:   96:#endif
        -:   97:
        -:   98:#define BITSIZE_OF(type)    (sizeof(type) * CHAR_BIT)
        -:   99:
        -:  100:#if (MANUAL_BYTESWAPS == 1)
        -:  101:#define BASIC_convert32(src, dest)      \
        -:  102:{                                    \
        -:  103:    dest = (((src >> 24) & 0x000000FF) |\
        -:  104:            ((src >>  8) & 0x0000FF00) |\
        -:  105:            ((src <<  8) & 0x00FF0000) |\
        -:  106:            ((src << 24) & 0xFF000000));\
        -:  107:}
        -:  108:#else
        -:  109:#define BASIC_convert32(src, dest)      \
        -:  110:{                                    \
        -:  111:    dest = htonl((uint32_t)src);        \
        -:  112:}
        -:  113:#endif
        -:  114:
        -:  115:#if (MANUAL_BYTESWAPS == 1)
        -:  116:#define BASIC_convert16(src, dest)  \
        -:  117:{                                \
        -:  118:    dest = (((src >> 8) & 0x00FF) | \
        -:  119:            ((src << 8) & 0xFF00)); \
        -:  120:}
        -:  121:#else
        -:  122:#define BASIC_convert16(src, dest)  \
        -:  123:{                                \
        -:  124:    dest = htons((uint16_t)src);    \
        -:  125:}
        -:  126:#endif
        -:  127:
        -:  128:
        -:  129:/* changed the argument types to be char* instead of uint64_t* because the Sun compiler 
        -:  130:   prints out warnings that the function expects unsigned long long, but is being passed 
        -:  131:   signed long long in mpid_ext32_segment.c. */
        -:  132:static inline void BASIC_convert64(char *src, char *dest)
    #####:  133:{
        -:  134:    uint32_t tmp_src[2];
        -:  135:    uint32_t tmp_dest[2];
        -:  136:
    #####:  137:    tmp_src[0] = (uint32_t)(*((uint64_t *)src) >> 32);
    #####:  138:    tmp_src[1] = (uint32_t)((*((uint64_t *)src) << 32) >> 32);
        -:  139:
    #####:  140:    BASIC_convert32(tmp_src[0], tmp_dest[0]);
    #####:  141:    BASIC_convert32(tmp_src[1], tmp_dest[1]);
        -:  142:
    #####:  143:    *((uint64_t *)dest) = (uint64_t)tmp_dest[0];
    #####:  144:    *((uint64_t *)dest) <<= 32;
    #####:  145:    *((uint64_t *)dest) |= (uint64_t)tmp_dest[1];
    #####:  146:}
        -:  147:
        -:  148:static inline void BASIC_convert96(char *src, char *dest)
    #####:  149:{
        -:  150:    uint32_t tmp_src[3];
        -:  151:    uint32_t tmp_dest[3];
    #####:  152:    char *ptr = dest;
        -:  153:
    #####:  154:    tmp_src[0] = (uint32_t)(*((uint64_t *)src) >> 32);
    #####:  155:    tmp_src[1] = (uint32_t)((*((uint64_t *)src) << 32) >> 32);
    #####:  156:    tmp_src[2] = (uint32_t)
        -:  157:        (*((uint32_t *)((char *)src + sizeof(uint64_t))));
        -:  158:
    #####:  159:    BASIC_convert32(tmp_src[0], tmp_dest[0]);
    #####:  160:    BASIC_convert32(tmp_src[1], tmp_dest[1]);
    #####:  161:    BASIC_convert32(tmp_src[2], tmp_dest[2]);
        -:  162:
    #####:  163:    *((uint32_t *)ptr) = tmp_dest[0];
    #####:  164:    ptr += sizeof(uint32_t);
    #####:  165:    *((uint32_t *)ptr) = tmp_dest[1];
    #####:  166:    ptr += sizeof(uint32_t);
    #####:  167:    *((uint32_t *)ptr) = tmp_dest[2];
    #####:  168:}
        -:  169:
        -:  170:static inline void BASIC_convert128(char *src, char *dest)
    #####:  171:{
        -:  172:    uint64_t tmp_src[2];
        -:  173:    uint64_t tmp_dest[2];
    #####:  174:    char *ptr = dest;
        -:  175:
    #####:  176:    tmp_src[0] = *((uint64_t *)src);
    #####:  177:    tmp_src[1] = *((uint64_t *)((char *)src + sizeof(uint64_t)));
        -:  178:
    #####:  179:    BASIC_convert64((char *) &tmp_src[0], (char *) &tmp_dest[0]);
    #####:  180:    BASIC_convert64((char *) &tmp_src[1], (char *) &tmp_dest[1]);
        -:  181:
    #####:  182:    *((uint64_t *)ptr) = tmp_dest[0];
    #####:  183:    ptr += sizeof(uint64_t);
    #####:  184:    *((uint64_t *)ptr) = tmp_dest[1];
    #####:  185:}
        -:  186:
        -:  187:#if (BLENDIAN == 1)
        -:  188:#define BASIC_convert(src, dest)               \
        -:  189:{                                           \
        -:  190:    register int type_byte_size = sizeof(src); \
        -:  191:    switch(type_byte_size)                     \
        -:  192:    {                                          \
        -:  193:        case 1:                                \
        -:  194:            dest = src;                        \
        -:  195:            break;                             \
        -:  196:        case 2:                                \
        -:  197:            BASIC_convert16(src, dest);        \
        -:  198:            break;                             \
        -:  199:        case 4:                                \
        -:  200:            BASIC_convert32(src, dest);        \
        -:  201:            break;                             \
        -:  202:        case 8:                                \
        -:  203:            BASIC_convert64((char *)&src,  \
        -:  204:                            (char *)&dest);\
        -:  205:            break;                             \
        -:  206:    }                                          \
        -:  207:}
        -:  208:
        -:  209:/*
        -:  210:  http://www.mpi-forum.org/docs/mpi-20-html/node200.htm
        -:  211:
        -:  212:  When converting a larger size integer to a smaller size integer,
        -:  213:  only the less significant bytes are moved. Care must be taken to
        -:  214:  preserve the sign bit value. This allows no conversion errors if the
        -:  215:  data range is within the range of the smaller size integer. ( End of
        -:  216:  advice to implementors.)
        -:  217:*/
        -:  218:#define BASIC_mixed_convert(src, dest)
        -:  219:#else
        -:  220:#define BASIC_convert(src, dest)               \
        -:  221:        { dest = src; }
        -:  222:#define BASIC_mixed_convert(src, dest)         \
        -:  223:        { dest = src; }
        -:  224:#endif
        -:  225:
        -:  226:/*
        -:  227:  Notes on the IEEE floating point format
        -:  228:  ---------------------------------------
        -:  229:
        -:  230:  external32 for floating point types is big-endian IEEE format.
        -:  231:
        -:  232:  ---------------------
        -:  233:  32 bit floating point
        -:  234:  ---------------------
        -:  235:  * big endian byte order
        -:  236:  struct be_ieee754_single_precision
        -:  237:  {
        -:  238:  unsigned int sign_neg:1;
        -:  239:  unsigned int exponent:8;
        -:  240:  unsigned int mantissa:23;
        -:  241:  };
        -:  242:
        -:  243:  * little endian byte order
        -:  244:  struct le_ieee754_single_precision
        -:  245:  {
        -:  246:  unsigned int mantissa:23;
        -:  247:  unsigned int exponent:8;
        -:  248:  unsigned int sign_neg:1;
        -:  249:  };
        -:  250:  ---------------------
        -:  251:
        -:  252:  ---------------------
        -:  253:  64 bit floating point
        -:  254:  ---------------------
        -:  255:  * big endian byte order
        -:  256:  struct be_ieee754_double_precision
        -:  257:  {
        -:  258:  unsigned int sign_neg:1;
        -:  259:  unsigned int exponent:11;
        -:  260:  unsigned int mantissa0:20;
        -:  261:  unsigned int mantissa1:32;
        -:  262:  };
        -:  263:
        -:  264:  * little endian byte order
        -:  265:  * big endian float word order
        -:  266:  struct le_ieee754_double_precision
        -:  267:  {
        -:  268:  unsigned int mantissa0:20;
        -:  269:  unsigned int exponent:11;
        -:  270:  unsigned int sign_neg:1;
        -:  271:  unsigned int mantissa1:32;
        -:  272:  };
        -:  273:
        -:  274:  * little endian byte order
        -:  275:  * little endian float word order
        -:  276:  struct le_ieee754_double_precision
        -:  277:  {
        -:  278:  unsigned int mantissa1:32;
        -:  279:  unsigned int mantissa0:20;
        -:  280:  unsigned int exponent:11;
        -:  281:  unsigned int sign_neg:1;
        -:  282:  };
        -:  283:  ---------------------
        -:  284:
        -:  285:  ---------------------
        -:  286:  96 bit floating point
        -:  287:  ---------------------
        -:  288:  * big endian byte order
        -:  289:  struct be_ieee854_double_extended
        -:  290:  {
        -:  291:  unsigned int negative:1;
        -:  292:  unsigned int exponent:15;
        -:  293:  unsigned int empty:16;
        -:  294:  unsigned int mantissa0:32;
        -:  295:  unsigned int mantissa1:32;
        -:  296:  };
        -:  297:
        -:  298:  * little endian byte order
        -:  299:  * big endian float word order
        -:  300:  struct le_ieee854_double_extended
        -:  301:  {
        -:  302:  unsigned int exponent:15;
        -:  303:  unsigned int negative:1;
        -:  304:  unsigned int empty:16;
        -:  305:  unsigned int mantissa0:32;
        -:  306:  unsigned int mantissa1:32;
        -:  307:  };
        -:  308:
        -:  309:  * little endian byte order
        -:  310:  * little endian float word order
        -:  311:  struct le_ieee854_double_extended
        -:  312:  {
        -:  313:  unsigned int mantissa1:32;
        -:  314:  unsigned int mantissa0:32;
        -:  315:  unsigned int exponent:15;
        -:  316:  unsigned int negative:1;
        -:  317:  unsigned int empty:16;
        -:  318:  };
        -:  319:  ---------------------
        -:  320:
        -:  321:  128 bit floating point implementation notes
        -:  322:  ===========================================
        -:  323:
        -:  324:  "A 128-bit long double number consists of an ordered pair of
        -:  325:  64-bit double-precision numbers. The first member of the
        -:  326:  ordered pair contains the high-order part of the number, and
        -:  327:  the second member contains the low-order part. The value of the
        -:  328:  long double quantity is the sum of the two 64-bit numbers."
        -:  329:
        -:  330:  From http://nscp.upenn.edu/aix4.3html/aixprggd/genprogc/128bit_long_double_floating-point_datatype.htm
        -:  331:  [ as of 09/04/2003 ]
        -:  332:*/
        -:  333:
        -:  334:#if (BLENDIAN == 1)
        -:  335:#define FLOAT_convert(src, dest)              \
        -:  336:{                                          \
        -:  337:    register int type_byte_size = sizeof(src);\
        -:  338:    switch(type_byte_size)                    \
        -:  339:    {                                         \
        -:  340:        case 4:                               \
        -:  341:        {                                     \
        -:  342:           long d;                            \
        -:  343:           BASIC_convert32((long)src, d);     \
        -:  344:           dest = (float)d;                   \
        -:  345:        }                                     \
        -:  346:        break;                                \
        -:  347:        case 8:                               \
        -:  348:        {                                     \
        -:  349:           BASIC_convert64((char *)&src,  \
        -:  350:                           (char *)&dest);\
        -:  351:        }                                     \
        -:  352:        case 12:                              \
        -:  353:        {                                     \
        -:  354:           BASIC_convert96((char *)&src,      \
        -:  355:                           (char *)&dest);    \
        -:  356:        }                                     \
        -:  357:        case 16:                              \
        -:  358:        {                                     \
        -:  359:           BASIC_convert128((char *)&src,     \
        -:  360:                            (char *)&dest);   \
        -:  361:        }                                     \
        -:  362:        break;                                \
        -:  363:    }                                         \
        -:  364:}
        -:  365:#else
        -:  366:#define FLOAT_convert(src, dest)              \
        -:  367:        { dest = src; }
        -:  368:#endif
        -:  369:
        -:  370:#ifdef HAVE_INT16_T
        -:  371:#define TWO_BYTE_BASIC_TYPE int16_t
        -:  372:#else
        -:  373:#if (SIZEOF_SHORT == 2)
        -:  374:#define TWO_BYTE_BASIC_TYPE short
        -:  375:#else
        -:  376:#error "Cannot detect a basic type that is 2 bytes long"
        -:  377:#endif
        -:  378:#endif /* HAVE_INT16_T */
        -:  379:
        -:  380:#ifdef HAVE_INT32_T
        -:  381:#define FOUR_BYTE_BASIC_TYPE int32_t
        -:  382:#else
        -:  383:#if (SIZEOF_INT == 4)
        -:  384:#define FOUR_BYTE_BASIC_TYPE int
        -:  385:#elif (SIZEOF_LONG == 4)
        -:  386:#define FOUR_BYTE_BASIC_TYPE long
        -:  387:#else
        -:  388:#error "Cannot detect a basic type that is 4 bytes long"
        -:  389:#endif
        -:  390:#endif /* HAVE_INT32_T */
        -:  391:
        -:  392:#ifdef HAVE_INT64_T
        -:  393:#define EIGHT_BYTE_BASIC_TYPE int64_t
        -:  394:#else
        -:  395:#ifdef HAVE_INT64
        -:  396:#define EIGHT_BYTE_BASIC_TYPE __int64
        -:  397:#elif (SIZEOF_LONG_LONG == 8)
        -:  398:#define EIGHT_BYTE_BASIC_TYPE long long
        -:  399:#else
        -:  400:#error "Cannot detect a basic type that is 8 bytes long"
        -:  401:#endif
        -:  402:#endif /* HAVE_INT64_T */
        -:  403:
        -:  404:#if (SIZEOF_FLOAT == 4)
        -:  405:#define FOUR_BYTE_FLOAT_TYPE float
        -:  406:#else
        -:  407:#error "Cannot detect a float type that is 4 bytes long"
        -:  408:#endif
        -:  409:
        -:  410:#if (SIZEOF_DOUBLE == 8)
        -:  411:#define EIGHT_BYTE_FLOAT_TYPE double
        -:  412:#else
        -:  413:#error "Cannot detect a float type that is 8 bytes long"
        -:  414:#endif
        -:  415:
        -:  416:#endif /* MPIDEXT32SEGMENT_H */