gollvm: support build on arm64 linux

This CL serves as part of an initial change for enabling gollvm
building on arm64 linux (gollvm repo.), rest of the change will
be covered by another one made to the gofrontend repo.

It covers tool-chain setup, cpu attributes setting, and a few fixes
to cmake modules, some build settings are not flexible enough now
and require further refinement (perhaps along with x86_64).

The c-abi setup is not avaiable now.

Tested with triple aarch64-unknown-linux-gnu under Release and
Debug modes (with a minor change in llvm which will be investigated
further), clang 6.0+ or gcc-9 is recommended, and an additional
CMAKE option -DGOLLVM_USE_SPLIT_STACK=OFF is needed if your tool
chain doesn't support stack split.

Fixes golang/go#33711

Change-Id: I1554d2245cf53ea3f62c28e052f1155d67f6127c
Reviewed-on: https://go-review.googlesource.com/c/gollvm/+/194998
Reviewed-by: Than McIntosh <thanm@google.com>
diff --git a/cmake/modules/AddGollvm.cmake b/cmake/modules/AddGollvm.cmake
index 954965c..c6185bf 100644
--- a/cmake/modules/AddGollvm.cmake
+++ b/cmake/modules/AddGollvm.cmake
@@ -1,6 +1,10 @@
 
 # Library subdir within installation.
 # FIXME: select 32/64 based on default target triple
+# NOTE: default target triple has not been set at this point,
+#       we remain libsubdir unchanged with arm64 linux configuration
+#       for now, so libgo libraries and go*begin.a are put
+#       under 'lib64' as well, further fix required
 set(libsubdir "lib64")
 
 # Set version number string (used by install rules)
diff --git a/cmake/modules/AutoGenGo.cmake b/cmake/modules/AutoGenGo.cmake
index ae4d4bd..7bee31f 100644
--- a/cmake/modules/AutoGenGo.cmake
+++ b/cmake/modules/AutoGenGo.cmake
@@ -44,9 +44,7 @@
 
   # FIXME: add a real switch base on configuration params here.
 
-  if( NOT ${goarch} STREQUAL "amd64")
-    message(FATAL_ERROR "unsupported arch ${goarch}: currently only amd64 support")
-  else()
+  if( ${goarch} STREQUAL "amd64")
     set(archfamily "AMD64")
     set(bigendian "false")
     set(cachelinesize "64")
@@ -54,6 +52,18 @@
     set(pcquantum "1")
     set(int64align "8")
     set(minframesize 0)
+  elseif( ${goarch} STREQUAL "arm64")
+    # Simply picking up one typical setting
+    # Align with current sets in gofrontend/libgo/goarch.sh
+    set(archfamily "ARM64")
+    set(bigendian "false")
+    set(cachelinesize "32")
+    set(physpagesize "65536")
+    set(pcquantum "4")
+    set(int64align "8")
+    set(minframesize 8)
+  else()
+    message(FATAL_ERROR "unsupported arch ${goarch}: currently only amd64/arm64 support")
   endif()
 
   file(APPEND ${outfile} "const Goexperiment = ``\n")
@@ -372,7 +382,7 @@
   elseif(${s} EQUAL 12 AND ${o} EQUAL 8)
     file(APPEND ${outfile} "  Pad [4]byte\n  Fd int32\n")
   elseif(${s} EQUAL 16 AND ${o} EQUAL 8)
-    file(APPEND ${outfile} "  Pad [4]byte\n  Fd int32\n  Pad [4]byte\n  ")
+    file(APPEND ${outfile} "  Pad [4]byte\n  Fd int32\n  Pad2 [4]byte\n  ")
   else()
     message(SEND_ERROR "*** struct epoll_event data.fd offset unknown")
   endif()
diff --git a/cmake/modules/GoVars.cmake b/cmake/modules/GoVars.cmake
index edd4cfb..178e656 100644
--- a/cmake/modules/GoVars.cmake
+++ b/cmake/modules/GoVars.cmake
@@ -8,6 +8,9 @@
 # LLVM's "x86_64" is the same as Go's "amd64".
 if( ${llarch} STREQUAL "x86_64" )
   set(goarch "amd64")
+# LLVM's "aarch64" is the same as Go's "arm64".
+elseif( ${llarch} STREQUAL "aarch64" )
+  set(goarch "arm64")
 else()
   message(SEND_ERROR "Arch ${llarch} not yet supported")
 endif()
@@ -20,6 +23,10 @@
 # Set library suffix based on target triple
 if( ${llarch} STREQUAL "x86_64" )
   set(library_suffix "64")
+elseif( ${llarch} STREQUAL "aarch64" )
+# Driver::installedLibDir honors ./lib64 only
+# Future change needed (along with those in AddGollvm.cmake)
+  set(library_suffix "64")
 else()
   message(SEND_ERROR "Arch ${llarch} not yet supported")
 endif()
diff --git a/cmake/modules/LibbacktraceUtils.cmake b/cmake/modules/LibbacktraceUtils.cmake
index 1581cbf..d58a6e3 100644
--- a/cmake/modules/LibbacktraceUtils.cmake
+++ b/cmake/modules/LibbacktraceUtils.cmake
@@ -8,6 +8,9 @@
   if( ${goarch} STREQUAL "amd64")
     set(BACKTRACE_ELF_SIZE 64)
     set(HAVE_GETIPINFO 1)
+  elseif( ${goarch} STREQUAL "arm64")
+    set(BACKTRACE_ELF_SIZE 64)
+    set(HAVE_GETIPINFO 1)
   else()
     message(SEND_ERROR "Libbacktrace config setup not implemented for ${goarch}")
   endif()
diff --git a/cmake/modules/LibffiUtils.cmake b/cmake/modules/LibffiUtils.cmake
index 8f5bfeb..08562f4 100644
--- a/cmake/modules/LibffiUtils.cmake
+++ b/cmake/modules/LibffiUtils.cmake
@@ -5,6 +5,15 @@
 
 function(setup_libffi libffi_srcroot)
 
+  if(${llarch} STREQUAL "aarch64")
+    set(arch_dir "aarch64")
+  elseif(${llarch} STREQUAL "x86_64")
+    set(arch_dir "x86")
+  else()
+    message(SEND_ERROR "Arch ${llarch} not yet supported")
+  endif()
+
+
   # FIXME: currently hard-coded
   set(VERSION "3.99999")
 
@@ -26,7 +35,9 @@
     set(HAVE_64BIT 0)
   else()
     set(HAVE_64BIT 1)
-    set(HAVE_AS_X86_64_UNWIND_SECTION_TYPE 1)
+    if(NOT ${llarch} STREQUAL "aarch64")
+      set(HAVE_AS_X86_64_UNWIND_SECTION_TYPE 1)
+    endif()
   endif()
 
   # Pick up correct sources based on arch.
