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