]> git.proxmox.com Git - rustc.git/blame - src/librustc_trans/trans/cabi.rs
Imported Upstream version 1.7.0+dfsg1
[rustc.git] / src / librustc_trans / trans / cabi.rs
CommitLineData
1a4d82fc
JJ
1// Copyright 2012-2015 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
11pub use self::ArgKind::*;
12
13use llvm::Attribute;
14use std::option;
15use trans::context::CrateContext;
16use trans::cabi_x86;
17use trans::cabi_x86_64;
18use trans::cabi_x86_win64;
19use trans::cabi_arm;
20use trans::cabi_aarch64;
85aaf69f 21use trans::cabi_powerpc;
9cc50fc6 22use trans::cabi_powerpc64;
1a4d82fc
JJ
23use trans::cabi_mips;
24use trans::type_::Type;
25
26#[derive(Clone, Copy, PartialEq)]
27pub enum ArgKind {
28 /// Pass the argument directly using the normal converted
29 /// LLVM type or by coercing to another specified type
30 Direct,
31 /// Pass the argument indirectly via a hidden pointer
32 Indirect,
33 /// Ignore the argument (useful for empty struct)
34 Ignore,
35}
36
37/// Information about how a specific C type
38/// should be passed to or returned from a function
39///
40/// This is borrowed from clang's ABIInfo.h
41#[derive(Clone, Copy)]
42pub struct ArgType {
43 pub kind: ArgKind,
44 /// Original LLVM type
45 pub ty: Type,
46 /// Coerced LLVM Type
47 pub cast: option::Option<Type>,
48 /// Dummy argument, which is emitted before the real argument
49 pub pad: option::Option<Type>,
50 /// LLVM attribute of argument
51 pub attr: option::Option<Attribute>
52}
53
54impl ArgType {
55 pub fn direct(ty: Type, cast: option::Option<Type>,
56 pad: option::Option<Type>,
57 attr: option::Option<Attribute>) -> ArgType {
58 ArgType {
59 kind: Direct,
60 ty: ty,
61 cast: cast,
62 pad: pad,
63 attr: attr
64 }
65 }
66
67 pub fn indirect(ty: Type, attr: option::Option<Attribute>) -> ArgType {
68 ArgType {
69 kind: Indirect,
70 ty: ty,
71 cast: option::Option::None,
72 pad: option::Option::None,
73 attr: attr
74 }
75 }
76
77 pub fn ignore(ty: Type) -> ArgType {
78 ArgType {
79 kind: Ignore,
80 ty: ty,
81 cast: None,
82 pad: None,
83 attr: None,
84 }
85 }
86
87 pub fn is_indirect(&self) -> bool {
88 return self.kind == Indirect;
89 }
90
91 pub fn is_ignore(&self) -> bool {
92 return self.kind == Ignore;
93 }
94}
95
96/// Metadata describing how the arguments to a native function
97/// should be passed in order to respect the native ABI.
98///
99/// I will do my best to describe this structure, but these
100/// comments are reverse-engineered and may be inaccurate. -NDM
101pub struct FnType {
102 /// The LLVM types of each argument.
103 pub arg_tys: Vec<ArgType> ,
104
105 /// LLVM return type.
106 pub ret_ty: ArgType,
107}
108
109pub fn compute_abi_info(ccx: &CrateContext,
110 atys: &[Type],
111 rty: Type,
112 ret_def: bool) -> FnType {
c34b1796 113 match &ccx.sess().target.target.arch[..] {
1a4d82fc
JJ
114 "x86" => cabi_x86::compute_abi_info(ccx, atys, rty, ret_def),
115 "x86_64" => if ccx.sess().target.target.options.is_like_windows {
116 cabi_x86_win64::compute_abi_info(ccx, atys, rty, ret_def)
117 } else {
118 cabi_x86_64::compute_abi_info(ccx, atys, rty, ret_def)
119 },
1a4d82fc 120 "aarch64" => cabi_aarch64::compute_abi_info(ccx, atys, rty, ret_def),
85aaf69f
SL
121 "arm" => {
122 let flavor = if ccx.sess().target.target.target_os == "ios" {
123 cabi_arm::Flavor::Ios
124 } else {
125 cabi_arm::Flavor::General
126 };
127 cabi_arm::compute_abi_info(ccx, atys, rty, ret_def, flavor)
128 },
1a4d82fc 129 "mips" => cabi_mips::compute_abi_info(ccx, atys, rty, ret_def),
85aaf69f 130 "powerpc" => cabi_powerpc::compute_abi_info(ccx, atys, rty, ret_def),
9cc50fc6 131 "powerpc64" | "powerpc64le" => cabi_powerpc64::compute_abi_info(ccx, atys, rty, ret_def),
1a4d82fc 132 a => ccx.sess().fatal(&format!("unrecognized arch \"{}\" in target specification", a)
c34b1796 133 ),
1a4d82fc
JJ
134 }
135}