root/opal/util/arch.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. opal_arch_isbigendian
  2. opal_arch_ldisintel
  3. opal_arch_setmask
  4. opal_arch_init
  5. opal_arch_checkmask
  6. opal_arch_set_fortran_logical_size

   1 /* -*- Mode: C; c-basic-offset:4 ; -*- */
   2 /*
   3  * Copyright (c) 2004-2006 The Trustees of Indiana University and Indiana
   4  *                         University Research and Technology
   5  *                         Corporation.  All rights reserved.
   6  * Copyright (c) 2004-2006 The University of Tennessee and The University
   7  *                         of Tennessee Research Foundation.  All rights
   8  *                         reserved.
   9  * Copyright (c) 2004-2006 High Performance Computing Center Stuttgart,
  10  *                         University of Stuttgart.  All rights reserved.
  11  * Copyright (c) 2004-2006 The Regents of the University of California.
  12  *                         All rights reserved.
  13  * $COPYRIGHT$
  14  *
  15  * Additional copyrights may follow
  16  *
  17  * $HEADER$
  18  */
  19 #include "opal_config.h"
  20 
  21 #include "opal/constants.h"
  22 #include "opal/util/arch.h"
  23 
  24 uint32_t opal_local_arch = 0xFFFFFFFF;
  25 
  26 static inline int32_t opal_arch_isbigendian ( void )
  27 {
  28     const uint32_t value = 0x12345678;
  29     const char *ptr = (char*)&value;
  30     int x = 0;
  31 
  32     /* if( sizeof(int) == 8 ) x = 4; */
  33     if( ptr[x] == 0x12)  return 1; /* big endian, true */
  34     if( ptr[x] == 0x78 ) return 0; /* little endian, false */
  35     assert( 0 );  /* unknown architecture not little nor big endian */
  36     return -1;
  37 }
  38 
  39 /* we must find which representation of long double is used
  40  * intel or sparc. Both of them represent the long doubles using a close to
  41  * IEEE representation (seeeeeee..emmm...m) where the mantissa look like
  42  * 1.????. For the intel representaion the 1 is explicit, and for the sparc
  43  * the first one is implicit. If we take the number 2.0 the exponent is 1
  44  * and the mantissa is 1.0 (the sign of course should be 0). So if we check
  45  * for the first one in the binary representation of the number, we will
  46  * find the bit from the exponent, so the next one should be the begining
  47  * of the mantissa. If it's 1 then we have an intel representaion, if not
  48  * we have a sparc one. QED
  49  */
  50 static inline int32_t opal_arch_ldisintel( void )
  51 {
  52     long double ld = 2.0;
  53     int i, j;
  54     uint32_t* pui = (uint32_t*)(void*)&ld;
  55 
  56     j = LDBL_MANT_DIG / 32;
  57     i = (LDBL_MANT_DIG % 32) - 1;
  58     if( opal_arch_isbigendian() ) { /* big endian */
  59         j = (sizeof(long double) / sizeof(unsigned int)) - j;
  60         if( i < 0 ) {
  61             i = 31;
  62             j = j+1;
  63         }
  64     } else {
  65         if( i < 0 ) {
  66             i = 31;
  67             j = j-1;
  68         }
  69     }
  70     return (pui[j] & (1 << i) ? 1 : 0);
  71 }
  72 
  73 static inline void opal_arch_setmask ( uint32_t *var, uint32_t mask)
  74 {
  75     *var |= mask;
  76 }
  77 
  78 int opal_arch_init(void)
  79 {
  80     opal_local_arch = (OPAL_ARCH_HEADERMASK | OPAL_ARCH_UNUSEDMASK);
  81 
  82     /* Handle the size of long (can hold a pointer) */
  83     if( 8 == sizeof(long) )
  84         opal_arch_setmask( &opal_local_arch, OPAL_ARCH_LONGIS64 );
  85 
  86     /* sizeof bool */
  87     if (1 == sizeof(bool) ) {
  88         opal_arch_setmask( &opal_local_arch, OPAL_ARCH_BOOLIS8);
  89     } else if (2 == sizeof(bool)) {
  90         opal_arch_setmask( &opal_local_arch, OPAL_ARCH_BOOLIS16);
  91     } else if (4 == sizeof(bool)) {
  92         opal_arch_setmask( &opal_local_arch, OPAL_ARCH_BOOLIS32);
  93     }
  94 
  95     /* Note that fortran logical size is set later, to make
  96        abstractions a little less painful... */
  97 
  98     /* Initialize the information regarding the long double */
  99     if( 12 == sizeof(long double) )
 100         opal_arch_setmask( &opal_local_arch, OPAL_ARCH_LONGDOUBLEIS96 );
 101     else if( 16 == sizeof(long double) )
 102         opal_arch_setmask( &opal_local_arch, OPAL_ARCH_LONGDOUBLEIS128 );
 103 
 104     /* Big endian or little endian ? That's the question */
 105     if( opal_arch_isbigendian() )
 106         opal_arch_setmask( &opal_local_arch, OPAL_ARCH_ISBIGENDIAN );
 107 
 108     /* What's the maximum exponent ? */
 109     if ( LDBL_MAX_EXP == 16384 )
 110         opal_arch_setmask( &opal_local_arch, OPAL_ARCH_LDEXPSIZEIS15 );
 111 
 112     /* How about the length in bits of the mantissa */
 113     if ( LDBL_MANT_DIG == 64 )
 114         opal_arch_setmask( &opal_local_arch, OPAL_ARCH_LDMANTDIGIS64 );
 115     else if ( LDBL_MANT_DIG == 105 )
 116         opal_arch_setmask( &opal_local_arch, OPAL_ARCH_LDMANTDIGIS105 );
 117     else if ( LDBL_MANT_DIG == 106 )
 118         opal_arch_setmask( &opal_local_arch, OPAL_ARCH_LDMANTDIGIS106 );
 119     else if ( LDBL_MANT_DIG == 107 )
 120         opal_arch_setmask( &opal_local_arch, OPAL_ARCH_LDMANTDIGIS107 );
 121     else if ( LDBL_MANT_DIG == 113 )
 122         opal_arch_setmask( &opal_local_arch, OPAL_ARCH_LDMANTDIGIS113 );
 123 
 124     /* Intel data representation or Sparc ? */
 125     if( opal_arch_ldisintel() )
 126         opal_arch_setmask( &opal_local_arch, OPAL_ARCH_LDISINTEL );
 127 
 128     return OPAL_SUCCESS;
 129 }
 130 
 131 int32_t opal_arch_checkmask ( uint32_t *var, uint32_t mask )
 132 {
 133     unsigned int tmpvar = *var;
 134 
 135     /* Check whether the headers are set correctly,
 136        or whether this is an erroneous integer */
 137     if( !((*var) & OPAL_ARCH_HEADERMASK) ) {
 138         if( (*var) & OPAL_ARCH_HEADERMASK2 ) {
 139             char* pcDest, *pcSrc;
 140             /* Both ends of this integer have the wrong settings,
 141                maybe its just the wrong endian-representation. Try
 142                to swap it and check again. If it looks now correct,
 143                keep this version of the variable
 144             */
 145 
 146             pcDest = (char *) &tmpvar;
 147             pcSrc  = (char *) var + 3;
 148             *pcDest++ = *pcSrc--;
 149             *pcDest++ = *pcSrc--;
 150             *pcDest++ = *pcSrc--;
 151             *pcDest++ = *pcSrc--;
 152 
 153             if( (tmpvar & OPAL_ARCH_HEADERMASK) && (!(tmpvar & OPAL_ARCH_HEADERMASK2)) ) {
 154                 *var = tmpvar;
 155             } else
 156                 return -1;
 157         } else
 158             return -1;
 159     }
 160 
 161     /* Here is the real evaluation of the bitmask */
 162     return ( ((*var) & mask) == mask );
 163 }
 164 
 165 int
 166 opal_arch_set_fortran_logical_size(uint32_t size)
 167 {
 168     if (1 == size) {
 169         opal_arch_setmask( &opal_local_arch, OPAL_ARCH_LOGICALIS8);
 170     } else if (2 == size) {
 171         opal_arch_setmask( &opal_local_arch, OPAL_ARCH_LOGICALIS16);
 172     } else if (4 == size) {
 173         opal_arch_setmask( &opal_local_arch, OPAL_ARCH_LOGICALIS32);
 174     }
 175 
 176     return OPAL_SUCCESS;
 177 }

/* [<][>][^][v][top][bottom][index][help] */