Auto merge of #126907 - glaubitz:sparc-fixes, r=nagisa

Fixes for 32-bit SPARC on Linux

This PR fixes a number of issues which previously prevented `rustc` from being built
successfully for 32-bit SPARC using the `sparc-unknown-linux-gnu` triplet.

In particular, it adds linking against `libatomic` where necessary, uses portable `AtomicU64`
for `rustc_data_structures` and rewrites the spec for `sparc_unknown_linux_gnu` to use
`TargetOptions` and replaces the previously used `-mv8plus` with the more portable
`-mcpu=v9 -m32`.

To make `rustc` build successfully, support for 32-bit SPARC needs to be added to the `object`
crate as well as the `nix` crate which I will be sending out later as well.

r? nagisa
This commit is contained in:
bors 2024-06-27 05:44:47 +00:00
commit 536235f07e
6 changed files with 25 additions and 18 deletions

View File

@ -50,7 +50,7 @@ libc = "0.2"
memmap2 = "0.2.1"
# tidy-alphabetical-end
[target.'cfg(any(target_arch = "powerpc", target_arch = "mips"))'.dependencies]
[target.'cfg(any(target_arch = "mips", target_arch = "powerpc", target_arch = "sparc"))'.dependencies]
portable-atomic = "1.5.1"
[features]

View File

@ -147,14 +147,14 @@ macro_rules! already_sync {
[crate::owned_slice::OwnedSlice]
);
// PowerPC and MIPS platforms with 32-bit pointers do not
// MIPS, PowerPC and SPARC platforms with 32-bit pointers do not
// have AtomicU64 type.
#[cfg(not(any(target_arch = "powerpc", target_arch = "mips")))]
#[cfg(not(any(target_arch = "powerpc", target_arch = "powerpc", target_arch = "sparc")))]
already_sync!(
[std::sync::atomic::AtomicU64]
);
#[cfg(any(target_arch = "powerpc", target_arch = "mips"))]
#[cfg(any(target_arch = "mips", target_arch = "powerpc", target_arch = "sparc"))]
already_sync!(
[portable_atomic::AtomicU64]
);

View File

@ -270,12 +270,12 @@ fn clone(&self) -> Self {
pub use std::sync::atomic::{AtomicBool, AtomicUsize, AtomicU32};
// PowerPC and MIPS platforms with 32-bit pointers do not
// MIPS, PowerPC and SPARC platforms with 32-bit pointers do not
// have AtomicU64 type.
#[cfg(not(any(target_arch = "powerpc", target_arch = "mips")))]
#[cfg(not(any(target_arch = "mips", target_arch = "powerpc", target_arch = "sparc")))]
pub use std::sync::atomic::AtomicU64;
#[cfg(any(target_arch = "powerpc", target_arch = "mips"))]
#[cfg(any(target_arch = "mips", target_arch = "powerpc", target_arch = "sparc"))]
pub use portable_atomic::AtomicU64;
pub use std::sync::Arc as Lrc;

View File

@ -235,6 +235,7 @@ fn main() {
|| target.starts_with("mips-")
|| target.starts_with("mipsel-")
|| target.starts_with("powerpc-")
|| target.starts_with("sparc-")
{
// 32-bit targets need to link libatomic.
println!("cargo:rustc-link-lib=atomic");

View File

@ -1,13 +1,7 @@
use crate::abi::Endian;
use crate::spec::{base, Cc, LinkerFlavor, Lld, Target};
use crate::spec::{base, Cc, LinkerFlavor, Lld, Target, TargetOptions};
pub fn target() -> Target {
let mut base = base::linux_gnu::opts();
base.endian = Endian::Big;
base.cpu = "v9".into();
base.max_atomic_width = Some(32);
base.add_pre_link_args(LinkerFlavor::Gnu(Cc::Yes, Lld::No), &["-mv8plus"]);
Target {
llvm_target: "sparc-unknown-linux-gnu".into(),
metadata: crate::spec::TargetMetadata {
@ -19,6 +13,15 @@ pub fn target() -> Target {
pointer_width: 32,
data_layout: "E-m:e-p:32:32-i64:64-f128:64-n32-S64".into(),
arch: "sparc".into(),
options: base,
options: TargetOptions {
cpu: "v9".into(),
endian: Endian::Big,
late_link_args: TargetOptions::link_args(
LinkerFlavor::Gnu(Cc::Yes, Lld::No),
&["-mcpu=v9", "-m32"],
),
max_atomic_width: Some(32),
..base::linux_gnu::opts()
},
}
}

View File

@ -407,18 +407,21 @@ fn run(self, builder: &Builder<'_>) -> LlvmResult {
cfg.define("LLVM_LINK_LLVM_DYLIB", "ON");
}
if (target.starts_with("riscv") || target.starts_with("csky"))
if (target.starts_with("csky")
|| target.starts_with("riscv")
|| target.starts_with("sparc-"))
&& !target.contains("freebsd")
&& !target.contains("openbsd")
&& !target.contains("netbsd")
{
// RISC-V and CSKY GCC erroneously requires linking against
// CSKY and RISC-V GCC erroneously requires linking against
// `libatomic` when using 1-byte and 2-byte C++
// atomics but the LLVM build system check cannot
// detect this. Therefore it is set manually here.
// Some BSD uses Clang as its system compiler and
// provides no libatomic in its base system so does
// not want this.
// not want this. 32-bit SPARC requires linking against
// libatomic as well.
ldflags.exe.push(" -latomic");
ldflags.shared.push(" -latomic");
}