]> git.lizzy.rs Git - rust.git/blob - compiler/rustc_target/src/abi/call/s390x.rs
dea5d4605d13488a152044530eafdb74d2308c02
[rust.git] / compiler / rustc_target / src / abi / call / s390x.rs
1 // FIXME: The assumes we're using the non-vector ABI, i.e., compiling
2 // for a pre-z13 machine or using -mno-vx.
3
4 use crate::abi::call::{ArgAbi, FnAbi, Reg};
5 use crate::abi::{self, HasDataLayout, LayoutOf, TyAndLayout, TyAndLayoutMethods};
6
7 fn classify_ret<Ty>(ret: &mut ArgAbi<'_, Ty>) {
8     if !ret.layout.is_aggregate() && ret.layout.size.bits() <= 64 {
9         ret.extend_integer_width_to(64);
10     } else {
11         ret.make_indirect();
12     }
13 }
14
15 fn is_single_fp_element<'a, Ty, C>(cx: &C, layout: TyAndLayout<'a, Ty>) -> bool
16 where
17     Ty: TyAndLayoutMethods<'a, C>,
18     C: LayoutOf<'a, Ty = Ty, TyAndLayout = TyAndLayout<'a, Ty>> + HasDataLayout,
19 {
20     match layout.abi {
21         abi::Abi::Scalar(ref scalar) => scalar.value.is_float(),
22         abi::Abi::Aggregate { .. } => {
23             if layout.fields.count() == 1 && layout.fields.offset(0).bytes() == 0 {
24                 is_single_fp_element(cx, layout.field(cx, 0))
25             } else {
26                 false
27             }
28         }
29         _ => false,
30     }
31 }
32
33 fn classify_arg<'a, Ty, C>(cx: &C, arg: &mut ArgAbi<'a, Ty>)
34 where
35     Ty: TyAndLayoutMethods<'a, C> + Copy,
36     C: LayoutOf<'a, Ty = Ty, TyAndLayout = TyAndLayout<'a, Ty>> + HasDataLayout,
37 {
38     if !arg.layout.is_aggregate() && arg.layout.size.bits() <= 64 {
39         arg.extend_integer_width_to(64);
40         return;
41     }
42
43     if is_single_fp_element(cx, arg.layout) {
44         match arg.layout.size.bytes() {
45             4 => arg.cast_to(Reg::f32()),
46             8 => arg.cast_to(Reg::f64()),
47             _ => arg.make_indirect(),
48         }
49     } else {
50         match arg.layout.size.bytes() {
51             1 => arg.cast_to(Reg::i8()),
52             2 => arg.cast_to(Reg::i16()),
53             4 => arg.cast_to(Reg::i32()),
54             8 => arg.cast_to(Reg::i64()),
55             _ => arg.make_indirect(),
56         }
57     }
58 }
59
60 pub fn compute_abi_info<'a, Ty, C>(cx: &C, fn_abi: &mut FnAbi<'a, Ty>)
61 where
62     Ty: TyAndLayoutMethods<'a, C> + Copy,
63     C: LayoutOf<'a, Ty = Ty, TyAndLayout = TyAndLayout<'a, Ty>> + HasDataLayout,
64 {
65     if !fn_abi.ret.is_ignore() {
66         classify_ret(&mut fn_abi.ret);
67     }
68
69     for arg in &mut fn_abi.args {
70         if arg.is_ignore() {
71             continue;
72         }
73         classify_arg(cx, arg);
74     }
75 }