@@ -36,10 +47,11 @@
     "${libffi_srcroot}/src/types.c"
     "${libffi_srcroot}/src/raw_api.c"
     "${libffi_srcroot}/src/java_raw_api.c"
-    "${libffi_srcroot}/src/x86/ffi.c")
-  set(asm_srcs
-    "${libffi_srcroot}/src/x86/sysv.S")
-  if(HAVE_64BIT)
+    "${libffi_srcroot}/src/${arch_dir}/ffi.c")
+
+    set(asm_srcs "${libffi_srcroot}/src/${arch_dir}/sysv.S")
+
+  if(HAVE_64BIT AND ${llarch} STREQUAL "x86_64")
     list(APPEND c_srcs "${libffi_srcroot}/src/x86/ffi64.c" "${libffi_srcroot}/src/x86/ffiw64.c")
     list(APPEND asm_srcs "${libffi_srcroot}/src/x86/unix64.S")
     list(APPEND asm_srcs "${libffi_srcroot}/src/x86/win64.S")
@@ -47,7 +59,9 @@
   set_source_files_properties(${asm_srcs} PROPERTIES LANGUAGE C)
 
   # Set target based on arch.
-  if(HAVE_64BIT)
+  if(HAVE_64BIT AND ${llarch} STREQUAL "aarch64")
+    set(TARGET AARCH64)
+  elseif(HAVE_64BIT)
     set(TARGET X86_64)
   else()
     set(TARGET X86)
@@ -74,7 +88,7 @@
   string(APPEND libffiflags " ${GOLLVM_EXTRA_CFLAGS}")
 
   # Copy correct version of ffitarget.h to libgo binary root.
-  file(COPY "${libffi_srcroot}/src/x86/ffitarget.h" DESTINATION ${CMAKE_CURRENT_BINARY_DIR})
+  file(COPY "${libffi_srcroot}/src/${arch_dir}/ffitarget.h" DESTINATION ${CMAKE_CURRENT_BINARY_DIR})
 
   # At this point we can generate the necessary headers.
   configure_file("${CMAKE_CURRENT_SOURCE_DIR}/fficonfig.h.cmake" "${CMAKE_CURRENT_BINARY_DIR}/fficonfig.h")
diff --git a/driver/ArchCpusAttrs.h b/driver/ArchCpusAttrs.h
index 7064d9e..b04ef7e 100644
--- a/driver/ArchCpusAttrs.h
+++ b/driver/ArchCpusAttrs.h
@@ -1,10 +1,10 @@
 // DO NOT EDIT: this file auto-generated by the following command:
 //
-//    ./capture-fcn-attributes -o ArchCpusAttrs.h -triples x86_64-unknown-linux-gnu
+//    ./capture-fcn-attributes -o ArchCpusAttrs.h -triples x86_64-unknown-linux-gnu,aarch64-unknown-linux-gnu
 //
 // in combination with clang:
 //
