diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 168fe4b760f5cd0e8de1014e5c4ed873f20599e4..107469465fa423d55fd282b6592bc3af8e734d2f 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -2,7 +2,7 @@ variables: GIT_SSL_NO_VERIFY: "1" # Commit of ghc/ci-images repository from which to pull Docker images - DOCKER_REV: 59da90988f9f3caa36572bf47d5f78704a969dea + DOCKER_REV: 6e9f8f17086e56e83adae4a8a9d63e2fec3cb6c7 # Sequential version number of all cached things. # Bump to invalidate GitLab CI cache. diff --git a/.gitlab/ci.sh b/.gitlab/ci.sh index 33574ac7f11800a71f569e9ca3ee2f6cc3ab8ae6..59b8d09104bfac20b1f503c02f733d08c37f8f4a 100755 --- a/.gitlab/ci.sh +++ b/.gitlab/ci.sh @@ -561,9 +561,17 @@ function install_bindist() { *) read -r -a args <<< "${INSTALL_CONFIGURE_ARGS:-}" + if [[ "${CROSS_TARGET:-no_cross_target}" =~ "mingw" ]]; then + # We suppose that host target = build target. + # By the fact above it is clearly turning out which host value is + # for currently built compiler. + # The fix for #21970 will probably remove this if-branch. + local -r CROSS_HOST_GUESS=$($SHELL ./config.guess) + args+=( "--target=$CROSS_TARGET" "--host=$CROSS_HOST_GUESS" ) + # FIXME: The bindist configure script shouldn't need to be reminded of # the target platform. See #21970. - if [ -n "${CROSS_TARGET:-}" ]; then + elif [ -n "${CROSS_TARGET:-}" ]; then args+=( "--target=$CROSS_TARGET" "--host=$CROSS_TARGET" ) fi @@ -572,7 +580,7 @@ function install_bindist() { "${args[@]+"${args[@]}"}" || fail "bindist configure failed" make_install_destdir "$TOP"/destdir "$instdir" # And check the `--info` of the installed compiler, sometimes useful in CI log. - "$instdir"/bin/ghc --info + "$instdir/bin/${cross_prefix}ghc$exe" --info ;; esac popd @@ -629,8 +637,23 @@ function test_hadrian() { install_bindist _build/bindist/ghc-*/ "$instdir" echo 'main = putStrLn "hello world"' > expected run "$test_compiler" -package ghc "$TOP/.gitlab/hello.hs" -o hello - ${CROSS_EMULATOR:-} ./hello > actual - run diff expected actual + + if [[ "${CROSS_TARGET:-no_cross_target}" =~ "mingw" ]]; then + ${CROSS_EMULATOR:-} ./hello.exe > actual + else + ${CROSS_EMULATOR:-} ./hello > actual + fi + + # We have to use `-w` to make the test more stable across supported + # platforms, i.e. Windows: + # $ cmp expected actual + # differ: byte 30, line 1 + # $ diff expected actual + # 1c1 + # < main = putStrLn "hello world" + # --- + # > main = putStrLn "hello world" + run diff -w expected actual elif [[ -n "${REINSTALL_GHC:-}" ]]; then run_hadrian \ test \ diff --git a/.gitlab/generate-ci/gen_ci.hs b/.gitlab/generate-ci/gen_ci.hs index ed285ca703a050508fa60066cc157284814cb9ff..de041435e7b0aaafe2ca0cac3655f7401b6fa963 100644 --- a/.gitlab/generate-ci/gen_ci.hs +++ b/.gitlab/generate-ci/gen_ci.hs @@ -112,6 +112,7 @@ data Opsys data LinuxDistro = Debian12 + | Debian12Wine | Debian12Riscv | Debian11 | Debian11Js @@ -315,6 +316,7 @@ distroName Debian12 = "deb12" distroName Debian11 = "deb11" distroName Debian11Js = "deb11-emsdk-closure" distroName Debian12Riscv = "deb12-riscv" +distroName Debian12Wine = "deb12-wine" distroName Debian10 = "deb10" distroName Debian9 = "deb9" distroName Fedora33 = "fedora33" @@ -724,6 +726,8 @@ data ValidateRule | IpeData -- ^ Run this job when the "IPE" label is set | TestPrimops -- ^ Run this job when "test-primops" label is set | I386Backend -- ^ Run this job when the "i386" label is set + | WinArm64 -- ^ Run this job when the "aarch64" and "Windows" labels are set together without "LLVM backend" + | WinArm64LLVM -- ^ Run this job when the "aarch64" and "Windows" labels are set together with "LLVM backend" deriving (Show, Ord, Eq) -- | Convert the state of the rule into a string that gitlab understand. @@ -768,6 +772,15 @@ validateRuleString NonmovingGc = labelString "non-moving GC" validateRuleString IpeData = labelString "IPE" validateRuleString TestPrimops = labelString "test-primops" validateRuleString I386Backend = labelString "i386" +validateRuleString WinArm64 = and_all + [ labelString "aarch64" + , labelString "Windows" + ] +validateRuleString WinArm64LLVM = and_all + [ labelString "aarch64" + , labelString "Windows" + , validateRuleString LLVMBackend + ] --------------------------------------------------------------------- -- The Job type @@ -1260,11 +1273,51 @@ cross_jobs = [ make_wasm_jobs wasm_build_config {bignumBackend = Native} , modifyValidateJobs manual $ make_wasm_jobs wasm_build_config {unregisterised = True} + + -- Linux Aarch64 (Wine + FEX + MSYS64) => Windows Aarch64 + , makeWinArmJobs + $ addValidateRule WinArm64 + (validateBuilds AArch64 (Linux Debian12Wine) winAarch64Config) + , makeWinArmJobs + $ addValidateRule WinArm64LLVM + (validateBuilds AArch64 (Linux Debian12Wine) (winAarch64Config {llvmBootstrap = True})) ] where javascriptConfig = (crossConfig "javascript-unknown-ghcjs" (Emulator "js-emulator") (Just "emconfigure")) { bignumBackend = Native } + makeWinArmJobs = modifyJobs + ( -- Cross compiler validate does not need any docs + setVariable "HADRIAN_ARGS" "--docs=none" + . setVariable "AR" (llvm_prefix ++ "llvm-ar") + . setVariable "CC" (llvm_prefix ++ "clang") + . setVariable "CXX" (llvm_prefix ++ "clang++") + . setVariable "NM" (llvm_prefix ++ "nm") + . setVariable "OBJCOPY" (llvm_prefix ++ "objcopy") + . setVariable "OBJDUMP" (llvm_prefix ++ "objdump") + . setVariable "RANLIB" (llvm_prefix ++ "llvm-ranlib") + . setVariable "SIZE" (llvm_prefix ++ "size") + . setVariable "STRINGS" (llvm_prefix ++ "strings") + . setVariable "STRIP" (llvm_prefix ++ "strip") + . setVariable "WindresCmd" (llvm_prefix ++ "windres") + . setVariable "LLVMAS" (llvm_prefix ++ "clang") + . setVariable "LD" (llvm_prefix ++ "ld") + -- Windows target require to make linker merge feature check disabled. + . setVariable "MergeObjsCmd" "" + -- LLVM MinGW Linux Toolchain expects to recieve "aarch64-w64-mingw32" + -- as a triple but we use more common "aarch64-unknown-mingw32". + -- Due of this we need configure ld manually for clang beacause + -- it will use system's ld otherwise when --target will be specified to + -- unexpected triple. + . setVariable "CFLAGS" cflags + . setVariable "CONF_CC_OPTS_STAGE2" cflags + ) where + llvm_prefix = "/opt/llvm-mingw-linux/bin/aarch64-w64-mingw32-" + cflags = "-fuse-ld=" ++ llvm_prefix ++ "ld --rtlib=compiler-rt" + + winAarch64Config = (crossConfig "aarch64-unknown-mingw32" (Emulator "/opt/wine-arm64ec-msys2-deb12/bin/wine") Nothing) + { bignumBackend = Native } + make_wasm_jobs cfg = modifyJobs ( -- See Note [Testing wasm ghci browser mode] @@ -1323,6 +1376,7 @@ platform_mapping = Map.map go combined_result , "x86_64-linux-deb11-cross_aarch64-linux-gnu-validate" , "x86_64-windows-validate" , "aarch64-linux-deb12-validate" + , "aarch64-linux-deb12-wine-int_native-cross_aarch64-unknown-mingw32-validate" , "nightly-x86_64-linux-alpine3_20-wasm-cross_wasm32-wasi-release+host_fully_static+text_simdutf" , "nightly-x86_64-linux-deb11-validate" , "nightly-x86_64-linux-deb12-validate" @@ -1330,6 +1384,7 @@ platform_mapping = Map.map go combined_result , "x86_64-linux-deb12-validate+thread_sanitizer_cmm" , "nightly-aarch64-linux-deb10-validate" , "nightly-aarch64-linux-deb12-validate" + , "nightly-aarch64-linux-deb12-wine-int_native-cross_aarch64-unknown-mingw32-validate" , "nightly-x86_64-linux-alpine3_12-validate" , "nightly-x86_64-linux-deb10-validate" , "nightly-x86_64-linux-fedora33-release" diff --git a/.gitlab/hello.hs b/.gitlab/hello.hs index 4b1c65932ccd33da02ef16fd64f67a324b9983cb..486778c3a414327dc3f711d476403eaa19d3e1c5 100644 --- a/.gitlab/hello.hs +++ b/.gitlab/hello.hs @@ -1,6 +1,5 @@ {-# OPTIONS_GHC -Wall -Wno-missing-fields #-} -import GHC.Unit.Types (stringToUnitId) import GHC hiding (parseModule) import GHC.Data.StringBuffer import GHC.Driver.Config.Parser diff --git a/.gitlab/jobs.yaml b/.gitlab/jobs.yaml index 961d10794d362641a70adb2dd8385a2458a393b2..c26705a754e1a99e7d2a7616ae282f0d0424e250 100644 --- a/.gitlab/jobs.yaml +++ b/.gitlab/jobs.yaml @@ -315,6 +315,168 @@ "TEST_ENV": "aarch64-linux-deb12-validate+llvm" } }, + "aarch64-linux-deb12-wine-int_native-cross_aarch64-unknown-mingw32-validate": { + "after_script": [ + ".gitlab/ci.sh save_cache", + ".gitlab/ci.sh save_test_output", + ".gitlab/ci.sh clean", + "cat ci_timings" + ], + "allow_failure": false, + "artifacts": { + "expire_in": "2 weeks", + "paths": [ + "ghc-aarch64-linux-deb12-wine-int_native-cross_aarch64-unknown-mingw32-validate.tar.xz", + "junit.xml", + "unexpected-test-output.tar.gz" + ], + "reports": { + "junit": "junit.xml" + }, + "when": "always" + }, + "cache": { + "key": "aarch64-linux-deb12-wine-$CACHE_REV", + "paths": [ + "cabal-cache", + "toolchain" + ] + }, + "dependencies": [], + "image": "registry.gitlab.haskell.org/ghc/ci-images/aarch64-linux-deb12-wine:$DOCKER_REV", + "needs": [ + { + "artifacts": false, + "job": "hadrian-ghc-in-ghci" + } + ], + "rules": [ + { + "if": "((($ONLY_JOBS) && ($ONLY_JOBS =~ /.*\\baarch64-linux-deb12-wine-int_native-cross_aarch64-unknown-mingw32-validate(\\s|$).*/)) || (($ONLY_JOBS == null) && ((($CI_MERGE_REQUEST_LABELS =~ /.*full-ci.*/) || ($CI_MERGE_REQUEST_LABELS =~ /.*marge_bot_batch_merge_job.*/) || ($CI_COMMIT_BRANCH == \"master\") || ($CI_COMMIT_BRANCH =~ /ghc-[0-9]+\\.[0-9]+/)) || (($CI_MERGE_REQUEST_LABELS =~ /.*aarch64.*/) && ($CI_MERGE_REQUEST_LABELS =~ /.*Windows.*/))))) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY == null)", + "when": "on_success" + } + ], + "script": [ + "sudo chown ghc:ghc -R .", + ".gitlab/ci.sh setup", + ".gitlab/ci.sh configure", + ".gitlab/ci.sh build_hadrian", + ".gitlab/ci.sh test_hadrian" + ], + "stage": "full-build", + "tags": [ + "aarch64-linux" + ], + "variables": { + "AR": "/opt/llvm-mingw-linux/bin/aarch64-w64-mingw32-llvm-ar", + "BIGNUM_BACKEND": "native", + "BIN_DIST_NAME": "ghc-aarch64-linux-deb12-wine-int_native-cross_aarch64-unknown-mingw32-validate", + "BUILD_FLAVOUR": "validate", + "CC": "/opt/llvm-mingw-linux/bin/aarch64-w64-mingw32-clang", + "CFLAGS": "-fuse-ld=/opt/llvm-mingw-linux/bin/aarch64-w64-mingw32-ld --rtlib=compiler-rt", + "CONFIGURE_ARGS": "--with-intree-gmp --enable-strict-ghc-toolchain-check", + "CONF_CC_OPTS_STAGE2": "-fuse-ld=/opt/llvm-mingw-linux/bin/aarch64-w64-mingw32-ld --rtlib=compiler-rt", + "CROSS_EMULATOR": "/opt/wine-arm64ec-msys2-deb12/bin/wine", + "CROSS_TARGET": "aarch64-unknown-mingw32", + "CXX": "/opt/llvm-mingw-linux/bin/aarch64-w64-mingw32-clang++", + "HADRIAN_ARGS": "--docs=none", + "INSTALL_CONFIGURE_ARGS": "--enable-strict-ghc-toolchain-check", + "LD": "/opt/llvm-mingw-linux/bin/aarch64-w64-mingw32-ld", + "LLVMAS": "/opt/llvm-mingw-linux/bin/aarch64-w64-mingw32-clang", + "MergeObjsCmd": "", + "NM": "/opt/llvm-mingw-linux/bin/aarch64-w64-mingw32-nm", + "OBJCOPY": "/opt/llvm-mingw-linux/bin/aarch64-w64-mingw32-objcopy", + "OBJDUMP": "/opt/llvm-mingw-linux/bin/aarch64-w64-mingw32-objdump", + "RANLIB": "/opt/llvm-mingw-linux/bin/aarch64-w64-mingw32-llvm-ranlib", + "RUNTEST_ARGS": "", + "SIZE": "/opt/llvm-mingw-linux/bin/aarch64-w64-mingw32-size", + "STRINGS": "/opt/llvm-mingw-linux/bin/aarch64-w64-mingw32-strings", + "STRIP": "/opt/llvm-mingw-linux/bin/aarch64-w64-mingw32-strip", + "TEST_ENV": "aarch64-linux-deb12-wine-int_native-cross_aarch64-unknown-mingw32-validate", + "WindresCmd": "/opt/llvm-mingw-linux/bin/aarch64-w64-mingw32-windres" + } + }, + "aarch64-linux-deb12-wine-int_native-cross_aarch64-unknown-mingw32-validate+llvm": { + "after_script": [ + ".gitlab/ci.sh save_cache", + ".gitlab/ci.sh save_test_output", + ".gitlab/ci.sh clean", + "cat ci_timings" + ], + "allow_failure": false, + "artifacts": { + "expire_in": "2 weeks", + "paths": [ + "ghc-aarch64-linux-deb12-wine-int_native-cross_aarch64-unknown-mingw32-validate+llvm.tar.xz", + "junit.xml", + "unexpected-test-output.tar.gz" + ], + "reports": { + "junit": "junit.xml" + }, + "when": "always" + }, + "cache": { + "key": "aarch64-linux-deb12-wine-$CACHE_REV", + "paths": [ + "cabal-cache", + "toolchain" + ] + }, + "dependencies": [], + "image": "registry.gitlab.haskell.org/ghc/ci-images/aarch64-linux-deb12-wine:$DOCKER_REV", + "needs": [ + { + "artifacts": false, + "job": "hadrian-ghc-in-ghci" + } + ], + "rules": [ + { + "if": "((($ONLY_JOBS) && ($ONLY_JOBS =~ /.*\\baarch64-linux-deb12-wine-int_native-cross_aarch64-unknown-mingw32-validate\\+llvm(\\s|$).*/)) || (($ONLY_JOBS == null) && ((($CI_MERGE_REQUEST_LABELS =~ /.*full-ci.*/) || ($CI_MERGE_REQUEST_LABELS =~ /.*marge_bot_batch_merge_job.*/) || ($CI_COMMIT_BRANCH == \"master\") || ($CI_COMMIT_BRANCH =~ /ghc-[0-9]+\\.[0-9]+/)) || (($CI_MERGE_REQUEST_LABELS =~ /.*aarch64.*/) && ($CI_MERGE_REQUEST_LABELS =~ /.*Windows.*/) && ($CI_MERGE_REQUEST_LABELS =~ /.*LLVM backend.*/))))) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY == null)", + "when": "on_success" + } + ], + "script": [ + "sudo chown ghc:ghc -R .", + ".gitlab/ci.sh setup", + ".gitlab/ci.sh configure", + ".gitlab/ci.sh build_hadrian", + ".gitlab/ci.sh test_hadrian" + ], + "stage": "full-build", + "tags": [ + "aarch64-linux" + ], + "variables": { + "AR": "/opt/llvm-mingw-linux/bin/aarch64-w64-mingw32-llvm-ar", + "BIGNUM_BACKEND": "native", + "BIN_DIST_NAME": "ghc-aarch64-linux-deb12-wine-int_native-cross_aarch64-unknown-mingw32-validate+llvm", + "BUILD_FLAVOUR": "validate+llvm", + "CC": "/opt/llvm-mingw-linux/bin/aarch64-w64-mingw32-clang", + "CFLAGS": "-fuse-ld=/opt/llvm-mingw-linux/bin/aarch64-w64-mingw32-ld --rtlib=compiler-rt", + "CONFIGURE_ARGS": "--with-intree-gmp --enable-strict-ghc-toolchain-check", + "CONF_CC_OPTS_STAGE2": "-fuse-ld=/opt/llvm-mingw-linux/bin/aarch64-w64-mingw32-ld --rtlib=compiler-rt", + "CROSS_EMULATOR": "/opt/wine-arm64ec-msys2-deb12/bin/wine", + "CROSS_TARGET": "aarch64-unknown-mingw32", + "CXX": "/opt/llvm-mingw-linux/bin/aarch64-w64-mingw32-clang++", + "HADRIAN_ARGS": "--docs=none", + "INSTALL_CONFIGURE_ARGS": "--enable-strict-ghc-toolchain-check", + "LD": "/opt/llvm-mingw-linux/bin/aarch64-w64-mingw32-ld", + "LLVMAS": "/opt/llvm-mingw-linux/bin/aarch64-w64-mingw32-clang", + "MergeObjsCmd": "", + "NM": "/opt/llvm-mingw-linux/bin/aarch64-w64-mingw32-nm", + "OBJCOPY": "/opt/llvm-mingw-linux/bin/aarch64-w64-mingw32-objcopy", + "OBJDUMP": "/opt/llvm-mingw-linux/bin/aarch64-w64-mingw32-objdump", + "RANLIB": "/opt/llvm-mingw-linux/bin/aarch64-w64-mingw32-llvm-ranlib", + "RUNTEST_ARGS": "", + "SIZE": "/opt/llvm-mingw-linux/bin/aarch64-w64-mingw32-size", + "STRINGS": "/opt/llvm-mingw-linux/bin/aarch64-w64-mingw32-strings", + "STRIP": "/opt/llvm-mingw-linux/bin/aarch64-w64-mingw32-strip", + "TEST_ENV": "aarch64-linux-deb12-wine-int_native-cross_aarch64-unknown-mingw32-validate+llvm", + "WindresCmd": "/opt/llvm-mingw-linux/bin/aarch64-w64-mingw32-windres" + } + }, "i386-linux-alpine3_20-validate": { "after_script": [ ".gitlab/ci.sh save_cache", @@ -822,6 +984,170 @@ "XZ_OPT": "-9" } }, + "nightly-aarch64-linux-deb12-wine-int_native-cross_aarch64-unknown-mingw32-validate": { + "after_script": [ + ".gitlab/ci.sh save_cache", + ".gitlab/ci.sh save_test_output", + ".gitlab/ci.sh clean", + "cat ci_timings" + ], + "allow_failure": false, + "artifacts": { + "expire_in": "8 weeks", + "paths": [ + "ghc-aarch64-linux-deb12-wine-int_native-cross_aarch64-unknown-mingw32-validate.tar.xz", + "junit.xml", + "unexpected-test-output.tar.gz" + ], + "reports": { + "junit": "junit.xml" + }, + "when": "always" + }, + "cache": { + "key": "aarch64-linux-deb12-wine-$CACHE_REV", + "paths": [ + "cabal-cache", + "toolchain" + ] + }, + "dependencies": [], + "image": "registry.gitlab.haskell.org/ghc/ci-images/aarch64-linux-deb12-wine:$DOCKER_REV", + "needs": [ + { + "artifacts": false, + "job": "hadrian-ghc-in-ghci" + } + ], + "rules": [ + { + "if": "(\"true\" == \"true\") && ($RELEASE_JOB != \"yes\") && ($NIGHTLY)", + "when": "on_success" + } + ], + "script": [ + "sudo chown ghc:ghc -R .", + ".gitlab/ci.sh setup", + ".gitlab/ci.sh configure", + ".gitlab/ci.sh build_hadrian", + ".gitlab/ci.sh test_hadrian" + ], + "stage": "full-build", + "tags": [ + "aarch64-linux" + ], + "variables": { + "AR": "/opt/llvm-mingw-linux/bin/aarch64-w64-mingw32-llvm-ar", + "BIGNUM_BACKEND": "native", + "BIN_DIST_NAME": "ghc-aarch64-linux-deb12-wine-int_native-cross_aarch64-unknown-mingw32-validate", + "BUILD_FLAVOUR": "validate", + "CC": "/opt/llvm-mingw-linux/bin/aarch64-w64-mingw32-clang", + "CFLAGS": "-fuse-ld=/opt/llvm-mingw-linux/bin/aarch64-w64-mingw32-ld --rtlib=compiler-rt", + "CONFIGURE_ARGS": "--with-intree-gmp --enable-strict-ghc-toolchain-check", + "CONF_CC_OPTS_STAGE2": "-fuse-ld=/opt/llvm-mingw-linux/bin/aarch64-w64-mingw32-ld --rtlib=compiler-rt", + "CROSS_EMULATOR": "/opt/wine-arm64ec-msys2-deb12/bin/wine", + "CROSS_TARGET": "aarch64-unknown-mingw32", + "CXX": "/opt/llvm-mingw-linux/bin/aarch64-w64-mingw32-clang++", + "HADRIAN_ARGS": "--docs=none", + "INSTALL_CONFIGURE_ARGS": "--enable-strict-ghc-toolchain-check", + "LD": "/opt/llvm-mingw-linux/bin/aarch64-w64-mingw32-ld", + "LLVMAS": "/opt/llvm-mingw-linux/bin/aarch64-w64-mingw32-clang", + "MergeObjsCmd": "", + "NM": "/opt/llvm-mingw-linux/bin/aarch64-w64-mingw32-nm", + "OBJCOPY": "/opt/llvm-mingw-linux/bin/aarch64-w64-mingw32-objcopy", + "OBJDUMP": "/opt/llvm-mingw-linux/bin/aarch64-w64-mingw32-objdump", + "RANLIB": "/opt/llvm-mingw-linux/bin/aarch64-w64-mingw32-llvm-ranlib", + "RUNTEST_ARGS": "", + "SIZE": "/opt/llvm-mingw-linux/bin/aarch64-w64-mingw32-size", + "STRINGS": "/opt/llvm-mingw-linux/bin/aarch64-w64-mingw32-strings", + "STRIP": "/opt/llvm-mingw-linux/bin/aarch64-w64-mingw32-strip", + "TEST_ENV": "aarch64-linux-deb12-wine-int_native-cross_aarch64-unknown-mingw32-validate", + "WindresCmd": "/opt/llvm-mingw-linux/bin/aarch64-w64-mingw32-windres", + "XZ_OPT": "-9" + } + }, + "nightly-aarch64-linux-deb12-wine-int_native-cross_aarch64-unknown-mingw32-validate+llvm": { + "after_script": [ + ".gitlab/ci.sh save_cache", + ".gitlab/ci.sh save_test_output", + ".gitlab/ci.sh clean", + "cat ci_timings" + ], + "allow_failure": false, + "artifacts": { + "expire_in": "8 weeks", + "paths": [ + "ghc-aarch64-linux-deb12-wine-int_native-cross_aarch64-unknown-mingw32-validate+llvm.tar.xz", + "junit.xml", + "unexpected-test-output.tar.gz" + ], + "reports": { + "junit": "junit.xml" + }, + "when": "always" + }, + "cache": { + "key": "aarch64-linux-deb12-wine-$CACHE_REV", + "paths": [ + "cabal-cache", + "toolchain" + ] + }, + "dependencies": [], + "image": "registry.gitlab.haskell.org/ghc/ci-images/aarch64-linux-deb12-wine:$DOCKER_REV", + "needs": [ + { + "artifacts": false, + "job": "hadrian-ghc-in-ghci" + } + ], + "rules": [ + { + "if": "(\"true\" == \"true\") && ($RELEASE_JOB != \"yes\") && ($NIGHTLY)", + "when": "on_success" + } + ], + "script": [ + "sudo chown ghc:ghc -R .", + ".gitlab/ci.sh setup", + ".gitlab/ci.sh configure", + ".gitlab/ci.sh build_hadrian", + ".gitlab/ci.sh test_hadrian" + ], + "stage": "full-build", + "tags": [ + "aarch64-linux" + ], + "variables": { + "AR": "/opt/llvm-mingw-linux/bin/aarch64-w64-mingw32-llvm-ar", + "BIGNUM_BACKEND": "native", + "BIN_DIST_NAME": "ghc-aarch64-linux-deb12-wine-int_native-cross_aarch64-unknown-mingw32-validate+llvm", + "BUILD_FLAVOUR": "validate+llvm", + "CC": "/opt/llvm-mingw-linux/bin/aarch64-w64-mingw32-clang", + "CFLAGS": "-fuse-ld=/opt/llvm-mingw-linux/bin/aarch64-w64-mingw32-ld --rtlib=compiler-rt", + "CONFIGURE_ARGS": "--with-intree-gmp --enable-strict-ghc-toolchain-check", + "CONF_CC_OPTS_STAGE2": "-fuse-ld=/opt/llvm-mingw-linux/bin/aarch64-w64-mingw32-ld --rtlib=compiler-rt", + "CROSS_EMULATOR": "/opt/wine-arm64ec-msys2-deb12/bin/wine", + "CROSS_TARGET": "aarch64-unknown-mingw32", + "CXX": "/opt/llvm-mingw-linux/bin/aarch64-w64-mingw32-clang++", + "HADRIAN_ARGS": "--docs=none", + "INSTALL_CONFIGURE_ARGS": "--enable-strict-ghc-toolchain-check", + "LD": "/opt/llvm-mingw-linux/bin/aarch64-w64-mingw32-ld", + "LLVMAS": "/opt/llvm-mingw-linux/bin/aarch64-w64-mingw32-clang", + "MergeObjsCmd": "", + "NM": "/opt/llvm-mingw-linux/bin/aarch64-w64-mingw32-nm", + "OBJCOPY": "/opt/llvm-mingw-linux/bin/aarch64-w64-mingw32-objcopy", + "OBJDUMP": "/opt/llvm-mingw-linux/bin/aarch64-w64-mingw32-objdump", + "RANLIB": "/opt/llvm-mingw-linux/bin/aarch64-w64-mingw32-llvm-ranlib", + "RUNTEST_ARGS": "", + "SIZE": "/opt/llvm-mingw-linux/bin/aarch64-w64-mingw32-size", + "STRINGS": "/opt/llvm-mingw-linux/bin/aarch64-w64-mingw32-strings", + "STRIP": "/opt/llvm-mingw-linux/bin/aarch64-w64-mingw32-strip", + "TEST_ENV": "aarch64-linux-deb12-wine-int_native-cross_aarch64-unknown-mingw32-validate+llvm", + "WindresCmd": "/opt/llvm-mingw-linux/bin/aarch64-w64-mingw32-windres", + "XZ_OPT": "-9" + } + }, "nightly-i386-linux-alpine3_20-validate": { "after_script": [ ".gitlab/ci.sh save_cache", diff --git a/compiler/CodeGen.Platform.h b/compiler/CodeGen.Platform.h index 78a712072d5e5773be79f93ba7107aab542704f0..989528526a3637ccc145a6c1ecdb3ff1a87fb380 100644 --- a/compiler/CodeGen.Platform.h +++ b/compiler/CodeGen.Platform.h @@ -1032,11 +1032,15 @@ freeReg 29 = False -- ip0 -- used for spill offset computations freeReg 16 = False -#if defined(darwin_HOST_OS) || defined(ios_HOST_OS) +-- Note [Aarch64 Register x18 at Darwin and Windows] +-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -- x18 is reserved by the platform on Darwin/iOS, and can not be used -- More about ARM64 ABI that Apple platforms support: -- https://developer.apple.com/documentation/xcode/writing-arm64-code-for-apple-platforms -- https://github.com/Siguza/ios-resources/blob/master/bits/arm64.md +-- It is a reserved at Windows as well. Acts like TEB register in user mode at Windows. +-- https://learn.microsoft.com/en-us/cpp/build/arm64-windows-abi-conventions +#if defined(darwin_HOST_OS) || defined(ios_HOST_OS) || defined(mingw32_HOST_OS) freeReg 18 = False #endif diff --git a/compiler/GHC/CmmToAsm/AArch64/CodeGen.hs b/compiler/GHC/CmmToAsm/AArch64/CodeGen.hs index 300f46c29846479cd059aa10b9d364279f74054c..780af270d7c0b56b5eb217c39828bd79e3f10071 100644 --- a/compiler/GHC/CmmToAsm/AArch64/CodeGen.hs +++ b/compiler/GHC/CmmToAsm/AArch64/CodeGen.hs @@ -1,5 +1,6 @@ {-# language GADTs, LambdaCase #-} {-# LANGUAGE OverloadedStrings #-} + module GHC.CmmToAsm.AArch64.CodeGen ( cmmTopCodeGen , generateJumpTableForInstr @@ -281,7 +282,11 @@ generateJumpTableForInstr config (J_TBL ids (Just lbl) _) = ) where blockLabel = blockLbl blockid - in Just (CmmData (Section ReadOnlyData lbl) (CmmStaticsRaw lbl jumpTable)) + sectionType = case platformOS (ncgPlatform config) of + -- Aarch64 Windows platform requires LLVM 20 to support .rodata + OSMinGW32 -> Text + _ -> ReadOnlyData + in Just (CmmData (Section sectionType lbl) (CmmStaticsRaw lbl jumpTable)) generateJumpTableForInstr _ _ = Nothing -- ----------------------------------------------------------------------------- diff --git a/compiler/GHC/CmmToAsm/AArch64/Instr.hs b/compiler/GHC/CmmToAsm/AArch64/Instr.hs index 968ff50063e2167c6c03dc47fc918003914c512c..39182be09f61508a2fbffe556db6d789f8545c09 100644 --- a/compiler/GHC/CmmToAsm/AArch64/Instr.hs +++ b/compiler/GHC/CmmToAsm/AArch64/Instr.hs @@ -211,7 +211,7 @@ regUsageOfInstr platform instr = case instr of -- | <---- argument passing -------------> | <-- callee saved (lower 64 bits) ---> | <--------------------------------------- caller saved ----------------------> | -- | <------ free registers -------------> | F1 | F2 | F3 | F4 | D1 | D2 | D3 | D4 | <------ free registers -----------------------------------------------------> | -- '---------------------------------------------------------------------------------------------------------------------------------------------------------------' --- IR: Indirect result location register, IP: Intra-procedure register, PL: Platform register, FP: Frame pointer, LR: Link register, SP: Stack pointer +-- IR: Indirect result location register, IP: Intra-procedure register, PL: Platform register (See Note [Aarch64 Register x18 at Darwin and Windows]), FP: Frame pointer, LR: Link register, SP: Stack pointer -- BR: Base, SL: SpLim -- -- TODO: The zero register is currently mapped to -1 but should get it's own separate number. diff --git a/compiler/GHC/CmmToAsm/AArch64/Ppr.hs b/compiler/GHC/CmmToAsm/AArch64/Ppr.hs index 80fe6f02cce2c69a6cc3033d7215570a1a52ab2c..25c448feaf30e8097685ac835bfde26329c172ae 100644 --- a/compiler/GHC/CmmToAsm/AArch64/Ppr.hs +++ b/compiler/GHC/CmmToAsm/AArch64/Ppr.hs @@ -1,5 +1,4 @@ {-# OPTIONS_GHC -fno-warn-orphans #-} -{-# LANGUAGE CPP #-} module GHC.CmmToAsm.AArch64.Ppr (pprNatCmmDecl, pprInstr, pprBasicBlock) where @@ -43,7 +42,9 @@ pprNatCmmDecl config proc@(CmmProc top_info lbl _ (ListGraph blocks)) = pprSectionAlign config (Section Text lbl) $$ -- do not -- pprProcAlignment config $$ - pprLabel platform lbl $$ -- blocks guaranteed not null, so label needed + (if lbl /= blockLbl (blockId (head blocks)) -- blocks can have clashed names + then pprLabel platform lbl -- blocks guaranteed not null, so label needed + else empty) $$ vcat (map (pprBasicBlock platform with_dwarf top_info) blocks) $$ (if ncgDwarfEnabled config then line (pprAsmLabel platform (mkAsmTempEndLabel lbl) <> char ':') else empty) $$ @@ -461,63 +462,51 @@ pprInstr platform instr = case instr of STR _f o1 o2 -> op2 (text "\tstr") o1 o2 STLR _f o1 o2 -> op2 (text "\tstlr") o1 o2 -#if defined(darwin_HOST_OS) LDR _f o1 (OpImm (ImmIndex lbl' off)) | Just (_info, lbl) <- dynamicLinkerLabelInfo lbl' -> - op_adrp o1 (pprAsmLabel platform lbl <> text "@gotpage") $$ - op_ldr o1 (pprAsmLabel platform lbl <> text "@gotpageoff") $$ - op_add o1 (char '#' <> int off) -- TODO: check that off is in 12bits. + let (adrp', ldr') = op_adrp_reloc_dynamic $ pprAsmLabel platform lbl in + op_adrp o1 (adrp') $$ + op_ldr o1 (ldr') $$ + op_add o1 (check_off off) LDR _f o1 (OpImm (ImmIndex lbl off)) | isForeignLabel lbl -> - op_adrp o1 (pprAsmLabel platform lbl <> text "@gotpage") $$ - op_ldr o1 (pprAsmLabel platform lbl <> text "@gotpageoff") $$ - op_add o1 (char '#' <> int off) -- TODO: check that off is in 12bits. + case platformOS platform of + OSMinGW32 -> + let (adrp', add') = op_adrp_reloc_local $ pprAsmLabel platform lbl in + op_adrp o1 (adrp') $$ + op_add o1 add' $$ + op_add o1 (check_off off) + _ -> + let (adrp', ldr') = op_adrp_reloc_dynamic $ pprAsmLabel platform lbl in + op_adrp o1 (adrp') $$ + op_ldr o1 (ldr') $$ + op_add o1 (check_off off) LDR _f o1 (OpImm (ImmIndex lbl off)) -> - op_adrp o1 (pprAsmLabel platform lbl <> text "@page") $$ - op_add o1 (pprAsmLabel platform lbl <> text "@pageoff") $$ - op_add o1 (char '#' <> int off) -- TODO: check that off is in 12bits. + let (adrp', add') = op_adrp_reloc_local $ pprAsmLabel platform lbl in + op_adrp o1 (adrp') $$ + op_add o1 (add') $$ + op_add o1 (check_off off) LDR _f o1 (OpImm (ImmCLbl lbl')) | Just (_info, lbl) <- dynamicLinkerLabelInfo lbl' -> - op_adrp o1 (pprAsmLabel platform lbl <> text "@gotpage") $$ - op_ldr o1 (pprAsmLabel platform lbl <> text "@gotpageoff") + let (adrp', ldr') = op_adrp_reloc_dynamic $ pprAsmLabel platform lbl in + op_adrp o1 (adrp') $$ + op_ldr o1 (ldr') LDR _f o1 (OpImm (ImmCLbl lbl)) | isForeignLabel lbl -> - op_adrp o1 (pprAsmLabel platform lbl <> text "@gotpage") $$ - op_ldr o1 (pprAsmLabel platform lbl <> text "@gotpageoff") + case platformOS platform of + OSMinGW32 -> + let (adrp', add') = op_adrp_reloc_local $ pprAsmLabel platform lbl in + op_adrp o1 (adrp') $$ + op_add o1 add' + _ -> + let (adrp', ldr') = op_adrp_reloc_dynamic $ pprAsmLabel platform lbl in + op_adrp o1 (adrp') $$ + op_ldr o1 (ldr') LDR _f o1 (OpImm (ImmCLbl lbl)) -> - op_adrp o1 (pprAsmLabel platform lbl <> text "@page") $$ - op_add o1 (pprAsmLabel platform lbl <> text "@pageoff") - -#else - LDR _f o1 (OpImm (ImmIndex lbl' off)) | Just (_info, lbl) <- dynamicLinkerLabelInfo lbl' -> - op_adrp o1 (text ":got:" <> pprAsmLabel platform lbl) $$ - op_ldr o1 (text ":got_lo12:" <> pprAsmLabel platform lbl) $$ - op_add o1 (char '#' <> int off) -- TODO: check that off is in 12bits. - - LDR _f o1 (OpImm (ImmIndex lbl off)) | isForeignLabel lbl -> - op_adrp o1 (text ":got:" <> pprAsmLabel platform lbl) $$ - op_ldr o1 (text ":got_lo12:" <> pprAsmLabel platform lbl) $$ - op_add o1 (char '#' <> int off) -- TODO: check that off is in 12bits. - - LDR _f o1 (OpImm (ImmIndex lbl off)) -> - op_adrp o1 (pprAsmLabel platform lbl) $$ - op_add o1 (text ":lo12:" <> pprAsmLabel platform lbl) $$ - op_add o1 (char '#' <> int off) -- TODO: check that off is in 12bits. - - LDR _f o1 (OpImm (ImmCLbl lbl')) | Just (_info, lbl) <- dynamicLinkerLabelInfo lbl' -> - op_adrp o1 (text ":got:" <> pprAsmLabel platform lbl) $$ - op_ldr o1 (text ":got_lo12:" <> pprAsmLabel platform lbl) - - LDR _f o1 (OpImm (ImmCLbl lbl)) | isForeignLabel lbl -> - op_adrp o1 (text ":got:" <> pprAsmLabel platform lbl) $$ - op_ldr o1 (text ":got_lo12:" <> pprAsmLabel platform lbl) - - LDR _f o1 (OpImm (ImmCLbl lbl)) -> - op_adrp o1 (pprAsmLabel platform lbl) $$ - op_add o1 (text ":lo12:" <> pprAsmLabel platform lbl) - -#endif + let (adrp', ldr') = op_adrp_reloc_local $ pprAsmLabel platform lbl in + op_adrp o1 adrp' $$ + op_add o1 ldr' LDR _f o1@(OpReg W8 (RegReal (RealRegSingle i))) o2 | i < 32 -> op2 (text "\tldrb") o1 o2 @@ -553,6 +542,21 @@ pprInstr platform instr = case instr of op_adrp o1 rest = line $ text "\tadrp" <+> pprOp platform o1 <> comma <+> rest op_add o1 rest = line $ text "\tadd" <+> pprOp platform o1 <> comma <+> pprOp platform o1 <> comma <+> rest + op_adrp_reloc_dynamic asm_lbl = case platformOS platform of + OSDarwin -> (asm_lbl <> text "@gotpage", asm_lbl <> text "@gotpageoff") + OSLinux -> (text ":got:" <> asm_lbl, text ":got_lo12:" <> asm_lbl) + OSMinGW32 -> (text "__imp_" <> asm_lbl, text ":lo12:__imp_" <> asm_lbl) + os' -> pgmError $ "GHC.CmmToAsm.AArch64.Ppr.op_adrp_reloc_dynamic : " ++ show os' ++ " is unsuppported by relocations" + + op_adrp_reloc_local asm_lbl = case platformOS platform of + OSDarwin -> (asm_lbl <> text "@page", asm_lbl <> text "@pageoff") + OSLinux -> (asm_lbl, text ":lo12:" <> asm_lbl) + OSMinGW32 -> (asm_lbl, text ":lo12:" <> asm_lbl) + os' -> pgmError $ "GHC.CmmToAsm.AArch64.Ppr.op_adrp_reloc_local : " ++ show os' ++ " is unsuppported by relocations" + + check_off off = if off >= 0 && off <= 4095 then char '#' <> int off else + pgmError $ "GHC.CmmToAsm.AArch64.Ppr.check_off : " ++ show off ++ " is out of 12 bit" + pprBcond :: IsLine doc => Cond -> doc pprBcond c = text "b." <> pprCond c diff --git a/compiler/GHC/CmmToAsm/Reg/Linear/AArch64.hs b/compiler/GHC/CmmToAsm/Reg/Linear/AArch64.hs index 64ed25e92ddc934e76c08ab77b377699f09100ae..95fbe77fbb986a32a67a7b73eeb6aa51796d4b6c 100644 --- a/compiler/GHC/CmmToAsm/Reg/Linear/AArch64.hs +++ b/compiler/GHC/CmmToAsm/Reg/Linear/AArch64.hs @@ -118,6 +118,7 @@ getFreeRegs :: RegClass -> FreeRegs -> [RealReg] getFreeRegs cls (FreeRegs g f) = case cls of RcFloatOrVector -> go 32 f 31 + -- x18 is a platform-reserved register for Win/Mac and free for Linux (See Note [Aarch64 Register x18 at Darwin and Windows]) RcInteger -> go 0 g 18 where go _ _ i | i < 0 = [] diff --git a/compiler/GHC/Driver/Session.hs b/compiler/GHC/Driver/Session.hs index aeed58acaafaeb6cd02f4cd90f24a657c434274a..cfdd08fd9e67840deb95477429436180eb9c05cc 100644 --- a/compiler/GHC/Driver/Session.hs +++ b/compiler/GHC/Driver/Session.hs @@ -3652,6 +3652,14 @@ makeDynFlagsConsistent dflags , Nothing <- outputFile dflags = pgmError "--output must be specified when using --merge-objs" + | platformTablesNextToCode platform + && os == OSMinGW32 + && arch == ArchAArch64 + = case backendCodeOutput (backend dflags) of + LlvmCodeOutput -> pgmError "-fllvm is incompatible with enabled TablesNextToCode at Windows Aarch64" + NcgCodeOutput -> pgmError "-fasm is incompatible with enabled TablesNextToCode at Windows Aarch64" + _ -> (dflags, mempty, mempty) + -- When we do ghci, force using dyn ways if the target RTS linker -- only supports dynamic code | LinkInMemory <- ghcLink dflags diff --git a/compiler/GHC/Platform/Regs.hs b/compiler/GHC/Platform/Regs.hs index 429f977a99c54859a2c5769ff6f424b4d3721783..bdb3a5897556cce45002394c36febc73a24176b7 100644 --- a/compiler/GHC/Platform/Regs.hs +++ b/compiler/GHC/Platform/Regs.hs @@ -112,7 +112,18 @@ freeReg platform ArchX86_64 -> X86_64.freeReg ArchS390X -> S390X.freeReg ArchARM {} -> ARM.freeReg - ArchAArch64 -> AArch64.freeReg + ArchAArch64 -> + -- See Note [Aarch64 Register x18 at Darwin and Windows]. + -- It already has `freeReg 18 = False` but that line does not work for cross-compile when + -- we use host not from the list (darwin_HOST_OS, ios_HOST_OS, mingw32_HOST_OS) i.e. Linux + if platformOS platform == OSMinGW32 || platformOS platform == OSDarwin + then + let + x18Check :: RegNo -> Bool + x18Check 18 = False + x18Check a = AArch64.freeReg a + in x18Check + else AArch64.freeReg ArchRISCV64 -> RISCV64.freeReg ArchWasm32 -> Wasm32.freeReg ArchLoongArch64 -> LoongArch64.freeReg diff --git a/hadrian/src/Oracles/Setting.hs b/hadrian/src/Oracles/Setting.hs index 807fab63bfcb913f4e7adcc8e95f63ff4ebefc82..b6a8943abf14876988dd7983f0c26debe1a5d2fa 100644 --- a/hadrian/src/Oracles/Setting.hs +++ b/hadrian/src/Oracles/Setting.hs @@ -11,6 +11,7 @@ module Oracles.Setting ( -- ** Target platform things anyTargetOs, anyTargetArch, anyHostOs, isElfTarget, isOsxTarget, isWinTarget, isJsTarget, isArmTarget, + isWinHost, targetArmVersion ) where @@ -156,6 +157,9 @@ getSetting = expr . setting bashPath :: Action FilePath bashPath = setting BourneShell +isWinHost :: Action Bool +isWinHost = anyHostOs [OSMinGW32] + isWinTarget :: Action Bool isWinTarget = anyTargetOs [OSMinGW32] diff --git a/hadrian/src/Rules/BinaryDist.hs b/hadrian/src/Rules/BinaryDist.hs index 187ae211344de006cfa6f9bef7feefc428ae079c..af8fa5c7d36e715a691a1f4417c135dd8166a029 100644 --- a/hadrian/src/Rules/BinaryDist.hs +++ b/hadrian/src/Rules/BinaryDist.hs @@ -301,7 +301,8 @@ bindistRules = do let buildBinDist compressor = do win_target <- isWinTarget - when win_target (error "normal binary-dist does not work for Windows targets, use `reloc-binary-dist-*` target instead.") + win_host <- isWinHost + when (win_target && win_host) (error "normal binary-dist does not work at Windows, use `reloc-binary-dist-*` target instead.") buildBinDistX "binary-dist-dir" "bindist" compressor buildBinDistReloc = buildBinDistX "reloc-binary-dist-dir" "reloc-bindist" diff --git a/libraries/Cabal b/libraries/Cabal index 269fd808e5d80223a229b6b19edfe6f5b109007a..703582f80f6d7f0c914ef4b885affcfc7b7b6ec8 160000 --- a/libraries/Cabal +++ b/libraries/Cabal @@ -1 +1 @@ -Subproject commit 269fd808e5d80223a229b6b19edfe6f5b109007a +Subproject commit 703582f80f6d7f0c914ef4b885affcfc7b7b6ec8 diff --git a/libraries/Win32 b/libraries/Win32 index 027cbcf0de25d681823ea92fb545a2604c3a6a8b..f340d2c3d846fce73117dd2548ad1bf0c56ceb9d 160000 --- a/libraries/Win32 +++ b/libraries/Win32 @@ -1 +1 @@ -Subproject commit 027cbcf0de25d681823ea92fb545a2604c3a6a8b +Subproject commit f340d2c3d846fce73117dd2548ad1bf0c56ceb9d diff --git a/libraries/base/src/System/CPUTime/Windows.hsc b/libraries/base/src/System/CPUTime/Windows.hsc index 547e7fa4805bdbb5158d13ef4abda66fe5cd7562..4bae075d4645b6e65688fc561fd4c31fae312735 100644 --- a/libraries/base/src/System/CPUTime/Windows.hsc +++ b/libraries/base/src/System/CPUTime/Windows.hsc @@ -60,7 +60,7 @@ type HANDLE = () #if defined(i386_HOST_ARCH) foreign import stdcall unsafe "GetCurrentProcess" getCurrentProcess :: IO (Ptr HANDLE) foreign import stdcall unsafe "GetProcessTimes" getProcessTimes :: Ptr HANDLE -> Ptr FILETIME -> Ptr FILETIME -> Ptr FILETIME -> Ptr FILETIME -> IO CInt -#elif defined(x86_64_HOST_ARCH) +#elif defined(x86_64_HOST_ARCH) || defined(aarch64_HOST_ARCH) foreign import ccall unsafe "GetCurrentProcess" getCurrentProcess :: IO (Ptr HANDLE) foreign import ccall unsafe "GetProcessTimes" getProcessTimes :: Ptr HANDLE -> Ptr FILETIME -> Ptr FILETIME -> Ptr FILETIME -> Ptr FILETIME -> IO CInt #else diff --git a/libraries/base/tests/perf/encodingAllocations.hs b/libraries/base/tests/perf/encodingAllocations.hs index cd136963cb948c6365d934dc863b7b7af2f72816..58b31b0853383ea14fc68eff31e33ad39a06dce9 100755 --- a/libraries/base/tests/perf/encodingAllocations.hs +++ b/libraries/base/tests/perf/encodingAllocations.hs @@ -13,13 +13,13 @@ import Distribution.Simple.Utils main :: IO () -main = withTempFile "." "encodingAllocations.tmp" (const $ loop 1000000) +main = withTempFile "encodingAllocations.tmp" (loop 1000000) -loop :: Int -> Handle -> IO () -loop 0 !_ = pure () -loop !n !h = do +loop :: Int -> FilePath -> Handle -> IO () +loop 0 !_ !_ = pure () +loop !n !fp !h = do hPutChar h $! dummy_char n - loop (n-1) h + loop (n-1) fp h -- unsafe efficient version of `chr` my_chr :: Int -> Char diff --git a/libraries/directory b/libraries/directory index 005fa061171a55d35ce8dfe936cf3703525a8616..eb40bbebcaf86153bbc60772fb2e0466d35c95c4 160000 --- a/libraries/directory +++ b/libraries/directory @@ -1 +1 @@ -Subproject commit 005fa061171a55d35ce8dfe936cf3703525a8616 +Subproject commit eb40bbebcaf86153bbc60772fb2e0466d35c95c4 diff --git a/libraries/ghc-internal/jsbits/base.js b/libraries/ghc-internal/jsbits/base.js index 9150799d130d885c2e356f3b2696adfa7d15b91f..d7a78a46379c96a99e06d6f90569f432867d356b 100644 --- a/libraries/ghc-internal/jsbits/base.js +++ b/libraries/ghc-internal/jsbits/base.js @@ -44,30 +44,45 @@ function h$base_close(fd, c) { } function h$close(fd,c) { - if (c) { - //asynchronous - var fdo = h$base_fds[fd]; - if(fdo) { + var fdo = h$base_fds[fd]; + + // File descriptor was closed already? + // It may happen only if its reference count reached <1 and actual closing is processed at underlying fd + if (!fdo) { + h$setErrno('EINVAL'); + + if (c) { + TRACE_IO("base_close: file descriptor not found, already closed?") + c(-1); + return; + } + + TRACE_IO("base_close sync: file descriptor not found, already closed?") + return (-1); + } + + fdo.refs--; + + if (fdo.refs < 1) { + // Process closing at underlying fd + + if (c) { + TRACE_IO("base_close: closing underlying fd") + if (fdo.close) { + fdo.close(fd, fdo, c); + } else { + TRACE_IO("base_close: no actual underlying fd close, dummy implementation") delete h$base_fds[fd]; - if(--fdo.refs < 1) { - TRACE_IO("base_close: closing underlying fd") - if(fdo.close) { - fdo.close(fd, fdo, c); - } else { - c(0); - } - } else { - TRACE_IO("base_close: remaining references, not closing underlying fd") - c(0); - } - } else { - TRACE_IO("base_close: file descriptor not found, already closed?") - h$errno = CONST_EINVAL; - c(-1); + c(0); + } + return; } - } else { - //synchronous + + TRACE_IO("base_close sync: closing underlying fd") try { + // See: https://nodejs.org/api/fs.html#fsclosesyncfd + // Calling fs.closeSync() on any file descriptor (fd) that is currently in use through any other fs operation may lead to undefined behavior. + delete h$base_fds[fd]; h$fs.closeSync(fd); return 0; } catch(err) { @@ -75,6 +90,16 @@ function h$close(fd,c) { return (-1); } } + + // Dummy process closing due of remaining references + if (c) { + TRACE_IO("base_close: remaining references, not closing underlying fd") + c(0); + return; + } + + TRACE_IO("base_close sync: remaining references, not closing underlying fd") + return 0; } function h$base_dup(fd, c) { @@ -122,7 +147,7 @@ function h$base_dup2(fd, new_fd, c) { } function h$base_fstat(fd, stat, stat_off, c) { - TRACE_IO("base_stat") + TRACE_IO("base_fstat") #ifndef GHCJS_BROWSER if(h$isNode()) { h$fs.fstat(fd, function(err, fs) { @@ -384,11 +409,13 @@ function h$rmdir(file, file_off) { } function h$rename(old_path, old_path_off, new_path, new_path_off) { - TRACE_IO("rename") + var old_path_str = h$decodeUtf8z(old_path, old_path_off); + var new_path_str = h$decodeUtf8z(new_path, new_path_off); + TRACE_IO("rename sync: " + old_path_str + " -> " + new_path_str) #ifndef GHCJS_BROWSER if (h$isNode()) { try { - h$fs.renameSync(h$decodeUtf8z(old_path, old_path_off), h$decodeUtf8z(new_path, new_path_off)); + h$fs.renameSync(old_path_str, new_path_str); return 0; } catch(e) { h$setErrno(e); @@ -473,11 +500,13 @@ function h$calculate_at(dirfd, file, file_off) { function h$openat(dirfd, file, file_off, how, mode, c) { var path = h$calculate_at(dirfd, file, file_off); + TRACE_IO("openat" + (!!c ? ": " : " sync: ") + path) return h$base_open(path, how, mode, c); } function h$open(file, file_off, how, mode, c) { var path = h$decodeUtf8z(file, file_off); + TRACE_IO("open" + (!!c ? ": " : " sync: ") + path) return h$base_open(path, how, mode, c); } @@ -485,7 +514,7 @@ function h$base_open(fp, how, mode, c) { #ifndef GHCJS_BROWSER if(h$isNode()) { var flags, off; - TRACE_IO("open: " + fp) + TRACE_IO("base_open" + (!!c ? ": " : " sync: ") + fp) var acc = how & h$base_o_accmode; // passing a number lets node.js use it directly as the flags (undocumented) if(acc === h$base_o_rdonly) { @@ -539,7 +568,7 @@ function h$base_open(fp, how, mode, c) { , pos: p , refs: 1 }; - TRACE_IO("open: " + fp + " -> " + fd) + TRACE_IO("base_open sync: " + fp + " -> " + fd) } if(off === -1) { var fs = h$fs.statSync(fp); @@ -944,8 +973,8 @@ if(h$isNode()) { h$base_closeFile = function(fd, fdo, c) { TRACE_IO("base_closeFile: " + fd + " (" + fdo.fd + ")") var real_fd = typeof fdo.fd === 'number' ? fdo.fd : fd; + delete h$base_fds[fd]; h$fs.close(real_fd, function(err) { - delete h$base_fds[fd]; h$handleErrnoC(err, -1, 0, c); }); } diff --git a/libraries/ghc-internal/jsbits/errno.js b/libraries/ghc-internal/jsbits/errno.js index ff31029baaa5f15e84c28776eba6685fa6d9279f..7bfd3dae83893269144b3434052ed8001758ae06 100644 --- a/libraries/ghc-internal/jsbits/errno.js +++ b/libraries/ghc-internal/jsbits/errno.js @@ -52,6 +52,7 @@ function h$setErrno(e) { if(es.indexOf('EBADF') !== -1) return CONST_EBADF; if(es.indexOf('ENOSPC') !== -1) return CONST_ENOSPC; if(es.indexOf('EACCES') !== -1) return CONST_EACCES; + if(es.indexOf('EXDEV') !== -1) return CONST_EXDEV; if(es.indexOf('Bad argument') !== -1) return CONST_ENOENT; // fixme? throw ("setErrno not yet implemented for: " + e); @@ -72,6 +73,7 @@ var h$errorStrs = { CONST_E2BIG: "Argument list too long" , CONST_EPIPE: "Broken pipe" , CONST_EAGAIN: "Resource temporarily unavailable" , CONST_ESPIPE: "Illegal seek" + , CONST_EXDEV: "Cross-device link" // See https://en.cppreference.com/w/cpp/error/errno_macros } function h$handleErrno(r_err, f) { diff --git a/libraries/ghc-internal/src/GHC/Internal/System/Posix/Internals.hs b/libraries/ghc-internal/src/GHC/Internal/System/Posix/Internals.hs index db100866e0a506df3c1d160dd18e602a9751eb56..7fd0fe75159d1d3971a50e0079cf16935c79cfe2 100644 --- a/libraries/ghc-internal/src/GHC/Internal/System/Posix/Internals.hs +++ b/libraries/ghc-internal/src/GHC/Internal/System/Posix/Internals.hs @@ -556,6 +556,8 @@ foreign import javascript interruptible "h$open" c_interruptible_open_ :: CFilePath -> CInt -> CMode -> IO CInt foreign import javascript interruptible "h$open" c_safe_open_ :: CFilePath -> CInt -> CMode -> IO CInt +foreign import javascript interruptible "h$openat" + c_openat :: CInt -> CFilePath -> CInt -> CMode -> IO CInt foreign import javascript interruptible "h$base_read" c_read :: CInt -> Ptr Word8 -> CSize -> IO CSsize foreign import javascript interruptible "h$base_read" diff --git a/libraries/haskeline b/libraries/haskeline index 5f4bf62bf1f4846ad0b8d1fa9d45f902e3934511..5f1a790a5db1cb3708d105d4f532c32fcbeb4296 160000 --- a/libraries/haskeline +++ b/libraries/haskeline @@ -1 +1 @@ -Subproject commit 5f4bf62bf1f4846ad0b8d1fa9d45f902e3934511 +Subproject commit 5f1a790a5db1cb3708d105d4f532c32fcbeb4296 diff --git a/libraries/process b/libraries/process index 9c3bfc214c72bbd0c8a30a1c41465deed0feaf47..fbbe60718736999db701c12528c85cbc605ab4fb 160000 --- a/libraries/process +++ b/libraries/process @@ -1 +1 @@ -Subproject commit 9c3bfc214c72bbd0c8a30a1c41465deed0feaf47 +Subproject commit fbbe60718736999db701c12528c85cbc605ab4fb diff --git a/libraries/unix b/libraries/unix index 74ae1c0d9dd1518434f7d6cd3e63d7769599e0f9..47d5fc4a8f19207819030725e7de23c65fa61a04 160000 --- a/libraries/unix +++ b/libraries/unix @@ -1 +1 @@ -Subproject commit 74ae1c0d9dd1518434f7d6cd3e63d7769599e0f9 +Subproject commit 47d5fc4a8f19207819030725e7de23c65fa61a04 diff --git a/llvm-targets b/llvm-targets index c42f3e7d8b28a1619033c2a5a5123714f485ee85..daafe8c18fcad65de1f4a2178b25f259b9ccca00 100644 --- a/llvm-targets +++ b/llvm-targets @@ -1,4 +1,5 @@ [("x86_64-unknown-windows-gnu", ("e-m:w-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128", "x86-64", "")) +,("aarch64-unknown-windows-gnu", ("e-m:w-p:64:64-i32:32-i64:64-i128:128-n32:64-S128-Fn32", "generic", "+v8a +fp-armv8 +neon")) ,("arm-unknown-linux-gnueabi", ("e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64", "arm7tdmi", "+strict-align")) ,("arm-unknown-linux-gnueabihf", ("e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64", "arm1176jzf-s", "+strict-align")) ,("arm-unknown-linux-musleabihf", ("e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64", "arm1176jzf-s", "+strict-align")) diff --git a/m4/fp_cc_supports_target.m4 b/m4/fp_cc_supports_target.m4 index a8b8bf907432133823f31bd58a7a6788d2f224ad..177c9824bd90d6e678d7f3054fe034c16ca672c5 100644 --- a/m4/fp_cc_supports_target.m4 +++ b/m4/fp_cc_supports_target.m4 @@ -20,7 +20,7 @@ AC_DEFUN([FP_CC_SUPPORTS_TARGET], # See Note [Don't pass --target to emscripten toolchain] in GHC.Toolchain.Program CONF_CC_SUPPORTS_TARGET=NO AC_MSG_RESULT([no]) - elif $1 --target=$LlvmTarget -Werror conftest.c > /dev/null 2>&1 ; then + elif $1 --target=$LlvmTarget -Werror -c conftest.c > /dev/null 2>&1 ; then CONF_CC_SUPPORTS_TARGET=YES AC_MSG_RESULT([yes]) else diff --git a/m4/fptools_set_platform_vars.m4 b/m4/fptools_set_platform_vars.m4 index 4c022da52b0e4507f05dc7a64c8cbb80c971491f..3f82257501e31f14cc04198052f7056757ae3adb 100644 --- a/m4/fptools_set_platform_vars.m4 +++ b/m4/fptools_set_platform_vars.m4 @@ -93,7 +93,7 @@ AC_DEFUN([FPTOOLS_OVERRIDE_PLATFORM_FROM_BOOTSTRAP], # FPTOOLS_SET_PLATFORM_VARS(platform,Platform) # ---------------------------------- -# Set the platform variables for a single plaform (one of build, host, +# Set the platform variables for a single platform (one of build, host, # or target). Assumes <platform>Arch, <platform>Vendor, and <platform>OS # are defined, and does everything else in terms of them. AC_DEFUN([FPTOOLS_SET_PLATFORM_VARS], diff --git a/m4/ghc_tables_next_to_code.m4 b/m4/ghc_tables_next_to_code.m4 index 3e0ced2137dfaa0f0a1798ac1867aa7e0f25a65c..9bf473a712cb03d8132cf32ee5e9d476ace5a254 100644 --- a/m4/ghc_tables_next_to_code.m4 +++ b/m4/ghc_tables_next_to_code.m4 @@ -22,8 +22,13 @@ AC_DEFUN([GHC_TABLES_NEXT_TO_CODE], AC_MSG_RESULT([no]) ;; *) - TablesNextToCodeDefault=YES - AC_MSG_RESULT([yes]) + if test "$TargetOS" = "mingw32" && test "$TargetArch" = "aarch64"; then + TablesNextToCodeDefault=NO + AC_MSG_RESULT([no]) + else + TablesNextToCodeDefault=YES + AC_MSG_RESULT([yes]) + fi ;; esac ;; diff --git a/rts/StgCRun.c b/rts/StgCRun.c index 2e283a73bfee56611bc624ad6476478dae75cbc5..fe6cde6f99979546096e47a2961a98e0ef0f3588 100644 --- a/rts/StgCRun.c +++ b/rts/StgCRun.c @@ -863,8 +863,12 @@ StgRun(StgFunPtr f, StgRegTable *basereg) { */ "br %1\n\t" +#if defined(mingw32_HOST_OS) + ".globl " STG_RETURN "\n" +#else ".globl " STG_RETURN "\n\t" -#if !defined(ios_HOST_OS) && !defined(darwin_HOST_OS) +#endif +#if !defined(ios_HOST_OS) && !defined(darwin_HOST_OS) && !defined(mingw32_HOST_OS) ".type " STG_RETURN ", %%function\n" #endif STG_RETURN ":\n\t" diff --git a/rts/linker/PEi386.c b/rts/linker/PEi386.c index 5f22d74da87963798146251b2b9c310c8704cdf1..8764c173274a59087f143159c3d87dafba6c1bb6 100644 --- a/rts/linker/PEi386.c +++ b/rts/linker/PEi386.c @@ -1195,6 +1195,12 @@ verifyCOFFHeader ( uint16_t machine, IMAGE_FILE_HEADER *hdr, errorBelch("%" PATH_FMT ": Not a x86_64 PE+ file.", fileName); return false; } +#elif defined(aarch64_HOST_ARCH) + if (machine != IMAGE_FILE_MACHINE_ARM64) { + errorBelch("%" PATH_FMT ": Not a ARM64 PE+ file.", fileName); + return false; + } + errorBelch("PE/PE+ not supported on ARM64."); #else errorBelch("PE/PE+ not supported on this arch."); #endif @@ -2132,6 +2138,19 @@ ocResolve_PEi386 ( ObjectCode* oc ) *(uint32_t *)pP = (uint32_t)v; break; } +#elif defined(aarch64_HOST_ARCH) + case 1: // IMAGE_REL_ARM64_ADDR32, see https://llvm.org/doxygen/namespacellvm_1_1COFF.html, https://learn.microsoft.com/en-us/windows/win32/debug/pe-format#arm64-processors + { + // We have to put this stub due of errors like: + // warning: variable 'A' set but not used. + uint64_t v; + v = S + A; + + debugBelch("%" PATH_FMT ": Catch ARM64 PEi386 relocation type %d, %llx\n", + oc->fileName, reloc->Type, v); + releaseOcInfo (oc); + return false; + } #endif default: debugBelch("%" PATH_FMT ": unhandled PEi386 relocation type %d\n", diff --git a/rts/win32/veh_excn.c b/rts/win32/veh_excn.c index 999580c7ef310f0e8349f6b9fa4b0bee684b132b..183c4657e9ad1b29148bd65c783266c567c5ea4e 100644 --- a/rts/win32/veh_excn.c +++ b/rts/win32/veh_excn.c @@ -287,6 +287,16 @@ void generateStack (EXCEPTION_POINTERS* pExceptionPointers) stackFrame.AddrStack.Offset = context->Rsp; stackFrame.AddrStack.Mode = AddrModeFlat; +#elif defined(aarch64_HOST_ARCH) + machineType = IMAGE_FILE_MACHINE_ARM64; + stackFrame.AddrPC.Offset = context->Pc; + stackFrame.AddrPC.Mode = AddrModeFlat; + + stackFrame.AddrFrame.Offset = context->Fp; + stackFrame.AddrFrame.Mode = AddrModeFlat; + + stackFrame.AddrStack.Offset = context->Sp; + stackFrame.AddrStack.Mode = AddrModeFlat; #endif fprintf (stderr, "\n Attempting to reconstruct a stack trace...\n\n"); if (!SymInitialize (GetCurrentProcess (), NULL, true)) diff --git a/testsuite/tests/ghc-api/fixed-nodes/all.T b/testsuite/tests/ghc-api/fixed-nodes/all.T index 7d512269d258482185efb1a1182bd6556692c2d7..961b3e66172c8ded16e3b228208dd768f067a17e 100644 --- a/testsuite/tests/ghc-api/fixed-nodes/all.T +++ b/testsuite/tests/ghc-api/fixed-nodes/all.T @@ -2,7 +2,6 @@ test('FixedNodes', [extra_run_opts(f'"{config.libdir}"'), extra_files(['T1A.hs', 'T1B.hs', 'T1C.hs']), wasm_broken(25953), - js_broken(25953) ], compile_and_run, ['-package ghc']) diff --git a/testsuite/tests/interface-stability/base-exports.stdout-javascript-unknown-ghcjs b/testsuite/tests/interface-stability/base-exports.stdout-javascript-unknown-ghcjs index 43f9b7bcb2c48c155edad04799c7f87425b3e023..d67be89fb65b19ebcd25b5c93d4a38c76a35d2dd 100644 --- a/testsuite/tests/interface-stability/base-exports.stdout-javascript-unknown-ghcjs +++ b/testsuite/tests/interface-stability/base-exports.stdout-javascript-unknown-ghcjs @@ -13536,6 +13536,7 @@ module System.Posix.Internals where c_lseek :: GHC.Internal.Foreign.C.Types.CInt -> GHC.Internal.System.Posix.Types.COff -> GHC.Internal.Foreign.C.Types.CInt -> GHC.Internal.Types.IO GHC.Internal.System.Posix.Types.COff c_mkfifo :: GHC.Internal.Foreign.C.String.Encoding.CString -> GHC.Internal.System.Posix.Types.CMode -> GHC.Internal.Types.IO GHC.Internal.Foreign.C.Types.CInt c_open :: CFilePath -> GHC.Internal.Foreign.C.Types.CInt -> GHC.Internal.System.Posix.Types.CMode -> GHC.Internal.Types.IO GHC.Internal.Foreign.C.Types.CInt + c_openat :: GHC.Internal.Foreign.C.Types.CInt -> CFilePath -> GHC.Internal.Foreign.C.Types.CInt -> GHC.Internal.System.Posix.Types.CMode -> GHC.Internal.Types.IO GHC.Internal.Foreign.C.Types.CInt c_pipe :: GHC.Internal.Ptr.Ptr GHC.Internal.Foreign.C.Types.CInt -> GHC.Internal.Types.IO GHC.Internal.Foreign.C.Types.CInt c_read :: GHC.Internal.Foreign.C.Types.CInt -> GHC.Internal.Ptr.Ptr GHC.Internal.Word.Word8 -> GHC.Internal.Foreign.C.Types.CSize -> GHC.Internal.Types.IO GHC.Internal.System.Posix.Types.CSsize c_s_isblk :: GHC.Internal.System.Posix.Types.CMode -> GHC.Internal.Foreign.C.Types.CInt diff --git a/utils/ghc-toolchain/exe/Main.hs b/utils/ghc-toolchain/exe/Main.hs index 71faaf79a171fb87219f1d4bebb1822f084060bf..7e75e7b1bb3670b9f90c9164c128108e7269695d 100644 --- a/utils/ghc-toolchain/exe/Main.hs +++ b/utils/ghc-toolchain/exe/Main.hs @@ -348,6 +348,7 @@ tablesNextToCodeSupported archOs = ArchPPC -> False ArchPPC_64 _ -> False ArchS390X -> False + ArchAArch64 -> archOS_OS archOs /= OSMinGW32 _ -> True determineTablesNextToCode diff --git a/utils/hsc2hs b/utils/hsc2hs index c3b21800a67366c9591dc85a471d1dfdb1efcf29..2fab2f4cdffef12afe561ef03f5ebdace7dbae67 160000 --- a/utils/hsc2hs +++ b/utils/hsc2hs @@ -1 +1 @@ -Subproject commit c3b21800a67366c9591dc85a471d1dfdb1efcf29 +Subproject commit 2fab2f4cdffef12afe561ef03f5ebdace7dbae67 diff --git a/utils/llvm-targets/gen-data-layout.sh b/utils/llvm-targets/gen-data-layout.sh index 2f50bf15de3a37de111eb899d825342e20abc62d..b594f141a936660be75a9b9790bfccab9368bd10 100755 --- a/utils/llvm-targets/gen-data-layout.sh +++ b/utils/llvm-targets/gen-data-layout.sh @@ -27,6 +27,7 @@ TARGETS=( # Windows "x86_64-unknown-windows-gnu" + "aarch64-unknown-windows-gnu" ######################### # Linux