Skip to content

Support targeting Windows on ARM64 with MSVC - #143

Closed
sebgod wants to merge 1 commit into
Mercury-Language:masterfrom
sebgod:support-msvc-arm64
Closed

Support targeting Windows on ARM64 with MSVC#143
sebgod wants to merge 1 commit into
Mercury-Language:masterfrom
sebgod:support-msvc-arm64

Conversation

@sebgod

@sebgod sebgod commented Apr 24, 2026

Copy link
Copy Markdown
Contributor

Extend the MSVC port to cover ARM64 (aarch64) in addition to x86 and x64.

Detect _M_ARM64 at configure time, add a cc_cl_arm64 constructor to
the c_compiler_type type in compiler/globals.m, and thread it through
every site that already pattern-matches on cc_cl_x86/cc_cl_x64 in the
compiler. In get_restricted_command_line_link_opts_for_c, add an arm64
case that passes -machine:arm64 to the linker. Map msvc_arm64 to
BOEHM_WINDOWS_CPU_TYPE=ARM64 so the bundled Boehm GC is built with
CPU=ARM64.

Depends on Mercury-Language/bdwgc#3 — the boehm_gc submodule pointer
bump in this PR relies on that NT_MAKEFILE change to land first on
release-8_2-mercury.

Documentation/README.MS-VisualC.md and NEWS.md are updated. The
expected output in tests/warnings/help_text.err_exp is updated to
include the new msvc_arm64 value in the --c-compiler-type help.

@juliensf

Copy link
Copy Markdown
Member

The compiler changes look fine. I suggest merging the two MSVC-related NEWS entries into a single entry.
We will need to sort out the Boehm GC side of things before merging this one.

@sebgod

sebgod commented Apr 25, 2026

Copy link
Copy Markdown
Contributor Author

The compiler changes look fine. I suggest merging the two MSVC-related NEWS entries into a single entry. We will need to sort out the Boehm GC side of things before merging this one.

Hey I wanted to send out these PRs on the mailing list as well but didn't get to it before you spotted this PR? Re: Boehm GC, you think this is change: Mercury-Language/bdwgc#3 is not sufficient? It has been a while since I dabbled with this, in the process of building this on my Surface with a Snapdragon X

@sebgod

sebgod commented Apr 25, 2026

Copy link
Copy Markdown
Contributor Author

when I tried to build the latest ROTD with msys2 and clang arm64 I got the following error:

