public inbox for [email protected]  
help / color / mirror / Atom feed
From: Niyas Sait <[email protected]>
To: Michael Paquier <[email protected]>
To: Andres Freund <[email protected]>
Cc: Ian Lawrence Barwick <[email protected]>
Cc: Tom Lane <[email protected]>
Cc: Thomas Munro <[email protected]>
Cc: Julien Rouhaud <[email protected]>
Cc: PostgreSQL Hackers <[email protected]>
Subject: Re: [PATCH] Add native windows on arm64 support
Date: Thu, 1 Dec 2022 17:53:47 +0000
Message-ID: <[email protected]> (raw)
In-Reply-To: <[email protected]>
References: <[email protected]>
	<[email protected]>
	<[email protected]>
	<[email protected]>
	<Yw/9pgS35urJZu/[email protected]>
	<[email protected]>
	<[email protected]>
	<CAB8KJ=jEZZa=2sgtpjq4raTaqh3vxx5GFFKWF=OZFHo6vp0cGg@mail.gmail.com>
	<CAFPTBD8CCT9BNdQQ0QELoo7HPqx26_Zkn0jxg9F9u+bPz-jnEg@mail.gmail.com>
	<[email protected]>
	<[email protected]>
	<[email protected]>

Hello,

I've attached a new revision of the patch (v4) and includes following 
changes,

1. Add support for meson build system
2. Extend MSVC scripts to handle ARM64 platform.
3. Add arm64 definition of spin_delay function.
4. Exclude arm_acle.h import with MSVC compiler.

V3->V4: Add support for meson build system
V2->V3: Removed ASLR enablement and rebased on master.
V1->V2: Rebased on top of master

-- 
Niyas
From 872f538f6261b36a32cbcecae82e99778b747799 Mon Sep 17 00:00:00 2001
From: Niyas Sait <[email protected]>
Date: Tue, 22 Feb 2022 13:07:24 +0000
Subject: [PATCH v4] Enable postgres native build for windows-arm64 platform

Following changes are included

- Extend MSVC scripts to handle ARM64 platform
- Add arm64 definition of spin_delay function
- Exclude arm_acle.h import for MSVC
- Add support for meson build
---
 meson.build                      | 33 +++++++++++++++++++-------------
 src/include/storage/s_lock.h     | 10 +++++++++-
 src/port/pg_crc32c_armv8.c       |  2 ++
 src/tools/msvc/MSBuildProject.pm | 16 ++++++++++++----
 src/tools/msvc/Mkvcbuild.pm      |  9 +++++++--
 src/tools/msvc/Solution.pm       | 11 ++++++++---
 src/tools/msvc/gendef.pl         |  8 ++++----
 7 files changed, 62 insertions(+), 27 deletions(-)

diff --git a/meson.build b/meson.build
index 725e10d815..e354ad7650 100644
--- a/meson.build
+++ b/meson.build
@@ -1944,7 +1944,13 @@ int main(void)
 
 elif host_cpu == 'arm' or host_cpu == 'aarch64'
 
-  prog = '''
+  if cc.get_id() == 'msvc'
+    cdata.set('USE_ARMV8_CRC32C', false)
+    cdata.set('USE_ARMV8_CRC32C_WITH_RUNTIME_CHECK', 1)
+    have_optimized_crc = true
+  else
+
+    prog = '''
 #include <arm_acle.h>
 
 int main(void)
