Removing all m4 references for CPUID by creating special C program to parse

CPUID and directly doing compiler checks in autoconf.ac
This commit is contained in:
Kevin Greenan 2015-05-03 17:13:02 -07:00
parent 738d579185
commit f3a99e81e9
4 changed files with 169 additions and 361 deletions

View File

@ -97,6 +97,74 @@ dnl Expand the sources and objects needed to build the library
AC_SUBST(ac_aux_dir)
AC_SUBST(OBJECTS)
dnl Do CPUID and associated compiler flag checks
SUPPORTED_FLAGS=""
$CC - -E -mmmx </dev/null >/dev/null 2>&1
if [[ $? == "0" ]]; then
SUPPORTED_FLAGS="-mmmx"
AC_MSG_RESULT([$CC supports -mmmx])
fi
$CC - -E -msse </dev/null >/dev/null 2>&1
if [[ $? == "0" ]]; then
SUPPORTED_FLAGS="$SUPPORTED_FLAGS -msse"
AC_MSG_RESULT([$CC supports -msse])
fi
$CC - -E -msse2 </dev/null >/dev/null 2>&1
if [[ $? == "0" ]]; then
SUPPORTED_FLAGS="$SUPPORTED_FLAGS -msse2"
AC_MSG_RESULT([$CC supports -msse2])
fi
$CC - -E -msse3 </dev/null >/dev/null 2>&1
if [[ $? == "0" ]]; then
SUPPORTED_FLAGS="$SUPPORTED_FLAGS -msse3"
AC_MSG_RESULT([$CC supports -msse3])
fi
$CC - -E -mssse3 </dev/null >/dev/null 2>&1
if [[ $? == "0" ]]; then
SUPPORTED_FLAGS="$SUPPORTED_FLAGS -mssse3"
AC_MSG_RESULT([$CC supports -mssse3])
fi
$CC - -E -msse4.1 </dev/null >/dev/null 2>&1
if [[ $? == "0" ]]; then
SUPPORTED_FLAGS="$SUPPORTED_FLAGS -msse4.1"
AC_MSG_RESULT([$CC supports -msse4.1])
fi
$CC - -E -msse4.2 </dev/null >/dev/null 2>&1
if [[ $? == "0" ]]; then
SUPPORTED_FLAGS="$SUPPORTED_FLAGS -msse4.2"
AC_MSG_RESULT([$CC supports -msse4.2])
fi
$CC - -E -mavx </dev/null >/dev/null 2>&1
if [[ $? == "0" ]]; then
SUPPORTED_FLAGS="$SUPPORTED_FLAGS -mavx"
AC_MSG_RESULT([$CC supports -mavx])
fi
# Detect the SIMD features supported by both the compiler and the CPU
SIMD_FLAGS=""
cat get_flags_from_cpuid.c | sed "s/FLAGSFROMAUTOCONF/${SUPPORTED_FLAGS}/" | $CC -x c -g - -o get_flags_from_cpuid
if [[ -e ./get_flags_from_cpuid ]]; then
chmod 755 get_flags_from_cpuid; ./get_flags_from_cpuid; rm ./get_flags_from_cpuid
if [[ -e compiler_flags ]]; then
SIMD_FLAGS=`cat compiler_flags`
rm -f compiler_flags
else
AC_MSG_WARN([Could not run the CPUID detection program])
fi
else
AC_MSG_WARN([Could not compile the CPUID detection program])
fi
AC_MSG_RESULT([Generating with SIMD flags: $SIMD_FLAGS])
CFLAGS="$CFLAGS $SIMD_FLAGS"
# Certain code may be dependent on 32 vs. 64-bit arch, so add a
# flag for 64-bit
if test "$ac_cv_sizeof_long" -eq 8; then
CFLAGS="$CFLAGS -DARCH_64"
fi
#################################################################################
# Doxygen Documentation
#################################################################################

101
get_flags_from_cpuid.c Normal file
View File

