diff --git a/configure.ac b/configure.ac
index f10fbac92c69cd4c814048edcece5c2a10ba7a65..288f2a6aed9571078ff94aefd71977dd2cb9c602 100644
--- a/configure.ac
+++ b/configure.ac
@@ -148,10 +148,14 @@ if test "$enable_opt" = "yes" ; then
    ac_test_CFLAGS="yes"
    CFLAGS="$old_CFLAGS $CFLAGS"
 
-   # Check SSE & AVX support (some overlap with AX_CC_MAXOPT).
+   # Check SSE & AVX support (some overlap with AX_CC_MAXOPT). 
+   # Don't use the SIMD_FLAGS result with Intel compilers. The -x<code>
+   # value from AX_CC_MAXOPT should be sufficient.
    AX_EXT
    if test "$SIMD_FLAGS" != ""; then
-       CFLAGS="$CFLAGS $SIMD_FLAGS"
+       if test "$ax_cv_c_compiler_vendor" != "intel"; then
+           CFLAGS="$CFLAGS $SIMD_FLAGS"
+       fi
    fi
 fi
 
diff --git a/m4/ax_append_flag.m4 b/m4/ax_append_flag.m4
index aeab89979ac1ae08522681ed58decb11987273a6..08f2e07ec61bd428279958705ab200cded8e59d0 100644
--- a/m4/ax_append_flag.m4
+++ b/m4/ax_append_flag.m4
@@ -49,7 +49,7 @@
 #   modified version of the Autoconf Macro, you may extend this special
 #   exception to the GPL to apply to your modified version as well.
 
-#serial 5
+#serial 6
 
 AC_DEFUN([AX_APPEND_FLAG],
 [dnl
@@ -59,7 +59,7 @@ AS_VAR_SET_IF(FLAGS,[
   AS_CASE([" AS_VAR_GET(FLAGS) "],
     [*" $1 "*], [AC_RUN_LOG([: FLAGS already contains $1])],
     [
-     AS_VAR_APPEND(FLAGS," $1")
+     AS_VAR_APPEND(FLAGS,[" $1"])
      AC_RUN_LOG([: FLAGS="$FLAGS"])
     ])
   ],
diff --git a/m4/ax_cc_maxopt.m4 b/m4/ax_cc_maxopt.m4
index 0d442612d161f18091aba6200ee965b85a797110..d2a0937232e0e8bf9c3e7e79c20267bfa1d75880 100644
--- a/m4/ax_cc_maxopt.m4
+++ b/m4/ax_cc_maxopt.m4
@@ -125,7 +125,7 @@ if test "$ac_test_CFLAGS" != "set"; then
 		    *1?6[[aef]]?:*:*:*|*2?6[[5cef]]?:*:*:*) icc_flags="-xSSE4.2 -xS -xT -xB -xK" ;;
 		    *2?6[[ad]]?:*:*:*) icc_flags="-xAVX -SSE4.2 -xS -xT -xB -xK" ;;
 		    *3?6[[ae]]?:*:*:*) icc_flags="-xCORE-AVX-I -xAVX -SSE4.2 -xS -xT -xB -xK" ;;
-		    *3?6[[cf]]?:*:*:*|*4?6[[56]]?:*:*:*) icc_flags="-xCORE-AVX2 -xCORE-AVX-I -xAVX -SSE4.2 -xS -xT -xB -xK" ;;
+		    *3?6[[cf]]?:*:*:*|*4?6[[56]]?:*:*:*|*4?6[[ef]]?:*:*:*) icc_flags="-xCORE-AVX2 -xCORE-AVX-I -xAVX -SSE4.2 -xS -xT -xB -xK" ;;
 		    *000?f[[346]]?:*:*:*|?f[[346]]?:*:*:*|f[[346]]?:*:*:*) icc_flags="-xSSE3 -xP -xO -xN -xW -xK" ;;
 		    *00??f??:*:*:*|??f??:*:*:*|?f??:*:*:*|f??:*:*:*) icc_flags="-xSSE2 -xN -xW -xK" ;;
                   esac ;;
diff --git a/m4/ax_ext.m4 b/m4/ax_ext.m4
index 368223ce1ecfc27ba7d50e8f2c5ce48ecf95e9a0..8da8c61decc9aa35737fb977def82d51ade5ef0c 100644
--- a/m4/ax_ext.m4
+++ b/m4/ax_ext.m4
@@ -8,23 +8,35 @@
 #
 # DESCRIPTION
 #
-#   Find supported SIMD extensions by requesting cpuid. When an SIMD
+#   Find supported SIMD extensions by requesting cpuid. When a SIMD
 #   extension is found, the -m"simdextensionname" is added to SIMD_FLAGS if
-#   compiler supports it. For example, if "sse2" is available, then "-msse2"
+#   compiler supports it. For example, if "sse2" is available then "-msse2"
 #   is added to SIMD_FLAGS.
 #
+#   Find other supported CPU extensions by requesting cpuid. When a
+#   processor extension is found, the -m"extensionname" is added to
+#   CPUEXT_FLAGS if compiler supports it. For example, if "bmi2" is
+#   available then "-mbmi2" is added to CPUEXT_FLAGS.
+#
 #   This macro calls:
 #
 #     AC_SUBST(SIMD_FLAGS)
+#     AC_SUBST(CPUEXT_FLAGS)
 #
 #   And defines:
 #
-#     HAVE_MMX / HAVE_SSE / HAVE_SSE2 / HAVE_SSE3 / HAVE_SSSE3 / HAVE_SSE4.1 / HAVE_SSE4.2 / HAVE_AVX
+#     HAVE_RDRND / HAVE_BMI1 / HAVE_BMI2 / HAVE_ADX / HAVE_MPX
+#     HAVE_PREFETCHWT1 / HAVE_ABM / HAVE_MMX / HAVE_SSE / HAVE_SSE2
+#     HAVE_SSE3 / HAVE_SSSE3 / HAVE_SSE4_1 / HAVE_SSE4_2 / HAVE_SSE4a
+#     HAVE_SHA / HAVE_AES / HAVE_AVX / HAVE_FMA3 / HAVE_FMA4 / HAVE_XOP
+#     HAVE_AVX2 / HAVE_AVX512_F / HAVE_AVX512_CD / HAVE_AVX512_PF
+#     HAVE_AVX512_ER / HAVE_AVX512_VL / HAVE_AVX512_BW / HAVE_AVX512_DQ
+#     HAVE_AVX512_IFMA / HAVE_AVX512_VBMI
 #
 # LICENSE
 #
 #   Copyright (c) 2007 Christophe Tournayre <turn3r@users.sourceforge.net>
-#   Copyright (c) 2013 Michael Petch <mpetch@capp-sysware.com>
+#   Copyright (c) 2013,2015 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
@@ -32,14 +44,18 @@
 #   warranty.
 
 #   SWIFT modifications. Intel compilers accept these flags, but warn about
-#   the order of the flags when more than one is used. Given that reverse
-#   the check order and break on the highest accepted.
+#   the order of the flags when more than one is used. Given that we just
+#   set SIMD_FLAGS to the most specific value, rather than all accepted ones.
 
