diff options
| author | Pietro Albini <pietro@pietroalbini.org> | 2018-11-18 23:24:31 +0100 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2018-11-18 23:24:31 +0100 |
| commit | 36e1d9f3edee62058a871d432a07dc4326f3e082 (patch) | |
| tree | 17134d2d35ceaa595dc281b1575aa2a6ebe5a6b6 | |
| parent | 13c9439925797cd7a65c917d047c07a500d9bfe6 (diff) | |
| parent | 4f9c86038529880458195daafd97d4cbc8f9ee27 (diff) | |
| download | rust-36e1d9f3edee62058a871d432a07dc4326f3e082.tar.gz rust-36e1d9f3edee62058a871d432a07dc4326f3e082.zip | |
Rollup merge of #55562 - smaeul:powerpc-linux-musl, r=alexcrichton
Add powerpc- and powerpc64-unknown-linux-musl targets Add targets for musl on 32-bit and 64-bit powerpc. This requires some ABI fixes, as musl [uses the ELFv2 ABI on regardless of endianness](http://git.musl-libc.org/cgit/musl/tree/configure?id=8084d6ab57cdb0b8f328d3cdbad3b9d09eaaee04#n638). At the moment, powerpc64 support requires [an LLVM patch](https://reviews.llvm.org/D52013) to select the correct ABI; or I can add [a patch to Rust's LLVM backend](https://github.com/smaeul/rust/commit/e8eaa2afd51ed9950096359a040ba1603907cdd1) to always choose the right ABI. Both architectures are able to run an extended bootstrap, and with some test fixes (e.g. #55561), there are no architecture-dependent test failures on powerpc64 (most failures in `src/test` are existing musl-host-related issues).
| -rw-r--r-- | src/librustc_target/abi/call/powerpc64.rs | 44 | ||||
| -rw-r--r-- | src/librustc_target/abi/mod.rs | 2 | ||||
| -rw-r--r-- | src/librustc_target/spec/mod.rs | 2 | ||||
| -rw-r--r-- | src/librustc_target/spec/powerpc64_unknown_linux_musl.rs | 32 | ||||
| -rw-r--r-- | src/librustc_target/spec/powerpc_unknown_linux_musl.rs | 31 |
5 files changed, 88 insertions, 23 deletions
diff --git a/src/librustc_target/abi/call/powerpc64.rs b/src/librustc_target/abi/call/powerpc64.rs index 80a4d693dc3..f7ef1390f14 100644 --- a/src/librustc_target/abi/call/powerpc64.rs +++ b/src/librustc_target/abi/call/powerpc64.rs @@ -14,11 +14,12 @@ use abi::call::{FnType, ArgType, Reg, RegKind, Uniform}; use abi::{Align, Endian, HasDataLayout, LayoutOf, TyLayout, TyLayoutMethods}; +use spec::HasTargetSpec; #[derive(Debug, Clone, Copy, PartialEq)] enum ABI { ELFv1, // original ABI used for powerpc64 (big-endian) - ELFv2, // newer ABI used for powerpc64le + ELFv2, // newer ABI used for powerpc64le and musl (both endians) } use self::ABI::*; @@ -75,7 +76,9 @@ fn classify_ret_ty<'a, Ty, C>(cx: &C, ret: &mut ArgType<'a, Ty>, abi: ABI) let size = ret.layout.size; let bits = size.bits(); if bits <= 128 { - let unit = if bits <= 8 { + let unit = if cx.data_layout().endian == Endian::Big { + Reg { kind: RegKind::Integer, size } + } else if bits <= 8 { Reg::i8() } else if bits <= 16 { Reg::i16() @@ -110,22 +113,15 @@ fn classify_arg_ty<'a, Ty, C>(cx: &C, arg: &mut ArgType<'a, Ty>, abi: ABI) } let size = arg.layout.size; - let (unit, total) = match abi { - ELFv1 => { - // In ELFv1, aggregates smaller than a doubleword should appear in - // the least-significant bits of the parameter doubleword. The rest - // should be padded at their tail to fill out multiple doublewords. - if size.bits() <= 64 { - (Reg { kind: RegKind::Integer, size }, size) - } else { - let align = Align::from_bits(64, 64).unwrap(); - (Reg::i64(), size.abi_align(align)) - } - }, - ELFv2 => { - // In ELFv2, we can just cast directly. - (Reg::i64(), size) - }, + let (unit, total) = if size.bits() <= 64 { + // Aggregates smaller than a doubleword should appear in + // the least-significant bits of the parameter doubleword. + (Reg { kind: RegKind::Integer, size }, size) + } else { + // Aggregates larger than a doubleword should be padded + // at the tail to fill out a whole number of doublewords. + let align = Align::from_bits(64, 64).unwrap(); + (Reg::i64(), size.abi_align(align)) }; arg.cast_to(Uniform { @@ -136,11 +132,15 @@ fn classify_arg_ty<'a, Ty, C>(cx: &C, arg: &mut ArgType<'a, Ty>, abi: ABI) pub fn compute_abi_info<'a, Ty, C>(cx: &C, fty: &mut FnType<'a, Ty>) where Ty: TyLayoutMethods<'a, C> + Copy, - C: LayoutOf<Ty = Ty, TyLayout = TyLayout<'a, Ty>> + HasDataLayout + C: LayoutOf<Ty = Ty, TyLayout = TyLayout<'a, Ty>> + HasDataLayout + HasTargetSpec { - let abi = match cx.data_layout().endian { - Endian::Big => ELFv1, - Endian::Little => ELFv2, + let abi = if cx.target_spec().target_env == "musl" { + ELFv2 + } else { + match cx.data_layout().endian { + Endian::Big => ELFv1, + Endian::Little => ELFv2 + } }; if !fty.ret.is_ignore() { diff --git a/src/librustc_target/abi/mod.rs b/src/librustc_target/abi/mod.rs index 88f22912fa6..22afb0da05b 100644 --- a/src/librustc_target/abi/mod.rs +++ b/src/librustc_target/abi/mod.rs @@ -229,7 +229,7 @@ impl HasDataLayout for TargetDataLayout { } /// Endianness of the target, which must match cfg(target-endian). -#[derive(Copy, Clone)] +#[derive(Copy, Clone, PartialEq)] pub enum Endian { Little, Big diff --git a/src/librustc_target/spec/mod.rs b/src/librustc_target/spec/mod.rs index 16dc2a91030..f67152ee90b 100644 --- a/src/librustc_target/spec/mod.rs +++ b/src/librustc_target/spec/mod.rs @@ -297,7 +297,9 @@ supported_targets! { ("mipsel-unknown-linux-gnu", mipsel_unknown_linux_gnu), ("powerpc-unknown-linux-gnu", powerpc_unknown_linux_gnu), ("powerpc-unknown-linux-gnuspe", powerpc_unknown_linux_gnuspe), + ("powerpc-unknown-linux-musl", powerpc_unknown_linux_musl), ("powerpc64-unknown-linux-gnu", powerpc64_unknown_linux_gnu), + ("powerpc64-unknown-linux-musl", powerpc64_unknown_linux_musl), ("powerpc64le-unknown-linux-gnu", powerpc64le_unknown_linux_gnu), ("powerpc64le-unknown-linux-musl", powerpc64le_unknown_linux_musl), ("s390x-unknown-linux-gnu", s390x_unknown_linux_gnu), diff --git a/src/librustc_target/spec/powerpc64_unknown_linux_musl.rs b/src/librustc_target/spec/powerpc64_unknown_linux_musl.rs new file mode 100644 index 00000000000..95e95510e1f --- /dev/null +++ b/src/librustc_target/spec/powerpc64_unknown_linux_musl.rs @@ -0,0 +1,32 @@ +// Copyright 2018 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +use spec::{LinkerFlavor, Target, TargetResult}; + +pub fn target() -> TargetResult { + let mut base = super::linux_musl_base::opts(); + base.cpu = "ppc64".to_string(); + base.pre_link_args.get_mut(&LinkerFlavor::Gcc).unwrap().push("-m64".to_string()); + base.max_atomic_width = Some(64); + + Ok(Target { + llvm_target: "powerpc64-unknown-linux-musl".to_string(), + target_endian: "big".to_string(), + target_pointer_width: "64".to_string(), + target_c_int_width: "32".to_string(), + data_layout: "E-m:e-i64:64-n32:64".to_string(), + arch: "powerpc64".to_string(), + target_os: "linux".to_string(), + target_env: "musl".to_string(), + target_vendor: "unknown".to_string(), + linker_flavor: LinkerFlavor::Gcc, + options: base, + }) +} diff --git a/src/librustc_target/spec/powerpc_unknown_linux_musl.rs b/src/librustc_target/spec/powerpc_unknown_linux_musl.rs new file mode 100644 index 00000000000..1a4d0cb323f --- /dev/null +++ b/src/librustc_target/spec/powerpc_unknown_linux_musl.rs @@ -0,0 +1,31 @@ +// Copyright 2018 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +use spec::{LinkerFlavor, Target, TargetResult}; + +pub fn target() -> TargetResult { + let mut base = super::linux_musl_base::opts(); + base.pre_link_args.get_mut(&LinkerFlavor::Gcc).unwrap().push("-m32".to_string()); + base.max_atomic_width = Some(32); + + Ok(Target { + llvm_target: "powerpc-unknown-linux-musl".to_string(), + target_endian: "big".to_string(), + target_pointer_width: "32".to_string(), + target_c_int_width: "32".to_string(), + data_layout: "E-m:e-p:32:32-i64:64-n32".to_string(), + arch: "powerpc".to_string(), + target_os: "linux".to_string(), + target_env: "musl".to_string(), + target_vendor: "unknown".to_string(), + linker_flavor: LinkerFlavor::Gcc, + options: base, + }) +} |