-//  clang version 7.0.0 (trunk 333637) (llvm/trunk 333650)
+//  clang version 10.0.0 (https://github.com/llvm/llvm-project.git 53f967f2bdb6aa7b08596880c3689d1ecad6f0ff)
 //
 
 typedef struct {
@@ -20,55 +20,94 @@
 // triple: x86_64-unknown-linux-gnu
 static const CpuAttrs attrs0[] = {
   // first entry is default cpu
-  { "x86-64", "+fxsr,+mmx,+sse,+sse2,+x87" },
-  { "amdfam10", "+3dnow,+3dnowa,+fxsr,+lzcnt,+mmx,+popcnt,+prfchw,+sahf,+sse,+sse2,+sse3,+sse4a,+x87" },
-  { "athlon-fx", "+3dnow,+3dnowa,+fxsr,+mmx,+prfchw,+sse,+sse2,+x87" },
-  { "athlon64", "+3dnow,+3dnowa,+fxsr,+mmx,+prfchw,+sse,+sse2,+x87" },
-  { "athlon64-sse3", "+3dnow,+3dnowa,+fxsr,+mmx,+prfchw,+sse,+sse2,+sse3,+x87" },
-  { "atom", "+cx16,+fxsr,+mmx,+movbe,+sahf,+sse,+sse2,+sse3,+ssse3,+x87" },
-  { "barcelona", "+3dnow,+3dnowa,+fxsr,+lzcnt,+mmx,+popcnt,+prfchw,+sahf,+sse,+sse2,+sse3,+sse4a,+x87" },
-  { "bdver1", "+aes,+avx,+cx16,+fma4,+fxsr,+lwp,+lzcnt,+mmx,+pclmul,+popcnt,+prfchw,+sahf,+sse,+sse2,+sse3,+sse4.1,+sse4.2,+sse4a,+ssse3,+x87,+xop,+xsave" },
-  { "bdver2", "+aes,+avx,+bmi,+cx16,+f16c,+fma,+fma4,+fxsr,+lwp,+lzcnt,+mmx,+pclmul,+popcnt,+prfchw,+sahf,+sse,+sse2,+sse3,+sse4.1,+sse4.2,+sse4a,+ssse3,+tbm,+x87,+xop,+xsave" },
-  { "bdver3", "+aes,+avx,+bmi,+cx16,+f16c,+fma,+fma4,+fsgsbase,+fxsr,+lwp,+lzcnt,+mmx,+pclmul,+popcnt,+prfchw,+sahf,+sse,+sse2,+sse3,+sse4.1,+sse4.2,+sse4a,+ssse3,+tbm,+x87,+xop,+xsave,+xsaveopt" },
-  { "bdver4", "+aes,+avx,+avx2,+bmi,+bmi2,+cx16,+f16c,+fma,+fma4,+fsgsbase,+fxsr,+lwp,+lzcnt,+mmx,+mwaitx,+pclmul,+popcnt,+prfchw,+sahf,+sse,+sse2,+sse3,+sse4.1,+sse4.2,+sse4a,+ssse3,+tbm,+x87,+xop,+xsave,+xsaveopt" },
-  { "bonnell", "+cx16,+fxsr,+mmx,+movbe,+sahf,+sse,+sse2,+sse3,+ssse3,+x87" },
-  { "broadwell", "+adx,+aes,+avx,+avx2,+bmi,+bmi2,+cx16,+f16c,+fma,+fsgsbase,+fxsr,+invpcid,+lzcnt,+mmx,+movbe,+pclmul,+popcnt,+prfchw,+rdrnd,+rdseed,+sahf,+sse,+sse2,+sse3,+sse4.1,+sse4.2,+ssse3,+x87,+xsave,+xsaveopt" },
-  { "btver1", "+cx16,+fxsr,+lzcnt,+mmx,+popcnt,+prfchw,+sahf,+sse,+sse2,+sse3,+sse4a,+ssse3,+x87" },
-  { "btver2", "+aes,+avx,+bmi,+cx16,+f16c,+fxsr,+lzcnt,+mmx,+movbe,+pclmul,+popcnt,+prfchw,+sahf,+sse,+sse2,+sse3,+sse4.1,+sse4.2,+sse4a,+ssse3,+x87,+xsave,+xsaveopt" },
-  { "cannonlake", "+adx,+aes,+avx,+avx2,+avx512bw,+avx512cd,+avx512dq,+avx512f,+avx512ifma,+avx512vbmi,+avx512vl,+bmi,+bmi2,+clflushopt,+cx16,+f16c,+fma,+fsgsbase,+fxsr,+invpcid,+lzcnt,+mmx,+movbe,+mpx,+pclmul,+pku,+popcnt,+prfchw,+rdrnd,+rdseed,+rtm,+sahf,+sgx,+sha,+sse,+sse2,+sse3,+sse4.1,+sse4.2,+ssse3,+x87,+xsave,+xsavec,+xsaveopt,+xsaves" },
-  { "core-avx-i", "+aes,+avx,+cx16,+f16c,+fsgsbase,+fxsr,+mmx,+pclmul,+popcnt,+rdrnd,+sahf,+sse,+sse2,+sse3,+sse4.1,+sse4.2,+ssse3,+x87,+xsave,+xsaveopt" },
-  { "core-avx2", "+aes,+avx,+avx2,+bmi,+bmi2,+cx16,+f16c,+fma,+fsgsbase,+fxsr,+invpcid,+lzcnt,+mmx,+movbe,+pclmul,+popcnt,+rdrnd,+sahf,+sse,+sse2,+sse3,+sse4.1,+sse4.2,+ssse3,+x87,+xsave,+xsaveopt" },
-  { "core2", "+cx16,+fxsr,+mmx,+sahf,+sse,+sse2,+sse3,+ssse3,+x87" },
-  { "corei7", "+cx16,+fxsr,+mmx,+popcnt,+sahf,+sse,+sse2,+sse3,+sse4.1,+sse4.2,+ssse3,+x87" },
-  { "corei7-avx", "+aes,+avx,+cx16,+fxsr,+mmx,+pclmul,+popcnt,+sahf,+sse,+sse2,+sse3,+sse4.1,+sse4.2,+ssse3,+x87,+xsave,+xsaveopt" },
-  { "goldmont", "+aes,+clflushopt,+cx16,+fsgsbase,+fxsr,+mmx,+movbe,+mpx,+pclmul,+popcnt,+prfchw,+rdrnd,+rdseed,+sahf,+sha,+sse,+sse2,+sse3,+sse4.1,+sse4.2,+ssse3,+x87,+xsave,+xsavec,+xsaveopt,+xsaves" },
-  { "goldmont-plus", "+aes,+clflushopt,+cx16,+fsgsbase,+fxsr,+mmx,+movbe,+mpx,+pclmul,+popcnt,+prfchw,+ptwrite,+rdpid,+rdrnd,+rdseed,+sahf,+sgx,+sha,+sse,+sse2,+sse3,+sse4.1,+sse4.2,+ssse3,+x87,+xsave,+xsavec,+xsaveopt,+xsaves" },
-  { "haswell", "+aes,+avx,+avx2,+bmi,+bmi2,+cx16,+f16c,+fma,+fsgsbase,+fxsr,+invpcid,+lzcnt,+mmx,+movbe,+pclmul,+popcnt,+rdrnd,+sahf,+sse,+sse2,+sse3,+sse4.1,+sse4.2,+ssse3,+x87,+xsave,+xsaveopt" },
-  { "icelake-client", "+adx,+aes,+avx,+avx2,+avx512bitalg,+avx512bw,+avx512cd,+avx512dq,+avx512f,+avx512ifma,+avx512vbmi,+avx512vbmi2,+avx512vl,+avx512vnni,+avx512vpopcntdq,+bmi,+bmi2,+clflushopt,+clwb,+cx16,+f16c,+fma,+fsgsbase,+fxsr,+gfni,+invpcid,+lzcnt,+mmx,+movbe,+mpx,+pclmul,+pku,+popcnt,+prfchw,+rdpid,+rdrnd,+rdseed,+rtm,+sahf,+sgx,+sha,+sse,+sse2,+sse3,+sse4.1,+sse4.2,+ssse3,+vaes,+vpclmulqdq,+x87,+xsave,+xsavec,+xsaveopt,+xsaves" },
-  { "icelake-server", "+adx,+aes,+avx,+avx2,+avx512bitalg,+avx512bw,+avx512cd,+avx512dq,+avx512f,+avx512ifma,+avx512vbmi,+avx512vbmi2,+avx512vl,+avx512vnni,+avx512vpopcntdq,+bmi,+bmi2,+clflushopt,+clwb,+cx16,+f16c,+fma,+fsgsbase,+fxsr,+gfni,+invpcid,+lzcnt,+mmx,+movbe,+mpx,+pclmul,+pconfig,+pku,+popcnt,+prfchw,+rdpid,+rdrnd,+rdseed,+rtm,+sahf,+sgx,+sha,+sse,+sse2,+sse3,+sse4.1,+sse4.2,+ssse3,+vaes,+vpclmulqdq,+wbnoinvd,+x87,+xsave,+xsavec,+xsaveopt,+xsaves" },
-  { "ivybridge", "+aes,+avx,+cx16,+f16c,+fsgsbase,+fxsr,+mmx,+pclmul,+popcnt,+rdrnd,+sahf,+sse,+sse2,+sse3,+sse4.1,+sse4.2,+ssse3,+x87,+xsave,+xsaveopt" },
-  { "k8", "+3dnow,+3dnowa,+fxsr,+mmx,+prfchw,+sse,+sse2,+x87" },
-  { "k8-sse3", "+3dnow,+3dnowa,+fxsr,+mmx,+prfchw,+sse,+sse2,+sse3,+x87" },
-  { "knl", "+adx,+aes,+avx,+avx2,+avx512cd,+avx512er,+avx512f,+avx512pf,+bmi,+bmi2,+cx16,+f16c,+fma,+fsgsbase,+fxsr,+lzcnt,+mmx,+movbe,+pclmul,+popcnt,+prefetchwt1,+prfchw,+rdrnd,+rdseed,+rtm,+sahf,+sse,+sse2,+sse3,+sse4.1,+sse4.2,+ssse3,+x87,+xsave,+xsaveopt" },
-  { "knm", "+adx,+aes,+avx,+avx2,+avx512cd,+avx512er,+avx512f,+avx512pf,+avx512vpopcntdq,+bmi,+bmi2,+cx16,+f16c,+fma,+fsgsbase,+fxsr,+lzcnt,+mmx,+movbe,+pclmul,+popcnt,+prefetchwt1,+prfchw,+rdrnd,+rdseed,+rtm,+sahf,+sse,+sse2,+sse3,+sse4.1,+sse4.2,+ssse3,+x87,+xsave,+xsaveopt" },
-  { "nehalem", "+cx16,+fxsr,+mmx,+popcnt,+sahf,+sse,+sse2,+sse3,+sse4.1,+sse4.2,+ssse3,+x87" },
-  { "nocona", "+cx16,+fxsr,+mmx,+sse,+sse2,+sse3,+x87" },
-  { "opteron", "+3dnow,+3dnowa,+fxsr,+mmx,+prfchw,+sse,+sse2,+x87" },
-  { "opteron-sse3", "+3dnow,+3dnowa,+fxsr,+mmx,+prfchw,+sse,+sse2,+sse3,+x87" },
-  { "penryn", "+cx16,+fxsr,+mmx,+sahf,+sse,+sse2,+sse3,+sse4.1,+ssse3,+x87" },
-  { "sandybridge", "+aes,+avx,+cx16,+fxsr,+mmx,+pclmul,+popcnt,+sahf,+sse,+sse2,+sse3,+sse4.1,+sse4.2,+ssse3,+x87,+xsave,+xsaveopt" },
-  { "silvermont", "+aes,+cx16,+fxsr,+mmx,+movbe,+pclmul,+popcnt,+prfchw,+rdrnd,+sahf,+sse,+sse2,+sse3,+sse4.1,+sse4.2,+ssse3,+x87" },
-  { "skx", "+adx,+aes,+avx,+avx2,+avx512bw,+avx512cd,+avx512dq,+avx512f,+avx512vl,+bmi,+bmi2,+clflushopt,+clwb,+cx16,+f16c,+fma,+fsgsbase,+fxsr,+invpcid,+lzcnt,+mmx,+movbe,+mpx,+pclmul,+pku,+popcnt,+prfchw,+rdrnd,+rdseed,+rtm,+sahf,+sse,+sse2,+sse3,+sse4.1,+sse4.2,+ssse3,+x87,+xsave,+xsavec,+xsaveopt,+xsaves" },
-  { "skylake", "+adx,+aes,+avx,+avx2,+bmi,+bmi2,+clflushopt,+cx16,+f16c,+fma,+fsgsbase,+fxsr,+invpcid,+lzcnt,+mmx,+movbe,+mpx,+pclmul,+popcnt,+prfchw,+rdrnd,+rdseed,+rtm,+sahf,+sgx,+sse,+sse2,+sse3,+sse4.1,+sse4.2,+ssse3,+x87,+xsave,+xsavec,+xsaveopt,+xsaves" },
-  { "skylake-avx512", "+adx,+aes,+avx,+avx2,+avx512bw,+avx512cd,+avx512dq,+avx512f,+avx512vl,+bmi,+bmi2,+clflushopt,+clwb,+cx16,+f16c,+fma,+fsgsbase,+fxsr,+invpcid,+lzcnt,+mmx,+movbe,+mpx,+pclmul,+pku,+popcnt,+prfchw,+rdrnd,+rdseed,+rtm,+sahf,+sse,+sse2,+sse3,+sse4.1,+sse4.2,+ssse3,+x87,+xsave,+xsavec,+xsaveopt,+xsaves" },
-  { "slm", "+aes,+cx16,+fxsr,+mmx,+movbe,+pclmul,+popcnt,+prfchw,+rdrnd,+sahf,+sse,+sse2,+sse3,+sse4.1,+sse4.2,+ssse3,+x87" },
-  { "tremont", "+aes,+cldemote,+clflushopt,+cx16,+fsgsbase,+fxsr,+gfni,+mmx,+movbe,+movdir64b,+movdiri,+mpx,+pclmul,+popcnt,+prfchw,+ptwrite,+rdpid,+rdrnd,+rdseed,+sahf,+sgx,+sha,+sse,+sse2,+sse3,+sse4.1,+sse4.2,+ssse3,+waitpkg,+x87,+xsave,+xsavec,+xsaveopt,+xsaves" },
-  { "westmere", "+aes,+cx16,+fxsr,+mmx,+pclmul,+popcnt,+sahf,+sse,+sse2,+sse3,+sse4.1,+sse4.2,+ssse3,+x87" },
-  { "znver1", "+adx,+aes,+avx,+avx2,+bmi,+bmi2,+clflushopt,+clzero,+cx16,+f16c,+fma,+fsgsbase,+fxsr,+lzcnt,+mmx,+movbe,+mwaitx,+pclmul,+popcnt,+prfchw,+rdrnd,+rdseed,+sahf,+sha,+sse,+sse2,+sse3,+sse4.1,+sse4.2,+sse4a,+ssse3,+x87,+xsave,+xsavec,+xsaveopt,+xsaves" },
+  { "x86-64", "+cx8,+fxsr,+mmx,+sse,+sse2,+x87" },
+  { "amdfam10", "+3dnow,+3dnowa,+cx8,+fxsr,+lzcnt,+mmx,+popcnt,+prfchw,+sahf,+sse,+sse2,+sse3,+sse4a,+x87" },
+  { "athlon-fx", "+3dnow,+3dnowa,+cx8,+fxsr,+mmx,+prfchw,+sse,+sse2,+x87" },
+  { "athlon64", "+3dnow,+3dnowa,+cx8,+fxsr,+mmx,+prfchw,+sse,+sse2,+x87" },
+  { "athlon64-sse3", "+3dnow,+3dnowa,+cx8,+fxsr,+mmx,+prfchw,+sse,+sse2,+sse3,+x87" },
+  { "atom", "+cx16,+cx8,+fxsr,+mmx,+movbe,+sahf,+sse,+sse2,+sse3,+ssse3,+x87" },
+  { "barcelona", "+3dnow,+3dnowa,+cx8,+fxsr,+lzcnt,+mmx,+popcnt,+prfchw,+sahf,+sse,+sse2,+sse3,+sse4a,+x87" },
+  { "bdver1", "+aes,+avx,+cx16,+cx8,+fma4,+fxsr,+lwp,+lzcnt,+mmx,+pclmul,+popcnt,+prfchw,+sahf,+sse,+sse2,+sse3,+sse4.1,+sse4.2,+sse4a,+ssse3,+x87,+xop,+xsave" },
+  { "bdver2", "+aes,+avx,+bmi,+cx16,+cx8,+f16c,+fma,+fma4,+fxsr,+lwp,+lzcnt,+mmx,+pclmul,+popcnt,+prfchw,+sahf,+sse,+sse2,+sse3,+sse4.1,+sse4.2,+sse4a,+ssse3,+tbm,+x87,+xop,+xsave" },
+  { "bdver3", "+aes,+avx,+bmi,+cx16,+cx8,+f16c,+fma,+fma4,+fsgsbase,+fxsr,+lwp,+lzcnt,+mmx,+pclmul,+popcnt,+prfchw,+sahf,+sse,+sse2,+sse3,+sse4.1,+sse4.2,+sse4a,+ssse3,+tbm,+x87,+xop,+xsave,+xsaveopt" },
+  { "bdver4", "+aes,+avx,+avx2,+bmi,+bmi2,+cx16,+cx8,+f16c,+fma,+fma4,+fsgsbase,+fxsr,+lwp,+lzcnt,+mmx,+mwaitx,+pclmul,+popcnt,+prfchw,+sahf,+sse,+sse2,+sse3,+sse4.1,+sse4.2,+sse4a,+ssse3,+tbm,+x87,+xop,+xsave,+xsaveopt" },
+  { "bonnell", "+cx16,+cx8,+fxsr,+mmx,+movbe,+sahf,+sse,+sse2,+sse3,+ssse3,+x87" },
+  { "broadwell", "+adx,+avx,+avx2,+bmi,+bmi2,+cx16,+cx8,+f16c,+fma,+fsgsbase,+fxsr,+invpcid,+lzcnt,+mmx,+movbe,+pclmul,+popcnt,+prfchw,+rdrnd,+rdseed,+sahf,+sse,+sse2,+sse3,+sse4.1,+sse4.2,+ssse3,+x87,+xsave,+xsaveopt" },
+  { "btver1", "+cx16,+cx8,+fxsr,+lzcnt,+mmx,+popcnt,+prfchw,+sahf,+sse,+sse2,+sse3,+sse4a,+ssse3,+x87" },
+  { "btver2", "+aes,+avx,+bmi,+cx16,+cx8,+f16c,+fxsr,+lzcnt,+mmx,+movbe,+pclmul,+popcnt,+prfchw,+sahf,+sse,+sse2,+sse3,+sse4.1,+sse4.2,+sse4a,+ssse3,+x87,+xsave,+xsaveopt" },
+  { "cannonlake", "+adx,+aes,+avx,+avx2,+avx512bw,+avx512cd,+avx512dq,+avx512f,+avx512ifma,+avx512vbmi,+avx512vl,+bmi,+bmi2,+clflushopt,+cx16,+cx8,+f16c,+fma,+fsgsbase,+fxsr,+invpcid,+lzcnt,+mmx,+movbe,+mpx,+pclmul,+pku,+popcnt,+prfchw,+rdrnd,+rdseed,+sahf,+sgx,+sha,+sse,+sse2,+sse3,+sse4.1,+sse4.2,+ssse3,+x87,+xsave,+xsavec,+xsaveopt,+xsaves" },
+  { "cascadelake", "+adx,+aes,+avx,+avx2,+avx512bw,+avx512cd,+avx512dq,+avx512f,+avx512vl,+avx512vnni,+bmi,+bmi2,+clflushopt,+clwb,+cx16,+cx8,+f16c,+fma,+fsgsbase,+fxsr,+invpcid,+lzcnt,+mmx,+movbe,+mpx,+pclmul,+pku,+popcnt,+prfchw,+rdrnd,+rdseed,+sahf,+sse,+sse2,+sse3,+sse4.1,+sse4.2,+ssse3,+x87,+xsave,+xsavec,+xsaveopt,+xsaves" },
+  { "cooperlake", "+adx,+aes,+avx,+avx2,+avx512bf16,+avx512bw,+avx512cd,+avx512dq,+avx512f,+avx512vl,+avx512vnni,+bmi,+bmi2,+clflushopt,+clwb,+cx16,+cx8,+f16c,+fma,+fsgsbase,+fxsr,+invpcid,+lzcnt,+mmx,+movbe,+mpx,+pclmul,+pku,+popcnt,+prfchw,+rdrnd,+rdseed,+sahf,+sse,+sse2,+sse3,+sse4.1,+sse4.2,+ssse3,+x87,+xsave,+xsavec,+xsaveopt,+xsaves" },
+  { "core-avx-i", "+avx,+cx16,+cx8,+f16c,+fsgsbase,+fxsr,+mmx,+pclmul,+popcnt,+rdrnd,+sahf,+sse,+sse2,+sse3,+sse4.1,+sse4.2,+ssse3,+x87,+xsave,+xsaveopt" },
+  { "core-avx2", "+avx,+avx2,+bmi,+bmi2,+cx16,+cx8,+f16c,+fma,+fsgsbase,+fxsr,+invpcid,+lzcnt,+mmx,+movbe,+pclmul,+popcnt,+rdrnd,+sahf,+sse,+sse2,+sse3,+sse4.1,+sse4.2,+ssse3,+x87,+xsave,+xsaveopt" },
+  { "core2", "+cx16,+cx8,+fxsr,+mmx,+sahf,+sse,+sse2,+sse3,+ssse3,+x87" },
+  { "corei7", "+cx16,+cx8,+fxsr,+mmx,+popcnt,+sahf,+sse,+sse2,+sse3,+sse4.1,+sse4.2,+ssse3,+x87" },
+  { "corei7-avx", "+avx,+cx16,+cx8,+fxsr,+mmx,+pclmul,+popcnt,+sahf,+sse,+sse2,+sse3,+sse4.1,+sse4.2,+ssse3,+x87,+xsave,+xsaveopt" },
+  { "goldmont", "+aes,+clflushopt,+cx16,+cx8,+fsgsbase,+fxsr,+mmx,+movbe,+mpx,+pclmul,+popcnt,+prfchw,+rdrnd,+rdseed,+sahf,+sha,+sse,+sse2,+sse3,+sse4.1,+sse4.2,+ssse3,+x87,+xsave,+xsavec,+xsaveopt,+xsaves" },
+  { "goldmont-plus", "+aes,+clflushopt,+cx16,+cx8,+fsgsbase,+fxsr,+mmx,+movbe,+mpx,+pclmul,+popcnt,+prfchw,+ptwrite,+rdpid,+rdrnd,+rdseed,+sahf,+sgx,+sha,+sse,+sse2,+sse3,+sse4.1,+sse4.2,+ssse3,+x87,+xsave,+xsavec,+xsaveopt,+xsaves" },
+  { "haswell", "+avx,+avx2,+bmi,+bmi2,+cx16,+cx8,+f16c,+fma,+fsgsbase,+fxsr,+invpcid,+lzcnt,+mmx,+movbe,+pclmul,+popcnt,+rdrnd,+sahf,+sse,+sse2,+sse3,+sse4.1,+sse4.2,+ssse3,+x87,+xsave,+xsaveopt" },
+  { "icelake-client", "+adx,+aes,+avx,+avx2,+avx512bitalg,+avx512bw,+avx512cd,+avx512dq,+avx512f,+avx512ifma,+avx512vbmi,+avx512vbmi2,+avx512vl,+avx512vnni,+avx512vpopcntdq,+bmi,+bmi2,+clflushopt,+clwb,+cx16,+cx8,+f16c,+fma,+fsgsbase,+fxsr,+gfni,+invpcid,+lzcnt,+mmx,+movbe,+mpx,+pclmul,+pku,+popcnt,+prfchw,+rdpid,+rdrnd,+rdseed,+sahf,+sgx,+sha,+sse,+sse2,+sse3,+sse4.1,+sse4.2,+ssse3,+vaes,+vpclmulqdq,+x87,+xsave,+xsavec,+xsaveopt,+xsaves" },
+  { "icelake-server", "+adx,+aes,+avx,+avx2,+avx512bitalg,+avx512bw,+avx512cd,+avx512dq,+avx512f,+avx512ifma,+avx512vbmi,+avx512vbmi2,+avx512vl,+avx512vnni,+avx512vpopcntdq,+bmi,+bmi2,+clflushopt,+clwb,+cx16,+cx8,+f16c,+fma,+fsgsbase,+fxsr,+gfni,+invpcid,+lzcnt,+mmx,+movbe,+mpx,+pclmul,+pconfig,+pku,+popcnt,+prfchw,+rdpid,+rdrnd,+rdseed,+sahf,+sgx,+sha,+sse,+sse2,+sse3,+sse4.1,+sse4.2,+ssse3,+vaes,+vpclmulqdq,+wbnoinvd,+x87,+xsave,+xsavec,+xsaveopt,+xsaves" },
+  { "ivybridge", "+avx,+cx16,+cx8,+f16c,+fsgsbase,+fxsr,+mmx,+pclmul,+popcnt,+rdrnd,+sahf,+sse,+sse2,+sse3,+sse4.1,+sse4.2,+ssse3,+x87,+xsave,+xsaveopt" },
+  { "k8", "+3dnow,+3dnowa,+cx8,+fxsr,+mmx,+prfchw,+sse,+sse2,+x87" },
+  { "k8-sse3", "+3dnow,+3dnowa,+cx8,+fxsr,+mmx,+prfchw,+sse,+sse2,+sse3,+x87" },
+  { "knl", "+adx,+aes,+avx,+avx2,+avx512cd,+avx512er,+avx512f,+avx512pf,+bmi,+bmi2,+cx16,+cx8,+f16c,+fma,+fsgsbase,+fxsr,+lzcnt,+mmx,+movbe,+pclmul,+popcnt,+prefetchwt1,+prfchw,+rdrnd,+rdseed,+sahf,+sse,+sse2,+sse3,+sse4.1,+sse4.2,+ssse3,+x87,+xsave,+xsaveopt" },
+  { "knm", "+adx,+aes,+avx,+avx2,+avx512cd,+avx512er,+avx512f,+avx512pf,+avx512vpopcntdq,+bmi,+bmi2,+cx16,+cx8,+f16c,+fma,+fsgsbase,+fxsr,+lzcnt,+mmx,+movbe,+pclmul,+popcnt,+prefetchwt1,+prfchw,+rdrnd,+rdseed,+sahf,+sse,+sse2,+sse3,+sse4.1,+sse4.2,+ssse3,+x87,+xsave,+xsaveopt" },
+  { "nehalem", "+cx16,+cx8,+fxsr,+mmx,+popcnt,+sahf,+sse,+sse2,+sse3,+sse4.1,+sse4.2,+ssse3,+x87" },
+  { "nocona", "+cx16,+cx8,+fxsr,+mmx,+sse,+sse2,+sse3,+x87" },
+  { "opteron", "+3dnow,+3dnowa,+cx8,+fxsr,+mmx,+prfchw,+sse,+sse2,+x87" },
+  { "opteron-sse3", "+3dnow,+3dnowa,+cx8,+fxsr,+mmx,+prfchw,+sse,+sse2,+sse3,+x87" },
+  { "penryn", "+cx16,+cx8,+fxsr,+mmx,+sahf,+sse,+sse2,+sse3,+sse4.1,+ssse3,+x87" },
+  { "sandybridge", "+avx,+cx16,+cx8,+fxsr,+mmx,+pclmul,+popcnt,+sahf,+sse,+sse2,+sse3,+sse4.1,+sse4.2,+ssse3,+x87,+xsave,+xsaveopt" },
+  { "silvermont", "+cx16,+cx8,+fxsr,+mmx,+movbe,+pclmul,+popcnt,+prfchw,+rdrnd,+sahf,+sse,+sse2,+sse3,+sse4.1,+sse4.2,+ssse3,+x87" },
+  { "skx", "+adx,+aes,+avx,+avx2,+avx512bw,+avx512cd,+avx512dq,+avx512f,+avx512vl,+bmi,+bmi2,+clflushopt,+clwb,+cx16,+cx8,+f16c,+fma,+fsgsbase,+fxsr,+invpcid,+lzcnt,+mmx,+movbe,+mpx,+pclmul,+pku,+popcnt,+prfchw,+rdrnd,+rdseed,+sahf,+sse,+sse2,+sse3,+sse4.1,+sse4.2,+ssse3,+x87,+xsave,+xsavec,+xsaveopt,+xsaves" },
+  { "skylake", "+adx,+aes,+avx,+avx2,+bmi,+bmi2,+clflushopt,+cx16,+cx8,+f16c,+fma,+fsgsbase,+fxsr,+invpcid,+lzcnt,+mmx,+movbe,+mpx,+pclmul,+popcnt,+prfchw,+rdrnd,+rdseed,+sahf,+sgx,+sse,+sse2,+sse3,+sse4.1,+sse4.2,+ssse3,+x87,+xsave,+xsavec,+xsaveopt,+xsaves" },
+  { "skylake-avx512", "+adx,+aes,+avx,+avx2,+avx512bw,+avx512cd,+avx512dq,+avx512f,+avx512vl,+bmi,+bmi2,+clflushopt,+clwb,+cx16,+cx8,+f16c,+fma,+fsgsbase,+fxsr,+invpcid,+lzcnt,+mmx,+movbe,+mpx,+pclmul,+pku,+popcnt,+prfchw,+rdrnd,+rdseed,+sahf,+sse,+sse2,+sse3,+sse4.1,+sse4.2,+ssse3,+x87,+xsave,+xsavec,+xsaveopt,+xsaves" },
+  { "slm", "+cx16,+cx8,+fxsr,+mmx,+movbe,+pclmul,+popcnt,+prfchw,+rdrnd,+sahf,+sse,+sse2,+sse3,+sse4.1,+sse4.2,+ssse3,+x87" },
+  { "tremont", "+aes,+cldemote,+clflushopt,+cx16,+cx8,+fsgsbase,+fxsr,+gfni,+mmx,+movbe,+movdir64b,+movdiri,+mpx,+pclmul,+popcnt,+prfchw,+ptwrite,+rdpid,+rdrnd,+rdseed,+sahf,+sgx,+sha,+sse,+sse2,+sse3,+sse4.1,+sse4.2,+ssse3,+waitpkg,+x87,+xsave,+xsavec,+xsaveopt,+xsaves" },
+  { "westmere", "+cx16,+cx8,+fxsr,+mmx,+pclmul,+popcnt,+sahf,+sse,+sse2,+sse3,+sse4.1,+sse4.2,+ssse3,+x87" },
+  { "znver1", "+adx,+aes,+avx,+avx2,+bmi,+bmi2,+clflushopt,+clzero,+cx16,+cx8,+f16c,+fma,+fsgsbase,+fxsr,+lzcnt,+mmx,+movbe,+mwaitx,+pclmul,+popcnt,+prfchw,+rdrnd,+rdseed,+sahf,+sha,+sse,+sse2,+sse3,+sse4.1,+sse4.2,+sse4a,+ssse3,+x87,+xsave,+xsavec,+xsaveopt,+xsaves" },
+  { "znver2", "+adx,+aes,+avx,+avx2,+bmi,+bmi2,+clflushopt,+clwb,+clzero,+cx16,+cx8,+f16c,+fma,+fsgsbase,+fxsr,+lzcnt,+mmx,+movbe,+mwaitx,+pclmul,+popcnt,+prfchw,+rdpid,+rdrnd,+rdseed,+sahf,+sha,+sse,+sse2,+sse3,+sse4.1,+sse4.2,+sse4a,+ssse3,+wbnoinvd,+x87,+xsave,+xsavec,+xsaveopt,+xsaves" },
+  { "", "" } // sentinel
+};
+
+// triple: aarch64-unknown-linux-gnu
+static const CpuAttrs attrs1[] = {
+  // first entry is default cpu
+  { "generic", "+neon" },
+  { "cortex-a35", "+aes,+crc,+crypto,+fp-armv8,+neon,+sha2" },
+  { "cortex-a53", "+aes,+crc,+crypto,+fp-armv8,+neon,+sha2" },
+  { "cortex-a55", "+aes,+crc,+crypto,+dotprod,+fp-armv8,+fullfp16,+lse,+neon,+ras,+rcpc,+rdm,+sha2,+v8.2a" },
+  { "cortex-a57", "+aes,+crc,+crypto,+fp-armv8,+neon,+sha2" },
+  { "cortex-a65", "+aes,+crc,+crypto,+dotprod,+fp-armv8,+fullfp16,+lse,+neon,+ras,+rcpc,+rdm,+sha2,+v8.2a" },
+  { "cortex-a65ae", "+aes,+crc,+crypto,+dotprod,+fp-armv8,+fullfp16,+lse,+neon,+ras,+rcpc,+rdm,+sha2,+v8.2a" },
+  { "cortex-a72", "+aes,+crc,+crypto,+fp-armv8,+neon,+sha2" },
+  { "cortex-a73", "+aes,+crc,+crypto,+fp-armv8,+neon,+sha2" },
+  { "cortex-a75", "+aes,+crc,+crypto,+dotprod,+fp-armv8,+fullfp16,+lse,+neon,+ras,+rcpc,+rdm,+sha2,+v8.2a" },
+  { "cortex-a76", "+aes,+crc,+crypto,+dotprod,+fp-armv8,+fullfp16,+lse,+neon,+ras,+rcpc,+rdm,+sha2,+v8.2a" },
+  { "cortex-a76ae", "+aes,+crc,+crypto,+dotprod,+fp-armv8,+fullfp16,+lse,+neon,+ras,+rcpc,+rdm,+sha2,+v8.2a" },
+  { "cyclone", "+aes,+crypto,+fp-armv8,+neon,+sha2,+zcm,+zcz" },
+  { "exynos-m1", "+aes,+crc,+crypto,+fp-armv8,+neon,+sha2" },
+  { "exynos-m2", "+aes,+crc,+crypto,+fp-armv8,+neon,+sha2" },
+  { "exynos-m3", "+aes,+crc,+crypto,+fp-armv8,+neon,+sha2" },
+  { "exynos-m4", "+aes,+crc,+crypto,+dotprod,+fp-armv8,+fullfp16,+lse,+neon,+ras,+rdm,+sha2,+v8.2a" },
+  { "exynos-m5", "+aes,+crc,+crypto,+dotprod,+fp-armv8,+fullfp16,+lse,+neon,+ras,+rdm,+sha2,+v8.2a" },
+  { "falkor", "+aes,+crc,+crypto,+fp-armv8,+neon,+rdm,+sha2" },
+  { "kryo", "+aes,+crc,+crypto,+fp-armv8,+neon,+sha2" },
+  { "neoverse-e1", "+aes,+crc,+crypto,+dotprod,+fp-armv8,+fullfp16,+lse,+neon,+ras,+rcpc,+rdm,+sha2,+v8.2a" },
+  { "neoverse-n1", "+aes,+crc,+crypto,+dotprod,+fp-armv8,+fullfp16,+lse,+neon,+ras,+rcpc,+rdm,+sha2,+spe,+v8.2a" },
+  { "saphira", "+aes,+crc,+crypto,+fp-armv8,+lse,+neon,+ras,+rcpc,+rdm,+sha2,+spe,+v8.3a" },
+  { "thunderx", "+aes,+crc,+crypto,+fp-armv8,+neon,+sha2,+spe" },
+  { "thunderx2t99", "+aes,+crc,+crypto,+fp-armv8,+lse,+neon,+rdm,+sha2,+v8.1a" },
+  { "thunderxt81", "+aes,+crc,+crypto,+fp-armv8,+neon,+sha2,+spe" },
+  { "thunderxt83", "+aes,+crc,+crypto,+fp-armv8,+neon,+sha2,+spe" },
+  { "thunderxt88", "+aes,+crc,+crypto,+fp-armv8,+neon,+sha2,+spe" },
+  { "tsv110", "+aes,+crc,+crypto,+dotprod,+fp-armv8,+fp16fml,+fullfp16,+lse,+neon,+ras,+rdm,+sha2,+spe,+v8.2a" },
   { "", "" } // sentinel
 };
 
 const TripleCpus triples[] = {
   { "x86_64-unknown-linux-gnu", &attrs0[0] },
+  { "aarch64-unknown-linux-gnu", &attrs1[0] },
   { "", nullptr } // sentinel
 };
diff --git a/driver/Driver.cpp b/driver/Driver.cpp
index 62c62dd..e00d3bc 100644
--- a/driver/Driver.cpp
+++ b/driver/Driver.cpp
@@ -59,7 +59,20 @@
 std::string Driver::installedLibDir()
 {
   llvm::SmallString<256> ldir(installDir_);
-  llvm::sys::path::append(ldir, "../lib64");
+  const llvm::Triple::ArchType arch = triple().getArch();
+
+  switch (arch) {
+    // multilib is not supported on major aarch64/arm64 linux distributions
+    // (subject to change when more scenarios to be taken into account)
+    // NOTE: set aarch64's lib dir to "lib64" temporarily, until necessary
+    //       change is made to cmake module files
+    case llvm::Triple::aarch64:
+      llvm::sys::path::append(ldir, "../lib64");
+      break;
+    default:
+      llvm::sys::path::append(ldir, "../lib64");
+      break;
+  }
   return std::string(ldir.str());
 }
 
diff --git a/driver/GccUtils.cpp b/driver/GccUtils.cpp
index 70a5e11..079722c 100644
--- a/driver/GccUtils.cpp
+++ b/driver/GccUtils.cpp
@@ -176,6 +176,18 @@
         s.suffixes = {""};
       }
       break;