make[2]: Entering directory '/c/Users/SebastianGodelet/source/repos/sebgod/mercury-srcdist-rotd-2026-04-23/trace'
../scripts/mgnuc --grade hlc.gc.pregen    --c-debug   --      -c mercury_event_spec.c -o mercury_event_spec.o
../scripts/mgnuc --grade hlc.gc.pregen    --c-debug   --      -c mercury_event_parser.c -o mercury_event_parser.o
../scripts/mgnuc --grade hlc.gc.pregen    --c-debug   --      -c mercury_event_scanner.c -o mercury_event_scanner.o
../scripts/mgnuc --grade hlc.gc.pregen    --c-debug   --      -c mercury_trace.c -o mercury_trace.o
../scripts/mgnuc --grade hlc.gc.pregen    --c-debug   --      -c mercury_trace_alias.c -o mercury_trace_alias.o
../scripts/mgnuc --grade hlc.gc.pregen    --c-debug   --      -c mercury_trace_browse.c -o mercury_trace_browse.o
../scripts/mgnuc --grade hlc.gc.pregen    --c-debug   --      -c mercury_trace_cmd_backward.c -o mercury_trace_cmd_backward.o
../scripts/mgnuc --grade hlc.gc.pregen    --c-debug   --      -c mercury_trace_cmd_breakpoint.c -o mercury_trace_cmd_breakpoint.o
../scripts/mgnuc --grade hlc.gc.pregen    --c-debug   --      -c mercury_trace_cmd_browsing.c -o mercury_trace_cmd_browsing.o
../scripts/mgnuc --grade hlc.gc.pregen    --c-debug   --      -c mercury_trace_cmd_dd.c -o mercury_trace_cmd_dd.o
../scripts/mgnuc --grade hlc.gc.pregen    --c-debug   --      -c mercury_trace_cmd_developer.c -o mercury_trace_cmd_developer.o
../scripts/mgnuc --grade hlc.gc.pregen    --c-debug   --      -c mercury_trace_cmd_exp.c -o mercury_trace_cmd_exp.o
../scripts/mgnuc --grade hlc.gc.pregen    --c-debug   --      -c mercury_trace_cmd_forward.c -o mercury_trace_cmd_forward.o
../scripts/mgnuc --grade hlc.gc.pregen    --c-debug   --      -c mercury_trace_cmd_help.c -o mercury_trace_cmd_help.o
../scripts/mgnuc --grade hlc.gc.pregen    --c-debug   --      -c mercury_trace_cmd_misc.c -o mercury_trace_cmd_misc.o
../scripts/mgnuc --grade hlc.gc.pregen    --c-debug   --      -c mercury_trace_cmd_parameter.c -o mercury_trace_cmd_parameter.o
../scripts/mgnuc --grade hlc.gc.pregen    --c-debug   --      -c mercury_trace_cmd_queries.c -o mercury_trace_cmd_queries.o
../scripts/mgnuc --grade hlc.gc.pregen    --c-debug   --      -c mercury_trace_cmd_table_io.c -o mercury_trace_cmd_table_io.o
../scripts/mgnuc --grade hlc.gc.pregen    --c-debug   --      -c mercury_trace_command_queue.c -o mercury_trace_command_queue.o
../scripts/mgnuc --grade hlc.gc.pregen    --c-debug   --      -c mercury_trace_completion.c -o mercury_trace_completion.o
../scripts/mgnuc --grade hlc.gc.pregen    --c-debug   --      -c mercury_trace_declarative.c -o mercury_trace_declarative.o
../scripts/mgnuc --grade hlc.gc.pregen    --c-debug   --      -c mercury_trace_external.c -o mercury_trace_external.o
../scripts/mgnuc --grade hlc.gc.pregen    --c-debug   --      -c mercury_trace_help.c -o mercury_trace_help.o
../scripts/mgnuc --grade hlc.gc.pregen    --c-debug   --      -c mercury_trace_hold_vars.c -o mercury_trace_hold_vars.o
../scripts/mgnuc --grade hlc.gc.pregen    --c-debug   --      -c mercury_trace_internal.c -o mercury_trace_internal.o
../scripts/mgnuc --grade hlc.gc.pregen    --c-debug   --      -c mercury_trace_readline.c -o mercury_trace_readline.o
../scripts/mgnuc --grade hlc.gc.pregen    --c-debug   --      -c mercury_trace_source.c -o mercury_trace_source.o
mercury_trace_readline.c:62:9: error: use of undeclared identifier 'rl_instream'
   62 |         rl_instream = in;
      |         ^~~~~~~~~~~
mercury_trace_readline.c:63:9: error: use of undeclared identifier 'rl_outstream'
   63 |         rl_outstream = out;
      |         ^~~~~~~~~~~~
mercury_trace_readline.c:77:13: error: use of undeclared identifier 'rl_prep_term_function'
   77 |             rl_prep_term_function = (void *) MR_dummy_prep_term_function;
      |             ^~~~~~~~~~~~~~~~~~~~~
mercury_trace_readline.c:78:13: error: use of undeclared identifier 'rl_deprep_term_function'
   78 |             rl_deprep_term_function = (void *) MR_dummy_deprep_term_function;
      |             ^~~~~~~~~~~~~~~~~~~~~~~
4 errors generated.
make[2]: *** [/tmp/mmake.B3M9up:1462: mercury_trace_readline.o] Error 1

should try gcc instead as a follow up

@juliensf

juliensf commented Apr 25, 2026

Copy link
Copy Markdown
Member

