From b379f8d81f6141336c8585b19f9703bc26b99e2a Mon Sep 17 00:00:00 2001 From: Ian Lance Taylor Date: Tue, 3 Jan 2017 20:41:54 +0000 Subject: [PATCH] re PR go/78789 (Error: no such instruction: `aesenc %xmm0,%xmm2' when compiling libgo/runtime/aeshash.c) PR go/78789 runtime: don't build aeshash.c if the assembler doesn't support it This is for CentOS 5, whose assembler does not know the aesinc instruction. Fixes GCC PR 78789. Patch by Uros Bizjak. Reviewed-on: https://go-review.googlesource.com/34796 From-SVN: r244031 --- gcc/go/gofrontend/MERGE | 2 +- libgo/config.h.in | 3 +++ libgo/configure | 26 ++++++++++++++++++++++++++ libgo/configure.ac | 18 ++++++++++++++++++ libgo/go/runtime/alg.go | 1 + libgo/go/runtime/runtime2.go | 3 ++- libgo/go/runtime/stubs.go | 6 ++++++ libgo/runtime/aeshash.c | 6 +++--- libgo/runtime/runtime.h | 2 ++ libgo/runtime/runtime_c.c | 4 ++++ 10 files changed, 66 insertions(+), 5 deletions(-) diff --git a/gcc/go/gofrontend/MERGE b/gcc/go/gofrontend/MERGE index b03fb620a97..a48719637f4 100644 --- a/gcc/go/gofrontend/MERGE +++ b/gcc/go/gofrontend/MERGE @@ -1,4 +1,4 @@ -ebe9d824adca053066837b8b19461048ced34aff +eac28020ee4b2532d4cd43f448fe612e84e0a108 The first line of this file holds the git revision number of the last merge done from the gofrontend repository. diff --git a/libgo/config.h.in b/libgo/config.h.in index d3b3067d32a..a669ff7add1 100644 --- a/libgo/config.h.in +++ b/libgo/config.h.in @@ -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 diff --git a/libgo/configure b/libgo/configure index 4129ebed0ff..2cd390859bb 100755 --- a/libgo/configure +++ b/libgo/configure @@ -15490,6 +15490,32 @@ $as_echo "#define HAVE_AS_X86_64_UNWIND_SECTION_TYPE 1" >>confdefs.h 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 diff --git a/libgo/configure.ac b/libgo/configure.ac index b7710cad038..a3267308ed1 100644 --- a/libgo/configure.ac +++ b/libgo/configure.ac @@ -934,6 +934,24 @@ if test "x$libgo_cv_as_x86_64_unwind_section_type" = xyes; then [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 diff --git a/libgo/go/runtime/alg.go b/libgo/go/runtime/alg.go index 5ec19d0a9f9..53312313017 100644 --- a/libgo/go/runtime/alg.go +++ b/libgo/go/runtime/alg.go @@ -233,6 +233,7 @@ func alginit() { // 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}) diff --git a/libgo/go/runtime/runtime2.go b/libgo/go/runtime/runtime2.go index 978a3172d0f..6686e1f29b3 100644 --- a/libgo/go/runtime/runtime2.go +++ b/libgo/go/runtime/runtime2.go @@ -771,7 +771,8 @@ var ( // 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 diff --git a/libgo/go/runtime/stubs.go b/libgo/go/runtime/stubs.go index dde9ebdfdd6..c299ae0e8eb 100644 --- a/libgo/go/runtime/stubs.go +++ b/libgo/go/runtime/stubs.go @@ -272,6 +272,12 @@ func setCpuidECX(v uint32) { 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 diff --git a/libgo/runtime/aeshash.c b/libgo/runtime/aeshash.c index bdfea5f93fe..7f29baa07b2 100644 --- a/libgo/runtime/aeshash.c +++ b/libgo/runtime/aeshash.c @@ -12,7 +12,7 @@ uintptr aeshashbody(void*, uintptr, uintptr, Slice) 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 #include @@ -573,7 +573,7 @@ uintptr aeshashbody(void* p, uintptr seed, uintptr size, Slice aeskeysched) { #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 @@ uintptr aeshashbody(void* p __attribute__((unused)), runtime_throw("impossible call to aeshashbody"); } -#endif // !defined(__i386__) && !defined(__x86_64__) +#endif // !defined(__i386__) && !defined(__x86_64__) || !defined(HAVE_AS_X86_AES) diff --git a/libgo/runtime/runtime.h b/libgo/runtime/runtime.h index 6cbf02df368..54bdcf8ce72 100644 --- a/libgo/runtime/runtime.h +++ b/libgo/runtime/runtime.h @@ -599,6 +599,8 @@ extern void setIsCgo(void) __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) diff --git a/libgo/runtime/runtime_c.c b/libgo/runtime/runtime_c.c index ad167877bc8..464531263f5 100644 --- a/libgo/runtime/runtime_c.c +++ b/libgo/runtime/runtime_c.c @@ -190,5 +190,9 @@ runtime_cpuinit() if (__get_cpuid(1, &eax, &ebx, &ecx, &edx)) { setCpuidECX(ecx); } + +#if defined(HAVE_AS_X86_AES) + setSupportAES(true); +#endif #endif } -- 2.30.2