1 // Copyright 2012-2013 The Rust Project Developers. See the COPYRIGHT
2 // file at the top-level directory of this distribution and at
3 // http://rust-lang.org/COPYRIGHT.
5 // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6 // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8 // option. This file may not be copied, modified, or distributed
9 // except according to those terms.
11 use abi
::call
::{Conv, FnType, ArgType, Reg, RegKind, Uniform}
;
12 use abi
::{HasDataLayout, LayoutOf, TyLayout, TyLayoutMethods}
;
13 use spec
::HasTargetSpec
;
15 fn is_homogeneous_aggregate
<'a
, Ty
, C
>(cx
: C
, arg
: &mut ArgType
<'a
, Ty
>)
17 where Ty
: TyLayoutMethods
<'a
, C
> + Copy
,
18 C
: LayoutOf
<Ty
= Ty
, TyLayout
= TyLayout
<'a
, Ty
>> + HasDataLayout
20 arg
.layout
.homogeneous_aggregate(cx
).and_then(|unit
| {
21 let size
= arg
.layout
.size
;
23 // Ensure we have at most four uniquely addressable members.
24 if size
> unit
.size
.checked_mul(4, cx
).unwrap() {
28 let valid_unit
= match unit
.kind
{
29 RegKind
::Integer
=> false,
30 RegKind
::Float
=> true,
31 RegKind
::Vector
=> size
.bits() == 64 || size
.bits() == 128
45 fn classify_ret_ty
<'a
, Ty
, C
>(cx
: C
, ret
: &mut ArgType
<'a
, Ty
>, vfp
: bool
)
46 where Ty
: TyLayoutMethods
<'a
, C
> + Copy
,
47 C
: LayoutOf
<Ty
= Ty
, TyLayout
= TyLayout
<'a
, Ty
>> + HasDataLayout
49 if !ret
.layout
.is_aggregate() {
50 ret
.extend_integer_width_to(32);
55 if let Some(uniform
) = is_homogeneous_aggregate(cx
, ret
) {
61 let size
= ret
.layout
.size
;
62 let bits
= size
.bits();
64 let unit
= if bits
<= 8 {
66 } else if bits
<= 16 {
80 fn classify_arg_ty
<'a
, Ty
, C
>(cx
: C
, arg
: &mut ArgType
<'a
, Ty
>, vfp
: bool
)
81 where Ty
: TyLayoutMethods
<'a
, C
> + Copy
,
82 C
: LayoutOf
<Ty
= Ty
, TyLayout
= TyLayout
<'a
, Ty
>> + HasDataLayout
84 if !arg
.layout
.is_aggregate() {
85 arg
.extend_integer_width_to(32);
90 if let Some(uniform
) = is_homogeneous_aggregate(cx
, arg
) {
96 let align
= arg
.layout
.align
.abi();
97 let total
= arg
.layout
.size
;
99 unit
: if align
<= 4 { Reg::i32() }
else { Reg::i64() }
,
104 pub fn compute_abi_info
<'a
, Ty
, C
>(cx
: C
, fty
: &mut FnType
<'a
, Ty
>)
105 where Ty
: TyLayoutMethods
<'a
, C
> + Copy
,
106 C
: LayoutOf
<Ty
= Ty
, TyLayout
= TyLayout
<'a
, Ty
>> + HasDataLayout
+ HasTargetSpec
108 // If this is a target with a hard-float ABI, and the function is not explicitly
109 // `extern "aapcs"`, then we must use the VFP registers for homogeneous aggregates.
110 let vfp
= cx
.target_spec().llvm_target
.ends_with("hf")
111 && fty
.conv
!= Conv
::ArmAapcs
114 if !fty
.ret
.is_ignore() {
115 classify_ret_ty(cx
, &mut fty
.ret
, vfp
);
118 for arg
in &mut fty
.args
{
119 if arg
.is_ignore() { continue; }
120 classify_arg_ty(cx
, arg
, vfp
);