Sorry for the noise. I discovered that this patch originated in another thread [0], so I spent some time updating the attributions. Please let me know if there are any inaccuracies.
On Tue, Dec 16, 2025 at 12:07:34PM -0600, Nathan Bossart wrote: > 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. Hm. I think the USE_LLVM_BACKPORT_SECTION_MEMORY_MANAGER thing might need work, too. We don't have any Windows buildfarm machines with LLVM enabled, but IIUC it should be possible. Perhaps we can add that to unicorn. > 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. Actually, I'm not sure there's anything specific to Windows 11 in this patch, besides perhaps the choice to set USE_ARMV8_CRC32C unconditionally. I don't know how likely it is that someone will try to run Postgres on Windows on an AArch64 machine without CRC extension support, though. [0] https://postgr.es/m/CAFPTBD-74%2BAEuN9n7caJ0YUnW5A0r-KBX8rYoEJWqFPgLKpzdg%40mail.gmail.com -- nathan
>From b335f9712ce23fc4d3ed71bf28aa556d1d940b9c Mon Sep 17 00:00:00 2001 From: Nathan Bossart <[email protected]> Date: Tue, 16 Dec 2025 15:30:53 -0600 Subject: [PATCH v13 1/1] Add support for building with MSVC for 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(). The existing implementation for MSVC 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., atomics/arch-arm.h, simd.h, pg_popcount_aarch64.c), but those can be dealt with later. Author: Niyas Sait <[email protected]> Co-authored-by: Greg Burd <[email protected]> Co-authored-by: Dave Cramer <[email protected]> Reviewed-by: Michael Paquier <[email protected]> Reviewed-by: John Naylor <[email protected]> Reviewed-by: Peter Eisentraut <[email protected]> Reviewed-by: Andres Freund <[email protected]> Reviewed-by: Thomas Munro <[email protected]> Tested-by: Andrew Dunstan <[email protected]> Discussion: https://postgr.es/m/A6152C7C-F5E3-4958-8F8E-7692D259FF2F%40greg.burd.me Discussion: https://postgr.es/m/CAFPTBD-74%2BAEuN9n7caJ0YUnW5A0r-KBX8rYoEJWqFPgLKpzdg%40mail.gmail.com --- 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)
