]> git.proxmox.com Git - rustc.git/blame - src/librustc_target/abi/call/sparc64.rs
New upstream version 1.32.0~beta.2+dfsg1
[rustc.git] / src / librustc_target / abi / call / sparc64.rs
CommitLineData
32a655c1
SL
1// Copyright 2014-2016 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.
4//
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.
10
11// FIXME: This needs an audit for correctness and completeness.
12
83c7162d
XL
13use abi::call::{FnType, ArgType, Reg, RegKind, Uniform};
14use abi::{HasDataLayout, LayoutOf, TyLayout, TyLayoutMethods};
32a655c1 15
a1dfa0c6 16fn is_homogeneous_aggregate<'a, Ty, C>(cx: &C, arg: &mut ArgType<'a, Ty>)
83c7162d
XL
17 -> Option<Uniform>
18 where Ty: TyLayoutMethods<'a, C> + Copy,
19 C: LayoutOf<Ty = Ty, TyLayout = TyLayout<'a, Ty>> + HasDataLayout
20{
2c00a5a8 21 arg.layout.homogeneous_aggregate(cx).and_then(|unit| {
cc61c64b 22 // Ensure we have at most eight uniquely addressable members.
2c00a5a8 23 if arg.layout.size > unit.size.checked_mul(8, cx).unwrap() {
cc61c64b 24 return None;
32a655c1
SL
25 }
26
cc61c64b
XL
27 let valid_unit = match unit.kind {
28 RegKind::Integer => false,
29 RegKind::Float => true,
ff7c6d11 30 RegKind::Vector => arg.layout.size.bits() == 128
cc61c64b 31 };
32a655c1 32
cc61c64b
XL
33 if valid_unit {
34 Some(Uniform {
35 unit,
ff7c6d11 36 total: arg.layout.size
cc61c64b 37 })
32a655c1
SL
38 } else {
39 None
40 }
41 })
42}
43
a1dfa0c6 44fn classify_ret_ty<'a, Ty, C>(cx: &C, ret: &mut ArgType<'a, Ty>)
83c7162d
XL
45 where Ty: TyLayoutMethods<'a, C> + Copy,
46 C: LayoutOf<Ty = Ty, TyLayout = TyLayout<'a, Ty>> + HasDataLayout
47{
cc61c64b 48 if !ret.layout.is_aggregate() {
32a655c1
SL
49 ret.extend_integer_width_to(64);
50 return;
51 }
52
2c00a5a8 53 if let Some(uniform) = is_homogeneous_aggregate(cx, ret) {
ff7c6d11 54 ret.cast_to(uniform);
32a655c1
SL
55 return;
56 }
ff7c6d11 57 let size = ret.layout.size;
cc61c64b 58 let bits = size.bits();
2c00a5a8 59 if bits <= 256 {
8faf50e0 60 let unit = Reg::i64();
ff7c6d11 61 ret.cast_to(Uniform {
cc61c64b
XL
62 unit,
63 total: size
64 });
32a655c1
SL
65 return;
66 }
cc61c64b
XL
67
68 // don't return aggregates in registers
ff7c6d11 69 ret.make_indirect();
32a655c1
SL
70}
71
a1dfa0c6 72fn classify_arg_ty<'a, Ty, C>(cx: &C, arg: &mut ArgType<'a, Ty>)
83c7162d
XL
73 where Ty: TyLayoutMethods<'a, C> + Copy,
74 C: LayoutOf<Ty = Ty, TyLayout = TyLayout<'a, Ty>> + HasDataLayout
75{
cc61c64b 76 if !arg.layout.is_aggregate() {
32a655c1
SL
77 arg.extend_integer_width_to(64);
78 return;
79 }
80
2c00a5a8 81 if let Some(uniform) = is_homogeneous_aggregate(cx, arg) {
ff7c6d11 82 arg.cast_to(uniform);
32a655c1
SL
83 return;
84 }
85
ff7c6d11 86 let total = arg.layout.size;
2c00a5a8
XL
87 if total.bits() > 128 {
88 arg.make_indirect();
89 return;
90 }
91
ff7c6d11 92 arg.cast_to(Uniform {
cc61c64b
XL
93 unit: Reg::i64(),
94 total
95 });
32a655c1
SL
96}
97
a1dfa0c6 98pub fn compute_abi_info<'a, Ty, C>(cx: &C, fty: &mut FnType<'a, Ty>)
83c7162d
XL
99 where Ty: TyLayoutMethods<'a, C> + Copy,
100 C: LayoutOf<Ty = Ty, TyLayout = TyLayout<'a, Ty>> + HasDataLayout
101{
32a655c1 102 if !fty.ret.is_ignore() {
2c00a5a8 103 classify_ret_ty(cx, &mut fty.ret);
32a655c1
SL
104 }
105
106 for arg in &mut fty.args {
107 if arg.is_ignore() { continue; }
2c00a5a8 108 classify_arg_ty(cx, arg);
32a655c1
SL
109 }
110}