when I tried to build the latest ROTD with msys2 and clang arm64 I got the following error:

...

mercury_trace_readline.c:62:9: error: use of undeclared identifier 'rl_instream'
62 | rl_instream = in;
| ^~~~~~~~~~~
mercury_trace_readline.c:63:9: error: use of undeclared identifier 'rl_outstream'
63 | rl_outstream = out;
| ^~~~~~~~~~~~
mercury_trace_readline.c:77:13: error: use of undeclared identifier 'rl_prep_term_function'
77 | rl_prep_term_function = (void *) MR_dummy_prep_term_function;
| ^~~~~~~~~~~~~~~~~~~~~
mercury_trace_readline.c:78:13: error: use of undeclared identifier 'rl_deprep_term_function'
78 | rl_deprep_term_function = (void *) MR_dummy_deprep_term_function;
| ^~~~~~~~~~~~~~~~~~~~~~~
4 errors generated.
make[2]: *** [/tmp/mmake.B3M9up:1462: mercury_trace_readline.o] Error 1

Do you have the mingw-w64-clang-aarch64-readline package installed? If not, it's possible that
the configuration script is seeing the readline installation for the MSYS environment and configure
thinks that readline is present even though it isn't.

@juliensf

Copy link
Copy Markdown
Member

The compiler changes look fine. I suggest merging the two MSVC-related NEWS entries into a single entry. We will need to sort out the Boehm GC side of things before merging this one.

Hey I wanted to send out these PRs on the mailing list as well but didn't get to it before you spotted this PR? Re: Boehm GC, you think this is change: Mercury-Language/bdwgc#3 is not sufficient? It has been a while since I dabbled with this, in the process of building this on my Surface with a Snapdragon X

The Boehm changes look necessary, I can't see whether they are sufficient since I don't have access to and ARM64 system with MSVC. Boehm upstream doesn't seem to support that combination, at the very least upstream NT_MAKEFILE makes no reference to ARM64. Have you tired the collector with ARM64 and MSVC? Did it work?

@sebgod

sebgod commented Apr 27, 2026

Copy link
Copy Markdown
Contributor Author

Thanks missed the readline but, here's output from using msys in MINGW64 shell:

../scripts/mgnuc --grade hlc.gc.pregen       --      -c uint8.c -o uint8.o
uint64.c: In function 'mercury__uint64__det_to_int_1_f_0':
uint64.c:1755:25: error: left shift count >= width of type [-Werror=shift-count-overflow]
 1755 |     mask_for_int = (1UL << 63) - 1;
      |                         ^~
uint64.c: In function 'mercury__uint64__to_int_2_p_0':
uint64.c:1804:25: error: left shift count >= width of type [-Werror=shift-count-overflow]
 1804 |     mask_for_int = (1UL << 63) - 1;
      |                         ^~
cc1.exe: all warnings being treated as errors
make[2]: *** [/tmp/mmake.3l8avs:57746: uint64.o] Error 1

now getting this when trying to build latest ROTD with
./configure --prefix=/c/mercury-rotd-gcc-amd64 --enable-minimal-install

$ gcc -v
Using built-in specs.
COLLECT_GCC=C:\msys64\mingw64\bin\gcc.exe
COLLECT_LTO_WRAPPER=C:/msys64/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/15.2.0/lto-wrapper.exe
Target: x86_64-w64-mingw32
Configured with: ../gcc-15.2.0/configure --prefix=/mingw64 --with-local-prefix=/mingw64/local --libexecdir=/mingw64/lib --enable-bootstrap --enable-checking=release --with-arch=nocona --with-tune=generic --enable-mingw-wildcard --enable-languages=c,lto,c++,fortran,ada,objc,obj-c++,jit --enable-shared --enable-static --enable-libatomic --enable-threads=posix --enable-graphite --enable-fully-dynamic-string --enable-libstdcxx-backtrace=yes --enable-libstdcxx-filesystem-ts --enable-libstdcxx-time --disable-libstdcxx-pch --enable-lto --enable-libgomp --disable-libssp --disable-multilib --disable-rpath --disable-win32-registry --disable-nls --disable-werror --disable-symvers --with-libiconv --with-system-zlib --with-gmp=/mingw64 --with-mpfr=/mingw64 --with-mpc=/mingw64 --with-isl=/mingw64 --with-pkgversion='Rev14, Built by MSYS2 project' --with-bugurl=https://github.com/msys2/MINGW-packages/issues --with-gnu-as --with-gnu-ld --with-libstdcxx-zoneinfo=yes --disable-libstdcxx-debug --enable-plugin --with-boot-ldflags=-static-libstdc++ --with-stage1-ldflags=-static-libstdc++
Thread model: posix
Supported LTO compression algorithms: zlib zstd
gcc version 15.2.0 (Rev14, Built by MSYS2 project)

