Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
project file of the test project
[simgrid.git] / acmacro / gras_arch.m4
1 # BEGIN OF GRAS ARCH CHECK
2 dnl
3 dnl GRAS_DO_CHECK_SIZEOF: Get the size of a datatype (even in cross-compile)
4 dnl  1: type tested
5 dnl  2: extra include lines
6 dnl  3: extra sizes to test
7 dnl ("adapted" from openldap)
8 dnl
9 AC_DEFUN([GRAS_DO_CHECK_SIZEOF],
10 [changequote(<<, >>)dnl 
11  dnl The cache variable name (and of the result). 
12  define(<<GRAS_CHECK_SIZEOF_RES>>, translit(ac_cv_sizeof_$1, [ *()], [_pLR]))dnl
13  changequote([, ])dnl 
14  AC_CACHE_VAL(GRAS_CHECK_SIZEOF_RES, 
15  [for ac_size in 4 8 1 2 16 $3 ; do # List sizes in rough order of prevalence. 
16    AC_COMPILE_IFELSE(AC_LANG_PROGRAM([#include "confdefs.h" 
17    #include <sys/types.h> 
18    $2 
19    ], [switch (0) case 0: case (sizeof ($1) == $ac_size):;]), GRAS_CHECK_SIZEOF_RES=$ac_size) 
20    if test x$GRAS_CHECK_SIZEOF_RES != x ; then break; fi 
21   done 
22  ]) 
23 ])
24
25 dnl
26 dnl GRAS_CHECK_SIZEOF: Get the size of a datatype (even in cross-compile), with msg display, and define the result
27 dnl  1: type tested
28 dnl  2: extra include lines
29 dnl  3: extra sizes to test
30 dnl ("adapted" from openldap)
31 dnl
32 AC_DEFUN([GRAS_CHECK_SIZEOF],
33 [AC_MSG_CHECKING(size of $1) 
34 GRAS_DO_CHECK_SIZEOF($1,$2)
35 if test x$GRAS_CHECK_SIZEOF_RES = x ; then 
36   AC_MSG_ERROR([cannot determine a size for $1]) 
37 fi 
38 AC_MSG_RESULT($GRAS_CHECK_SIZEOF_RES) 
39 ])
40
41 dnl
42 dnl GRAS_TWO_COMPLEMENT([type]): Make sure the type is two-complement
43 dnl warning, this does not work with char (quite logical)
44 dnl
45 AC_DEFUN([GRAS_TWO_COMPLEMENT],
46 [
47 AC_MSG_CHECKING(whether $1 is two-complement)
48 AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include "confdefs.h"
49 union {
50    signed $1 testInt;
51    unsigned char bytes[sizeof($1)];
52 } intTester;
53 ]],[[
54    intTester.testInt = -2;
55    switch (0) {
56     case 0:
57     case (((unsigned int)intTester.bytes[0] +
58            (unsigned int)intTester.bytes[sizeof($1) - 1]) - 509) == 0:
59    }
60 ]])], dnl end of AC LANG PROGRAM
61 [two_complement=yes],[two_complement=no] )dnl end of AC COMPILE IFELSE
62
63 AC_MSG_RESULT($two_complement)
64 if test x$two_complement != xyes ; then
65   AC_MSG_ERROR([GRAS works only two-complement integers (yet)])
66 fi
67 ])
68
69 dnl
70 dnl GRAS_SIGNED_SIZEOF: Get the size of the datatype, and make sure that
71 dnl signed, unsigned and unspecified have the same size
72 dnl
73 AC_DEFUN([GRAS_SIGNED_SIZEOF],
74 [AC_MSG_CHECKING(size of $1)
75 GRAS_DO_CHECK_SIZEOF($1,$2)
76 unspecif=$GRAS_CHECK_SIZEOF_RES
77 if test x$unspecif = x ; then
78   AC_MSG_ERROR([cannot determine a size for $1]) 
79 fi 
80
81 GRAS_DO_CHECK_SIZEOF(signed $1,$2)
82 signed=$GRAS_CHECK_SIZEOF_RES
83 if test x$signed = x ; then
84   AC_MSG_ERROR([cannot determine a size for signed $1]) 
85 fi 
86 if test x$unspecif != x$signed ; then
87   AC_MSG_ERROR(['signed $1' and '$1' have different sizes ! ($signed != $unspecif)]) 
88 fi 
89
90 GRAS_DO_CHECK_SIZEOF(unsigned $1,$2)
91 unsigned=$GRAS_CHECK_SIZEOF_RES
92 if test x$unsigned = x ; then
93   AC_MSG_ERROR([cannot determine a size for unsigned $1]) 
94 fi 
95 if test x$unsigned != x$signed ; then
96   AC_MSG_ERROR(['signed $1' and 'unsigned $1' have different sizes ! ($signed != $unsigned)]) 
97 fi 
98
99 AC_MSG_RESULT($GRAS_CHECK_SIZEOF_RES) 
100 ])
101
102 dnl
103 dnl End of CHECK_SIGNED_SIZEOF
104 dnl
105
106 # GRAS_STRUCT_BOUNDARY(): Check the minimal alignment boundary of $1 in structures
107 # ---------------------
108 # (using integer, I hope no arch let it change with the content)
109 AC_DEFUN([GRAS_STRUCT_BOUNDARY],
110 [changequote(<<, >>)dnl 
111  dnl The cache variable name (and of the result). 
112  define(<<GRAS_STRUCT_BOUNDARY_RES>>, translit(ac_cv_struct_boundary_$1, [ *()], [_pLR]))dnl
113  changequote([, ])dnl 
114  AC_MSG_CHECKING(for the minimal structure boundary of $1)
115
116  AC_CACHE_VAL(GRAS_STRUCT_BOUNDARY_RES, 
117  [for ac_size in 1 2 4 8 16 32 64 3 ; do # List sizes in rough order of prevalence. 
118    AC_COMPILE_IFELSE(AC_LANG_PROGRAM([#include "confdefs.h" 
119      #include <sys/types.h> 
120      struct s { char c; $1 i; };
121      ],[switch (0) case 0: case (sizeof (struct s) == $ac_size+sizeof($1)):;]), GRAS_STRUCT_BOUNDARY_RES=$ac_size)
122    if test x$GRAS_STRUCT_BOUNDARY_RES != x ; then break; fi 
123   done 
124  ])
125  AC_MSG_RESULT($GRAS_STRUCT_BOUNDARY_RES)
126  if test x$GRAS_STRUCT_BOUNDARY_RES = x ; then
127    AC_MSG_ERROR([Cannot determine the minimal alignment boundary of $1 in structures])
128  fi
129 ])
130
131 # GRAS_ARCH(): check the gras_architecture of this plateform
132 # -----------
133 # The different cases here must be syncronized with the array in src/base/DataDesc/ddt_convert.c
134 #
135 AC_DEFUN([GRAS_ARCH],
136 [
137 # Check for the architecture
138 AC_C_BIGENDIAN(endian=1,endian=0,AC_MSG_ERROR([GRAS works only for little or big endian systems (yet)]))
139 dnl Make sure we don't run on a non-two-complement arch, since we dunno convert them
140 dnl G RAS_TWO_COMPLEMENT(int) don't do this, it breaks cross-compile and all
141 dnl archs conform to this
142 AC_DEFINE_UNQUOTED(GRAS_BIGENDIAN,$endian,[define if big endian])
143           
144 GRAS_SIGNED_SIZEOF(char)              GRAS_STRUCT_BOUNDARY(char)
145 GRAS_SIGNED_SIZEOF(short int)         GRAS_STRUCT_BOUNDARY(short int)
146 GRAS_SIGNED_SIZEOF(int)               GRAS_STRUCT_BOUNDARY(int)
147 GRAS_SIGNED_SIZEOF(long int)          GRAS_STRUCT_BOUNDARY(long int)
148 GRAS_SIGNED_SIZEOF(long long int)     GRAS_STRUCT_BOUNDARY(long long int)
149
150 GRAS_STRUCT_BOUNDARY(float)           GRAS_STRUCT_BOUNDARY(double)
151
152 GRAS_CHECK_SIZEOF(void *)             GRAS_STRUCT_BOUNDARY(void *)
153 GRAS_CHECK_SIZEOF(void (*) (void))    
154                                                                   
155
156 AC_MSG_CHECKING(the GRAS signature of this architecture)
157 if test x$endian = x1 ; then
158   trace_endian=B
159 else
160   trace_endian=l
161 fi
162 gras_arch=unknown
163 trace="$trace_endian"
164
165 trace="${trace}_C:${ac_cv_sizeof_char}/${ac_cv_struct_boundary_char}:"
166
167 trace="${trace}_I:${ac_cv_sizeof_short_int}/${ac_cv_struct_boundary_short_int}"
168 trace="${trace}:${ac_cv_sizeof_int}/${ac_cv_struct_boundary_int}"
169 trace="${trace}:${ac_cv_sizeof_long_int}/${ac_cv_struct_boundary_long_int}"
170 trace="${trace}:${ac_cv_sizeof_long_long_int}/${ac_cv_struct_boundary_long_long_int}:"
171
172 trace="${trace}_P:${ac_cv_sizeof_void_p}/${ac_cv_struct_boundary_void_p}"
173 trace="${trace}:${ac_cv_sizeof_void_LpR_LvoidR}/${ac_cv_struct_boundary_void_p}:"
174
175 trace="${trace}_D:4/${ac_cv_struct_boundary_float}:8/${ac_cv_struct_boundary_double}:"
176
177 # sizeof float/double are not tested since IEEE 754 is assumed.
178 # Check README.IEEE for rational.
179
180 # The numbers after the _ in the arch name are the maximal packing boundary.
181 # big32_2   means that all data are aligned on a 2 bytes boundary.              (ARM)
182 # big32_8_4 means that some or them are aligned on 8 bytes, some are on 4 bytes (AIX)
183 case $trace in
184   l_C:1/1:_I:2/1:4/1:4/1:8/1:_P:4/1:4/1:_D:4/1:8/1:) gras_arch=0; gras_arch_name=little32_1;;
185   l_C:1/1:_I:2/2:4/2:4/2:8/2:_P:4/2:4/2:_D:4/2:8/2:) gras_arch=1; gras_arch_name=little32_2;;
186   l_C:1/1:_I:2/2:4/4:4/4:8/4:_P:4/4:4/4:_D:4/4:8/4:) gras_arch=2; gras_arch_name=little32_4;;
187   l_C:1/1:_I:2/2:4/4:4/4:8/8:_P:4/4:4/4:_D:4/4:8/8:) gras_arch=3; gras_arch_name=little32_8;;
188   
189   l_C:1/1:_I:2/2:4/4:8/8:8/8:_P:8/8:8/8:_D:4/4:8/8:) gras_arch=4; gras_arch_name=little64;;
190   
191   B_C:1/1:_I:2/2:4/4:4/4:8/8:_P:4/4:4/4:_D:4/4:8/8:) gras_arch=5; gras_arch_name=big32;;
192   B_C:1/1:_I:2/2:4/4:4/4:8/8:_P:4/4:4/4:_D:4/4:8/4:) gras_arch=6; gras_arch_name=big32_8_4;;
193   B_C:1/1:_I:2/2:4/4:4/4:8/4:_P:4/4:4/4:_D:4/4:8/4:) gras_arch=7; gras_arch_name=big32_4;;
194   B_C:1/1:_I:2/2:4/2:4/2:8/2:_P:4/2:4/2:_D:4/2:8/2:) gras_arch=8; gras_arch_name=big32_2;;
195   
196   B_C:1/1:_I:2/2:4/4:8/8:8/8:_P:8/8:8/8:_D:4/4:8/8:) gras_arch=9; gras_arch_name=big64;;
197   B_C:1/1:_I:2/2:4/4:8/8:8/8:_P:8/8:8/8:_D:4/4:8/4:) gras_arch=10;gras_arch_name=big64_8_4;;
198 esac
199 if test x$gras_arch = xunknown ; then
200   AC_MSG_RESULT([damnit ($trace)])
201   AC_MSG_ERROR([Impossible to determine the GRAS architecture signature.
202 Please report this architecture trace ($trace) and what it corresponds to.])
203 fi
204 echo "$as_me:$LINENO: GRAS trace of this machine: $trace" >&AS_MESSAGE_LOG_FD
205 AC_DEFINE_UNQUOTED(GRAS_THISARCH,$gras_arch,[defines the GRAS architecture signature of this machine])
206 AC_MSG_RESULT($gras_arch ($gras_arch_name))
207
208 AC_MSG_CHECKING(the maximal size of scalar)
209 ac_cv_sizeof_max=0
210 for s in $ac_cv_sizeof_char \
211          $ac_cv_sizeof_short_int $ac_cv_sizeof_int $ac_cv_sizeof_long_int $ac_cv_sizeof_long_long_int \
212          $ac_cv_sizeof_void_p $ac_cv_sizeof_void_LpR_LvoidR \
213          4 8; do
214          
215   if test $ac_cv_sizeof_max -lt $s ; then 
216     ac_cv_sizeof_max=$s
217   fi
218 done
219 AC_MSG_RESULT($ac_cv_sizeof_max)
220 AC_DEFINE_UNQUOTED([SIZEOF_MAX],$ac_cv_sizeof_max,[The maximal size of any scalar on this arch])
221
222 ])
223 # END OF GRAS ARCH CHECK
224
225 AC_DEFUN([GRAS_CHECK_STRUCT_COMPACTION],
226 [  AC_MSG_CHECKING(whether the struct gets packed)
227    AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include "confdefs.h" 
228         #include <sys/types.h>
229         #include <stddef.h> /* offsetof() */
230         struct s {char c; double d;}; 
231        ]],[[switch (0) 
232         case 0: 
233         case (sizeof(struct s) == sizeof(double)+sizeof(char)):;
234        ]])],[gras_struct_packed=yes],[gras_struct_packed=no])
235      
236    AC_MSG_RESULT($gras_struct_packed)
237    if test x$gras_struct_packed = "xyes" ; then
238      AC_MSG_ERROR([GRAS does not support packed structures since it leads to nasty misalignments])
239    fi
240    
241    AC_MSG_CHECKING(whether the struct gets compacted)
242    AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include "confdefs.h" 
243         #include <sys/types.h>
244         #include <stddef.h> /* offsetof() */
245         struct s {double d; int i; char c;}; 
246        ]],[[switch (0) 
247         case 0: 
248         case (offsetof(struct s,c) == sizeof(double)+sizeof(int)):;
249        ]])],[gras_struct_compact=yes],[gras_struct_compact=no])
250      
251    AC_MSG_RESULT($gras_struct_compact)
252    
253    if test x$gras_struct_compact != xyes ; then
254      AC_MSG_ERROR([GRAS works only on structure compacting architectures (yet)])
255    fi
256    AC_DEFINE_UNQUOTED(GRAS_STRUCT_COMPACT, 1,
257       [Defined if structures are compacted when possible.
258           
259        Consider this structure: struct s {double d; int i; char c;}; 
260           
261        If it is allowed, the char is placed just after the int. If not,
262        it has to be on the 8 bytes boundary imposed by the double.
263        
264        For now, GRAS requires the structures to be compacted.
265       ])
266    AC_MSG_CHECKING(whether arrays can straddle struct alignment boundaries)
267
268    AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include "confdefs.h" 
269       #include <sys/types.h>
270         #include <stddef.h> /* offsetof() */
271         struct s { double d; int i; char c[6]; };
272      ]],[[switch (0) 
273       case 0: 
274       case (offsetof(struct s,c) == sizeof(double)+sizeof(int)):;
275      ]])],[gras_array_straddle_struct=yes],[gras_array_straddle_struct=no])
276      
277    AC_MSG_RESULT($gras_array_straddle_struct)
278
279    if test x$gras_array_straddle_struct = xyes ; then
280      AC_DEFINE_UNQUOTED(GRAS_ARRAY_STRADDLE_STRUCT, 1,
281         [Defined if arrays in struct can straddle struct alignment boundaries.
282         
283          This is like than the structure compaction above, but this time,
284          the argument to be compacted is an array whom each element would be
285          normally compacted. Exemple:
286          
287          struct s { double d; int i; char c[6]; };
288          
289          Arrays can straddle if c is allowed to come just after i.
290          
291          Note that GRAS only support architecture presenting this
292          caracteristic so far.
293         ])
294    else
295      AC_MSG_ERROR([GRAS can only work on architectures allowing array fields to straddle alignment boundaries (yet)])
296    fi
297 ])
298 # END OF GRAS CHECK STRUCT COMPACTION
299
300 AC_DEFUN([GRAS_C_COMPACT_STRUCT],
301 [  AC_MSG_CHECKING(whether the struct gets compacted)
302    AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include "confdefs.h" 
303         #include <sys/types.h>
304         #include <stddef.h> /* offsetof() */
305         struct s {double d; int a; int b;}; 
306        ]],[[switch (0) 
307         case 0: 
308         case (offsetof(struct s,b) == sizeof(double)+sizeof(int)):;
309        ]])],[gras_compact_struct=yes],[gras_compact_struct=no])
310      
311    AC_MSG_RESULT($gras_compact_struct)
312    
313    if test x$gras_compact_struct = xyes ; then
314      AC_DEFINE_UNQUOTED(GRAS_COMPACT_STRUCT, 1,
315           [Defined if structures are compacted when possible])
316    fi     
317 ])
318 # END OF GRAS COMPACT STRUCT
319