From 81303d7d90b483b8e2611cef09adc56c02ccfc50 Mon Sep 17 00:00:00 2001 From: Samuel Holland Date: Mon, 10 Sep 2018 01:35:35 +0000 Subject: [PATCH 1/4] Add powerpc-unknown-linux-musl target --- src/librustc_target/spec/mod.rs | 1 + .../spec/powerpc_unknown_linux_musl.rs | 31 +++++++++++++++++++ 2 files changed, 32 insertions(+) create mode 100644 src/librustc_target/spec/powerpc_unknown_linux_musl.rs diff --git a/src/librustc_target/spec/mod.rs b/src/librustc_target/spec/mod.rs index 16dc2a91030f1..792afc759e166 100644 --- a/src/librustc_target/spec/mod.rs +++ b/src/librustc_target/spec/mod.rs @@ -297,6 +297,7 @@ 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), ("powerpc64le-unknown-linux-gnu", powerpc64le_unknown_linux_gnu), ("powerpc64le-unknown-linux-musl", powerpc64le_unknown_linux_musl), 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 0000000000000..1a4d0cb323f1f --- /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 or the MIT license +// , 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, + }) +} From 346e97600bafd916c41c24d01ef8671511d691c2 Mon Sep 17 00:00:00 2001 From: Samuel Holland Date: Sun, 16 Sep 2018 16:34:15 +0000 Subject: [PATCH 2/4] Fix powerpc64 ELFv2 big-endian struct-passing ABI The requirements here are not "ELFv1" requirements, but big-endian requirements, as the extension or non-extension of the argument is necessary to put the argument in the correct half of the register. Parameter passing in the ELFv2 ABI needs these same transformations. Since this code makes no difference on little-endian machines, simplify it to use the same code path everywhere. --- src/librustc_target/abi/call/powerpc64.rs | 29 ++++++++++------------- src/librustc_target/abi/mod.rs | 2 +- 2 files changed, 13 insertions(+), 18 deletions(-) diff --git a/src/librustc_target/abi/call/powerpc64.rs b/src/librustc_target/abi/call/powerpc64.rs index 80a4d693dc36b..56d09c072924d 100644 --- a/src/librustc_target/abi/call/powerpc64.rs +++ b/src/librustc_target/abi/call/powerpc64.rs @@ -75,7 +75,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 +112,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 { diff --git a/src/librustc_target/abi/mod.rs b/src/librustc_target/abi/mod.rs index 88f22912fa6fc..22afb0da05bc1 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 From 2bb5029d748ceee2f0501fbba786944a3ead6019 Mon Sep 17 00:00:00 2001 From: Samuel Holland Date: Wed, 8 Aug 2018 22:06:18 -0500 Subject: [PATCH 3/4] Use the ELFv2 ABI on powerpc64 musl --- src/librustc_target/abi/call/powerpc64.rs | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/src/librustc_target/abi/call/powerpc64.rs b/src/librustc_target/abi/call/powerpc64.rs index 56d09c072924d..f7ef1390f14de 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::*; @@ -131,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> + HasDataLayout + C: LayoutOf> + 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() { From 4f9c86038529880458195daafd97d4cbc8f9ee27 Mon Sep 17 00:00:00 2001 From: Samuel Holland Date: Tue, 7 Aug 2018 21:59:15 -0500 Subject: [PATCH 4/4] Add powerpc64-unknown-linux-musl target --- src/librustc_target/spec/mod.rs | 1 + .../spec/powerpc64_unknown_linux_musl.rs | 32 +++++++++++++++++++ 2 files changed, 33 insertions(+) create mode 100644 src/librustc_target/spec/powerpc64_unknown_linux_musl.rs diff --git a/src/librustc_target/spec/mod.rs b/src/librustc_target/spec/mod.rs index 792afc759e166..f67152ee90b7a 100644 --- a/src/librustc_target/spec/mod.rs +++ b/src/librustc_target/spec/mod.rs @@ -299,6 +299,7 @@ supported_targets! { ("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 0000000000000..95e95510e1fea --- /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 or the MIT license +// , 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, + }) +}