+    case llvm::Triple::aarch64:
+      // more triples to be identified and added
+      s.tripleAliases = {
+        triple_.str(),
+        "aarch64-linux-gnu", "aarch64-unknown-linux-gnu"
+      };
+      // multilib is not supported on major aarch64/arm64 linux distributions
+      // subject to change when more scenarios to be taken into account
+      s.libdirs.push_back("lib");
+      s.triple.setTriple(triple_.str());
+      s.suffixes = {""};
+      break;
     default:
       llvm::errs() << "error: unsupported triple "
                    << triple_.str() << " in " << __FUNCTION__ << "\n";
diff --git a/driver/GnuTools.cpp b/driver/GnuTools.cpp
index 026565d..38b69f6 100644
--- a/driver/GnuTools.cpp
+++ b/driver/GnuTools.cpp
@@ -115,6 +115,8 @@
       // NB: no GNUX32 support yet
       cmdArgs.push_back("--64");
       break;
+    case llvm::Triple::aarch64:
+      break;
     default:
       break;
   }
@@ -212,6 +214,9 @@
       // NB: no GNUX32 support
       cmdArgs.push_back("elf_x86_64");
       break;
+    case llvm::Triple::aarch64:
+      cmdArgs.push_back("aarch64elf");
+      break;
     default:
       // unhandled architecture
       cmdArgs.push_back("%unknown%");