@ -0,0 +1,101 @@
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#define EDX_MMX_BIT 23
#define EDX_SSE_BIT 25
#define EDX_SSE2_BIT 26
#define ECX_SSE3_BIT 0
#define ECX_SSSE3_BIT 9
#define ECX_SSE41_BIT 19
#define ECX_SSE42_BIT 20
#define ECX_AVXOS_BIT 27
#define ECX_AVX_BIT 28
uint64_t get_supported_flags()
{
uint64_t supp_comp_flgs = 0;
char *comp_flag = NULL;
char SUPPORTED_COMP_FLAGS[] ="FLAGSFROMAUTOCONF\0";
for (comp_flag = strtok(SUPPORTED_COMP_FLAGS, " "); comp_flag != NULL; comp_flag = strtok(NULL, " ")) {
if (strncmp(comp_flag, "-m", 2) != 0) {
fprintf(stderr, "Invalid comp_flag: %s\n", comp_flag);
exit(2);
}
if (strcmp(comp_flag, "-mmmx\0") == 0) {
supp_comp_flgs |= (1 << EDX_MMX_BIT);
}
if (strcmp(comp_flag, "-msse\0") == 0) {
supp_comp_flgs |= (1 << EDX_SSE_BIT);
}
if (strcmp(comp_flag, "-msse2\0") == 0) {
supp_comp_flgs |= (1 << EDX_SSE2_BIT);
}
if (strcmp(comp_flag, "-msse3\0") == 0) {
supp_comp_flgs |= (1 << ECX_SSE3_BIT);
}
if (strcmp(comp_flag, "-mssse3\0") == 0) {
supp_comp_flgs |= (1 << ECX_SSSE3_BIT);
}
if (strcmp(comp_flag, "-msse4.1\0") == 0) {
supp_comp_flgs |= (1 << ECX_SSE41_BIT);
}
if (strcmp(comp_flag, "-msse4.2\0") == 0) {
supp_comp_flgs |= (1 << ECX_SSE42_BIT);
}
if (strcmp(comp_flag, "-mavx\0") == 0) {
supp_comp_flgs |= (1 << ECX_AVX_BIT);
}
}
return supp_comp_flgs;
}
int is_supported(int cpuid_reg, uint64_t comp_flags, int feature_bit)
{
return ((cpuid_reg >> feature_bit) & 0x1) && ((comp_flags >> feature_bit) & 0x1);
}
int main(int argc, char** argv)
{
int feature_eax, feature_ebx, feature_ecx, feature_edx;
uint64_t supp_comp_flgs = get_supported_flags(argc, argv);
FILE *f = fopen("compiler_flags", "w");
__asm__("cpuid"
: "=a" (feature_eax), "=b" (feature_ebx), "=c" (feature_ecx), "=d" (feature_edx)
: "a" (0x00000001));
if (is_supported(feature_edx, supp_comp_flgs, EDX_MMX_BIT)) {
fprintf(f, "-mmmx -DINTEL_MMX ");
}
if (is_supported(feature_edx, supp_comp_flgs, EDX_SSE_BIT)) {
fprintf(f, "-msse -DINTEL_SSE ");
}
if (is_supported(feature_edx, supp_comp_flgs, EDX_SSE2_BIT)) {
fprintf(f, "-msse2 -DINTEL_SSE2 ");
}
if (is_supported(feature_ecx, supp_comp_flgs, ECX_SSE3_BIT)) {
fprintf(f, "-msse3 -DINTEL_SSE3 ");
}
if (is_supported(feature_ecx, supp_comp_flgs, ECX_SSSE3_BIT)) {
fprintf(f, "-mssse3 -DINTEL_SSSE3 ");
}
if (is_supported(feature_ecx, supp_comp_flgs, ECX_SSE41_BIT)) {
fprintf(f, "-msse4.1 -DINTEL_SSE41 ");
}
if (is_supported(feature_ecx, supp_comp_flgs, ECX_SSE42_BIT)) {
fprintf(f, "-msse4.2 -DINTEL_SSE42 ");
}
if (is_supported(feature_ecx, supp_comp_flgs, ECX_AVX_BIT)) {
if ((feature_ecx >> ECX_AVXOS_BIT) & 0x1) {
fprintf(f, "-mavx -DINTEL_AVX ");
}
}
fclose(f);
return 0;
}

View File

