On Tue, Dec 16, 2025 at 08:23:19AM -0500, Greg Burd wrote:
> On Mon, Dec 15, 2025, at 6:08 PM, Andres Freund wrote:
>> LGTM
> 
> LGTM, thanks everyone.

Here's what I have staged for commit.  I searched around for anything else
that might be missing, and I only found a couple of small things.  First,
there are some optional AArch64 optimizations (simd.h and popcount) that
likely need more work, but those can wait for now.  Also, while the patch
is targeting Windows 11 (IIUC), there are some notes in the docs that give
the impression Windows 10 is supported, too [0].  I could easily change it
to say that AArch64 requires Windows 11, but I don't know what to do with
the references to specific versions of Visual Studio and the Windows SDK.
Thoughts?  Maybe that can wait, too.

[0] 
https://www.postgresql.org/docs/devel/installation-platform-notes.html#INSTALLATION-NOTES-VISUAL-STUDIO

-- 
nathan
>From d2f2c2ea6c4e1e7677745b6f8dbdb0fad2437de2 Mon Sep 17 00:00:00 2001
From: Nathan Bossart <[email protected]>
Date: Tue, 16 Dec 2025 11:44:15 -0600
Subject: [PATCH v12 1/1] Add support for Windows on AArch64.

This commit does the following to get tests passing for
MSVC/AArch64:

* Implements spin_delay() with an ISB instruction (like we do for
gcc/clang on AArch64).

* Sets USE_ARMV8_CRC32C unconditionally.  Vendor-supported versions
of Windows for AArch64 require at least ARMv8.1, which is where CRC
extension support became mandatory.

* Implements S_UNLOCK() with _InterlockedExchange().  x86_64 uses
_ReadWriteBarrier() (a compiler barrier), which is insufficient for
this purpose on non-TSO architectures.

There are likely other changes required to take full advantage of
the hardware (e.g., simd.h and pg_popcount_aarch64.c), but those
are optional and can be dealt with in a later commit.

Author: Greg Burd <[email protected]>
Co-authored-by: Dave Cramer <[email protected]>
Reviewed-by: Peter Eisentraut <[email protected]>
Reviewed-by: Andres Freund <[email protected]>
Reviewed-by: Thomas Munro <[email protected]>
Discussion: 
https://postgr.es/m/A6152C7C-F5E3-4958-8F8E-7692D259FF2F%40greg.burd.me
---
 doc/src/sgml/installation.sgml |  3 ++-
 meson.build                    |  6 +++++-
 src/include/storage/s_lock.h   | 30 +++++++++++++++++++++++++-----
 src/port/pg_crc32c_armv8.c     |  4 ++++
 src/tools/msvc_gendef.pl       |  8 ++++----
 5 files changed, 40 insertions(+), 11 deletions(-)

diff --git a/doc/src/sgml/installation.sgml b/doc/src/sgml/installation.sgml
index fe8d73e1f8c..c903ccff988 100644
--- a/doc/src/sgml/installation.sgml
+++ b/doc/src/sgml/installation.sgml
@@ -3967,7 +3967,8 @@ configure ... LDFLAGS="-R 
/usr/sfw/lib:/opt/sfw/lib:/usr/local/lib"
    <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 AArch64 architectures 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 d7c5193d4ce..d521e13690c 100644
--- a/meson.build
+++ b/meson.build
@@ -2523,7 +2523,11 @@ int main(void)
 }
 '''
 
-  if cc.links(prog, name: '__crc32cb, __crc32ch, __crc32cw, and __crc32cd 
without -march=armv8-a+crc',
+  # Vendor-supported versions of Windows for AArch64 require at least ARMv8.1,
+  # which is where CRC extension support became mandatory.  Thus, use it
+  # unconditionally on MSVC/AArch64.
+  if (host_cpu == 'aarch64' and cc.get_id() == 'msvc') or \
+        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 7f8f566bd40..20badae8e41 100644
--- a/src/include/storage/s_lock.h
+++ b/src/include/storage/s_lock.h
@@ -602,13 +602,24 @@ 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 defined(_WIN64)
+#ifdef _M_ARM64
+static __forceinline void
+spin_delay(void)
+{
+       /*
+        * Research indicates ISB is better than __yield() on AArch64.  See
+        * 
https://postgr.es/m/1c2a29b8-5b1e-44f7-a871-71ec5fefc120%40app.fastmail.com.
+        */
+       __isb(_ARM64_BARRIER_SY);
+}
+#elif defined(_WIN64)
 static __forceinline void
 spin_delay(void)
 {
+       /*
+        * If using Visual C++ on Win64, inline assembly is unavailable.
+        * Use a _mm_pause intrinsic instead of rep nop.
+        */
        _mm_pause();
 }
 #else
@@ -621,12 +632,21 @@ spin_delay(void)
 #endif
 
 #include <intrin.h>
-#pragma intrinsic(_ReadWriteBarrier)
 
+#ifdef _M_ARM64
+
+/* _ReadWriteBarrier() is insufficient on non-TSO architectures. */
+#pragma intrinsic(_InterlockedExchange)
+#define S_UNLOCK(lock) _InterlockedExchange(lock, 0)
+
+#else
+
+#pragma intrinsic(_ReadWriteBarrier)
 #define S_UNLOCK(lock) \
        do { _ReadWriteBarrier(); (*(lock)) = 0; } while (0)
 
 #endif
+#endif
 
 
 #endif /* !defined(HAS_TEST_AND_SET) */
diff --git a/src/port/pg_crc32c_armv8.c b/src/port/pg_crc32c_armv8.c
index 5ba070bb99d..e49b383b26a 100644
--- a/src/port/pg_crc32c_armv8.c
+++ b/src/port/pg_crc32c_armv8.c
@@ -14,7 +14,11 @@
  */
 #include "c.h"
 
+#ifdef _MSC_VER
+#include <intrin.h>
+#else
 #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 868aad51b09..c92c94c4775 100644
--- a/src/tools/msvc_gendef.pl
+++ b/src/tools/msvc_gendef.pl
@@ -118,9 +118,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.
@@ -141,7 +141,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"
@@ -158,7 +158,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;
 
-- 
2.39.5 (Apple Git-154)

Reply via email to