diff --git a/compiler/rustc_target/src/spec/apple_base.rs b/compiler/rustc_target/src/spec/apple_base.rs index 5c6dcc0aba9c3..4c7f64b20785b 100644 --- a/compiler/rustc_target/src/spec/apple_base.rs +++ b/compiler/rustc_target/src/spec/apple_base.rs @@ -19,6 +19,7 @@ pub enum Arch { I386, I686, X86_64, + X86_64h, X86_64_sim, X86_64_macabi, Arm64_macabi, @@ -36,6 +37,7 @@ impl Arch { I386 => "i386", I686 => "i686", X86_64 | X86_64_sim | X86_64_macabi => "x86_64", + X86_64h => "x86_64h", } } @@ -44,13 +46,13 @@ impl Arch { Armv7 | Armv7k | Armv7s => "arm", Arm64 | Arm64_32 | Arm64_macabi | Arm64_sim => "aarch64", I386 | I686 => "x86", - X86_64 | X86_64_sim | X86_64_macabi => "x86_64", + X86_64 | X86_64_sim | X86_64_macabi | X86_64h => "x86_64", }) } fn target_abi(self) -> &'static str { match self { - Armv7 | Armv7k | Armv7s | Arm64 | Arm64_32 | I386 | I686 | X86_64 => "", + Armv7 | Armv7k | Armv7s | Arm64 | Arm64_32 | I386 | I686 | X86_64 | X86_64h => "", X86_64_macabi | Arm64_macabi => "macabi", // x86_64-apple-ios is a simulator target, even though it isn't // declared that way in the target like the other ones... @@ -67,6 +69,10 @@ impl Arch { Arm64_32 => "apple-s4", I386 | I686 => "yonah", X86_64 | X86_64_sim => "core2", + // Note: `core-avx2` is slightly more advanced than `x86_64h`, see + // comments (and disabled features) in `x86_64h_apple_darwin` for + // details. + X86_64h => "core-avx2", X86_64_macabi => "core2", Arm64_macabi => "apple-a12", Arm64_sim => "apple-a12", @@ -182,8 +188,13 @@ fn deployment_target(var_name: &str) -> Option<(u32, u32)> { } fn macos_default_deployment_target(arch: Arch) -> (u32, u32) { - // Note: Arm64_sim is not included since macOS has no simulator. - if matches!(arch, Arm64 | Arm64_macabi) { (11, 0) } else { (10, 7) } + match arch { + // Note: Arm64_sim is not included since macOS has no simulator. + Arm64 | Arm64_macabi => (11, 0), + // x86_64h-apple-darwin only supports macOS 10.8 and later + X86_64h => (10, 8), + _ => (10, 7), + } } fn macos_deployment_target(arch: Arch) -> (u32, u32) { @@ -227,7 +238,7 @@ fn link_env_remove(arch: Arch, os: &'static str) -> StaticCow<[StaticCow]> // of the linking environment that's wrong and reversed. match arch { Armv7 | Armv7k | Armv7s | Arm64 | Arm64_32 | I386 | I686 | X86_64 | X86_64_sim - | Arm64_sim => { + | X86_64h | Arm64_sim => { cvs!["MACOSX_DEPLOYMENT_TARGET"] } X86_64_macabi | Arm64_macabi => cvs!["IPHONEOS_DEPLOYMENT_TARGET"], diff --git a/compiler/rustc_target/src/spec/mod.rs b/compiler/rustc_target/src/spec/mod.rs index 0d86a3032a659..9747789c25435 100644 --- a/compiler/rustc_target/src/spec/mod.rs +++ b/compiler/rustc_target/src/spec/mod.rs @@ -1110,6 +1110,7 @@ supported_targets! { ("aarch64-apple-darwin", aarch64_apple_darwin), ("x86_64-apple-darwin", x86_64_apple_darwin), + ("x86_64h-apple-darwin", x86_64h_apple_darwin), ("i686-apple-darwin", i686_apple_darwin), // FIXME(#106649): Remove aarch64-fuchsia in favor of aarch64-unknown-fuchsia diff --git a/compiler/rustc_target/src/spec/x86_64h_apple_darwin.rs b/compiler/rustc_target/src/spec/x86_64h_apple_darwin.rs new file mode 100644 index 0000000000000..54f7490b2c052 --- /dev/null +++ b/compiler/rustc_target/src/spec/x86_64h_apple_darwin.rs @@ -0,0 +1,44 @@ +use super::apple_base::{macos_llvm_target, opts, Arch}; +use crate::spec::{Cc, FramePointer, LinkerFlavor, Lld, SanitizerSet}; +use crate::spec::{StackProbeType, Target, TargetOptions}; + +pub fn target() -> Target { + let arch = Arch::X86_64h; + let mut base = opts("macos", arch); + base.max_atomic_width = Some(128); + base.frame_pointer = FramePointer::Always; + base.add_pre_link_args(LinkerFlavor::Darwin(Cc::Yes, Lld::No), &["-m64"]); + base.stack_probes = StackProbeType::X86; + base.supported_sanitizers = + SanitizerSet::ADDRESS | SanitizerSet::CFI | SanitizerSet::LEAK | SanitizerSet::THREAD; + + // x86_64h is core2-avx without a few of the features which would otherwise + // be guaranteed, so we need to disable those. This imitates clang's logic: + // - https://github.com/llvm/llvm-project/blob/bd1f7c417/clang/lib/Driver/ToolChains/Arch/X86.cpp#L77-L78 + // - https://github.com/llvm/llvm-project/blob/bd1f7c417/clang/lib/Driver/ToolChains/Arch/X86.cpp#L133-L141 + // + // FIXME: Sadly, turning these off here disables them in such a way that they + // aren't re-enabled by `-Ctarget-cpu=native` (on a machine that has them). + // It would be nice if this were not the case, but fixing it seems tricky + // (and given that the main use-case for this target is for use in universal + // binaries, probably not that important). + base.features = "-rdrnd,-aes,-pclmul,-rtm,-fsgsbase".into(); + // Double-check that the `cpu` is what we expect (if it's not the list above + // may need updating). + assert_eq!( + base.cpu, "core-avx2", + "you need to adjust the feature list in x86_64h-apple-darwin if you change this", + ); + + Target { + // Clang automatically chooses a more specific target based on + // MACOSX_DEPLOYMENT_TARGET. To enable cross-language LTO to work + // correctly, we do too. + llvm_target: macos_llvm_target(arch).into(), + pointer_width: 64, + data_layout: "e-m:o-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128" + .into(), + arch: arch.target_arch(), + options: TargetOptions { mcount: "\u{1}mcount".into(), ..base }, + } +} diff --git a/src/doc/rustc/src/SUMMARY.md b/src/doc/rustc/src/SUMMARY.md index 752f1cc4aba03..64197c0e27b7e 100644 --- a/src/doc/rustc/src/SUMMARY.md +++ b/src/doc/rustc/src/SUMMARY.md @@ -40,6 +40,7 @@ - [wasm64-unknown-unknown](platform-support/wasm64-unknown-unknown.md) - [x86_64-fortanix-unknown-sgx](platform-support/x86_64-fortanix-unknown-sgx.md) - [x86_64-unknown-none](platform-support/x86_64-unknown-none.md) + - [x86_64h-apple-darwin](platform-support/x86_64h-apple-darwin.md) - [Targets](targets/index.md) - [Built-in Targets](targets/built-in.md) - [Custom Targets](targets/custom.md) diff --git a/src/doc/rustc/src/platform-support.md b/src/doc/rustc/src/platform-support.md index 9eafa27e2b7c8..29df3c7f1f1a0 100644 --- a/src/doc/rustc/src/platform-support.md +++ b/src/doc/rustc/src/platform-support.md @@ -322,5 +322,6 @@ target | std | host | notes `x86_64-uwp-windows-gnu` | ✓ | | `x86_64-uwp-windows-msvc` | ✓ | | `x86_64-wrs-vxworks` | ? | | +`x86_64h-apple-darwin` | ✓ | ✓ | macOS with late-gen Intel (at least Haswell) [runs on NVIDIA GPUs]: https://github.com/japaric-archived/nvptx#targets diff --git a/src/doc/rustc/src/platform-support/x86_64h-apple-darwin.md b/src/doc/rustc/src/platform-support/x86_64h-apple-darwin.md new file mode 100644 index 0000000000000..1a6f7bb834cf5 --- /dev/null +++ b/src/doc/rustc/src/platform-support/x86_64h-apple-darwin.md @@ -0,0 +1,57 @@ +# `x86_64h-apple-darwin` + +**Tier: 3** + +Target for macOS on late-generation `x86_64` Apple chips, usable as the +`x86_64h` entry in universal binaries, and equivalent to LLVM's +`x86_64h-apple-macosx*` targets. + +## Target maintainers + +- Thom Chiovoloni `thom@shift.click` + +## Requirements + +This target is an `x86_64` target that only supports Apple's late-gen +(Haswell-compatible) Intel chips. It enables a set of target features available +on these chips (AVX2 and similar), and MachO binaries built with this target may +be used as the `x86_64h` entry in universal binaries ("fat" MachO binaries), and +will fail to load on machines that do not support this. + +It should support the full standard library (`std` and `alloc` either with +default or user-defined allocators). This target is probably most useful when +targetted via cross-compilation (including from `x86_64-apple-darwin`), but if +built manually, the host tools work. + +It is similar to `x86_64-apple-darwin` in nearly all respects, although the +minimum supported OS version is slightly higher (it requires 10.8 rather than +`x86_64-apple-darwin`'s 10.7). + +## Building the target + +Users on Apple targets can build this by adding it to the `target` list in +`config.toml`, or with `-Zbuild-std`. + +## Building Rust programs + +Rust does not yet ship pre-compiled artifacts for this target. To compile for +this target, you will either need to build Rust with the target enabled (see +"Building the target" above), or build your own copy of `core` by using +`build-std` or similar. + +## Testing + +Code built with this target can be run on the set of Intel macOS machines that +support running `x86_64h` binaries (relatively recent Intel macs). The Rust test +suite seems to work. + +## Cross-compilation toolchains and C code + +Cross-compilation to this target from Apple hosts should generally work without +much configuration, so long as XCode and the CommandLineTools are installed. +Targetting it from non-Apple hosts is difficult, but no moreso than targetting +`x86_64-apple-darwin`. + +When compiling C code for this target, either the "`x86_64h-apple-macosx*`" LLVM +targets should be used, or an argument like `-arch x86_64h` should be passed to +the C compiler.