v1-0001-Address-build-issues-for-ARM64-using-MSVC.patch
application/octet-stream
Filename: v1-0001-Address-build-issues-for-ARM64-using-MSVC.patch
Type: application/octet-stream
Part: 0
From b245143d7c6afa23e341ac69d5377083ccaf0edd Mon Sep 17 00:00:00 2001
From: Dave Cramer <davecramer@gmail.com>
Date: Sun, 13 Jul 2025 06:33:17 -0400
Subject: [PATCH v1 1/2] Address build issues for ARM64 using MSVC
This patch adds support for the ARM64 architecture on Windows 11
and includes work that enables building with MSVC. This patch also
includes a new intrinsic for spin_delay that is platform specific.
---
doc/src/sgml/installation.sgml | 2 +-
meson.build | 11 +++++++++--
src/include/storage/s_lock.h | 20 ++++++++++++++++++--
src/port/pg_crc32c_armv8.c | 2 ++
src/tools/msvc_gendef.pl | 8 ++++----
5 files changed, 34 insertions(+), 9 deletions(-)
diff --git a/doc/src/sgml/installation.sgml b/doc/src/sgml/installation.sgml
index 593202f4fb2..1cddb047a9f 100644
--- a/doc/src/sgml/installation.sgml
+++ b/doc/src/sgml/installation.sgml
@@ -3967,7 +3967,7 @@ 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 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 c1e17aa3040..cb572927319 100644
--- a/meson.build
+++ b/meson.build
@@ -1663,7 +1663,7 @@ endif
zlibopt = get_option('zlib')
zlib = not_found_dep
if not zlibopt.disabled()
- zlib_t = dependency('zlib', required: zlibopt)
+ zlib_t = dependency('zlib', method : 'pkg-config', required: zlibopt)
if zlib_t.type_name() == 'internal'
# if fallback was used, we don't need to test if headers are present (they
@@ -2494,6 +2494,9 @@ int main(void)
elif host_cpu == 'arm' or host_cpu == 'aarch64'
prog = '''
+#ifdef _MSC_VER
+#include <intrin.h>
+#else
#include <arm_acle.h>
unsigned int crc;
@@ -2509,7 +2512,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 7f8f566bd40..be7aaf6b013 100644
--- a/src/include/storage/s_lock.h
+++ b/src/include/storage/s_lock.h
@@ -602,15 +602,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 5ba070bb99d..6a155ddde1e 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 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.52.0.windows.1