-#serial 13
+#serial 15
 
 AC_DEFUN([AX_EXT],
 [
   AC_REQUIRE([AC_CANONICAL_HOST])
+  AC_REQUIRE([AC_PROG_CC])
+
+  CPUEXT_FLAGS=""
+  SIMD_FLAGS=""
 
   case $host_cpu in
     powerpc*)
@@ -58,199 +74,234 @@ AC_DEFUN([AX_EXT],
           fi
     ;;
 
-
     i[[3456]]86*|x86_64*|amd64*)
 
       AC_REQUIRE([AX_GCC_X86_CPUID])
+      AC_REQUIRE([AX_GCC_X86_CPUID_COUNT])
       AC_REQUIRE([AX_GCC_X86_AVX_XGETBV])
 
-      AX_GCC_X86_CPUID(0x00000001)
-      ecx=0
-      edx=0
-      if test "$ax_cv_gcc_x86_cpuid_0x00000001" != "unknown";
+      eax_cpuid0=0
+      AX_GCC_X86_CPUID(0x00000000)
+      if test "$ax_cv_gcc_x86_cpuid_0x00000000" != "unknown";
       then
-        ecx=`echo $ax_cv_gcc_x86_cpuid_0x00000001 | cut -d ":" -f 3`
-        edx=`echo $ax_cv_gcc_x86_cpuid_0x00000001 | cut -d ":" -f 4`
+        eax_cpuid0=`echo $ax_cv_gcc_x86_cpuid_0x00000000 | cut -d ":" -f 1`
       fi
 
-      AC_CACHE_CHECK([whether mmx is supported], [ax_cv_have_mmx_ext],
-      [
-        ax_cv_have_mmx_ext=no
-        if test "$((0x$edx>>23&0x01))" = 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 "$((0x$edx>>25&0x01))" = 1; then
-          ax_cv_have_sse_ext=yes
-        fi
-      ])
+      eax_cpuid80000000=0
+      AX_GCC_X86_CPUID(0x80000000)
+      if test "$ax_cv_gcc_x86_cpuid_0x80000000" != "unknown";
+      then
+        eax_cpuid80000000=`echo $ax_cv_gcc_x86_cpuid_0x80000000 | cut -d ":" -f 1`
+      fi
 
-      AC_CACHE_CHECK([whether sse2 is supported], [ax_cv_have_sse2_ext],
-      [
-        ax_cv_have_sse2_ext=no
-        if test "$((0x$edx>>26&0x01))" = 1; then
-          ax_cv_have_sse2_ext=yes
+      ecx_cpuid1=0
+      edx_cpuid1=0
+      if test "$((0x$eax_cpuid0))" -ge 1 ; then
+        AX_GCC_X86_CPUID(0x00000001)
+        if test "$ax_cv_gcc_x86_cpuid_0x00000001" != "unknown";
+        then
+          ecx_cpuid1=`echo $ax_cv_gcc_x86_cpuid_0x00000001 | cut -d ":" -f 3`
+          edx_cpuid1=`echo $ax_cv_gcc_x86_cpuid_0x00000001 | cut -d ":" -f 4`
         fi
-      ])
+      fi
 
-      AC_CACHE_CHECK([whether sse3 is supported], [ax_cv_have_sse3_ext],
-      [
-        ax_cv_have_sse3_ext=no
-        if test "$((0x$ecx&0x01))" = 1; then
-          ax_cv_have_sse3_ext=yes
+      ebx_cpuid7=0
+      ecx_cpuid7=0
+      if test "$((0x$eax_cpuid0))" -ge 7 ; then
+        AX_GCC_X86_CPUID_COUNT(0x00000007, 0x00)
+        if test "$ax_cv_gcc_x86_cpuid_0x00000007" != "unknown";
+        then
+          ebx_cpuid7=`echo $ax_cv_gcc_x86_cpuid_0x00000007 | cut -d ":" -f 2`
+          ecx_cpuid7=`echo $ax_cv_gcc_x86_cpuid_0x00000007 | cut -d ":" -f 3`
         fi
-      ])
+      fi
 
-      AC_CACHE_CHECK([whether ssse3 is supported], [ax_cv_have_ssse3_ext],
-      [
-        ax_cv_have_ssse3_ext=no
-        if test "$((0x$ecx>>9&0x01))" = 1; then
-          ax_cv_have_ssse3_ext=yes
+      ecx_cpuid80000001=0
+      edx_cpuid80000001=0
+      if test "$((0x$eax_cpuid80000000))" -ge "$((0x80000001))" ; then
+        AX_GCC_X86_CPUID(0x80000001)
+        if test "$ax_cv_gcc_x86_cpuid_0x80000001" != "unknown";
+        then
+          ecx_cpuid80000001=`echo $ax_cv_gcc_x86_cpuid_0x80000001 | cut -d ":" -f 3`
+          edx_cpuid80000001=`echo $ax_cv_gcc_x86_cpuid_0x80000001 | cut -d ":" -f 4`
         fi
-      ])
+      fi
 
-      AC_CACHE_CHECK([whether sse4.1 is supported], [ax_cv_have_sse41_ext],
+      AC_CACHE_VAL([ax_cv_have_mmx_os_support_ext],
       [
-        ax_cv_have_sse41_ext=no
-        if test "$((0x$ecx>>19&0x01))" = 1; then
-          ax_cv_have_sse41_ext=yes
-        fi
+        ax_cv_have_mmx_os_support_ext=yes
       ])
 
-      AC_CACHE_CHECK([whether sse4.2 is supported], [ax_cv_have_sse42_ext],
-      [
-        ax_cv_have_sse42_ext=no
-        if test "$((0x$ecx>>20&0x01))" = 1; then
-          ax_cv_have_sse42_ext=yes
-        fi
-      ])
+      ax_cv_have_none_os_support_ext=yes
 
-      AC_CACHE_CHECK([whether avx is supported by processor], [ax_cv_have_avx_cpu_ext],
+      AC_CACHE_VAL([ax_cv_have_sse_os_support_ext],
       [
-        ax_cv_have_avx_cpu_ext=no
-        if test "$((0x$ecx>>28&0x01))" = 1; then
-          ax_cv_have_avx_cpu_ext=yes
+        ax_cv_have_sse_os_support_ext=no,
+        if test "$((0x$edx_cpuid1>>25&0x01))" = 1; then
+          AC_LANG_PUSH([C])
+          AC_TRY_RUN([
+#include <signal.h>
+#include <stdlib.h>
+            /* No way at ring1 to ring3 in protected mode to check the CR0 and CR4
+               control registers directly. Execute an SSE instruction.
+               If it raises SIGILL then OS doesn't support SSE based instructions */
+            void sig_handler(int signum){ exit(1); }
+            int main(){
+              signal(SIGILL, sig_handler);
+              /* SSE instruction xorps  %xmm0,%xmm0 */
+              __asm__ __volatile__ (".byte 0x0f, 0x57, 0xc0");
+              return 0;
+            }],
+            ax_cv_have_sse_os_support_ext=yes,
+            ax_cv_have_sse_os_support_ext=no,
+            ax_cv_have_sse_os_support_ext=no)
+          AC_LANG_POP([C])
         fi
       ])
 
-      if test x"$ax_cv_have_avx_cpu_ext" = x"yes"; then
+      xgetbv_eax=0
+      if test "$((0x$ecx_cpuid1>>28&0x01))" = 1; then
         AX_GCC_X86_AVX_XGETBV(0x00000000)
 
-        xgetbv_eax="0"
         if test x"$ax_cv_gcc_x86_avx_xgetbv_0x00000000" != x"unknown"; then
           xgetbv_eax=`echo $ax_cv_gcc_x86_avx_xgetbv_0x00000000 | cut -d ":" -f 1`
         fi
 
-        AC_CACHE_CHECK([whether avx is supported by operating system], [ax_cv_have_avx_ext],
+        AC_CACHE_VAL([ax_cv_have_avx_os_support_ext],
         [
-          ax_cv_have_avx_ext=no
-
-          if test "$((0x$ecx>>27&0x01))" = 1; then
+          ax_cv_have_avx_os_support_ext=no
+          if test "$((0x$ecx_cpuid1>>27&0x01))" = 1; then
             if test "$((0x$xgetbv_eax&0x6))" = 6; then
-              ax_cv_have_avx_ext=yes
+              ax_cv_have_avx_os_support_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
 
-      checkmore=yes
-
-      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])
-          checkmore=no
-        else
-          AC_MSG_WARN([Your processor supports avx instructions but not your compiler, can you try another compiler?])
-        fi
-      fi
-
-      if test $checkmore = yes -a "$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"
-          AC_DEFINE(HAVE_SSE4_2,,[Support SSSE4.2 (Streaming SIMD Extensions 4.2) instructions])
-          checkmore=no
-        else
-          AC_MSG_WARN([Your processor supports sse4.2 instructions but not your compiler, can you try another compiler?])
-        fi
-      fi
-
-      if test $checkmore = yes -a "$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"
-          AC_DEFINE(HAVE_SSE4_1,,[Support SSSE4.1 (Streaming SIMD Extensions 4.1) instructions])
-          checkmore=no
-        else
-          AC_MSG_WARN([Your processor supports sse4.1 instructions but not your compiler, can you try another compiler?])
-        fi
-      fi
-
-      if test $checkmore = yes -a "$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])
-          checkmore=no
-        else
-          AC_MSG_WARN([Your processor supports ssse3 instructions but not your compiler, can you try another compiler?])
-        fi
-      fi
-
-      if test $checkmore = yes -a "$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"
-          AC_DEFINE(HAVE_SSE3,,[Support SSE3 (Streaming SIMD Extensions 3) instructions])
-          checkmore=no
-        else
-          AC_MSG_WARN([Your processor supports sse3 instructions but not your compiler, can you try another compiler?])
-        fi
-      fi
-
-      if test $checkmore = yes -a "$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"
-          AC_DEFINE(HAVE_SSE2,,[Support SSE2 (Streaming SIMD Extensions 2) instructions])
-          checkmore=no
-        else
-          AC_MSG_WARN([Your processor supports sse2 instructions but not your compiler, can you try another compiler?])
-        fi
-      fi
-
-      if test $checkmore = yes -a "$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"
-          AC_DEFINE(HAVE_SSE,,[Support SSE (Streaming SIMD Extensions) instructions])
-          checkmore=no
-        else
-          AC_MSG_WARN([Your processor supports sse instructions but not your compiler, can you try another compiler?])
-        fi
-      fi
-
-      if test $checkmore = yes -a "$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?])
+      AC_CACHE_VAL([ax_cv_have_avx512_os_support_ext],
+      [
+        ax_cv_have_avx512_os_support_ext=no
+        if test "$ax_cv_have_avx_os_support_ext" = yes; then
+          if test "$((0x$xgetbv_eax&0xe6))" = "$((0xe6))"; then
+            ax_cv_have_avx512_os_support_ext=yes
+          fi
         fi
-      fi
+      ])
 
+      for ac_instr_info dnl
+      in "none;rdrnd;RDRND;ecx_cpuid1,30;-mrdrnd;HAVE_RDRND;CPUEXT_FLAGS" dnl
+         "none;bmi1;BMI1;ebx_cpuid7,3;-mbmi;HAVE_BMI1;CPUEXT_FLAGS" dnl
+         "none;bmi2;BMI2;ebx_cpuid7,8;-mbmi2;HAVE_BMI2;CPUEXT_FLAGS" dnl
+         "none;adx;ADX;ebx_cpuid7,19;-madx;HAVE_ADX;CPUEXT_FLAGS" dnl
+         "none;mpx;MPX;ebx_cpuid7,14;-mmpx;HAVE_MPX;CPUEXT_FLAGS" dnl
+         "none;prefetchwt1;PREFETCHWT1;ecx_cpuid7,0;-mprefetchwt1;HAVE_PREFETCHWT1;CPUEXT_FLAGS" dnl
+         "none;abm;ABM;ecx_cpuid80000001,5;-mabm;HAVE_ABM;CPUEXT_FLAGS" dnl
+         "mmx;mmx;MMX;edx_cpuid1,23;-mmmx;HAVE_MMX;SIMD_FLAGS" dnl
+         "sse;sse;SSE;edx_cpuid1,25;-msse;HAVE_SSE;SIMD_FLAGS" dnl
+         "sse;sse2;SSE2;edx_cpuid1,26;-msse2;HAVE_SSE2;SIMD_FLAGS" dnl
+         "sse;sse3;SSE3;ecx_cpuid1,1;-msse3;HAVE_SSE3;SIMD_FLAGS" dnl
+         "sse;ssse3;SSSE3;ecx_cpuid1,9;-mssse3;HAVE_SSSE3;SIMD_FLAGS" dnl
+         "sse;sse41;SSE4.1;ecx_cpuid1,19;-msse4.1;HAVE_SSE4_1;SIMD_FLAGS" dnl
+         "sse;sse42;SSE4.2;ecx_cpuid1,20;-msse4.2;HAVE_SSE4_2;SIMD_FLAGS" dnl
+         "sse;sse4a;SSE4a;ecx_cpuid80000001,6;-msse4a;HAVE_SSE4a;SIMD_FLAGS" dnl
+         "sse;sha;SHA;ebx_cpuid7,29;-msha;HAVE_SHA;SIMD_FLAGS" dnl
+         "sse;aes;AES;ecx_cpuid1,25;-maes;HAVE_AES;SIMD_FLAGS" dnl
+         "avx;avx;AVX;ecx_cpuid1,28;-mavx;HAVE_AVX;SIMD_FLAGS" dnl
+         "avx;fma3;FMA3;ecx_cpuid1,12;-mfma;HAVE_FMA3;SIMD_FLAGS" dnl
+         "avx;fma4;FMA4;ecx_cpuid80000001,16;-mfma4;HAVE_FMA4;SIMD_FLAGS" dnl
+         "avx;xop;XOP;ecx_cpuid80000001,11;-mxop;HAVE_XOP;SIMD_FLAGS" dnl
+         "avx;avx2;AVX2;ebx_cpuid7,5;-mavx2;HAVE_AVX2;SIMD_FLAGS" dnl
+         "avx512;avx512f;AVX512-F;ebx_cpuid7,16;-mavx512f;HAVE_AVX512_F;SIMD_FLAGS" dnl
+         "avx512;avx512cd;AVX512-CD;ebx_cpuid7,28;-mavx512cd;HAVE_AVX512_CD;SIMD_FLAGS" dnl
+         "avx512;avx512pf;AVX512-PF;ebx_cpuid7,26;-mavx512pf;HAVE_AVX512_PF;SIMD_FLAGS" dnl
+         "avx512;avx512er;AVX512-ER;ebx_cpuid7,27;-mavx512er;HAVE_AVX512_ER;SIMD_FLAGS" dnl
+         "avx512;avx512vl;AVX512-VL;ebx_cpuid7,31;-mavx512vl;HAVE_AVX512_VL;SIMD_FLAGS" dnl
+         "avx512;avx512bw;AVX512-BW;ebx_cpuid7,30;-mavx512bw;HAVE_AVX512_BW;SIMD_FLAGS" dnl
+         "avx512;avx512dq;AVX512-DQ;ebx_cpuid7,17;-mavx512dq;HAVE_AVX512_DQ;SIMD_FLAGS" dnl
+         "avx512;avx512ifma;AVX512-IFMA;ebx_cpuid7,21;-mavx512ifma;HAVE_AVX512_IFMA;SIMD_FLAGS" dnl
+         "avx512;avx512vbmi;AVX512-VBMI;ecx_cpuid7,1;-mavx512vbmi;HAVE_AVX512_VBMI;SIMD_FLAGS" dnl
+         #
+      do ac_instr_os_support=$(eval echo \$ax_cv_have_$(echo $ac_instr_info | cut -d ";" -f 1)_os_support_ext)
+         ac_instr_acvar=$(echo $ac_instr_info | cut -d ";" -f 2)
+         ac_instr_shortname=$(echo $ac_instr_info | cut -d ";" -f 3)
+         ac_instr_chk_loc=$(echo $ac_instr_info | cut -d ";" -f 4)
+         ac_instr_chk_reg=0x$(eval echo \$$(echo $ac_instr_chk_loc | cut -d "," -f 1))
+         ac_instr_chk_bit=$(echo $ac_instr_chk_loc | cut -d "," -f 2)
+         ac_instr_compiler_flags=$(echo $ac_instr_info | cut -d ";" -f 5)
+         ac_instr_have_define=$(echo $ac_instr_info | cut -d ";" -f 6)
+         ac_instr_flag_type=$(echo $ac_instr_info | cut -d ";" -f 7)
+
+         AC_CACHE_CHECK([whether ${ac_instr_shortname} is supported by the processor], [ax_cv_have_${ac_instr_acvar}_cpu_ext],
+         [
+           eval ax_cv_have_${ac_instr_acvar}_cpu_ext=no
+           if test "$((${ac_instr_chk_reg}>>${ac_instr_chk_bit}&0x01))" = 1 ; then
+             eval ax_cv_have_${ac_instr_acvar}_cpu_ext=yes
+           fi
+         ])
+
+         if test x"$(eval echo \$ax_cv_have_${ac_instr_acvar}_cpu_ext)" = x"yes"; then
+           AC_CACHE_CHECK([whether ${ac_instr_shortname} is supported by the processor and OS], [ax_cv_have_${ac_instr_acvar}_ext],
+           [
+             eval ax_cv_have_${ac_instr_acvar}_ext=no
+             if test x"${ac_instr_os_support}" = x"yes"; then
+               eval ax_cv_have_${ac_instr_acvar}_ext=yes
+             fi
+           ])
+
+           if test "$(eval echo \$ax_cv_have_${ac_instr_acvar}_ext)" = yes; then
+             AX_CHECK_COMPILE_FLAG(${ac_instr_compiler_flags}, eval ax_cv_support_${ac_instr_acvar}_ext=yes,
+                                                               eval ax_cv_support_${ac_instr_acvar}_ext=no)
+             if test x"$(eval echo \$ax_cv_support_${ac_instr_acvar}_ext)" = x"yes"; then
+               eval ${ac_instr_flag_type}=\"${ac_instr_compiler_flags}\"
+               AC_DEFINE_UNQUOTED([${ac_instr_have_define}])
+             else
+               AC_MSG_WARN([Your processor and OS supports ${ac_instr_shortname} instructions but not your compiler, can you try another compiler?])
+             fi
+           else
+             if test x"${ac_instr_os_support}" = x"no"; then
+               AC_CACHE_VAL(ax_cv_support_${ac_instr_acvar}_ext, eval ax_cv_support_${ac_instr_acvar}_ext=no)
+               AC_MSG_WARN([Your processor supports ${ac_instr_shortname}, but your OS doesn't])
+             fi
+           fi
+         else
+           AC_CACHE_VAL(ax_cv_have_${ac_instr_acvar}_ext, eval ax_cv_have_${ac_instr_acvar}_ext=no)
+           AC_CACHE_VAL(ax_cv_support_${ac_instr_acvar}_ext, eval ax_cv_support_${ac_instr_acvar}_ext=no)
+         fi
+      done
   ;;
   esac
 
+  AH_TEMPLATE([HAVE_RDRND],[Define to 1 to support Digital Random Number Generator])
+  AH_TEMPLATE([HAVE_BMI1],[Define to 1 to support Bit Manipulation Instruction Set 1])
+  AH_TEMPLATE([HAVE_BMI2],[Define to 1 to support Bit Manipulation Instruction Set 2])
+  AH_TEMPLATE([HAVE_ADX],[Define to 1 to support Multi-Precision Add-Carry Instruction Extensions])
+  AH_TEMPLATE([HAVE_MPX],[Define to 1 to support Memory Protection Extensions])
+  AH_TEMPLATE([HAVE_PREFETCHWT1],[Define to 1 to support Prefetch Vector Data Into Caches WT1])
+  AH_TEMPLATE([HAVE_ABM],[Define to 1 to support Advanced Bit Manipulation])
+  AH_TEMPLATE([HAVE_MMX],[Define to 1 to support Multimedia Extensions])
+  AH_TEMPLATE([HAVE_SSE],[Define to 1 to support Streaming SIMD Extensions])
+  AH_TEMPLATE([HAVE_SSE2],[Define to 1 to support Streaming SIMD Extensions])
+  AH_TEMPLATE([HAVE_SSE3],[Define to 1 to support Streaming SIMD Extensions 3])
+  AH_TEMPLATE([HAVE_SSSE3],[Define to 1 to support Supplemental Streaming SIMD Extensions 3])
+  AH_TEMPLATE([HAVE_SSE4_1],[Define to 1 to support Streaming SIMD Extensions 4.1])
+  AH_TEMPLATE([HAVE_SSE4_2],[Define to 1 to support Streaming SIMD Extensions 4.2])
+  AH_TEMPLATE([HAVE_SSE4a],[Define to 1 to support AMD Streaming SIMD Extensions 4a])
+  AH_TEMPLATE([HAVE_SHA],[Define to 1 to support Secure Hash Algorithm Extension])
+  AH_TEMPLATE([HAVE_AES],[Define to 1 to support Advanced Encryption Standard New Instruction Set (AES-NI)])
+  AH_TEMPLATE([HAVE_AVX],[Define to 1 to support Advanced Vector Extensions])
+  AH_TEMPLATE([HAVE_FMA3],[Define to 1 to support  Fused Multiply-Add Extensions 3])
+  AH_TEMPLATE([HAVE_FMA4],[Define to 1 to support Fused Multiply-Add Extensions 4])
+  AH_TEMPLATE([HAVE_XOP],[Define to 1 to support eXtended Operations Extensions])
+  AH_TEMPLATE([HAVE_AVX2],[Define to 1 to support Advanced Vector Extensions 2])
+  AH_TEMPLATE([HAVE_AVX512_F],[Define to 1 to support AVX-512 Foundation Extensions])
+  AH_TEMPLATE([HAVE_AVX512_CD],[Define to 1 to support AVX-512 Conflict Detection Instructions])
+  AH_TEMPLATE([HAVE_AVX512_PF],[Define to 1 to support AVX-512 Conflict Prefetch Instructions])
+  AH_TEMPLATE([HAVE_AVX512_ER],[Define to 1 to support AVX-512 Exponential & Reciprocal Instructions])
+  AH_TEMPLATE([HAVE_AVX512_VL],[Define to 1 to support AVX-512 Vector Length Extensions])
+  AH_TEMPLATE([HAVE_AVX512_BW],[Define to 1 to support AVX-512 Byte and Word Instructions])
+  AH_TEMPLATE([HAVE_AVX512_DQ],[Define to 1 to support AVX-512 Doubleword and Quadword Instructions])
+  AH_TEMPLATE([HAVE_AVX512_IFMA],[Define to 1 to support AVX-512 Integer Fused Multiply Add Instructions])
+  AH_TEMPLATE([HAVE_AVX512_VBMI],[Define to 1 to support AVX-512 Vector Byte Manipulation Instructions])
   AC_SUBST(SIMD_FLAGS)
+  AC_SUBST(CPUEXT_FLAGS)
 ])
diff --git a/m4/ax_gcc_x86_avx_xgetbv.m4 b/m4/ax_gcc_x86_avx_xgetbv.m4
index 0624eebc9ab03e24ede44a868096c3430e1a11ab..2b38bbb11b3c6a39abea37fbbcd584ce2a5e5850 100644
--- a/m4/ax_gcc_x86_avx_xgetbv.m4
+++ b/m4/ax_gcc_x86_avx_xgetbv.m4
@@ -54,7 +54,7 @@
 #   modified version of the Autoconf Macro, you may extend this special
 #   exception to the GPL to apply to your modified version as well.
 
-#serial 1
+#serial 2
 
 AC_DEFUN([AX_GCC_X86_AVX_XGETBV],
 [AC_REQUIRE([AC_PROG_CC])
@@ -64,7 +64,7 @@ AC_CACHE_CHECK(for x86-AVX xgetbv $1 output, ax_cv_gcc_x86_avx_xgetbv_$1,
      int op = $1, eax, edx;
      FILE *f;
       /* Opcodes for xgetbv */
-      __asm__(".byte 0x0f, 0x01, 0xd0"
+      __asm__ __volatile__ (".byte 0x0f, 0x01, 0xd0"
         : "=a" (eax), "=d" (edx)
         : "c" (op));
      f = fopen("conftest_xgetbv", "w"); if (!f) return 1;
diff --git a/m4/ax_gcc_x86_cpuid.m4 b/m4/ax_gcc_x86_cpuid.m4
index 7d46fee0219e970f98e960a5b0717a9ec061ee95..578b3a383ab41f1cfc0ffc87c8751f79ef1dd64c 100644
--- a/m4/ax_gcc_x86_cpuid.m4
+++ b/m4/ax_gcc_x86_cpuid.m4
@@ -5,13 +5,15 @@
 # SYNOPSIS
 #
 #   AX_GCC_X86_CPUID(OP)
+#   AX_GCC_X86_CPUID_COUNT(OP, COUNT)
 #
 # DESCRIPTION
 #
 #   On Pentium and later x86 processors, with gcc or a compiler that has a
 #   compatible syntax for inline assembly instructions, run a small program
 #   that executes the cpuid instruction with input OP. This can be used to
-#   detect the CPU type.
+#   detect the CPU type. AX_GCC_X86_CPUID_COUNT takes an additional COUNT
+#   parameter that gets passed into register ECX before calling cpuid.
 #
 #   On output, the values of the eax, ebx, ecx, and edx registers are stored
 #   as hexadecimal strings as "eax:ebx:ecx:edx" in the cache variable
@@ -28,6 +30,7 @@
 #
 #   Copyright (c) 2008 Steven G. Johnson <stevenj@alum.mit.edu>
 #   Copyright (c) 2008 Matteo Frigo
+#   Copyright (c) 2015 Michael Petch <mpetch@capp-sysware.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
@@ -55,18 +58,25 @@
 #   modified version of the Autoconf Macro, you may extend this special
 #   exception to the GPL to apply to your modified version as well.
 
-#serial 7
+#serial 9
 
 AC_DEFUN([AX_GCC_X86_CPUID],
+[AX_GCC_X86_CPUID_COUNT($1, 0)
+])
+
+AC_DEFUN([AX_GCC_X86_CPUID_COUNT],
 [AC_REQUIRE([AC_PROG_CC])
 AC_LANG_PUSH([C])
 AC_CACHE_CHECK(for x86 cpuid $1 output, ax_cv_gcc_x86_cpuid_$1,
  [AC_RUN_IFELSE([AC_LANG_PROGRAM([#include <stdio.h>], [
-     int op = $1, eax, ebx, ecx, edx;
+     int op = $1, level = $2, eax, ebx, ecx, edx;
      FILE *f;
-      __asm__("cpuid"
-        : "=a" (eax), "=b" (ebx), "=c" (ecx), "=d" (edx)
-        : "a" (op));
+      __asm__ __volatile__ ("xchg %%ebx, %1\n"
+        "cpuid\n"
+        "xchg %%ebx, %1\n"
+        : "=a" (eax), "=r" (ebx), "=c" (ecx), "=d" (edx)
+        : "a" (op), "2" (level));
+
      f = fopen("conftest_cpuid", "w"); if (!f) return 1;
      fprintf(f, "%x:%x:%x:%x\n", eax, ebx, ecx, edx);
      fclose(f);
diff --git a/m4/ax_prog_doxygen.m4 b/m4/ax_prog_doxygen.m4
index fd145991e636d4d47a3bf7000a222c41f0614104..c7fbaa0adcbe87ca0cb98d2aecd980ca9af06e59 100644
--- a/m4/ax_prog_doxygen.m4
+++ b/m4/ax_prog_doxygen.m4
@@ -4,7 +4,7 @@
 #
 # SYNOPSIS
 #
-#   DX_INIT_DOXYGEN(PROJECT-NAME, DOXYFILE-PATH, [OUTPUT-DIR])
+#   DX_INIT_DOXYGEN(PROJECT-NAME, [DOXYFILE-PATH], [OUTPUT-DIR], ...)
 #   DX_DOXYGEN_FEATURE(ON|OFF)
 #   DX_DOT_FEATURE(ON|OFF)
 #   DX_HTML_FEATURE(ON|OFF)
@@ -45,14 +45,19 @@
 #   Once all the feature defaults have been specified, call DX_INIT_DOXYGEN
 #   with the following parameters: a one-word name for the project for use
 #   as a filename base etc., an optional configuration file name (the
-#   default is 'Doxyfile', the same as Doxygen's default), and an optional
-#   output directory name (the default is 'doxygen-doc').
+#   default is '$(srcdir)/Doxyfile', the same as Doxygen's default), and an
+#   optional output directory name (the default is 'doxygen-doc'). To run
+#   doxygen multiple times for different configuration files and output
+#   directories provide more parameters: the second, forth, sixth, etc
+#   parameter are configuration file names and the third, fifth, seventh,
+#   etc parameter are output directories. No checking is done to catch
+#   duplicates.
 #
 #   Automake Support
 #
-#   The following is a template aminclude.am file for use with Automake.
-#   Make targets and variables values are controlled by the various
-#   DX_COND_* conditionals set by autoconf.
+#   The DX_RULES substitution can be used to add all needed rules to the
+#   Makefile. Note that this is a substitution without being a variable:
+#   only the @DX_RULES@ syntax will work.
 #
 #   The provided targets are:
 #
@@ -61,9 +66,7 @@
 #     doxygen-run: Run doxygen, which will generate some of the
 #                  documentation (HTML, CHM, CHI, MAN, RTF, XML)
 #                  but will not do the post processing required
-#                  for the rest of it (PS, PDF, and some MAN).
-#
-#     doxygen-man: Rename some doxygen generated man pages.
+#                  for the rest of it (PS, PDF).
 #
 #     doxygen-ps:  Generate doxygen PostScript documentation.
 #
@@ -84,178 +87,17 @@
 #
 #   Then add this variable to MOSTLYCLEANFILES.
 #
-#     ----- begin aminclude.am -------------------------------------
-#
-#     ## --------------------------------- ##
-#     ## Format-independent Doxygen rules. ##
-#     ## --------------------------------- ##
-#
-#     if DX_COND_doc
-#
-#     ## ------------------------------- ##
-#     ## Rules specific for HTML output. ##
-#     ## ------------------------------- ##
-#
-#     if DX_COND_html
-#
-#     DX_CLEAN_HTML = @DX_DOCDIR@/html
-#
-#     endif DX_COND_html
-#
-#     ## ------------------------------ ##
-#     ## Rules specific for CHM output. ##
-#     ## ------------------------------ ##
-#
-#     if DX_COND_chm
-#
-#     DX_CLEAN_CHM = @DX_DOCDIR@/chm
-#
-#     if DX_COND_chi
-#
-#     DX_CLEAN_CHI = @DX_DOCDIR@/@PACKAGE@.chi
-#
-#     endif DX_COND_chi
-#
-#     endif DX_COND_chm
-#
-#     ## ------------------------------ ##
-#     ## Rules specific for MAN output. ##
-#     ## ------------------------------ ##
-#
-#     if DX_COND_man
-#
-#     DX_CLEAN_MAN = @DX_DOCDIR@/man
-#
-#     endif DX_COND_man
-#
-#     ## ------------------------------ ##
-#     ## Rules specific for RTF output. ##
-#     ## ------------------------------ ##
-#
-#     if DX_COND_rtf
-#
-#     DX_CLEAN_RTF = @DX_DOCDIR@/rtf
-#
-#     endif DX_COND_rtf
-#
-#     ## ------------------------------ ##
-#     ## Rules specific for XML output. ##
-#     ## ------------------------------ ##
-#
-#     if DX_COND_xml
-#
-#     DX_CLEAN_XML = @DX_DOCDIR@/xml
-#
-#     endif DX_COND_xml
-#
-#     ## ----------------------------- ##
-#     ## Rules specific for PS output. ##
-#     ## ----------------------------- ##
-#
-#     if DX_COND_ps
-#
-#     DX_CLEAN_PS = @DX_DOCDIR@/@PACKAGE@.ps
-#
-#     DX_PS_GOAL = doxygen-ps
-#
-#     doxygen-ps: @DX_DOCDIR@/@PACKAGE@.ps
-#
-#     @DX_DOCDIR@/@PACKAGE@.ps: @DX_DOCDIR@/@PACKAGE@.tag
-#         cd @DX_DOCDIR@/latex; \
-#         rm -f *.aux *.toc *.idx *.ind *.ilg *.log *.out; \
-#         $(DX_LATEX) refman.tex; \
-#         $(MAKEINDEX_PATH) refman.idx; \
-#         $(DX_LATEX) refman.tex; \
-#         countdown=5; \
-#         while $(DX_EGREP) 'Rerun (LaTeX|to get cross-references right)' \
-#                           refman.log > /dev/null 2>&1 \
-#            && test $$countdown -gt 0; do \
-#             $(DX_LATEX) refman.tex; \
-#             countdown=`expr $$countdown - 1`; \
-#         done; \
-#         $(DX_DVIPS) -o ../@PACKAGE@.ps refman.dvi
-#
-#     endif DX_COND_ps
-#
-#     ## ------------------------------ ##
-#     ## Rules specific for PDF output. ##
-#     ## ------------------------------ ##
-#
-#     if DX_COND_pdf
-#
-#     DX_CLEAN_PDF = @DX_DOCDIR@/@PACKAGE@.pdf
-#
-#     DX_PDF_GOAL = doxygen-pdf
-#
-#     doxygen-pdf: @DX_DOCDIR@/@PACKAGE@.pdf
-#
-#     @DX_DOCDIR@/@PACKAGE@.pdf: @DX_DOCDIR@/@PACKAGE@.tag
-#         cd @DX_DOCDIR@/latex; \
-#         rm -f *.aux *.toc *.idx *.ind *.ilg *.log *.out; \
-#         $(DX_PDFLATEX) refman.tex; \
-#         $(DX_MAKEINDEX) refman.idx; \
-#         $(DX_PDFLATEX) refman.tex; \
-#         countdown=5; \
-#         while $(DX_EGREP) 'Rerun (LaTeX|to get cross-references right)' \
-#                           refman.log > /dev/null 2>&1 \
-#            && test $$countdown -gt 0; do \
-#             $(DX_PDFLATEX) refman.tex; \
-#             countdown=`expr $$countdown - 1`; \
-#         done; \
-#         mv refman.pdf ../@PACKAGE@.pdf
-#
-#     endif DX_COND_pdf
-#
-#     ## ------------------------------------------------- ##
-#     ## Rules specific for LaTeX (shared for PS and PDF). ##
-#     ## ------------------------------------------------- ##
-#
-#     if DX_COND_latex
-#
-#     DX_CLEAN_LATEX = @DX_DOCDIR@/latex
-#
-#     endif DX_COND_latex
-#
-#     .PHONY: doxygen-run doxygen-doc $(DX_PS_GOAL) $(DX_PDF_GOAL)
-#
-#     .INTERMEDIATE: doxygen-run $(DX_PS_GOAL) $(DX_PDF_GOAL)
-#
-#     doxygen-run: @DX_DOCDIR@/@PACKAGE@.tag
-#
-#     doxygen-doc: doxygen-run $(DX_PS_GOAL) $(DX_PDF_GOAL)
-#
-#     @DX_DOCDIR@/@PACKAGE@.tag: $(DX_CONFIG) $(pkginclude_HEADERS)
-#         rm -rf @DX_DOCDIR@
-#         $(DX_ENV) $(DX_DOXYGEN) $(srcdir)/$(DX_CONFIG)
-#         echo Timestamp >$@
-#
-#     DX_CLEANFILES = \
-#         @DX_DOCDIR@/@PACKAGE@.tag \
-#         -r \
-#         $(DX_CLEAN_HTML) \
-#         $(DX_CLEAN_CHM) \
-#         $(DX_CLEAN_CHI) \
-#         $(DX_CLEAN_MAN) \
-#         $(DX_CLEAN_RTF) \
-#         $(DX_CLEAN_XML) \
-#         $(DX_CLEAN_PS) \
-#         $(DX_CLEAN_PDF) \
-#         $(DX_CLEAN_LATEX)
-#
-#     endif DX_COND_doc
-#
-#     ----- end aminclude.am ---------------------------------------
-#
 # LICENSE
 #
 #   Copyright (c) 2009 Oren Ben-Kiki <oren@ben-kiki.org>
+#   Copyright (c) 2015 Olaf Mandel <olaf@mandel.name>
 #
 #   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 13
+#serial 18
 
 ## ----------##
 ## Defaults. ##
@@ -279,8 +121,14 @@ AC_DEFUN([DX_FEATURE_ps],   ON)
 
 # DX_ENV_APPEND(VARIABLE, VALUE)
 # ------------------------------
-# Append VARIABLE="VALUE" to DX_ENV for invoking doxygen.
-AC_DEFUN([DX_ENV_APPEND], [AC_SUBST([DX_ENV], ["$DX_ENV $1='$2'"])])
+# Append VARIABLE="VALUE" to DX_ENV for invoking doxygen and add it
+# as a substitution (but not a Makefile variable). The substitution
+# is skipped if the variable name is VERSION.
+AC_DEFUN([DX_ENV_APPEND],
+[AC_SUBST([DX_ENV], ["$DX_ENV $1='$2'"])dnl
+m4_if([$1], [VERSION], [], [AC_SUBST([$1], [$2])dnl
+AM_SUBST_NOTMAKE([$1])])dnl
+])
 
 # DX_DIRNAME_EXPR
 # ---------------
@@ -365,7 +213,6 @@ if DX_TEST_FEATURE([$1]); then
     $5
     :
 fi
-AM_CONDITIONAL(DX_COND_$1, DX_TEST_FEATURE([$1]))
 if DX_TEST_FEATURE([$1]); then
     $6
     :
@@ -393,21 +240,34 @@ AC_DEFUN([DX_XML_FEATURE],     [AC_DEFUN([DX_FEATURE_xml],  [$1])])
 AC_DEFUN([DX_PDF_FEATURE],     [AC_DEFUN([DX_FEATURE_pdf],  [$1])])
 AC_DEFUN([DX_PS_FEATURE],      [AC_DEFUN([DX_FEATURE_ps],   [$1])])
 
-# DX_INIT_DOXYGEN(PROJECT, [CONFIG-FILE], [OUTPUT-DOC-DIR])
-# ---------------------------------------------------------
+# DX_INIT_DOXYGEN(PROJECT, [CONFIG-FILE], [OUTPUT-DOC-DIR], ...)
+# --------------------------------------------------------------
 # PROJECT also serves as the base name for the documentation files.
-# The default CONFIG-FILE is "Doxyfile" and OUTPUT-DOC-DIR is "doxygen-doc".
+# The default CONFIG-FILE is "$(srcdir)/Doxyfile" and OUTPUT-DOC-DIR is
+# "doxygen-doc".
+# More arguments are interpreted as interleaved CONFIG-FILE and
+# OUTPUT-DOC-DIR values.
 AC_DEFUN([DX_INIT_DOXYGEN], [
 
 # Files:
 AC_SUBST([DX_PROJECT], [$1])
-AC_SUBST([DX_CONFIG], [ifelse([$2], [], Doxyfile, [$2])])
-AC_SUBST([DX_DOCDIR], [ifelse([$3], [], doxygen-doc, [$3])])
+AC_SUBST([DX_CONFIG], ['ifelse([$2], [], [$(srcdir)/Doxyfile], [$2])'])
+AC_SUBST([DX_DOCDIR], ['ifelse([$3], [], [doxygen-doc], [$3])'])
+m4_if(m4_eval(3 < m4_count($@)), 1, [m4_for([DX_i], 4, m4_count($@), 2,
+      [AC_SUBST([DX_CONFIG]m4_eval(DX_i[/2]),
+                'm4_default_nblank_quoted(m4_argn(DX_i, $@),
+                                          [$(srcdir)/Doxyfile])')])])dnl
+m4_if(m4_eval(3 < m4_count($@)), 1, [m4_for([DX_i], 5, m4_count($@,), 2,
+      [AC_SUBST([DX_DOCDIR]m4_eval([(]DX_i[-1)/2]),
+                'm4_default_nblank_quoted(m4_argn(DX_i, $@),
+                                          [doxygen-doc])')])])dnl
+m4_define([DX_loop], m4_dquote(m4_if(m4_eval(3 < m4_count($@)), 1,
+          [m4_for([DX_i], 4, m4_count($@), 2, [, m4_eval(DX_i[/2])])],
+          [])))dnl
 
 # Environment variables used inside doxygen.cfg:
 DX_ENV_APPEND(SRCDIR, $srcdir)
 DX_ENV_APPEND(PROJECT, $DX_PROJECT)
-DX_ENV_APPEND(DOCDIR, $DX_DOCDIR)
 DX_ENV_APPEND(VERSION, $PACKAGE_VERSION)
 
 # Doxygen itself:
@@ -495,7 +355,6 @@ DX_ARG_ABLE(pdf, [generate doxygen PDF documentation],
              DX_REQUIRE_PROG([DX_EGREP], egrep)])
 
 # LaTeX generation for PS and/or PDF:
-AM_CONDITIONAL(DX_COND_latex, DX_TEST_FEATURE(ps) || DX_TEST_FEATURE(pdf))
 if DX_TEST_FEATURE(ps) || DX_TEST_FEATURE(pdf); then
     DX_ENV_APPEND(GENERATE_LATEX, YES)
 else
@@ -518,6 +377,221 @@ a4wide|a4|letter|legal|executive)
 ;;
 esac
 
+# Rules:
+if test $DX_FLAG_html -eq 1; then
+    DX_SNIPPET_html="## ------------------------------- ##
+## Rules specific for HTML output. ##
+## ------------------------------- ##
+
+DX_CLEAN_HTML = \$(DX_DOCDIR)/html[]dnl
+m4_foreach([DX_i], [m4_shift(DX_loop)], [[\\
+                \$(DX_DOCDIR]DX_i[)/html]])
+
+"
+else
+    DX_SNIPPET_html=""
+fi
+if test $DX_FLAG_chi -eq 1; then
+    DX_SNIPPET_chi="
+DX_CLEAN_CHI = \$(DX_DOCDIR)/\$(PACKAGE).chi[]dnl
+m4_foreach([DX_i], [m4_shift(DX_loop)], [[\\
+               \$(DX_DOCDIR]DX_i[)/\$(PACKAGE).chi]])"
+else
+    DX_SNIPPET_chi=""
+fi
+if test $DX_FLAG_chm -eq 1; then
+    DX_SNIPPET_chm="## ------------------------------ ##
+## Rules specific for CHM output. ##
+## ------------------------------ ##
+
+DX_CLEAN_CHM = \$(DX_DOCDIR)/chm[]dnl
+m4_foreach([DX_i], [m4_shift(DX_loop)], [[\\
+               \$(DX_DOCDIR]DX_i[)/chm]])\
+${DX_SNIPPET_chi}
+
+"
+else
+    DX_SNIPPET_chm=""
+fi
+if test $DX_FLAG_man -eq 1; then
+    DX_SNIPPET_man="## ------------------------------ ##
+## Rules specific for MAN output. ##
+## ------------------------------ ##
+
+DX_CLEAN_MAN = \$(DX_DOCDIR)/man[]dnl
+m4_foreach([DX_i], [m4_shift(DX_loop)], [[\\
+               \$(DX_DOCDIR]DX_i[)/man]])
+
+"
+else
+    DX_SNIPPET_man=""
+fi
+if test $DX_FLAG_rtf -eq 1; then
+    DX_SNIPPET_rtf="## ------------------------------ ##
+## Rules specific for RTF output. ##
+## ------------------------------ ##
+
+DX_CLEAN_RTF = \$(DX_DOCDIR)/rtf[]dnl
+m4_foreach([DX_i], [m4_shift(DX_loop)], [[\\
+               \$(DX_DOCDIR]DX_i[)/rtf]])
+
+"
+else
+    DX_SNIPPET_rtf=""
+fi
+if test $DX_FLAG_xml -eq 1; then
+    DX_SNIPPET_xml="## ------------------------------ ##
+## Rules specific for XML output. ##
+## ------------------------------ ##
+
+DX_CLEAN_XML = \$(DX_DOCDIR)/xml[]dnl
+m4_foreach([DX_i], [m4_shift(DX_loop)], [[\\
+               \$(DX_DOCDIR]DX_i[)/xml]])
+
+"
+else
+    DX_SNIPPET_xml=""
+fi
+if test $DX_FLAG_ps -eq 1; then
+    DX_SNIPPET_ps="## ----------------------------- ##
+## Rules specific for PS output. ##
+## ----------------------------- ##
+
+DX_CLEAN_PS = \$(DX_DOCDIR)/\$(PACKAGE).ps[]dnl
+m4_foreach([DX_i], [m4_shift(DX_loop)], [[\\
+              \$(DX_DOCDIR]DX_i[)/\$(PACKAGE).ps]])
+
+DX_PS_GOAL = doxygen-ps
+
+doxygen-ps: \$(DX_CLEAN_PS)
+
+m4_foreach([DX_i], [DX_loop],
+[[\$(DX_DOCDIR]DX_i[)/\$(PACKAGE).ps: \$(DX_DOCDIR]DX_i[)/\$(PACKAGE).tag
+	\$(DX_V_LATEX)cd \$(DX_DOCDIR]DX_i[)/latex; \\
+	rm -f *.aux *.toc *.idx *.ind *.ilg *.log *.out; \\
+	\$(DX_LATEX) refman.tex; \\
+	\$(DX_MAKEINDEX) refman.idx; \\
+	\$(DX_LATEX) refman.tex; \\
+	countdown=5; \\
+	while \$(DX_EGREP) 'Rerun (LaTeX|to get cross-references right)' \\
+	                  refman.log > /dev/null 2>&1 \\
+	   && test \$\$countdown -gt 0; do \\
+	    \$(DX_LATEX) refman.tex; \\
+            countdown=\`expr \$\$countdown - 1\`; \\
+	done; \\
+	\$(DX_DVIPS) -o ../\$(PACKAGE).ps refman.dvi
+
+]])dnl
+"
+else
+    DX_SNIPPET_ps=""
+fi
+if test $DX_FLAG_pdf -eq 1; then
+    DX_SNIPPET_pdf="## ------------------------------ ##
+## Rules specific for PDF output. ##
+## ------------------------------ ##
+
+DX_CLEAN_PDF = \$(DX_DOCDIR)/\$(PACKAGE).pdf[]dnl
+m4_foreach([DX_i], [m4_shift(DX_loop)], [[\\
+               \$(DX_DOCDIR]DX_i[)/\$(PACKAGE).pdf]])
+
+DX_PDF_GOAL = doxygen-pdf
+
+doxygen-pdf: \$(DX_CLEAN_PDF)
+
+m4_foreach([DX_i], [DX_loop],
+[[\$(DX_DOCDIR]DX_i[)/\$(PACKAGE).pdf: \$(DX_DOCDIR]DX_i[)/\$(PACKAGE).tag
+	\$(DX_V_LATEX)cd \$(DX_DOCDIR]DX_i[)/latex; \\
+	rm -f *.aux *.toc *.idx *.ind *.ilg *.log *.out; \\
+	\$(DX_PDFLATEX) refman.tex; \\
+	\$(DX_MAKEINDEX) refman.idx; \\
+	\$(DX_PDFLATEX) refman.tex; \\
+	countdown=5; \\
+	while \$(DX_EGREP) 'Rerun (LaTeX|to get cross-references right)' \\
+	                  refman.log > /dev/null 2>&1 \\
+	   && test \$\$countdown -gt 0; do \\
+	    \$(DX_PDFLATEX) refman.tex; \\
+	    countdown=\`expr \$\$countdown - 1\`; \\
+	done; \\
+	mv refman.pdf ../\$(PACKAGE).pdf
+
+]])dnl
+"
+else
+    DX_SNIPPET_pdf=""
+fi
+if test $DX_FLAG_ps -eq 1 -o $DX_FLAG_pdf -eq 1; then
+    DX_SNIPPET_latex="## ------------------------------------------------- ##
+## Rules specific for LaTeX (shared for PS and PDF). ##
+## ------------------------------------------------- ##
+
+DX_V_LATEX = \$(_DX_v_LATEX_\$(V))
+_DX_v_LATEX_ = \$(_DX_v_LATEX_1))
+_DX_v_LATEX_0 = @echo \"  LATEX \" \$[]][[]@;
+
+DX_CLEAN_LATEX = \$(DX_DOCDIR)/latex[]dnl
+m4_foreach([DX_i], [m4_shift(DX_loop)], [[\\
+                 \$(DX_DOCDIR]DX_i[)/latex]])
+
+"
+else
+    DX_SNIPPET_latex=""
+fi
+
+if test $DX_FLAG_doc -eq 1; then
+    DX_SNIPPET_doc="## --------------------------------- ##
+## Format-independent Doxygen rules. ##
+## --------------------------------- ##
+
+${DX_SNIPPET_html}\
+${DX_SNIPPET_chm}\
+${DX_SNIPPET_man}\
+${DX_SNIPPET_rtf}\
+${DX_SNIPPET_xml}\
+${DX_SNIPPET_ps}\
+${DX_SNIPPET_pdf}\
+${DX_SNIPPET_latex}\
+DX_V_DXGEN = \$(_DX_v_DXGEN_\$(V))
+_DX_v_DXGEN_ = \$(_DX_v_DXGEN_1)
+_DX_v_DXGEN_0 = @echo \"  DXGEN \" \$<;
+
+.PHONY: doxygen-run doxygen-doc \$(DX_PS_GOAL) \$(DX_PDF_GOAL)
+
+.INTERMEDIATE: doxygen-run \$(DX_PS_GOAL) \$(DX_PDF_GOAL)
+
+doxygen-run:[]m4_foreach([DX_i], [DX_loop],
+                         [[ \$(DX_DOCDIR]DX_i[)/\$(PACKAGE).tag]])
+
+doxygen-doc: doxygen-run \$(DX_PS_GOAL) \$(DX_PDF_GOAL)
+
+m4_foreach([DX_i], [DX_loop],
+[[\$(DX_DOCDIR]DX_i[)/\$(PACKAGE).tag: \$(DX_CONFIG]DX_i[) \$(pkginclude_HEADERS)
+	\$(A""M_V_at)rm -rf \$(DX_DOCDIR]DX_i[)
+	\$(DX_V_DXGEN)\$(DX_ENV) DOCDIR=\$(DX_DOCDIR]DX_i[) \$(DX_DOXYGEN) \$(DX_CONFIG]DX_i[)
+	\$(A""M_V_at)echo Timestamp >\$][@
+
+]])dnl
+DX_CLEANFILES = \\
+m4_foreach([DX_i], [DX_loop],
+[[	\$(DX_DOCDIR]DX_i[)/\$(PACKAGE).tag \\
+]])dnl
+	-r \\
+	\$(DX_CLEAN_HTML) \\
+	\$(DX_CLEAN_CHM) \\
+	\$(DX_CLEAN_CHI) \\
+	\$(DX_CLEAN_MAN) \\
+	\$(DX_CLEAN_RTF) \\
+	\$(DX_CLEAN_XML) \\
+	\$(DX_CLEAN_PS) \\
+	\$(DX_CLEAN_PDF) \\
+	\$(DX_CLEAN_LATEX)"
+else
+    DX_SNIPPET_doc=""
+fi
+AC_SUBST([DX_RULES],
+["${DX_SNIPPET_doc}"])dnl
+AM_SUBST_NOTMAKE([DX_RULES])
+
 #For debugging:
 #echo DX_FLAG_doc=$DX_FLAG_doc
 #echo DX_FLAG_dot=$DX_FLAG_dot