about summary refs log tree commit diff
path: root/compiler/rustc_target/src
diff options
context:
space:
mode:
authorbeetrees <b@beetr.ee>2024-06-01 12:25:16 +0100
committerbeetrees <b@beetr.ee>2024-08-02 11:45:32 +0100
commitb1493ba5194fcc5cfe4f6315db288e4e18509110 (patch)
treecb3efa4fc9ab90d4155a7a01e9947717f49ecf96 /compiler/rustc_target/src
parenta886938671e1fde9d7271dce8ca3d6938bae9d2e (diff)
downloadrust-b1493ba5194fcc5cfe4f6315db288e4e18509110.tar.gz
rust-b1493ba5194fcc5cfe4f6315db288e4e18509110.zip
Move ZST ABI handling to `rustc_target`
Diffstat (limited to 'compiler/rustc_target/src')
-rw-r--r--compiler/rustc_target/src/abi/call/mod.rs13
-rw-r--r--compiler/rustc_target/src/abi/call/powerpc.rs20
-rw-r--r--compiler/rustc_target/src/abi/call/s390x.rs18
-rw-r--r--compiler/rustc_target/src/abi/call/sparc64.rs12
-rw-r--r--compiler/rustc_target/src/abi/call/x86_win64.rs10
5 files changed, 55 insertions, 18 deletions
diff --git a/compiler/rustc_target/src/abi/call/mod.rs b/compiler/rustc_target/src/abi/call/mod.rs
index 5bfc528dffc..25e4d70945b 100644
--- a/compiler/rustc_target/src/abi/call/mod.rs
+++ b/compiler/rustc_target/src/abi/call/mod.rs
@@ -642,7 +642,7 @@ impl<'a, Ty> ArgAbi<'a, Ty> {
     pub fn make_indirect(&mut self) {
         match self.mode {
             PassMode::Direct(_) | PassMode::Pair(_, _) => {
-                self.mode = Self::indirect_pass_mode(&self.layout);
+                self.make_indirect_force();
             }
             PassMode::Indirect { attrs: _, meta_attrs: _, on_stack: false } => {
                 // already indirect
@@ -652,6 +652,11 @@ impl<'a, Ty> ArgAbi<'a, Ty> {
         }
     }
 
+    /// Same as make_indirect, but doesn't check the current `PassMode`.
+    pub fn make_indirect_force(&mut self) {
+        self.mode = Self::indirect_pass_mode(&self.layout);
+    }
+
     /// Pass this argument indirectly, by placing it at a fixed stack offset.
     /// This corresponds to the `byval` LLVM argument attribute.
     /// This is only valid for sized arguments.
@@ -871,10 +876,10 @@ impl<'a, Ty> FnAbi<'a, Ty> {
             }
             "x86_64" => match abi {
                 spec::abi::Abi::SysV64 { .. } => x86_64::compute_abi_info(cx, self),
-                spec::abi::Abi::Win64 { .. } => x86_win64::compute_abi_info(self),
+                spec::abi::Abi::Win64 { .. } => x86_win64::compute_abi_info(cx, self),
                 _ => {
                     if cx.target_spec().is_like_windows {
-                        x86_win64::compute_abi_info(self)
+                        x86_win64::compute_abi_info(cx, self)
                     } else {
                         x86_64::compute_abi_info(cx, self)
                     }
@@ -898,7 +903,7 @@ impl<'a, Ty> FnAbi<'a, Ty> {
             "csky" => csky::compute_abi_info(self),
             "mips" | "mips32r6" => mips::compute_abi_info(cx, self),
             "mips64" | "mips64r6" => mips64::compute_abi_info(cx, self),
-            "powerpc" => powerpc::compute_abi_info(self),
+            "powerpc" => powerpc::compute_abi_info(cx, self),
             "powerpc64" => powerpc64::compute_abi_info(cx, self),
             "s390x" => s390x::compute_abi_info(cx, self),
             "msp430" => msp430::compute_abi_info(self),
diff --git a/compiler/rustc_target/src/abi/call/powerpc.rs b/compiler/rustc_target/src/abi/call/powerpc.rs
index 70c32db0a87..cb80d64c943 100644
--- a/compiler/rustc_target/src/abi/call/powerpc.rs
+++ b/compiler/rustc_target/src/abi/call/powerpc.rs
@@ -1,4 +1,5 @@
 use crate::abi::call::{ArgAbi, FnAbi};
+use crate::spec::HasTargetSpec;
 
 fn classify_ret<Ty>(ret: &mut ArgAbi<'_, Ty>) {
     if ret.layout.is_aggregate() {
@@ -8,7 +9,17 @@ fn classify_ret<Ty>(ret: &mut ArgAbi<'_, Ty>) {
     }
 }
 
-fn classify_arg<Ty>(arg: &mut ArgAbi<'_, Ty>) {
+fn classify_arg<Ty>(cx: &impl HasTargetSpec, arg: &mut ArgAbi<'_, Ty>) {
+    if arg.is_ignore() {
+        // powerpc-unknown-linux-{gnu,musl,uclibc} doesn't ignore ZSTs.
+        if cx.target_spec().os == "linux"
+            && matches!(&*cx.target_spec().env, "gnu" | "musl" | "uclibc")
+            && arg.layout.is_zst()
+        {
+            arg.make_indirect_force();
+        }
+        return;
+    }
     if arg.layout.is_aggregate() {
         arg.make_indirect();
     } else {
@@ -16,15 +27,12 @@ fn classify_arg<Ty>(arg: &mut ArgAbi<'_, Ty>) {
     }
 }
 
-pub fn compute_abi_info<Ty>(fn_abi: &mut FnAbi<'_, Ty>) {
+pub fn compute_abi_info<Ty>(cx: &impl HasTargetSpec, fn_abi: &mut FnAbi<'_, Ty>) {
     if !fn_abi.ret.is_ignore() {
         classify_ret(&mut fn_abi.ret);
     }
 
     for arg in fn_abi.args.iter_mut() {
-        if arg.is_ignore() {
-            continue;
-        }
-        classify_arg(arg);
+        classify_arg(cx, arg);
     }
 }
diff --git a/compiler/rustc_target/src/abi/call/s390x.rs b/compiler/rustc_target/src/abi/call/s390x.rs
index 1a2191082d5..7dcbb3e4a9e 100644
--- a/compiler/rustc_target/src/abi/call/s390x.rs
+++ b/compiler/rustc_target/src/abi/call/s390x.rs
@@ -3,6 +3,7 @@
 
 use crate::abi::call::{ArgAbi, FnAbi, Reg};
 use crate::abi::{HasDataLayout, TyAbiInterface};
+use crate::spec::HasTargetSpec;
 
 fn classify_ret<Ty>(ret: &mut ArgAbi<'_, Ty>) {
     if !ret.layout.is_aggregate() && ret.layout.size.bits() <= 64 {
@@ -15,12 +16,22 @@ fn classify_ret<Ty>(ret: &mut ArgAbi<'_, Ty>) {
 fn classify_arg<'a, Ty, C>(cx: &C, arg: &mut ArgAbi<'a, Ty>)
 where
     Ty: TyAbiInterface<'a, C> + Copy,
-    C: HasDataLayout,
+    C: HasDataLayout + HasTargetSpec,
 {
     if !arg.layout.is_sized() {
         // Not touching this...
         return;
     }
+    if arg.is_ignore() {
+        // s390x-unknown-linux-{gnu,musl,uclibc} doesn't ignore ZSTs.
+        if cx.target_spec().os == "linux"
+            && matches!(&*cx.target_spec().env, "gnu" | "musl" | "uclibc")
+            && arg.layout.is_zst()
+        {
+            arg.make_indirect_force();
+        }
+        return;
+    }
     if !arg.layout.is_aggregate() && arg.layout.size.bits() <= 64 {
         arg.extend_integer_width_to(64);
         return;
@@ -46,16 +57,13 @@ where
 pub fn compute_abi_info<'a, Ty, C>(cx: &C, fn_abi: &mut FnAbi<'a, Ty>)
 where
     Ty: TyAbiInterface<'a, C> + Copy,
-    C: HasDataLayout,
+    C: HasDataLayout + HasTargetSpec,
 {
     if !fn_abi.ret.is_ignore() {
         classify_ret(&mut fn_abi.ret);
     }
 
     for arg in fn_abi.args.iter_mut() {
-        if arg.is_ignore() {
-            continue;
-        }
         classify_arg(cx, arg);
     }
 }
diff --git a/compiler/rustc_target/src/abi/call/sparc64.rs b/compiler/rustc_target/src/abi/call/sparc64.rs
index c0952130e04..3b2bf9b3187 100644
--- a/compiler/rustc_target/src/abi/call/sparc64.rs
+++ b/compiler/rustc_target/src/abi/call/sparc64.rs
@@ -4,6 +4,7 @@ use crate::abi::call::{
     ArgAbi, ArgAttribute, ArgAttributes, ArgExtension, CastTarget, FnAbi, Reg, Uniform,
 };
 use crate::abi::{self, HasDataLayout, Scalar, Size, TyAbiInterface, TyAndLayout};
+use crate::spec::HasTargetSpec;
 
 #[derive(Clone, Debug)]
 pub struct Sdata {
@@ -211,7 +212,7 @@ where
 pub fn compute_abi_info<'a, Ty, C>(cx: &C, fn_abi: &mut FnAbi<'a, Ty>)
 where
     Ty: TyAbiInterface<'a, C> + Copy,
-    C: HasDataLayout,
+    C: HasDataLayout + HasTargetSpec,
 {
     if !fn_abi.ret.is_ignore() {
         classify_arg(cx, &mut fn_abi.ret, Size::from_bytes(32));
@@ -219,7 +220,14 @@ where
 
     for arg in fn_abi.args.iter_mut() {
         if arg.is_ignore() {
-            continue;
+            // sparc64-unknown-linux-{gnu,musl,uclibc} doesn't ignore ZSTs.
+            if cx.target_spec().os == "linux"
+                && matches!(&*cx.target_spec().env, "gnu" | "musl" | "uclibc")
+                && arg.layout.is_zst()
+            {
+                arg.make_indirect_force();
+            }
+            return;
         }
         classify_arg(cx, arg, Size::from_bytes(16));
     }
diff --git a/compiler/rustc_target/src/abi/call/x86_win64.rs b/compiler/rustc_target/src/abi/call/x86_win64.rs
index 4e19460bd28..6ca01cf84ea 100644
--- a/compiler/rustc_target/src/abi/call/x86_win64.rs
+++ b/compiler/rustc_target/src/abi/call/x86_win64.rs
@@ -1,9 +1,10 @@
 use crate::abi::call::{ArgAbi, FnAbi, Reg};
 use crate::abi::{Abi, Float, Primitive};
+use crate::spec::HasTargetSpec;
 
 // Win64 ABI: https://docs.microsoft.com/en-us/cpp/build/parameter-passing
 
-pub fn compute_abi_info<Ty>(fn_abi: &mut FnAbi<'_, Ty>) {
+pub fn compute_abi_info<Ty>(cx: &impl HasTargetSpec, fn_abi: &mut FnAbi<'_, Ty>) {
     let fixup = |a: &mut ArgAbi<'_, Ty>| {
         match a.layout.abi {
             Abi::Uninhabited | Abi::Aggregate { sized: false } => {}
@@ -37,6 +38,13 @@ pub fn compute_abi_info<Ty>(fn_abi: &mut FnAbi<'_, Ty>) {
     }
     for arg in fn_abi.args.iter_mut() {
         if arg.is_ignore() {
+            // x86_64-pc-windows-gnu doesn't ignore ZSTs.
+            if cx.target_spec().os == "windows"
+                && cx.target_spec().env == "gnu"
+                && arg.layout.is_zst()
+            {
+                arg.make_indirect_force();
+            }
             continue;
         }
         fixup(arg);