Hello!

Attached patch detect support for AES instructions and avoids
compiling runtime/aeshash.c with older assemblers (on e.g. CentOS
5.11). The result of configure is also communicated into go runtime,
so the library doesn't try to call non-existent aeshashbody routine.

Patch was tested on x86_64-linux-gnu, on Fedora 25 with AES capable
CPU and on CentOS 5.11 with non-AES capable CPU.

Uros.
Index: config.h.in
===================================================================
--- config.h.in (revision 244024)
+++ config.h.in (working copy)
@@ -21,6 +21,9 @@
 /* Define if your assembler supports unwind section type. */
 #undef HAVE_AS_X86_64_UNWIND_SECTION_TYPE
 
+/* Define if your assembler supports AES instructions. */
+#undef HAVE_AS_X86_AES
+
 /* Define if your assembler supports PC relative relocs. */
 #undef HAVE_AS_X86_PCREL
 
Index: configure
===================================================================
--- configure   (revision 244024)
+++ configure   (working copy)
@@ -15490,6 +15490,32 @@
 
 fi
 
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking assembler supports AES 
instructions" >&5
+$as_echo_n "checking assembler supports AES instructions... " >&6; }
+if test "${libgo_cv_as_x86_aes+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+
+libgo_cv_as_x86_aes=yes
+echo 'aesenc %xmm0, %xmm1' > conftest.s
+CFLAGS_hold=$CFLAGS
+if test "$libgo_cv_c_unused_arguments" = yes; then
+  CFLAGS="$CFLAGS -Qunused-arguments"
+fi
+if $CC $CFLAGS -c conftest.s 2>&1 | grep -i error > /dev/null; then
+    libgo_cv_as_x86_aes=no
+fi
+CFLAGS=$CFLAGS_hold
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $libgo_cv_as_x86_aes" >&5
+$as_echo "$libgo_cv_as_x86_aes" >&6; }
+if test "x$libgo_cv_as_x86_aes" = xyes; then
+
+$as_echo "#define HAVE_AS_X86_AES 1" >>confdefs.h
+
+fi
+
 cat >confcache <<\_ACEOF
 # This file is a shell script that caches the results of configure
 # tests run on this system so they can be shared between configure
Index: configure.ac
===================================================================
--- configure.ac        (revision 244024)
+++ configure.ac        (working copy)
@@ -934,6 +934,24 @@
            [Define if your assembler supports unwind section type.])
 fi
 
+AC_CACHE_CHECK([assembler supports AES instructions],
+libgo_cv_as_x86_aes, [
+libgo_cv_as_x86_aes=yes
+echo 'aesenc %xmm0, %xmm1' > conftest.s
+CFLAGS_hold=$CFLAGS
+if test "$libgo_cv_c_unused_arguments" = yes; then
+  CFLAGS="$CFLAGS -Qunused-arguments"
+fi
+if $CC $CFLAGS -c conftest.s 2>&1 | grep -i error > /dev/null; then
+    libgo_cv_as_x86_aes=no
+fi
+CFLAGS=$CFLAGS_hold
+])
+if test "x$libgo_cv_as_x86_aes" = xyes; then
+  AC_DEFINE(HAVE_AS_X86_AES, 1,
+           [Define if your assembler supports AES instructions.])
+fi
+
 AC_CACHE_SAVE
 
 if test ${multilib} = yes; then
Index: go/runtime/alg.go
===================================================================
--- go/runtime/alg.go   (revision 244024)
+++ go/runtime/alg.go   (working copy)
@@ -233,6 +233,7 @@
        // Install aes hash algorithm if we have the instructions we need
        if (GOARCH == "386" || GOARCH == "amd64") &&
                GOOS != "nacl" &&
+               support_aes &&
                cpuid_ecx&(1<<25) != 0 && // aes (aesenc)
                cpuid_ecx&(1<<9) != 0 && // sse3 (pshufb)
                cpuid_ecx&(1<<19) != 0 { // sse4.1 (pinsr{d,q})
Index: go/runtime/runtime2.go
===================================================================
--- go/runtime/runtime2.go      (revision 244024)
+++ go/runtime/runtime2.go      (working copy)
@@ -771,7 +771,8 @@
 
        // Information about what cpu features are available.
        // Set on startup.
-       cpuid_ecx uint32
+       cpuid_ecx         uint32
+       support_aes       bool
 
 //     cpuid_edx         uint32
 //     cpuid_ebx7        uint32
Index: go/runtime/stubs.go
===================================================================
--- go/runtime/stubs.go (revision 244024)
+++ go/runtime/stubs.go (working copy)
@@ -272,6 +272,12 @@
        cpuid_ecx = v
 }
 
+// For gccgo, to communicate from the C code to the Go code.
+//go:linkname setSupportAES runtime.setSupportAES
+func setSupportAES(v bool) {
+       support_aes = v
+}
+
 // typedmemmove copies a typed value.
 // For gccgo for now.
 //go:nosplit
Index: runtime/aeshash.c
===================================================================
--- runtime/aeshash.c   (revision 244024)
+++ runtime/aeshash.c   (working copy)
@@ -12,7 +12,7 @@
 uintptr aeshashbody(void*, uintptr, uintptr, Slice)
        __attribute__((no_split_stack));
 
-#if defined(__i386__) || defined(__x86_64__)
+#if (defined(__i386__) || defined(__x86_64__)) && defined(HAVE_AS_X86_AES)
 
 #include <emmintrin.h>
 #include <tmmintrin.h>
@@ -573,7 +573,7 @@
 
 #endif // !defined(__x86_64__)
 
-#else // !defined(__i386__) && !defined(__x86_64__)
+#else // !defined(__i386__) && !defined(__x86_64__) || 
!defined(HAVE_AS_X86_AES)
 
 uintptr aeshashbody(void* p __attribute__((unused)),
                    uintptr seed __attribute__((unused)),
@@ -583,4 +583,4 @@
        runtime_throw("impossible call to aeshashbody");
 }
 
-#endif // !defined(__i386__) && !defined(__x86_64__)
+#endif // !defined(__i386__) && !defined(__x86_64__) || 
!defined(HAVE_AS_X86_AES)
Index: runtime/runtime.h
===================================================================
--- runtime/runtime.h   (revision 244024)
+++ runtime/runtime.h   (working copy)
@@ -599,6 +599,8 @@
   __asm__ (GOSYM_PREFIX "runtime.setIsCgo");
 extern void setCpuidECX(uint32)
   __asm__ (GOSYM_PREFIX "runtime.setCpuidECX");
+extern void setSupportAES(bool)
+  __asm__ (GOSYM_PREFIX "runtime.setSupportAES");
 extern void makeMainInitDone(void)
   __asm__ (GOSYM_PREFIX "runtime.makeMainInitDone");
 extern void closeMainInitDone(void)
Index: runtime/runtime_c.c
===================================================================
--- runtime/runtime_c.c (revision 244024)
+++ runtime/runtime_c.c (working copy)
@@ -190,5 +190,9 @@
        if (__get_cpuid(1, &eax, &ebx, &ecx, &edx)) {
                setCpuidECX(ecx);
        }
+
+#if defined(HAVE_AS_X86_AES)
+       setSupportAES(true);
 #endif
+#endif
 }

Reply via email to