@ -1,72 +0,0 @@
# ===========================================================================
# http://www.gnu.org/software/autoconf-archive/ax_check_compile_flag.html
# ===========================================================================
#
# SYNOPSIS
#
# AX_CHECK_COMPILE_FLAG(FLAG, [ACTION-SUCCESS], [ACTION-FAILURE], [EXTRA-FLAGS])
#
# DESCRIPTION
#
# Check whether the given FLAG works with the current language's compiler
# or gives an error. (Warnings, however, are ignored)
#
# ACTION-SUCCESS/ACTION-FAILURE are shell commands to execute on
# success/failure.
#
# If EXTRA-FLAGS is defined, it is added to the current language's default
# flags (e.g. CFLAGS) when the check is done. The check is thus made with
# the flags: "CFLAGS EXTRA-FLAGS FLAG". This can for example be used to
# force the compiler to issue an error when a bad flag is given.
#
# NOTE: Implementation based on AX_CFLAGS_GCC_OPTION. Please keep this
# macro in sync with AX_CHECK_{PREPROC,LINK}_FLAG.
#
# LICENSE
#
# Copyright (c) 2008 Guido U. Draheim <guidod@gmx.de>
# Copyright (c) 2011 Maarten Bosmans <mkbosmans@gmail.com>
#
# This program is free software: you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by the
# Free Software Foundation, either version 3 of the License, or (at your
# option) any later version.
#
# This program is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
# Public License for more details.
#
# You should have received a copy of the GNU General Public License along
# with this program. If not, see <http://www.gnu.org/licenses/>.
#
# As a special exception, the respective Autoconf Macro's copyright owner
# gives unlimited permission to copy, distribute and modify the configure
# scripts that are the output of Autoconf when processing the Macro. You
# need not follow the terms of the GNU General Public License when using
# or distributing such scripts, even though portions of the text of the
# Macro appear in them. The GNU General Public License (GPL) does govern
# all other use of the material that constitutes the Autoconf Macro.
#
# This special exception to the GPL applies to versions of the Autoconf
# Macro released by the Autoconf Archive. When you make and distribute a
# modified version of the Autoconf Macro, you may extend this special
# exception to the GPL to apply to your modified version as well.
#serial 2
AC_DEFUN([AX_CHECK_COMPILE_FLAG],
[AC_PREREQ(2.59)dnl for _AC_LANG_PREFIX
AS_VAR_PUSHDEF([CACHEVAR],[ax_cv_check_[]_AC_LANG_ABBREV[]flags_$4_$1])dnl
AC_CACHE_CHECK([whether _AC_LANG compiler accepts $1], CACHEVAR, [
ax_check_save_flags=$[]_AC_LANG_PREFIX[]FLAGS
_AC_LANG_PREFIX[]FLAGS="$[]_AC_LANG_PREFIX[]FLAGS $4 $1"
AC_COMPILE_IFELSE([AC_LANG_PROGRAM()],
[AS_VAR_SET(CACHEVAR,[yes])],
[AS_VAR_SET(CACHEVAR,[no])])
_AC_LANG_PREFIX[]FLAGS=$ax_check_save_flags])
AS_IF([test x"AS_VAR_GET(CACHEVAR)" = xyes],
[m4_default([$2], :)],
[m4_default([$3], :)])
AS_VAR_POPDEF([CACHEVAR])dnl
])dnl AX_CHECK_COMPILE_FLAGS

View File