diff --git a/driver/LinuxToolChain.cpp b/driver/LinuxToolChain.cpp
index d3df39e..c4fb887 100644
--- a/driver/LinuxToolChain.cpp
+++ b/driver/LinuxToolChain.cpp
@@ -33,6 +33,10 @@
 
 static llvm::StringRef getOSLibDir(const llvm::Triple &triple)
 {
+  // multilib is not supported on major aarch64/arm64 linux distributions
+  // subject to change when more scenarios to be taken into account
+  if (triple.getArch() == llvm::Triple::aarch64)
+    return "lib";
   // x86 uses the lib32 variant, unlike other archs.
   if (triple.getArch() == llvm::Triple::x86)
     return "lib32";
@@ -112,6 +116,10 @@
     default:
       assert(false && "unsupported architecture");
       return "<unknown_dynamic_linker>";
+    case llvm::Triple::aarch64:
+      LibDir = "lib";
+      Loader = "ld-linux-aarch64.so.1";
+      break;
     case llvm::Triple::x86:
       LibDir = "lib";
       Loader = "ld-linux.so.2";
diff --git a/libgo/CMakeLists.txt b/libgo/CMakeLists.txt
index eddbd5a..8d0265a 100644
--- a/libgo/CMakeLists.txt
+++ b/libgo/CMakeLists.txt
@@ -439,13 +439,17 @@
   "go/log/syslog/syslog_c.c"
   "go/reflect/makefunc_ffi_c.c"
   "go/runtime/internal/atomic/atomic.c"
-  "go/golang.org/x/sys/cpu/cpu_gccgo.c"
   "go/internal/cpu/cpu_gccgo.c"
   "go/sync/atomic/atomic.c"
   "go/syscall/errno.c"
   "go/syscall/signame.c"
   "go/syscall/wait.c")
 
