Logo AND Algorithmique Numérique Distribuée

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