Logo AND Algorithmique Numérique Distribuée

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