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 (c) 2008 Cisco Systems, Inc. All rights reserved. 14 * $COPYRIGHT$ 15 * 16 * Additional copyrights may follow 17 * 18 * $HEADER$ 19 */ 20 #ifndef OPAL_ARCH_H_HAS_BEEN_INCLUDED 21 #define OPAL_ARCH_H_HAS_BEEN_INCLUDED 22 23 #include "opal_config.h" 24 25 #include <float.h> 26 #include <assert.h> 27 28 29 /*************************************************** 30 ** This file tries to classify the most relevant 31 ** platforms regarding their data representation. 32 ** Three aspects are important: 33 ** - byte ordering (little or big endian) 34 ** - integer representation 35 ** - floating point representation. 36 37 ** In addition, don't forget about the C/Fortran problems. 38 ** 39 *****************************************************/ 40 41 42 /***************************************************************** 43 ** Part 1: Integer representation. 44 ** 45 ** The following data types are considered relevant: 46 ** 47 ** short 48 ** int 49 ** long 50 ** long long 51 ** integer (fortran) 52 ** 53 ** The fortran integer is dismissed here, since there is no 54 ** platform known to me, were fortran and C-integer do not match 55 ** 56 ** The following abbriviations are introduced: 57 ** 58 ** a) il32 (int long are 32 bits) (e.g. IA32 LINUX, SGI n32, SUN) 59 ** 60 ** short: 16 (else it would appear in the name) 61 ** int: 32 62 ** long: 32 63 ** long long: 64 64 ** 65 ** b) il64 ( int long are 64 bits) (e.g. Cray T3E ) 66 ** short: 32 67 ** int: 64 68 ** long: 64 69 ** long long: 64 70 ** 71 ** c) l64 (long are 64 bits) (e.g. SGI 64 IRIX, NEC SX5) 72 ** 73 ** short: 16 74 ** int: 32 75 ** long: 64 76 ** long long: 64 77 ** 78 ***********************************************************************/ 79 80 /********************************************************************* 81 ** Part 2: Floating point representation 82 ** 83 ** The following datatypes are considered relevant 84 ** 85 ** float 86 ** double 87 ** long double 88 ** real 89 ** double precision 90 ** 91 ** Unfortunatly, here we have to take care, whether float and real, 92 ** respectively double and double precision do match... 93 ** 94 ** a) fr32 (float and real are 32 bits) (e.g. SGI n32 and 64, SUN, NEC SX5,...) 95 ** float: 32 96 ** double: 64 97 ** long double: 128 98 ** real: 32 99 ** double prec.:64 100 ** 101 ** a1) fr32ld96 (float and real 32, long double 96) (e.g. IA32 LINUX gcc/icc) 102 ** see a), except long double is 96 103 ** 104 ** a2) fr32ld64 (e.g. IBM ) 105 ** see a), except long double is 64 106 ** 107 ** b) cray ( e.g. Cray T3E) 108 ** float: 32 109 ** double: 64 110 ** long double: 64 111 ** real: 64 112 ** double prec.:64 113 ** 114 ** 115 ** Problem: long double is really treated differently on every machine. Therefore, 116 ** we are storing besides the length of the long double also the length of the mantisee, 117 ** and the number of *relevant* bits in the exponent. Here are the values: 118 ** 119 ** Architecture sizeof(long double) mantisee relevant bits for exp. 120 ** 121 ** SGIn32/64: 128 107 10 122 ** SUN(sparc): 128 113 14 123 ** IA64: 128 64 14 124 ** IA32: 96 64 14 125 ** Alpha: 128 113 14 126 ** 64 53 10 (gcc) 127 ** IBM: 64 53 10 128 ** (128 106 10) (special flags required). 129 ** SX5: 128 105 22 130 ** 131 ** We will not implement all of these routiens, but we consider them 132 ** now when defining the header-settings 133 ** 134 ***********************************************************************/ 135 136 /******************************************************************** 137 ** 138 ** Classification of machines: 139 ** 140 ** IA32 LINUX: il32, fr32ld96, little endian 141 ** SUN: il32, fr32, big endian 142 ** SGI n32: il32, fr32, big endian 143 ** SGI 64: l64, fr32, big endian 144 ** NEC SX5: l64, fr32 big endian 145 ** Cray T3E: il64, cray, big endian 146 ** Cray X1: i32(+), fr32, big endian 147 ** IBM: il32, fr32ld64, big endian 148 ** ALPHA: l64, fr32, little endian 149 ** ITANIUM: l64, fr32, little endian 150 ** 151 ** 152 ** + sizeof ( long long ) not known 153 ** ? alpha supports both, big and little endian 154 ***********************************************************************/ 155 156 157 /* Current conclusions: 158 ** we need at the moment three settings: 159 ** - big/little endian ? 160 ** - is long 32 or 64 bits ? 161 ** - is long double 64, 96 or 128 bits ? 162 ** - no. of rel. bits in the exponent of a long double ( 10 or 14 ) 163 ** - no. of bits of the mantiss of a long double ( 53, 64, 105, 106, 107, 113 ) 164 ** 165 ** To store this in a 32 bit integer, we use the following definition: 166 ** 167 ** 1 2 3 4 168 ** 12345678 12345678 12345678 12345678 169 ** 170 ** 1. Byte: 171 ** bits 1 & 2: 00 (header) (to recognize the correct end) 172 ** bits 3 & 4: encoding: 00 = little, 01 = big 173 ** bits 5 & 6: reserved for later use. currently set to 00 174 ** bits 7 & 8: reserved for later use. currently set to 00 175 ** 2. Byte: 176 ** bits 1 & 2: length of long: 00 = 32, 01 = 64 177 ** bits 3 & 4: lenght of long long (not used currently, set to 00). 178 ** bits 5 & 6: length of C/C++ bool (00 = 8, 01 = 16, 10 = 32) 179 ** bits 7 & 8: length of Fortran Logical (00 = 8, 01 = 16, 10 = 32) 180 ** 3. Byte: 181 ** bits 1 & 2: length of long double: 00=64, 01=96,10 = 128 182 ** bits 3 & 4: no. of rel. bits in the exponent: 00 = 10, 01 = 14) 183 ** bits 5 - 7: no. of bits of mantisse ( 000 = 53, 001 = 64, 010 = 105, 184 ** 011 = 106, 100 = 107,101 = 113 ) 185 ** bit 8: intel or sparc representation of mantisse (0 = sparc, 186 ** 1 = intel ) 187 ** 4. Byte: 188 ** bits 1 & 2: 11 (header) (to recognize the correct end) 189 ** bits 3 & 4: reserved for later use. currently set to 11 190 ** bits 5 & 6: reserved for later use. currently set to 11 191 ** bits 7 & 8: reserved for later use. currently set to 11 192 */ 193 194 /* These masks implement the specification above above */ 195 196 #define OPAL_ARCH_HEADERMASK 0x03000000 /* set the fields for the header */ 197 #define OPAL_ARCH_HEADERMASK2 0x00000003 /* other end, needed for checks */ 198 #define OPAL_ARCH_UNUSEDMASK 0xfc000000 /* mark the unused fields */ 199 200 /* BYTE 1 */ 201 #define OPAL_ARCH_ISBIGENDIAN 0x00000008 202 203 /* BYTE 2 */ 204 #define OPAL_ARCH_LONGISxx 0x0000c000 /* mask for sizeof long */ 205 #define OPAL_ARCH_LONGIS64 0x00001000 206 #define OPAL_ARCH_LONGLONGISxx 0x00003000 /* mask for sizeof long long */ 207 208 #define OPAL_ARCH_BOOLISxx 0x00000c00 /* mask for sizeof bool */ 209 #define OPAL_ARCH_BOOLIS8 0x00000000 /* bool is 8 bits */ 210 #define OPAL_ARCH_BOOLIS16 0x00000400 /* bool is 16 bits */ 211 #define OPAL_ARCH_BOOLIS32 0x00000800 /* bool is 32 bits */ 212 213 #define OPAL_ARCH_LOGICALISxx 0x00000300 /* mask for sizeof Fortran logical */ 214 #define OPAL_ARCH_LOGICALIS8 0x00000000 /* logical is 8 bits */ 215 #define OPAL_ARCH_LOGICALIS16 0x00000100 /* logical is 16 bits */ 216 #define OPAL_ARCH_LOGICALIS32 0x00000200 /* logical is 32 bits */ 217 218 /* BYTE 3 */ 219 #define OPAL_ARCH_LONGDOUBLEIS96 0x00020000 220 #define OPAL_ARCH_LONGDOUBLEIS128 0x00010000 221 222 #define OPAL_ARCH_LDEXPSIZEIS15 0x00080000 223 224 #define OPAL_ARCH_LDMANTDIGIS64 0x00400000 225 #define OPAL_ARCH_LDMANTDIGIS105 0x00200000 226 #define OPAL_ARCH_LDMANTDIGIS106 0x00600000 227 #define OPAL_ARCH_LDMANTDIGIS107 0x00100000 228 #define OPAL_ARCH_LDMANTDIGIS113 0x00500000 229 230 #define OPAL_ARCH_LDISINTEL 0x00800000 231 232 BEGIN_C_DECLS 233 234 /* Local Architecture */ 235 OPAL_DECLSPEC extern uint32_t opal_local_arch; 236 237 /* Initialize architecture and determine all but fortran logical fields */ 238 OPAL_DECLSPEC int opal_arch_init(void); 239 240 OPAL_DECLSPEC int32_t opal_arch_checkmask ( uint32_t *var, uint32_t mask ); 241 242 /* Set fortran logical fields after init, to keep fortran out of opal... */ 243 OPAL_DECLSPEC int opal_arch_set_fortran_logical_size(uint32_t size); 244 245 END_C_DECLS 246 247 #endif /* OPAL_ARCH_H_HAS_BEEN_INCLUDED */ 248