]>
Commit | Line | Data |
---|---|---|
f20569fa XL |
1 | use crate::abi::call::{ArgAbi, FnAbi, Uniform}; |
2 | use crate::abi::{HasDataLayout, LayoutOf, TyAndLayout, TyAndLayoutMethods}; | |
3 | ||
4 | fn unwrap_trivial_aggregate<'a, Ty, C>(cx: &C, val: &mut ArgAbi<'a, Ty>) -> bool | |
5 | where | |
6 | Ty: TyAndLayoutMethods<'a, C> + Copy, | |
7 | C: LayoutOf<Ty = Ty, TyAndLayout = TyAndLayout<'a, Ty>> + HasDataLayout, | |
8 | { | |
9 | if val.layout.is_aggregate() { | |
10 | if let Some(unit) = val.layout.homogeneous_aggregate(cx).ok().and_then(|ha| ha.unit()) { | |
11 | let size = val.layout.size; | |
12 | if unit.size == size { | |
13 | val.cast_to(Uniform { unit, total: size }); | |
14 | return true; | |
15 | } | |
16 | } | |
17 | } | |
18 | false | |
19 | } | |
20 | ||
21 | fn classify_ret<'a, Ty, C>(cx: &C, ret: &mut ArgAbi<'a, Ty>) | |
22 | where | |
23 | Ty: TyAndLayoutMethods<'a, C> + Copy, | |
24 | C: LayoutOf<Ty = Ty, TyAndLayout = TyAndLayout<'a, Ty>> + HasDataLayout, | |
25 | { | |
26 | ret.extend_integer_width_to(32); | |
27 | if ret.layout.is_aggregate() && !unwrap_trivial_aggregate(cx, ret) { | |
28 | ret.make_indirect(); | |
29 | } | |
30 | } | |
31 | ||
32 | fn classify_arg<'a, Ty, C>(cx: &C, arg: &mut ArgAbi<'a, Ty>) | |
33 | where | |
34 | Ty: TyAndLayoutMethods<'a, C> + Copy, | |
35 | C: LayoutOf<Ty = Ty, TyAndLayout = TyAndLayout<'a, Ty>> + HasDataLayout, | |
36 | { | |
37 | arg.extend_integer_width_to(32); | |
38 | if arg.layout.is_aggregate() && !unwrap_trivial_aggregate(cx, arg) { | |
39 | arg.make_indirect_byval(); | |
40 | } | |
41 | } | |
42 | ||
43 | pub fn compute_abi_info<'a, Ty, C>(cx: &C, fn_abi: &mut FnAbi<'a, Ty>) | |
44 | where | |
45 | Ty: TyAndLayoutMethods<'a, C> + Copy, | |
46 | C: LayoutOf<Ty = Ty, TyAndLayout = TyAndLayout<'a, Ty>> + HasDataLayout, | |
47 | { | |
48 | if !fn_abi.ret.is_ignore() { | |
49 | classify_ret(cx, &mut fn_abi.ret); | |
50 | } | |
51 | ||
52 | for arg in &mut fn_abi.args { | |
53 | if arg.is_ignore() { | |
54 | continue; | |
55 | } | |
56 | classify_arg(cx, arg); | |
57 | } | |
58 | } |