@ -1,289 +0,0 @@
#
# Updated by KMG to support -DINTEL_SSE for GF-Complete
#
# ===========================================================================
# http://www.gnu.org/software/autoconf-archive/ax_ext.html
# ===========================================================================
#
# SYNOPSIS
#
# AX_EXT
#
# DESCRIPTION
#
# Find supported SIMD extensions by requesting cpuid. When an SIMD
# extension is found, the -m"simdextensionname" is added to SIMD_FLAGS if
# compiler supports it. For example, if "sse2" is available, then "-msse2"
# is added to SIMD_FLAGS.
#
# This macro calls:
#
# AC_SUBST(SIMD_FLAGS)
#
# And defines:
#
# HAVE_MMX / HAVE_SSE / HAVE_SSE2 / HAVE_SSE3 / HAVE_SSSE3 / HAVE_SSE4.1 / HAVE_SSE4.2 / HAVE_AVX
#
# LICENSE
#
# Copyright (c) 2007 Christophe Tournayre <turn3r@users.sourceforge.net>
# Copyright (c) 2013 Michael Petch <mpetch@capp-sysware.com>
#
# Copying and distribution of this file, with or without modification, are
# permitted in any medium without royalty provided the copyright notice
# and this notice are preserved. This file is offered as-is, without any
# warranty.
#serial 12
AC_DEFUN([AX_EXT],
[
AC_REQUIRE([AC_CANONICAL_HOST])
case $host_cpu in
powerpc*)
AC_CACHE_CHECK([whether altivec is supported], [ax_cv_have_altivec_ext],
[
if test `/usr/sbin/sysctl -a 2>/dev/null| grep -c hw.optional.altivec` != 0; then
if test `/usr/sbin/sysctl -n hw.optional.altivec` = 1; then
ax_cv_have_altivec_ext=yes
fi
fi
])
if test "$ax_cv_have_altivec_ext" = yes; then
AC_DEFINE(HAVE_ALTIVEC,,[Support Altivec instructions])
AX_CHECK_COMPILE_FLAG(-faltivec, SIMD_FLAGS="$SIMD_FLAGS -faltivec", [])
fi
;;
i[[3456]]86*|x86_64*|amd64*)
AC_REQUIRE([AC_PROG_CC])
AC_LANG_PUSH([C])
# Note for the next 3 macros: m4 does not like '$' and '>', so
# we have to use the ascii values, 36 and 62, resp. to print the
# characters out to the temporary shell script used to detect
# CPUID settings
AC_CACHE_VAL([ax_cv_feature_ecx], [
AC_RUN_IFELSE([AC_LANG_PROGRAM([#include <stdio.h>], [
int eax, ebx, ecx, edx;
FILE *f;
__asm__("cpuid"
: "=a" (eax), "=b" (ebx), "=c" (ecx), "=d" (edx)
: "a" (0x00000001));
f = fopen("ax_cv_feature_ecx", "w");
fprintf(f, "if (( (0x%x %c%c %c0) & 0x1 )); then echo 1; else echo 0; fi\n", ecx, 62, 62, 36);
fclose(f);
return 0;
])],
#[ax_cv_feature_ecx=`cat ax_cv_feature_ecx`; rm -f ax_cv_feature_ecx],
[ax_cv_feature_ecx=`cat ax_cv_feature_ecx`],
[ax_cv_feature_ecx='echo 0'; rm -f ax_cv_feature_ecx],
[ax_cv_feature_ecx='echo 0'])])
AC_CACHE_VAL([ax_cv_feature_edx], [
AC_RUN_IFELSE([AC_LANG_PROGRAM([#include <stdio.h>], [
int eax, ebx, ecx, edx;
FILE *f;
__asm__("cpuid"
: "=a" (eax), "=b" (ebx), "=c" (ecx), "=d" (edx)
: "a" (0x00000001));
f = fopen("ax_cv_feature_edx", "w");
fprintf(f, "if (( (0x%x %c%c %c0) & 0x1 )); then echo 1; else echo 0; fi\n", edx, 62, 62, 36);
fclose(f);
return 0;
])],
[ax_cv_feature_edx=`cat ax_cv_feature_edx`; rm -f ax_cv_feature_edx],
[ax_cv_feature_edx='echo 0'; rm -f ax_cv_feature_edx],
[ax_cv_feature_edx='echo 0'])])
AC_CACHE_VAL([ax_cv_vendor_ecx], [
AC_RUN_IFELSE([AC_LANG_PROGRAM([#include <stdio.h>], [
int eax, ebx, ecx, edx;
FILE *f;
__asm__("cpuid"
: "=a" (eax), "=b" (ebx), "=c" (ecx), "=d" (edx)
: "a" (0x00000000));
f = fopen("ax_cv_vendor_ecx", "w");
fprintf(f, "if (( (0x%x %c%c %c0) & 0x1)); then echo 1; else echo 0; fi\n", ecx, 62, 62, 36);
fclose(f);
return 0;
])],
[ax_cv_vendor_ecx=`cat ax_cv_vendor_ecx`; rm -f ax_cv_vendor_ecx],
[ax_cv_vendor_ecx='echo 0'; rm -f ax_cv_vendor_ecx],
[ax_cv_vendor_ecx='echo 0'])])
AC_LANG_POP([C])
AC_CACHE_CHECK([whether mmx is supported], [ax_cv_have_mmx_ext],
[
ax_cv_have_mmx_ext=no
if test "$[[ `sh -c \"$ax_cv_feature_edx\" 23` ]]" = "1"; then
ax_cv_have_mmx_ext=yes
fi
])
AC_CACHE_CHECK([whether sse is supported], [ax_cv_have_sse_ext],
[
ax_cv_have_sse_ext=no
if test "$[[ `sh -c \"$ax_cv_feature_edx\" 25` ]]" = "1"; then
ax_cv_have_sse_ext=yes
fi
])
AC_CACHE_CHECK([whether sse2 is supported], [ax_cv_have_sse2_ext],
[
ax_cv_have_sse2_ext=no
if test "$[[ `sh -c \"$ax_cv_feature_edx\" 26` ]]" = "1"; then
ax_cv_have_sse2_ext=yes
fi
])
AC_CACHE_CHECK([whether sse3 is supported], [ax_cv_have_sse3_ext],
[
ax_cv_have_sse3_ext=no
if test "$[[ `sh -c \"$ax_cv_feature_ecx\" 0` ]]" = "1"; then
ax_cv_have_sse3_ext=yes
fi
])
AC_CACHE_CHECK([whether ssse3 is supported], [ax_cv_have_ssse3_ext],
[
ax_cv_have_ssse3_ext=no
if test "$[[ `sh -c \"$ax_cv_feature_ecx\" 9` ]]" = "1"; then
ax_cv_have_ssse3_ext=yes
fi
])
AC_CACHE_CHECK([whether sse4.1 is supported], [ax_cv_have_sse41_ext],
[
ax_cv_have_sse41_ext=no
if test "$[[ `sh -c \"$ax_cv_feature_ecx\" 19` ]]" = "1"; then
ax_cv_have_sse41_ext=yes
fi
])
AC_CACHE_CHECK([whether sse4.2 is supported], [ax_cv_have_sse42_ext],
[
ax_cv_have_sse42_ext=no
if test "$[[ `sh -c \"$ax_cv_feature_ecx\" 20` ]]" = "1"; then
ax_cv_have_sse42_ext=yes
fi
])
AC_CACHE_CHECK([whether avx is supported by processor], [ax_cv_have_avx_cpu_ext],
[
ax_cv_have_avx_cpu_ext=no
if test "$[[ `sh -c \"$ax_cv_feature_ecx\" 28` ]]" = "1"; then
ax_cv_have_avx_cpu_ext=yes
fi
])
if test x"$ax_cv_have_avx_cpu_ext" = x"yes"; then
AC_CACHE_CHECK([whether avx is supported by operating system], [ax_cv_have_avx_ext],
[
ax_cv_have_avx_ext=no
if test "$[[ `sh -c \"$ax_cv_feature_ecx\" 27` ]]" = "1"; then
if test "$[[ `sh -c \"$ax_cv_vendor_ecx\" 6` ]]" = "1"; then
ax_cv_have_avx_ext=yes
fi
fi
])
if test x"$ax_cv_have_avx_ext" = x"no"; then
AC_MSG_WARN([Your processor supports AVX, but your operating system doesn't])
fi
fi
if test "$ax_cv_have_mmx_ext" = yes; then
AX_CHECK_COMPILE_FLAG(-mmmx, ax_cv_support_mmx_ext=yes, [])
if test x"$ax_cv_support_mmx_ext" = x"yes"; then
SIMD_FLAGS="$SIMD_FLAGS -mmmx"
AC_DEFINE(HAVE_MMX,,[Support mmx instructions])
else
AC_MSG_WARN([Your processor supports mmx instructions but not your compiler, can you try another compiler?])
fi
fi
if test "$ac_cv_sizeof_long" -eq 8; then
SIMD_FLAGS="$SIMD_FLAGS -DARCH_64"
fi
if test "$ax_cv_have_sse_ext" = yes; then
AX_CHECK_COMPILE_FLAG(-msse, ax_cv_support_sse_ext=yes, [])
if test x"$ax_cv_support_sse_ext" = x"yes"; then
SIMD_FLAGS="$SIMD_FLAGS -msse -DINTEL_SSE"
AC_DEFINE(HAVE_SSE,,[Support SSE (Streaming SIMD Extensions) instructions])
else
AC_MSG_WARN([Your processor supports sse instructions but not your compiler, can you try another compiler?])
fi
fi
if test "$ax_cv_have_sse2_ext" = yes; then
AX_CHECK_COMPILE_FLAG(-msse2, ax_cv_support_sse2_ext=yes, [])
if test x"$ax_cv_support_sse2_ext" = x"yes"; then
SIMD_FLAGS="$SIMD_FLAGS -msse2 -DINTEL_SSE2"
AC_DEFINE(HAVE_SSE2,,[Support SSE2 (Streaming SIMD Extensions 2) instructions])
else
AC_MSG_WARN([Your processor supports sse2 instructions but not your compiler, can you try another compiler?])
fi
fi
if test "$ax_cv_have_sse3_ext" = yes; then
AX_CHECK_COMPILE_FLAG(-msse3, ax_cv_support_sse3_ext=yes, [])
if test x"$ax_cv_support_sse3_ext" = x"yes"; then
SIMD_FLAGS="$SIMD_FLAGS -msse3 -DINTEL_SSE3"
AC_DEFINE(HAVE_SSE3,,[Support SSE3 (Streaming SIMD Extensions 3) instructions])
else
AC_MSG_WARN([Your processor supports sse3 instructions but not your compiler, can you try another compiler?])
fi
fi
if test "$ax_cv_have_ssse3_ext" = yes; then
AX_CHECK_COMPILE_FLAG(-mssse3, ax_cv_support_ssse3_ext=yes, [])
if test x"$ax_cv_support_ssse3_ext" = x"yes"; then
SIMD_FLAGS="$SIMD_FLAGS -mssse3"
AC_DEFINE(HAVE_SSSE3,,[Support SSSE3 (Supplemental Streaming SIMD Extensions 3) instructions])
else
AC_MSG_WARN([Your processor supports ssse3 instructions but not your compiler, can you try another compiler?])
fi
fi
if test "$ax_cv_have_sse41_ext" = yes; then
AX_CHECK_COMPILE_FLAG(-msse4.1, ax_cv_support_sse41_ext=yes, [])
if test x"$ax_cv_support_sse41_ext" = x"yes"; then
SIMD_FLAGS="$SIMD_FLAGS -msse4.1 -DINTEL_SSE4"
AC_DEFINE(HAVE_SSE4_1,,[Support SSSE4.1 (Streaming SIMD Extensions 4.1) instructions])
else
AC_MSG_WARN([Your processor supports sse4.1 instructions but not your compiler, can you try another compiler?])
fi
fi
if test "$ax_cv_have_sse42_ext" = yes; then
AX_CHECK_COMPILE_FLAG(-msse4.2, ax_cv_support_sse42_ext=yes, [])
if test x"$ax_cv_support_sse42_ext" = x"yes"; then
SIMD_FLAGS="$SIMD_FLAGS -msse4.2 -DINTEL_SSE4"
AC_DEFINE(HAVE_SSE4_2,,[Support SSSE4.2 (Streaming SIMD Extensions 4.2) instructions])
else
AC_MSG_WARN([Your processor supports sse4.2 instructions but not your compiler, can you try another compiler?])
fi
fi
if test "$ax_cv_have_avx_ext" = yes; then
AX_CHECK_COMPILE_FLAG(-mavx, ax_cv_support_avx_ext=yes, [])
if test x"$ax_cv_support_avx_ext" = x"yes"; then
SIMD_FLAGS="$SIMD_FLAGS -mavx"
AC_DEFINE(HAVE_AVX,,[Support AVX (Advanced Vector Extensions) instructions])
else
AC_MSG_WARN([Your processor supports avx instructions but not your compiler, can you try another compiler?])
fi
fi
;;
esac
AC_SUBST(SIMD_FLAGS)
])