I think I followed the instructions by the latter but not exactly sure what is going on.
Next try will doing clang64 again but with the readline fix.
Next next try will be building the bootstrap compiler on x64 and copy it over (ARM64 has extensive support for running x64 apps so it should work, but its a stop-gap)

@zsomogyi

Copy link
Copy Markdown
Contributor

The error about shift count clearly indicates a misconfiguration.

That assignment to mask_for_int is guarded by "#if MR_BYTES_PER_WORD == 8"
in library/uint64.m, line 612. Yet the C compiler diagnostic says that the type width
is not 8 bytes/64 bits. It is unclear from that diagnostic whether "the type" it refers to
is the declared type of mark_for_int, which is uint64_t, or the type it assigns to 1UL,
but I suspect it is the latter.

@wangp

wangp commented Apr 27, 2026

Copy link
Copy Markdown
Member

Note that error has been occurring on https://testing.mercurylang.org for a while when cross-compiling with MinGW-w64.

uint64.c:1755:25: error: left shift count >= width of type [-Werror=shift-count-overflow]
uint64.c:1804:25: error: left shift count >= width of type [-Werror=shift-count-overflow]

@opturion-jfischer

Copy link
Copy Markdown

Note that error has been occurring on https://testing.mercurylang.org for a while when cross-compiling with MinGW-w64.

uint64.c:1755:25: error: left shift count >= width of type [-Werror=shift-count-overflow]
uint64.c:1804:25: error: left shift count >= width of type [-Werror=shift-count-overflow]

On 64-bit Windows, unsigned long is a 32-bit quantity. The constant should be UINT64_C(1) rather the 1UL (UINT32_C(1) in the other branch).

@sebgod

sebgod commented Apr 27, 2026

Copy link
Copy Markdown
Contributor Author

okay the clang-arm64 version rotd-2026-04-26 did finish building and installing. (with the readline addition)

@sebgod

sebgod commented Apr 27, 2026

Copy link
Copy Markdown
Contributor Author

okay now make fails I am investigating right now:

MMAKE_DIR=`pwd`/scripts scripts/mmake MMAKEFLAGS= all
make[1]: Entering directory '/c/Users/SebastianGodelet/source/repos/sebgod/mercury'
cd scripts && PATH=../scripts:../util:../mfilterjavac:../../mfilterjavac:$PATH MMAKE_VPATH=. MMAKE_DIR=../scripts DESTDIR= ../scripts/mmake
make[2]: Entering directory '/c/Users/SebastianGodelet/source/repos/sebgod/mercury/scripts'
making test_mdbrc
make[2]: Leaving directory '/c/Users/SebastianGodelet/source/repos/sebgod/mercury/scripts'
cd util && PATH=../scripts:../util:../mfilterjavac:../../mfilterjavac:$PATH MMAKE_VPATH=. MMAKE_DIR=../scripts DESTDIR= ../scripts/mmake  mfiltercc.exe
make[2]: Entering directory '/c/Users/SebastianGodelet/source/repos/sebgod/mercury/util'
make[2]: 'mfiltercc.exe' is up to date.
make[2]: Leaving directory '/c/Users/SebastianGodelet/source/repos/sebgod/mercury/util'
gc_grade=`scripts/ml --grade hlc.gc --print-gc-grade`; \
cd boehm_gc && PATH=../scripts:../util:../mfilterjavac:../../mfilterjavac:$PATH MMAKE_VPATH=. MMAKE_DIR=../scripts DESTDIR= ../scripts/mmake  GC_GRADE=$gc_grade
make[2]: Entering directory '/c/Users/SebastianGodelet/source/repos/sebgod/mercury/boehm_gc'
MAKEFLAGS=""; export MAKEFLAGS; \
nmake -f NT_MAKEFILE cdebug="" nodebug=1 CPU="ARM64" ENABLE_STATIC=1 gc.lib; \
cp gc.lib libgc.lib

