summaryrefslogtreecommitdiff
path: root/user/rust/0018-Fix-powerpc64-ELFv2-big-endian-struct-passing-ABI.patch
diff options
context:
space:
mode:
Diffstat (limited to 'user/rust/0018-Fix-powerpc64-ELFv2-big-endian-struct-passing-ABI.patch')
-rw-r--r--user/rust/0018-Fix-powerpc64-ELFv2-big-endian-struct-passing-ABI.patch93
1 files changed, 93 insertions, 0 deletions
diff --git a/user/rust/0018-Fix-powerpc64-ELFv2-big-endian-struct-passing-ABI.patch b/user/rust/0018-Fix-powerpc64-ELFv2-big-endian-struct-passing-ABI.patch
new file mode 100644
index 000000000..d1a6daa16
--- /dev/null
+++ b/user/rust/0018-Fix-powerpc64-ELFv2-big-endian-struct-passing-ABI.patch
@@ -0,0 +1,93 @@
+From c99f30986f8486cc24dda5630b685dd932d510d4 Mon Sep 17 00:00:00 2001
+From: Samuel Holland <samuel@sholland.org>
+Date: Sun, 16 Sep 2018 16:34:15 +0000
+Subject: [PATCH 18/29] 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
+