@@ -1960,18 +1966,19 @@ int main(void)
 }
 '''
 
-  if 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)
-    have_optimized_crc = true
-  elif cc.links(prog, name: '__crc32cb, __crc32ch, __crc32cw, and __crc32cd with -march=armv8-a+crc',
-      args: test_c_args + ['-march=armv8-a+crc'])
-    # Use ARM CRC Extension, with runtime check
-    cflags_crc += '-march=armv8-a+crc'
-    cdata.set('USE_ARMV8_CRC32C', false)
-    cdata.set('USE_ARMV8_CRC32C_WITH_RUNTIME_CHECK', 1)
-    have_optimized_crc = true
+    if 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)
+      have_optimized_crc = true
+    elif cc.links(prog, name: '__crc32cb, __crc32ch, __crc32cw, and __crc32cd with -march=armv8-a+crc',
+        args: test_c_args + ['-march=armv8-a+crc'])
+      # Use ARM CRC Extension, with runtime check
+      cflags_crc += '-march=armv8-a+crc'
+      cdata.set('USE_ARMV8_CRC32C', false)
+      cdata.set('USE_ARMV8_CRC32C_WITH_RUNTIME_CHECK', 1)
+      have_optimized_crc = true
+    endif
   endif
 endif
 
diff --git a/src/include/storage/s_lock.h b/src/include/storage/s_lock.h
index 8b19ab160f..bf6a6dba35 100644
--- a/src/include/storage/s_lock.h
+++ b/src/include/storage/s_lock.h
@@ -708,13 +708,21 @@ 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.
+ * Use _mm_pause (x64) or __isb(arm64) intrinsic instead of rep nop.
  */
 #if defined(_WIN64)
 static __forceinline void
 spin_delay(void)
 {
+#ifdef _M_ARM64
+	/*
+	 * arm64 way of hinting processor for spin loops optimisations
+	 * ref: https://community.arm.com/support-forums/f/infrastructure-solutions-forum/48654/ssetoneon-faq
+	*/
+	__isb(_ARM64_BARRIER_SY);
+#else
 	_mm_pause();
+#endif
 }
 #else
 static __forceinline void
diff --git a/src/port/pg_crc32c_armv8.c b/src/port/pg_crc32c_armv8.c
index 9e301f96f6..981718752f 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/MSBuildProject.pm b/src/tools/msvc/MSBuildProject.pm
index 58590fdac2..274ddc8860 100644
--- a/src/tools/msvc/MSBuildProject.pm
+++ b/src/tools/msvc/MSBuildProject.pm
@@ -310,10 +310,18 @@ sub WriteItemDefinitionGroup
 	  : ($self->{type} eq "dll" ? 'DynamicLibrary' : 'StaticLibrary');
 	my $libs = $self->GetAdditionalLinkerDependencies($cfgname, ';');
 
-	my $targetmachine =
-	  $self->{platform} eq 'Win32' ? 'MachineX86' : 'MachineX64';
-	my $arch =
-	  $self->{platform} eq 'Win32' ? 'x86' : 'x86_64';
+	my $targetmachine;
+	my $arch;
+	if ($self->{platform} eq 'Win32') {
+		$targetmachine = 'MachineX86';
+		$arch = 'x86';
+	} elsif ($self->{platform} eq 'ARM64'){
+		$targetmachine = 'MachineARM64';
+		$arch = 'aarch64';
+	} else {
+		$targetmachine = 'MachineX64';
+		$arch = 'x86_64';
+	}
 
 	my $includes = join ';', @{ $self->{includes} }, "";
 
diff --git a/src/tools/msvc/Mkvcbuild.pm b/src/tools/msvc/Mkvcbuild.pm
index 7e52e9ad0a..c6e8e91f5f 100644
--- a/src/tools/msvc/Mkvcbuild.pm
+++ b/src/tools/msvc/Mkvcbuild.pm
@@ -123,8 +123,13 @@ sub mkvcbuild
 
 	if ($vsVersion >= '9.00')
 	{
-		push(@pgportfiles, 'pg_crc32c_sse42_choose.c');
-		push(@pgportfiles, 'pg_crc32c_sse42.c');
+		if ($solution->{platform} eq 'ARM64') {
+			push(@pgportfiles, 'pg_crc32c_armv8_choose.c');
+			push(@pgportfiles, 'pg_crc32c_armv8.c');
+		} else {
+			push(@pgportfiles, 'pg_crc32c_sse42_choose.c');
+			push(@pgportfiles, 'pg_crc32c_sse42.c');
+		}
 		push(@pgportfiles, 'pg_crc32c_sb8.c');
 	}
 	else
diff --git a/src/tools/msvc/Solution.pm b/src/tools/msvc/Solution.pm
index c2acb58df0..891b7c5f5a 100644
--- a/src/tools/msvc/Solution.pm
+++ b/src/tools/msvc/Solution.pm
@@ -67,8 +67,13 @@ sub DeterminePlatform
 		# Examine CL help output to determine if we are in 32 or 64-bit mode.
 		my $output = `cl /help 2>&1`;
 		$? >> 8 == 0 or die "cl command not found";
-		$self->{platform} =
-		  ($output =~ /^\/favor:<.+AMD64/m) ? 'x64' : 'Win32';
+		if ($output =~ /^\/favor:<.+AMD64/m) {
+			$self->{platform} = 'x64';
+		} elsif($output =~ /for ARM64$/m) {
+			$self->{platform} = 'ARM64';
+		} else {
+			$self->{platform} = 'Win32';
+		}
 	}
 	else
 	{
@@ -423,7 +428,7 @@ sub GenerateFiles
 		STDC_HEADERS                        => 1,
 		STRERROR_R_INT                      => undef,
 		USE_ARMV8_CRC32C                    => undef,
-		USE_ARMV8_CRC32C_WITH_RUNTIME_CHECK => undef,
+		USE_ARMV8_CRC32C_WITH_RUNTIME_CHECK => 1,
 		USE_ASSERT_CHECKING => $self->{options}->{asserts} ? 1 : undef,
 		USE_BONJOUR         => undef,
 		USE_BSD_AUTH        => undef,
diff --git a/src/tools/msvc/gendef.pl b/src/tools/msvc/gendef.pl
index d6bed1ce15..ad1cf86ebd 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 ne "x86");
 
 		# 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: 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;
 
-- 
2.38.1



Attachments:

  [text/plain] v4-0001-Enable-postgres-native-build-for-windows-arm64-pl.patch (7.4K, ../[email protected]/2-v4-0001-Enable-postgres-native-build-for-windows-arm64-pl.patch)
  download | inline diff:
From 872f538f6261b36a32cbcecae82e99778b747799 Mon Sep 17 00:00:00 2001
From: Niyas Sait <[email protected]>
Date: Tue, 22 Feb 2022 13:07:24 +0000
Subject: [PATCH v4] Enable postgres native build for windows-arm64 platform

Following changes are included

- Extend MSVC scripts to handle ARM64 platform
- Add arm64 definition of spin_delay function
- Exclude arm_acle.h import for MSVC
- Add support for meson build
---
 meson.build                      | 33 +++++++++++++++++++-------------
 src/include/storage/s_lock.h     | 10 +++++++++-
 src/port/pg_crc32c_armv8.c       |  2 ++
 src/tools/msvc/MSBuildProject.pm | 16 ++++++++++++----
 src/tools/msvc/Mkvcbuild.pm      |  9 +++++++--
 src/tools/msvc/Solution.pm       | 11 ++++++++---
 src/tools/msvc/gendef.pl         |  8 ++++----
 7 files changed, 62 insertions(+), 27 deletions(-)

diff --git a/meson.build b/meson.build
index 725e10d815..e354ad7650 100644
--- a/meson.build
+++ b/meson.build
@@ -1944,7 +1944,13 @@ int main(void)
 
 elif host_cpu == 'arm' or host_cpu == 'aarch64'
 
-  prog = '''
+  if cc.get_id() == 'msvc'
+    cdata.set('USE_ARMV8_CRC32C', false)
+    cdata.set('USE_ARMV8_CRC32C_WITH_RUNTIME_CHECK', 1)
+    have_optimized_crc = true
+  else
+
+    prog = '''
 #include <arm_acle.h>
 
 int main(void)
@@ -1960,18 +1966,19 @@ int main(void)
 }
 '''
 
