diff options
Diffstat (limited to 'user/rust/0017-Fix-powerpc64-ELFv2-big-endian-struct-passing-ABI.patch')
-rw-r--r-- | user/rust/0017-Fix-powerpc64-ELFv2-big-endian-struct-passing-ABI.patch | 93 |
1 files changed, 93 insertions, 0 deletions
diff --git a/user/rust/0017-Fix-powerpc64-ELFv2-big-endian-struct-passing-ABI.patch b/user/rust/0017-Fix-powerpc64-ELFv2-big-endian-struct-passing-ABI.patch new file mode 100644 index 000000000..35bf35f6c --- /dev/null +++ b/user/rust/0017-Fix-powerpc64-ELFv2-big-endian-struct-passing-ABI.patch @@ -0,0 +1,93 @@ +From 87d7cb5226728f549af3a7f469a6107c3acbc41d Mon Sep 17 00:00:00 2001 +From: Samuel Holland <samuel@sholland.org> +Date: Sun, 16 Sep 2018 16:34:15 +0000 +Subject: [PATCH 17/28] 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 | 36 ++++++++++------------- + src/librustc_target/abi/mod.rs | 2 +- + 2 files changed, 17 insertions(+), 21 deletions(-) + +diff --git a/src/librustc_target/abi/call/powerpc64.rs b/src/librustc_target/abi/call/powerpc64.rs +index 4851b25fe7..9e616c034e 100644 +--- a/src/librustc_target/abi/call/powerpc64.rs ++++ b/src/librustc_target/abi/call/powerpc64.rs +@@ -76,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() +@@ -111,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 { +@@ -139,9 +134,10 @@ 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 + HasTargetSpec + { +- let abi = match cx.target_spec().target_env { +- "musl" => ELFv2, +- _ => match cx.data_layout().endian { ++ let abi = if cx.target_spec().target_env == "musl" { ++ ELFv2 ++ } else { ++ match cx.data_layout().endian { + Endian::Big => ELFv1, + Endian::Little => ELFv2 + } +diff --git a/src/librustc_target/abi/mod.rs b/src/librustc_target/abi/mod.rs +index dac4738e2b..35b1ceb967 100644 +--- a/src/librustc_target/abi/mod.rs ++++ b/src/librustc_target/abi/mod.rs +@@ -214,7 +214,7 @@ impl<'a> HasDataLayout for &'a TargetDataLayout { + } + + /// Endianness of the target, which must match cfg(target-endian). +-#[derive(Copy, Clone)] ++#[derive(Copy, Clone, PartialEq)] + pub enum Endian { + Little, + Big +-- +2.18.0 + |