+if (NOT ${goarch} STREQUAL "arm64")
+  list(APPEND runtimecfiles
+    "go/golang.org/x/sys/cpu/cpu_gccgo.c")
+endif()
+
 # Linux-specific C files.
 if(${goos} STREQUAL "linux")
   list(APPEND runtimecfiles
@@ -474,7 +478,11 @@
 # Special flags required for aeshash.c (functions in this file are called
 # only when running on the proper architecture, so it is safe to ask for
 # specific architectural features).
-set_source_files_properties(${libgo_csrcroot}/runtime/aeshash.c PROPERTIES COMPILE_FLAGS "-maes -mssse3")
+if (${goarch} STREQUAL "arm64")
+  set_source_files_properties(${libgo_csrcroot}/runtime/aeshash.c PROPERTIES COMPILE_FLAGS "-march=armv8-a+crypto")
+else()
+  set_source_files_properties(${libgo_csrcroot}/runtime/aeshash.c PROPERTIES COMPILE_FLAGS "-maes -mssse3")
+endif()
 
 # Object library based on libgo C code, PIC-compiled
 add_library(libgo_c_piclib OBJECT EXCLUDE_FROM_ALL ${runtimecpaths})
diff --git a/tools/capture-fcn-attributes.go b/tools/capture-fcn-attributes.go
index b4cd240..7ce26ba 100644
--- a/tools/capture-fcn-attributes.go
+++ b/tools/capture-fcn-attributes.go
@@ -42,9 +42,11 @@
 //
 // Representative usage:
 //
-// % go build capture-fcn-attributes
+// % go build capture-fcn-attributes.go
 // % export PATH=<llvm bin dir>:$PATH
 // % ./capture-fcn-attributes -o HeaderFile.h -triples x86_64-unknown-linux-gnu
+// To generate attributes for multiple targets
+// % ./capture-fcn-attributes -o HeaderFile.h -triples triple{,triple}+
 // %
 
 package main