From 872f538f6261b36a32cbcecae82e99778b747799 Mon Sep 17 00:00:00 2001 From: Niyas Sait 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 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 +#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 --deffile --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