-  if 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)
-    have_optimized_crc = true
-  elif cc.links(prog, name: '__crc32cb, __crc32ch, __crc32cw, and __crc32cd with -march=armv8-a+crc',
-      args: test_c_args + ['-march=armv8-a+crc'])
-    # Use ARM CRC Extension, with runtime check
-    cflags_crc += '-march=armv8-a+crc'
-    cdata.set('USE_ARMV8_CRC32C', false)
-    cdata.set('USE_ARMV8_CRC32C_WITH_RUNTIME_CHECK', 1)
-    have_optimized_crc = true
+    if 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)
+      have_optimized_crc = true
+    elif cc.links(prog, name: '__crc32cb, __crc32ch, __crc32cw, and __crc32cd with -march=armv8-a+crc',
+        args: test_c_args + ['-march=armv8-a+crc'])
+      # Use ARM CRC Extension, with runtime check
+      cflags_crc += '-march=armv8-a+crc'
+      cdata.set('USE_ARMV8_CRC32C', false)
+      cdata.set('USE_ARMV8_CRC32C_WITH_RUNTIME_CHECK', 1)
+      have_optimized_crc = true
+    endif
   endif
 endif
 
diff --git a/src/include/storage/s_lock.h b/src/include/storage/s_lock.h
index 8b19ab160f..bf6a6dba35 100644
--- a/src/include/storage/s_lock.h
+++ b/src/include/storage/s_lock.h
@@ -708,13 +708,21 @@ 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.
+ * Use _mm_pause (x64) or __isb(arm64) intrinsic instead of rep nop.
  */
 #if defined(_WIN64)
 static __forceinline void
 spin_delay(void)
 {
+#ifdef _M_ARM64
+	/*
+	 * arm64 way of hinting processor for spin loops optimisations
+	 * ref: https://community.arm.com/support-forums/f/infrastructure-solutions-forum/48654/ssetoneon-faq
+	*/
+	__isb(_ARM64_BARRIER_SY);
+#else
 	_mm_pause();
+#endif
 }
 #else
 static __forceinline void
