about summary refs log tree commit diff
path: root/compiler/rustc_target/src/callconv/x86.rs
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2024-10-23 22:28:57 +0000
committerbors <bors@rust-lang.org>2024-10-23 22:28:57 +0000
commitb8bb2968ce1e44d01520c9d59ee6299ed66df3f9 (patch)
tree82ca49a2923c40b61c67ae4a6508390d25ec2a49 /compiler/rustc_target/src/callconv/x86.rs
parent4f2f477fded0a47b21ed3f6aeddeafa5db8bf518 (diff)
parentfbe33e35aff61910178565013a7efbb4840e7629 (diff)
downloadrust-b8bb2968ce1e44d01520c9d59ee6299ed66df3f9.tar.gz
rust-b8bb2968ce1e44d01520c9d59ee6299ed66df3f9.zip
Auto merge of #132079 - fmease:rollup-agrd358, r=fmease
Rollup of 9 pull requests

Successful merges:

 - #130991 (Vectorized SliceContains)
 - #131928 (rustdoc: Document `markdown` module.)
 - #131955 (Set `signext` or `zeroext` for integer arguments on RISC-V and LoongArch64)
 - #131979 (Minor tweaks to `compare_impl_item.rs`)
 - #132036 (Add a test case for #131164)
 - #132039 (Specialize `read_exact` and `read_buf_exact` for `VecDeque`)
 - #132060 ("innermost", "outermost", "leftmost", and "rightmost" don't need hyphens)
 - #132065 (Clarify documentation of `ptr::dangling()` function)
 - #132066 (Fix a typo in documentation of `pointer::sub_ptr()`)

r? `@ghost`
`@rustbot` modify labels: rollup
Diffstat (limited to 'compiler/rustc_target/src/callconv/x86.rs')
-rw-r--r--compiler/rustc_target/src/callconv/x86.rs37
1 files changed, 36 insertions, 1 deletions
diff --git a/compiler/rustc_target/src/callconv/x86.rs b/compiler/rustc_target/src/callconv/x86.rs
index 40c3e7a891a..e907beecb38 100644
--- a/compiler/rustc_target/src/callconv/x86.rs
+++ b/compiler/rustc_target/src/callconv/x86.rs
@@ -1,6 +1,9 @@
 use crate::abi::call::{ArgAttribute, FnAbi, PassMode, Reg, RegKind};
-use crate::abi::{Abi, Align, HasDataLayout, TyAbiInterface, TyAndLayout};
+use crate::abi::{
+    Abi, AddressSpace, Align, Float, HasDataLayout, Pointer, TyAbiInterface, TyAndLayout,
+};
 use crate::spec::HasTargetSpec;
+use crate::spec::abi::Abi as SpecAbi;
 
 #[derive(PartialEq)]
 pub(crate) enum Flavor {
@@ -207,3 +210,35 @@ pub(crate) fn fill_inregs<'a, Ty, C>(
         }
     }
 }
+
+pub(crate) fn compute_rust_abi_info<'a, Ty, C>(cx: &C, fn_abi: &mut FnAbi<'a, Ty>, abi: SpecAbi)
+where
+    Ty: TyAbiInterface<'a, C> + Copy,
+    C: HasDataLayout + HasTargetSpec,
+{
+    // Avoid returning floats in x87 registers on x86 as loading and storing from x87
+    // registers will quiet signalling NaNs. Also avoid using SSE registers since they
+    // are not always available (depending on target features).
+    if !fn_abi.ret.is_ignore()
+        // Intrinsics themselves are not actual "real" functions, so theres no need to change their ABIs.
+        && abi != SpecAbi::RustIntrinsic
+    {
+        let has_float = match fn_abi.ret.layout.abi {
+            Abi::Scalar(s) => matches!(s.primitive(), Float(_)),
+            Abi::ScalarPair(s1, s2) => {
+                matches!(s1.primitive(), Float(_)) || matches!(s2.primitive(), Float(_))
+            }
+            _ => false, // anyway not passed via registers on x86
+        };
+        if has_float {
+            if fn_abi.ret.layout.size <= Pointer(AddressSpace::DATA).size(cx) {
+                // Same size or smaller than pointer, return in a register.
+                fn_abi.ret.cast_to(Reg { kind: RegKind::Integer, size: fn_abi.ret.layout.size });
+            } else {
+                // Larger than a pointer, return indirectly.
+                fn_abi.ret.make_indirect();
+            }
+            return;
+        }
+    }
+}