Microsoft (R) Program Maintenance Utility Version 14.50.35726.0
Copyright (C) Microsoft Corporation.  All rights reserved.

'gc.lib' is up-to-date
make[2]: Leaving directory '/c/Users/SebastianGodelet/source/repos/sebgod/mercury/boehm_gc'
cd runtime && PATH=../scripts:../util:../mfilterjavac:../../mfilterjavac:$PATH MMAKE_VPATH=. MMAKE_DIR=../scripts DESTDIR= ../scripts/mmake
make[2]: Entering directory '/c/Users/SebastianGodelet/source/repos/sebgod/mercury/runtime'
if test -f mercury_conf.h ; then \
        mv mercury_conf.h mercury_conf.h.was ; \
fi
../config.status --header=mercury_conf.h
config.status: creating mercury_conf.h
# Check to ensure there were no misspelt autoconf variable names.
if grep -n '[^$]@' mercury_conf.h; then false; else true; fi
# Check if we need to update the file, and if yes, do so.
if test -f mercury_conf.h.was -a -f mercury_conf.h.date && \
        cmp mercury_conf.h.was mercury_conf.h > /dev/null ; \
then \
        mv mercury_conf.h.was mercury_conf.h ; \
fi
# Update the datestamp to show that mercury_conf.h is now current,
# even if its modification date is old.
echo datestamp > mercury_conf.h.date ;
../scripts/mgnuc --grade hlc.gc    --c-debug   --       -c mercury.c -Fomercury.obj
 in .mgnuc_opts--no-mercury-stdlib-dir
make[2]: *** [/tmp/mmake.Xc8HAy:1660: mercury.obj] Error 1
make[2]: Leaving directory '/c/Users/SebastianGodelet/source/repos/sebgod/mercury/runtime'
make[1]: *** [/tmp/mmake.JJlShT:1114: runtime] Error 2
make[1]: Leaving directory '/c/Users/SebastianGodelet/source/repos/sebgod/mercury'
make: *** [Makefile:30: all] Error 2

@sebgod

sebgod commented Apr 27, 2026

Copy link
Copy Markdown
Contributor Author

sorry that was the darn core.autocrlf=true, I forgot that they made this the default again

@sebgod

sebgod commented Apr 27, 2026

Copy link
Copy Markdown
Contributor Author

this popped up while building the stdlib:
../scripts/mgnuc --grade hlc.gc -- -c uint64.c -Fouint64.obj
uint64.c
uint64.c(1832): warning C4293: '<<': shift count negative or too big, undefined behavior
uint64.c(1886): warning C4293: '<<': shift count negative or too big, undefined behavior

but getting so far means the gc.lib did build.

@sebgod

sebgod commented Apr 27, 2026

Copy link
Copy Markdown
Contributor Author

yay:

c:/mercury-dev-cl-arm64/bin/mercury --output-cc
cl -std:c11

not yet advanced in the staging but install

@sebgod
sebgod force-pushed the support-msvc-arm64 branch from afe21ee to 4f9f6e4 Compare April 27, 2026 11:40
@sebgod

sebgod commented Apr 27, 2026

Copy link
Copy Markdown
Contributor Author