diff --git a/src/port/pg_crc32c_armv8.c b/src/port/pg_crc32c_armv8.c
index 9e301f96f6..981718752f 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/MSBuildProject.pm b/src/tools/msvc/MSBuildProject.pm
index 58590fdac2..274ddc8860 100644
--- a/src/tools/msvc/MSBuildProject.pm
+++ b/src/tools/msvc/MSBuildProject.pm
@@ -310,10 +310,18 @@ sub WriteItemDefinitionGroup
 	  : ($self->{type} eq "dll" ? 'DynamicLibrary' : 'StaticLibrary');
 	my $libs = $self->GetAdditionalLinkerDependencies($cfgname, ';');
 
-	my $targetmachine =
-	  $self->{platform} eq 'Win32' ? 'MachineX86' : 'MachineX64';
-	my $arch =
-	  $self->{platform} eq 'Win32' ? 'x86' : 'x86_64';
+	my $targetmachine;
+	my $arch;
+	if ($self->{platform} eq 'Win32') {
+		$targetmachine = 'MachineX86';
+		$arch = 'x86';
+	} elsif ($self->{platform} eq 'ARM64'){
+		$targetmachine = 'MachineARM64';
+		$arch = 'aarch64';
+	} else {
+		$targetmachine = 'MachineX64';
+		$arch = 'x86_64';
+	}
 
 	my $includes = join ';', @{ $self->{includes} }, "";
 
diff --git a/src/tools/msvc/Mkvcbuild.pm b/src/tools/msvc/Mkvcbuild.pm
index 7e52e9ad0a..c6e8e91f5f 100644
--- a/src/tools/msvc/Mkvcbuild.pm
+++ b/src/tools/msvc/Mkvcbuild.pm
@@ -123,8 +123,13 @@ sub mkvcbuild
 
 	if ($vsVersion >= '9.00')
 	{
-		push(@pgportfiles, 'pg_crc32c_sse42_choose.c');
-		push(@pgportfiles, 'pg_crc32c_sse42.c');
+		if ($solution->{platform} eq 'ARM64') {
+			push(@pgportfiles, 'pg_crc32c_armv8_choose.c');
+			push(@pgportfiles, 'pg_crc32c_armv8.c');
+		} else {
+			push(@pgportfiles, 'pg_crc32c_sse42_choose.c');
+			push(@pgportfiles, 'pg_crc32c_sse42.c');
+		}
 		push(@pgportfiles, 'pg_crc32c_sb8.c');
 	}
 	else
diff --git a/src/tools/msvc/Solution.pm b/src/tools/msvc/Solution.pm
index c2acb58df0..891b7c5f5a 100644
--- a/src/tools/msvc/Solution.pm
+++ b/src/tools/msvc/Solution.pm
@@ -67,8 +67,13 @@ sub DeterminePlatform
 		# Examine CL help output to determine if we are in 32 or 64-bit mode.
 		my $output = `cl /help 2>&1`;
 		$? >> 8 == 0 or die "cl command not found";
-		$self->{platform} =
-		  ($output =~ /^\/favor:<.+AMD64/m) ? 'x64' : 'Win32';
+		if ($output =~ /^\/favor:<.+AMD64/m) {
+			$self->{platform} = 'x64';
+		} elsif($output =~ /for ARM64$/m) {
+			$self->{platform} = 'ARM64';
+		} else {
+			$self->{platform} = 'Win32';
+		}
 	}
 	else
 	{
@@ -423,7 +428,7 @@ sub GenerateFiles
 		STDC_HEADERS                        => 1,
 		STRERROR_R_INT                      => undef,
 		USE_ARMV8_CRC32C                    => undef,
-		USE_ARMV8_CRC32C_WITH_RUNTIME_CHECK => undef,
+		USE_ARMV8_CRC32C_WITH_RUNTIME_CHECK => 1,
 		USE_ASSERT_CHECKING => $self->{options}->{asserts} ? 1 : undef,
 		USE_BONJOUR         => undef,
 		USE_BSD_AUTH        => undef,
diff --git a/src/tools/msvc/gendef.pl b/src/tools/msvc/gendef.pl
index d6bed1ce15..ad1cf86ebd 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 ne "x86");
 
 		# 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: 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;
 
-- 
2.38.1



view thread (90+ messages)  latest in thread

reply

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Reply to all the recipients using the --to and --cc options:
  reply via email

  To: [email protected]
  Cc: [email protected], [email protected], [email protected], [email protected], [email protected], [email protected], [email protected], [email protected]
  Subject: Re: [PATCH] Add native windows on arm64 support
  In-Reply-To: <[email protected]>

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

This inbox is served by agora; see mirroring instructions
for how to clone and mirror all data and code used for this inbox