arm64.patch

text/x-patch

Filename: arm64.patch
Type: text/x-patch
Part: 0
Message: Re: [PATCH] Add native windows on arm64 support

Patch

Format: unified
File+
doc/src/sgml/installation.sgml 1 1
meson.build 9 2
src/include/storage/s_lock.h 18 2
src/port/pg_crc32c_armv8.c 2 0
src/tools/msvc_gendef.pl 4 4
diff --git a/doc/src/sgml/installation.sgml b/doc/src/sgml/installation.sgml
index ed5b285a5e..d9b8649dab 100644
--- a/doc/src/sgml/installation.sgml
+++ b/doc/src/sgml/installation.sgml
@@ -4150,7 +4150,7 @@ make: *** [postgres] Error 1
    <sect3 id="install-windows-full-64-bit">
     <title>Special Considerations for 64-Bit Windows</title>
     <para>
-     PostgreSQL will only build for the x64 architecture on 64-bit Windows.
+     PostgreSQL will only build for the x64 and ARM64 architecture on 64-bit Windows.
     </para>
     <para>
      Mixing 32- and 64-bit versions in the same build tree is not supported.
diff --git a/meson.build b/meson.build
index 8ed51b6aae..14aea924ec 100644
--- a/meson.build
+++ b/meson.build
@@ -2046,8 +2046,11 @@ int main(void)
 elif host_cpu == 'arm' or host_cpu == 'aarch64'
 
   prog = '''
+#ifdef _MSC_VER
+#include <intrin.h>
+#else
 #include <arm_acle.h>
-
+#endif
 int main(void)
 {
     unsigned int crc = 0;
@@ -2061,7 +2064,11 @@ int main(void)
 }
 '''
 
-  if cc.links(prog, name: '__crc32cb, __crc32ch, __crc32cw, and __crc32cd without -march=armv8-a+crc',
+  if cc.get_id() == 'msvc'
+    cdata.set('USE_ARMV8_CRC32C', false)
+    cdata.set('USE_ARMV8_CRC32C_WITH_RUNTIME_CHECK', 1)
+    have_optimized_crc = true
+  elif cc.links(prog, name: '__crc32cb, __crc32ch, __crc32cw, and __crc32cd without -march=armv8-a+crc',
       args: test_c_args)
     # Use ARM CRC Extension unconditionally
     cdata.set('USE_ARMV8_CRC32C', 1)
diff --git a/src/include/storage/s_lock.h b/src/include/storage/s_lock.h
index 69582f4ae7..44abd42691 100644
--- a/src/include/storage/s_lock.h
+++ b/src/include/storage/s_lock.h
@@ -707,15 +707,31 @@ typedef LONG slock_t;
 
 #define SPIN_DELAY() spin_delay()
 
-/* If using Visual C++ on Win64, inline assembly is unavailable.
- * Use a _mm_pause intrinsic instead of rep nop.
+/*
+ * If using Visual C++ on Win64, inline assembly is unavailable.
+ * Use architecture specific intrinsics.
  */
 #if defined(_WIN64)
+/*
+ * For Arm64, use __isb intrinsic. See aarch64 inline assembly definition for details.
+ */
+#ifdef _M_ARM64
+static __forceinline void
+spin_delay(void)
+{
+	 /* Reference: https://learn.microsoft.com/en-us/cpp/intrinsics/arm64-intrinsics#BarrierRestrictions */
+	__isb(_ARM64_BARRIER_SY);
+}
+#else
+/*
+ * For x64, use _mm_pause intrinsic instead of rep nop.
+ */
 static __forceinline void
 spin_delay(void)
 {
 	_mm_pause();
 }
+#endif
 #else
 static __forceinline void
 spin_delay(void)
diff --git a/src/port/pg_crc32c_armv8.c b/src/port/pg_crc32c_armv8.c
index d47d838c50..f18903a68a 100644
--- a/src/port/pg_crc32c_armv8.c
+++ b/src/port/pg_crc32c_armv8.c
@@ -14,7 +14,9 @@
  */
 #include "c.h"
 
+#ifndef _MSC_VER
 #include <arm_acle.h>
+#endif
 
 #include "port/pg_crc32c.h"
 
diff --git a/src/tools/msvc_gendef.pl b/src/tools/msvc_gendef.pl
index 12c49ed265..dfb26916bd 100644
--- a/src/tools/msvc_gendef.pl
+++ b/src/tools/msvc_gendef.pl
@@ -120,9 +120,9 @@ sub writedef
 	{
 		my $isdata = $def->{$f} eq 'data';
 
-		# Strip the leading underscore for win32, but not x64
+		# Strip the leading underscore for win32, but not x64 and aarch64
 		$f =~ s/^_//
-		  unless ($arch eq "x86_64");
+		  unless ($arch eq "x86_64" || $arch eq "aarch64");
 
 		# Emit just the name if it's a function symbol, or emit the name
 		# decorated with the DATA option for variables.
@@ -143,7 +143,7 @@ sub writedef
 sub usage
 {
 	die("Usage: msvc_gendef.pl --arch <arch> --deffile <deffile> --tempdir <tempdir> files-or-directories\n"
-		  . "    arch: x86 | x86_64\n"
+		  . "    arch: x86 | x86_64 | aarch64\n"
 		  . "    deffile: path of the generated file\n"
 		  . "    tempdir: directory for temporary files\n"
 		  . "    files or directories: object files or directory containing object files\n"
@@ -160,7 +160,7 @@ GetOptions(
 	'tempdir:s' => \$tempdir,) or usage();
 
 usage("arch: $arch")
-  unless ($arch eq 'x86' || $arch eq 'x86_64');
+  unless ($arch eq 'x86' || $arch eq 'x86_64' || $arch eq 'aarch64');
 
 my @files;