fix for uint64 is here: #145
I've also updated the NEWS entry as per request @juliensf

Extend the MSVC port to cover ARM64 (aarch64) in addition to x86 and x64.
Detect _M_ARM64 at configure time, add a matching c_compiler_type
constructor, and thread it through every site that already pattern-matches
on cc_cl_x86/cc_cl_x64 in the compiler.

m4/mercury.m4:
    Emit "msvc_arm64" from the C compiler detector when _M_ARM64 is
    defined.

configure.ac:
    Accept msvc_arm64 as a recognised MERCURY_HAVE_MSVC value.
    Map msvc_arm64 to BOEHM_WINDOWS_CPU_TYPE=ARM64 so that the bundled
    Boehm GC is built with CPU=ARM64.

compiler/globals.m:
    Add a cc_cl_arm64/1 constructor to the c_compiler_type type.
    Accept "msvc_arm64" in convert_c_compiler_type_simple and add a
    convert_msvc_arm64_version predicate to handle versioned strings
    of the form msvc_arm64_<MSC_VER>.

compiler/check_options.m:
    Add "msvc_arm64" to the list of valid --c-compiler-type arguments.

compiler/options.m:
    Extend the help text enum for --c-compiler-type to include
    msvc_arm64.

compiler/compile_target_code.m:
compiler/link_target_code.m:
    Extend existing cc_cl_x86/cc_cl_x64 pattern matches to cover
    cc_cl_arm64. In get_restricted_command_line_link_opts_for_c, add
    an arm64 case that passes -machine:arm64 to the linker instead of
    -machine:x86 or -machine:x64.

boehm_gc:
    Bump submodule pointer to pick up the ARM64 branch added to
    NT_MAKEFILE on support-cl-arm64.

Documentation/README.MS-VisualC.md:
    Document ARM64 as a third supported target architecture, including
    the ARM64 Native Tools Command Prompt and the additional Visual
    Studio component that is required.

Documentation/README.MSYS2.md:
    Document the GNU readline dependency. The MSYS environment's
    readline package is visible on the PATH of every other MSYS2
    environment, so configure detects a copy that is not usable for
    linking from UCRT64/MINGW64/MINGW32/CLANG64/CLANGARM64 and the
    build then fails in mercury_trace_readline.c. List the per-
    environment readline package to install via pacman, and note
    --without-readline as an alternative.

NEWS.md:
    Merge the existing x64 announcement and the new ARM64 announcement
    into a single entry that covers both 64-bit MSVC variants.

tests/warnings/help_text.err_exp:
    Update the expected --c-compiler-type enum to include msvc_arm64.

.gitattributes:
    Add a repository-wide line-ending policy ("* text=auto eol=lf",
    plus binary markers for common image and document extensions) so
    that Windows clones with core.autocrlf=true do not rewrite shell
    scripts and option files such as runtime/.mgnuc_opts to CRLF, which
    causes scripts/mgnuc to reject otherwise valid options when reading
    them with `for opt in $(cat .mgnuc_opts)`.
@sebgod
sebgod force-pushed the support-msvc-arm64 branch from 4f9f6e4 to f302bdb Compare April 27, 2026 22:00
@sebgod

sebgod commented Apr 27, 2026

Copy link
Copy Markdown
Contributor Author

okay I've rebased to that fix @juliensf

@sebgod

sebgod commented Apr 28, 2026

Copy link
Copy Markdown
Contributor Author

stage 2 compiler also working okay, did manage to compile itself

@sebgod

sebgod commented Apr 30, 2026

Copy link
Copy Markdown
Contributor Author

Hey @juliensf so Peter updated the bdwgc branch that is configured in the submodule so I believe it should just work now (as it does use the branch and not the commit hash), so this would be ready now

@juliensf

Copy link
Copy Markdown
Member

Thanks, those changes have now been merged.

@juliensf juliensf closed this Apr 30, 2026
@sebgod
sebgod deleted the support-msvc-arm64 branch April 30, 2026 10:06
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants