1 dnl machine.m4 --- machine characteristics
3 dnl Copyright (C) 2005, 2006, 2007, 2008 Sebastian Freundt
5 dnl Author: Sebastian Freundt <hroptatyr@sxemacs.org>
7 dnl This file is part of ASE.
10 AC_DEFUN([SXE_PROC_VENDORID], [dnl
11 ## arg 1 is the entire name (cpuid_0)
12 AC_REQUIRE([AC_PROG_CC])
15 AC_CHECK_HEADERS([stdio.h])
16 AC_CACHE_CHECK([for vendorid], [sxe_cv_proc_vendorid], [
17 AC_RUN_IFELSE([AC_LANG_PROGRAM([
22 void print_reg(FILE *f, long unsigned int reg);
25 print_reg(FILE *f, long unsigned int reg)
28 for (i = 0; i < 4; i++, reg >>= 8) {
29 fputc((int)(reg & 0xff), f);
34 long unsigned int eax, ebx, ecx, edx;
35 long unsigned int reg = 0;
38 f = fopen("conftest_vendorid", "w");
44 : "=a" (eax), "=b" (ebx), "=c" (ecx), "=d" (edx)
54 sxe_cv_proc_vendorid=$(cat "conftest_vendorid")
55 rm -f "conftest_vendorid"
58 sxe_cv_proc_vendorid="no"
59 rm -f "conftest_vendorid"], [
60 ## cross compiling case
61 sxe_cv_proc_vendorid="no"])])
64 ])dnl SXE_PROC_VENDORID
66 AC_DEFUN([__SXE_PROC_CPUID], [dnl
67 ## arg 1 is the file name into which to put the stuff
68 AC_REQUIRE([AC_PROG_CC])
71 AC_CHECK_HEADERS([stdio.h])
72 AC_CACHE_CHECK([for cpuid $1], [sxe_cv_proc_cpuid_$1], [
73 AC_RUN_IFELSE([AC_LANG_PROGRAM([
77 #define FMT "%08lx:%08lx:%08lx:%08lx:%08lx\n"
79 long unsigned int eax, ebx, ecx, edx;
80 long unsigned int reg = $1, max;
83 f = fopen("conftest_cpuid", "w");
90 : "=a" (eax), "=b" (ebx), "=c" (ecx), "=d" (edx)
92 fprintf(f, FMT, reg, eax, ebx, ecx, edx);
98 sxe_cv_proc_cpuid_$1=$(cat "conftest_cpuid" | \
100 rm -f "conftest_cpuid"
103 sxe_cv_proc_cpuid_$1="no"
104 rm -f "conftest_cpuid"], [
105 ## cross compiling case
106 sxe_cv_proc_cpuid_$1="no"])])
109 ])dnl __SXE_PROC_CPUID
111 AC_DEFUN([SXE_PROC_CPUID], [dnl
112 ## arg 1 is the file name into which to put the stuff
113 AC_REQUIRE([AC_PROG_CC])
116 cpuid_file=m4_default([$1],[cpuid])
117 AC_CHECK_HEADERS([stdio.h])
118 AC_CACHE_CHECK([for cpuid], [sxe_cv_proc_cpuid], [
119 AC_RUN_IFELSE([AC_LANG_PROGRAM([
123 #define FMT "%08lx:%08lx:%08lx:%08lx:%08lx\n"
127 long unsigned int eax, ebx, ecx, edx;
128 long unsigned int reg, max;
131 f = fopen("$cpuid_file", "w");
137 for (reg = max; reg <= max; reg++) {
139 : "=a" (eax), "=b" (ebx), "=c" (ecx), "=d" (edx)
144 fprintf(f, FMT, reg, eax, ebx, ecx, edx);
148 for (reg = max; reg <= max; reg++) {
150 : "=a" (eax), "=b" (ebx), "=c" (ecx), "=d" (edx)
152 if (reg == 0x80000000) {
155 fprintf(f, FMT, reg, eax, ebx, ecx, edx);
159 for (reg = max; reg <= max; reg++) {
161 : "=a" (eax), "=b" (ebx), "=c" (ecx), "=d" (edx)
163 if (reg == 0x80860000) {
166 fprintf(f, FMT, reg, eax, ebx, ecx, edx);
170 for (reg = max; reg <= max; reg++) {
172 : "=a" (eax), "=b" (ebx), "=c" (ecx), "=d" (edx)
174 if (reg == 0xc0000000) {
177 fprintf(f, FMT, reg, eax, ebx, ecx, edx);
184 sxe_cv_proc_cpuid="$cpuid_file"
187 sxe_cv_proc_cpuid="no"], [
188 ## cross compiling case
189 sxe_cv_proc_cpuid="no"])])
192 if test -r "$sxe_cv_proc_cpuid"; then
193 for line in $(cat "$sxe_cv_proc_cpuid"); do
194 dnl AS_MESSAGE([$line])
195 flag=$(echo "$line" | cut -d":" -f1)
196 AC_CACHE_CHECK([for cpuid $flag],
197 [sxe_cv_proc_cpuid_$flag], [
198 eval sxe_cv_proc_cpuid_$flag=$(echo "$line" | \
205 AC_DEFUN([SXE_CHECK_PROC_CPUINFO], [dnl
206 AC_CACHE_CHECK([for /proc/cpuinfo], [sxe_cv_file_proc_cpuinfo], [
207 if test -f "/proc/cpuinfo" -a \
208 -r "/proc/cpuinfo"; then
209 sxe_cv_file_proc_cpuinfo="yes"
211 sxe_cv_file_proc_cpuinfo="no"
213 ])dnl SXE_CHECK_PROC_CPUINFO
215 ## inspired by a snippet of Michael Paul Bailey <jinxidoru@byu.net>
216 AC_DEFUN([SXE_NPROCESSORS], [dnl
217 AC_REQUIRE([AC_PROG_EGREP])
218 AC_REQUIRE([SXE_CHECK_PROC_CPUINFO])
220 AC_CACHE_CHECK([for the number of processors], [sxe_cv_proc_number], [
221 if test "$sxe_cv_file_proc_cpuinfo" = "yes"; then
222 sxe_cv_proc_number=$($EGREP -c "^processor" "/proc/cpuinfo")
224 sxe_cv_proc_number="no"
227 sxe_nprocessors="$sxe_cv_proc_number"
229 ])dnl SXE_NPROCESSORS
231 AC_DEFUN([SXE_PROC_FLAGS], [dnl
232 AC_REQUIRE([AC_PROG_EGREP])
233 AC_REQUIRE([SXE_CHECK_PROC_CPUINFO])
235 AC_CACHE_CHECK([for processor flags], [sxe_cv_proc_flags], [
236 if test "$sxe_cv_file_proc_cpuinfo" = "yes"; then
237 sxe_cv_proc_flags=$($EGREP "^flags" "/proc/cpuinfo" | \
242 sxe_cv_proc_flags="no"
245 sxe_proc_flags="$sxe_cv_proc_flags"
249 AC_DEFUN([_SXE_CHECK_PROC_FLAG], [dnl
250 ## arg #1 is the cpu flag
251 ## arg #2 the action if supported
252 ## arg #3 the action if not supported
253 ## i.e. a call looks like
254 ## SXE_CHECK_PROC_FLAG([<FLAG>], [<ACTION-IF-TRUE>], [<ACTION-IF-FALSE>])
256 ## by side-effect this defines sxe_cv_proc_flag_<FLAG>
257 pushdef([FLAG], [$1])
258 pushdef([ACTION_IF_TRUE], [$2])
259 pushdef([ACTION_IF_FALSE], [$3])
261 AC_REQUIRE([AC_PROG_EGREP])
262 AC_REQUIRE([SXE_PROC_FLAGS])
264 SXE_MSG_CHECKING([whether cpu has ]FLAG[ flag])
265 sxe_cv_proc_flag_[]FLAG[]=$(\
266 echo "$sxe_cv_proc_flags" | $EGREP -c "\b[]FLAG[]\b")
268 if test "$sxe_cv_proc_flag_[]FLAG[]" -gt "0"; then
269 sxe_cv_proc_flag_[]FLAG[]="yes"
272 sxe_cv_proc_flag_[]FLAG[]="no"
275 SXE_MSG_RESULT([$sxe_cv_proc_flag_]FLAG)
277 popdef([ACTION_IF_FALSE])
278 popdef([ACTION_IF_TRUE])
280 ])dnl _SXE_CHECK_PROC_FLAG
282 AC_DEFUN([SXE_CHECK_PROC_FLAG], [dnl
283 ## a mitigating variant that checks if the cpuid stuff
284 ## is actually available
285 if test -n "${sxe_cv_proc_flags}" -a \
286 "${sxe_cv_proc_flags}" != "no"; then
287 ## expand the real macro now
288 _SXE_CHECK_PROC_FLAG($*)
290 ])dnl SXE_CHECK_PROC_FLAG
292 AC_DEFUN([_SXE_CHECK_PROC_CODE], [dnl
293 ## arg #1 is the cpuid
294 ## arg #2 is the register to query
295 ## arg #3 is the bit to query
296 ## arg #4 is a nick name for the defined cache variable
297 ## arg #5 the action if supported
298 ## arg #6 the action if not supported
300 ## by side-effect this defines sxe_cv_proc_code_<ID>_<REG>_<BIT>
301 ## which is yes if 1 and no when 0
302 ## if nick name (arg 4) is defined this one is used instead
306 pushdef([cv_nick], ifelse([$4], [],
307 [sxe_cv_proc_code_]ID[_]REG[_]BIT, [$4]))
308 pushdef([ACTION_IF_TRUE], [$5])
309 pushdef([ACTION_IF_FALSE], [$6])
311 AC_REQUIRE([SXE_PROC_FLAGS])
313 SXE_MSG_CHECKING([whether cpu has bit ]BIT[ in reg ]REG[ set in id ]ID)
333 sxe_cv_tmp="0x"$(echo $sxe_cv_proc_cpuid_[]ID[] | cut -d ":" -f $i)
335 if test "$(($sxe_cv_tmp >> []BIT[] & 1))" = "1"; then
342 SXE_MSG_RESULT([$]cv_nick[])
344 popdef([ACTION_IF_FALSE])
345 popdef([ACTION_IF_TRUE])
350 ])dnl _SXE_CHECK_PROC_CODE
352 AC_DEFUN([SXE_CHECK_PROC_CODE], [dnl
353 ## a mitigating variant that checks if the cpuid stuff
354 ## is actually available
356 if test -n "${sxe_cv_proc_cpuid}" -a \
357 "${sxe_cv_proc_cpuid}" != "no"; then
358 ## expand the real macro now
359 _SXE_CHECK_PROC_CODE($*)
361 ])dnl SXE_CHECK_PROC_CODE
365 AC_DEFUN([SXE_CHECK_PROC_MMX], [
366 SXE_MSG_CHECKING([for MMX extensions])
367 SXE_CHECK_PROC_CODE([00000001], [edx], [23], [sxe_cv_proc_mmx])
368 SXE_MSG_RESULT([$sxe_cv_proc_mmx])
369 ])dnl SXE_CHECK_PROC_MMX
371 AC_DEFUN([SXE_CHECK_PROC_AMDMMX], [
372 SXE_MSG_CHECKING([for AMD MMX extensions])
373 SXE_CHECK_PROC_CODE([80000001], [edx], [22], [sxe_cv_proc_amdmmx])
374 SXE_MSG_RESULT([$sxe_cv_proc_amdmmx])
375 ])dnl SXE_CHECK_PROC_MMX
377 AC_DEFUN([SXE_CHECK_PROC_3DNOW], [
378 SXE_MSG_CHECKING([for 3DNow! extensions])
379 SXE_CHECK_PROC_CODE([80000001], [edx], [31], [sxe_cv_proc_3dnow])
380 SXE_MSG_RESULT([$sxe_cv_proc_3dnow])
381 ])dnl SXE_CHECK_PROC_MMX
383 AC_DEFUN([SXE_CHECK_PROC_3DNOW2], [
384 SXE_MSG_CHECKING([for 3DNowExt extensions])
385 SXE_CHECK_PROC_CODE([80000001], [edx], [30], [sxe_cv_proc_3dnow2])
386 SXE_MSG_RESULT([$sxe_cv_proc_3dnow2])
387 ])dnl SXE_CHECK_PROC_MMX
389 AC_DEFUN([SXE_CHECK_PROC_SSE], [
390 SXE_MSG_CHECKING([for SSE extensions])
391 SXE_CHECK_PROC_CODE([00000001], [edx], [25], [sxe_cv_proc_sse])
392 SXE_MSG_RESULT([$sxe_cv_proc_sse])
393 ])dnl SXE_CHECK_PROC_SSE
395 AC_DEFUN([SXE_CHECK_PROC_SSE2], [
396 SXE_MSG_CHECKING([for SSE2 extensions])
397 SXE_CHECK_PROC_CODE([00000001], [edx], [26], [sxe_cv_proc_sse2])
398 SXE_MSG_RESULT([$sxe_cv_proc_sse2])
399 ])dnl SXE_CHECK_PROC_SSE2
401 AC_DEFUN([SXE_CHECK_PROC_SSE3], [
402 SXE_MSG_CHECKING([for SSE3 extensions])
403 SXE_CHECK_PROC_CODE([00000001], [ecx], [0], [sxe_cv_proc_sse3])
404 SXE_MSG_RESULT([$sxe_cv_proc_sse3])
405 ])dnl SXE_CHECK_PROC_SSE3
407 AC_DEFUN([SXE_CHECK_PROC_SSSE3], [
408 SXE_MSG_CHECKING([for SSSE3 extensions])
409 SXE_CHECK_PROC_CODE([00000001], [ecx], [9], [sxe_cv_proc_ssse3])
410 SXE_MSG_RESULT([$sxe_cv_proc_ssse3])
411 ])dnl SXE_CHECK_PROC_SSSE3
413 AC_DEFUN([SXE_CHECK_PROC_SSE41], [
414 SXE_MSG_CHECKING([for SSE4.1 extensions])
415 SXE_CHECK_PROC_CODE([00000001], [ecx], [19], [sxe_cv_proc_sse41])
416 SXE_MSG_RESULT([$sxe_cv_proc_sse41])
417 ])dnl SXE_CHECK_PROC_SSE41
419 AC_DEFUN([SXE_CHECK_PROC_SSE42], [
420 SXE_MSG_CHECKING([for SSE4.2 extensions])
421 SXE_CHECK_PROC_CODE([00000001], [ecx], [20], [sxe_cv_proc_sse42])
422 SXE_MSG_RESULT([$sxe_cv_proc_sse42])
423 ])dnl SXE_CHECK_PROC_SSE42
425 AC_DEFUN([SXE_CHECK_PROC_SSE4A], [
426 SXE_MSG_CHECKING([for SSE4A extensions])
427 SXE_CHECK_PROC_CODE([80000001], [ecx], [6], [sxe_cv_proc_sse4A])
428 SXE_MSG_RESULT([$sxe_cv_proc_sse4A])
429 ])dnl SXE_CHECK_PROC_SSE4A
431 AC_DEFUN([SXE_CHECK_PROC_SSE5], [
432 SXE_MSG_CHECKING([for SSE5 extensions])
433 SXE_CHECK_PROC_CODE([80000001], [ecx], [11], [sxe_cv_proc_sse5])
434 SXE_MSG_RESULT([$sxe_cv_proc_sse5])
435 ])dnl SXE_CHECK_PROC_SSE5
437 AC_DEFUN([SXE_CHECK_SIMD_EXTENSIONS], [
438 ## note that we enable "unsafe" fp optimisation with other compilers, too
441 SXE_CHECK_PROC_AMDMMX
443 SXE_CHECK_PROC_3DNOW2
453 SXE_CHECK_COMPILER_FLAGS([-mmmx])
454 SXE_CHECK_COMPILER_FLAGS([-maltivec])
455 SXE_CHECK_COMPILER_FLAGS([-m3dnow])
456 SXE_CHECK_COMPILER_FLAGS([-m3dnow -march=athlon])
457 SXE_CHECK_COMPILER_FLAGS([-msse])
458 SXE_CHECK_COMPILER_FLAGS([-msse2])
459 SXE_CHECK_COMPILER_FLAGS([-msse3])
460 SXE_CHECK_COMPILER_FLAGS([-mssse3])
461 SXE_CHECK_COMPILER_FLAGS([-msse4])
462 SXE_CHECK_COMPILER_FLAGS([-msse4.1])
463 SXE_CHECK_COMPILER_FLAGS([-msse4.2])
464 SXE_CHECK_COMPILER_FLAGS([-msse4a])
465 SXE_CHECK_COMPILER_FLAGS([-msse5])
466 SXE_CHECK_COMPILER_FLAGS([-mfpmath=sse])
467 SXE_CHECK_COMPILER_FLAGS([-msse -mfpmath=sse])
468 SXE_CHECK_COMPILER_FLAGS([-maes])
469 SXE_CHECK_COMPILER_FLAGS([-mabm])
470 SXE_CHECK_COMPILER_FLAGS([-mpclmul])
471 SXE_CHECK_COMPILER_FLAGS([-mavx])
476 ## actually the SSE sets contain each other, but this'll change
477 ## with the new generation stuff, SSE4.1, SSE4.2, SSE4a, SSE5
478 ## THUS we just include all them flags
479 sxe_cv_c_flags__msse_added="no"
480 if test "$sxe_cv_proc_sse5" = "yes" -a \
481 "$sxe_cv_c_flags__msse5"; then
482 sxe_cv_c_flags__msse_added="yes"
483 simdflags="$simdflags -msse5"
486 if test "$sxe_cv_proc_sse4A" = "yes" -a \
487 "$sxe_cv_c_flags__msse4a"; then
488 sxe_cv_c_flags__msse_added="yes"
489 simdflags="$simdflags -msse4a"
492 if test "$sxe_cv_proc_sse41" = "yes" -a \
493 "$sxe_cv_c_flags__msse4_1"; then
494 sxe_cv_c_flags__msse_added="yes"
495 simdflags="$simdflags -msse4.1"
498 if test "$sxe_cv_proc_sse42" = "yes" -a \
499 "$sxe_cv_c_flags__msse4_2"; then
500 sxe_cv_c_flags__msse_added="yes"
501 simdflags="$simdflags -msse4.2"
504 if test "$sxe_cv_proc_ssse3" = "yes" -a \
505 "$sxe_cv_c_flags__mssse3"; then
506 sxe_cv_c_flags__msse_added="yes"
507 simdflags="$simdflags -mssse3"
510 if test "$sxe_cv_proc_sse3" = "yes" -a \
511 "$sxe_cv_c_flags__msse3"; then
512 sxe_cv_c_flags__msse_added="yes"
513 simdflags="$simdflags -msse3"
516 if test "$sxe_cv_proc_sse2" = "yes" -a \
517 "$sxe_cv_c_flags__msse2" = "yes"; then
518 sxe_cv_c_flags__msse_added="yes"
519 simdflags="$simdflags -msse2"
522 if test "$sxe_cv_proc_sse" = "yes" -a \
523 "$sxe_cv_c_flags__msse" = "yes"; then
524 sxe_cv_c_flags__msse_added="yes"
525 simdflags="$simdflags -msse"
528 if test "$sxe_cv_c_flags__mfpmath_sse" = "yes" -a \
529 "$sxe_cv_c_flags__msse_added" = "yes"; then
530 simdflags="$simdflags -mfpmath=sse"
531 elif test "$sxe_cv_c_flags__msse__mfpmath_sse" = "yes" -a \
532 "$sxe_cv_c_flags__msse_added" = "no"; then
533 simdflags="$simdflags -mfpmath=sse"
536 ## also care about this new stuff ... what's their CPU proc equivalent?
537 if test "$sxe_cv_c_flags__maes" = "yes"; then
538 simdflags="$simdflags -maes"
540 if test "$sxe_cv_c_flags__mabm" = "yes"; then
541 simdflags="$simdflags -mabm"
543 if test "$sxe_cv_c_flags__mpclmul" = "yes"; then
544 simdflags="$simdflags -mpclmul"
547 AC_SUBST([simdflags])
548 ])dnl SXE_CHECK_SIMD_EXTENSIONS
551 AC_DEFUN([SXE_CHECK_PROC_X87FPU], [
552 SXE_MSG_CHECKING([whether x87 fpu is available])
553 SXE_CHECK_PROC_CODE([00000001], [edx], [0], [sxe_cv_proc_x87fpu])
554 SXE_MSG_RESULT([$sxe_cv_proc_x87fpu])
555 ])dnl SXE_CHECK_PROC_X87FPU
557 dnl conditional moves
558 AC_DEFUN([SXE_CHECK_PROC_CMOV], [
559 SXE_MSG_CHECKING([whether CMOV instructions are available])
560 SXE_CHECK_PROC_CODE([00000001], [edx], [15], [sxe_cv_proc_cmov])
561 SXE_MSG_RESULT([$sxe_cv_proc_cmov])
562 ])dnl SXE_CHECK_PROC_CMOV
564 dnl fast float storing and restoring
565 AC_DEFUN([SXE_CHECK_PROC_FXSR], [
566 SXE_MSG_CHECKING([whether FXSAVE/FXRSTOR instructions are available])
567 SXE_CHECK_PROC_CODE([00000001], [edx], [24], [sxe_cv_proc_fxsr])
568 SXE_MSG_RESULT([$sxe_cv_proc_fxsr])
569 ])dnl SXE_CHECK_PROC_FXSR
572 AC_DEFUN([SXE_CHECK_PROC_FFXSR], [
573 SXE_MSG_CHECKING([whether FXSAVE/FXRSTOR instruction optimisations are available])
574 SXE_CHECK_PROC_CODE([80000001], [edx], [25], [sxe_cv_proc_ffxsr])
575 SXE_MSG_RESULT([$sxe_cv_proc_ffxsr])
576 ])dnl SXE_CHECK_PROC_FFXSR
578 dnl AMD's bit fiddlers, VERY useful
579 AC_DEFUN([SXE_CHECK_PROC_ABM], [
580 SXE_MSG_CHECKING([whether advanced bit manipulation instructions (ABM) are available])
581 SXE_CHECK_PROC_CODE([80000001], [ecx], [5], [sxe_cv_proc_abm])
582 SXE_MSG_RESULT([$sxe_cv_proc_abm])
583 ])dnl SXE_CHECK_PROC_ABM
585 dnl time stamp counter
586 AC_DEFUN([SXE_CHECK_PROC_TSC], [
587 SXE_MSG_CHECKING([whether time stamp counter (TSC) is available])
588 SXE_CHECK_PROC_CODE([00000001], [edx], [4], [sxe_cv_proc_tsc])
589 SXE_MSG_RESULT([$sxe_cv_proc_tsc])
590 ])dnl SXE_CHECK_PROC_TSC
592 AC_DEFUN([SXE_CHECK_PROC_GOODNESS], [
593 SXE_CHECK_PROC_X87FPU
599 ])dnl SXE_CHECK_PROC_GOODNESS
601 dnl sxe-machine.m4 ends here