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" memmap2 = "0.2.1"
# tidy-alphabetical-end # 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" portable-atomic = "1.5.1"
[features] [features]

View File

@ -147,14 +147,14 @@ cfg_match! {
[crate::owned_slice::OwnedSlice] [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. // 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!( already_sync!(
[std::sync::atomic::AtomicU64] [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!( already_sync!(
[portable_atomic::AtomicU64] [portable_atomic::AtomicU64]
); );

View File

@ -270,12 +270,12 @@ cfg_match! {
pub use std::sync::atomic::{AtomicBool, AtomicUsize, AtomicU32}; 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. // 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; 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 portable_atomic::AtomicU64;
pub use std::sync::Arc as Lrc; pub use std::sync::Arc as Lrc;

View File

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

View File

@ -1,13 +1,7 @@
use crate::abi::Endian; 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 { 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 { Target {
llvm_target: "sparc-unknown-linux-gnu".into(), llvm_target: "sparc-unknown-linux-gnu".into(),
metadata: crate::spec::TargetMetadata { metadata: crate::spec::TargetMetadata {
@ -19,6 +13,15 @@ pub fn target() -> Target {
pointer_width: 32, pointer_width: 32,
data_layout: "E-m:e-p:32:32-i64:64-f128:64-n32-S64".into(), data_layout: "E-m:e-p:32:32-i64:64-f128:64-n32-S64".into(),
arch: "sparc".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 @@ impl Step for Llvm {
cfg.define("LLVM_LINK_LLVM_DYLIB", "ON"); 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("freebsd")
&& !target.contains("openbsd") && !target.contains("openbsd")
&& !target.contains("netbsd") && !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++ // `libatomic` when using 1-byte and 2-byte C++
// atomics but the LLVM build system check cannot // atomics but the LLVM build system check cannot
// detect this. Therefore it is set manually here. // detect this. Therefore it is set manually here.
// Some BSD uses Clang as its system compiler and // Some BSD uses Clang as its system compiler and
// provides no libatomic in its base system so does // 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.exe.push(" -latomic");
ldflags.shared.push(" -latomic"); ldflags.shared.push(" -latomic");
} }