]>
Commit | Line | Data |
---|---|---|
1a4d82fc JJ |
1 | use std::fmt; |
2 | ||
60c5eb7d XL |
3 | use rustc_macros::HashStable_Generic; |
4 | ||
416331ca XL |
5 | #[cfg(test)] |
6 | mod tests; | |
7 | ||
3dfed10e XL |
8 | #[derive(PartialEq, Eq, PartialOrd, Ord, Hash, Clone, Copy, Debug)] |
9 | #[derive(HashStable_Generic, Encodable, Decodable)] | |
223e47cc | 10 | pub enum Abi { |
f035d41b XL |
11 | // Multiplatform / generic ABIs |
12 | // | |
13 | // These ABIs come first because every time we add a new ABI, we | |
14 | // have to re-bless all the hashing tests. These are used in many | |
15 | // places, so giving them stable values reduces test churn. The | |
16 | // specific values are meaningless. | |
6a06907d XL |
17 | Rust, |
18 | C { unwind: bool }, | |
f035d41b | 19 | |
c30ab7b3 | 20 | // Single platform ABIs |
223e47cc | 21 | Cdecl, |
6a06907d | 22 | Stdcall { unwind: bool }, |
223e47cc | 23 | Fastcall, |
9cc50fc6 | 24 | Vectorcall, |
6a06907d | 25 | Thiscall { unwind: bool }, |
223e47cc | 26 | Aapcs, |
1a4d82fc | 27 | Win64, |
9e0c209e | 28 | SysV64, |
32a655c1 SL |
29 | PtxKernel, |
30 | Msp430Interrupt, | |
8bb4bdeb | 31 | X86Interrupt, |
8faf50e0 | 32 | AmdGpuKernel, |
e74abb32 | 33 | EfiApi, |
f035d41b XL |
34 | AvrInterrupt, |
35 | AvrNonBlockingInterrupt, | |
5869c6ff | 36 | CCmseNonSecureCall, |
cdc7bbd5 | 37 | Wasm, |
223e47cc | 38 | |
c30ab7b3 | 39 | // Multiplatform / generic ABIs |
6a06907d | 40 | System { unwind: bool }, |
223e47cc | 41 | RustIntrinsic, |
1a4d82fc | 42 | RustCall, |
e9174d1e | 43 | PlatformIntrinsic, |
dfeec247 | 44 | Unadjusted, |
223e47cc LB |
45 | } |
46 | ||
c34b1796 | 47 | #[derive(Copy, Clone)] |
1a4d82fc | 48 | pub struct AbiData { |
223e47cc LB |
49 | abi: Abi, |
50 | ||
c30ab7b3 | 51 | /// Name of this ABI as we like it called. |
223e47cc | 52 | name: &'static str, |
223e47cc | 53 | |
c30ab7b3 SL |
54 | /// A generic ABI is supported on all platforms. |
55 | generic: bool, | |
223e47cc LB |
56 | } |
57 | ||
1a4d82fc | 58 | #[allow(non_upper_case_globals)] |
b7449926 | 59 | const AbiDatas: &[AbiData] = &[ |
f035d41b XL |
60 | // Cross-platform ABIs |
61 | AbiData { abi: Abi::Rust, name: "Rust", generic: true }, | |
6a06907d XL |
62 | AbiData { abi: Abi::C { unwind: false }, name: "C", generic: true }, |
63 | AbiData { abi: Abi::C { unwind: true }, name: "C-unwind", generic: true }, | |
223e47cc | 64 | // Platform-specific ABIs |
dfeec247 | 65 | AbiData { abi: Abi::Cdecl, name: "cdecl", generic: false }, |
6a06907d XL |
66 | AbiData { abi: Abi::Stdcall { unwind: false }, name: "stdcall", generic: false }, |
67 | AbiData { abi: Abi::Stdcall { unwind: true }, name: "stdcall-unwind", generic: false }, | |
dfeec247 XL |
68 | AbiData { abi: Abi::Fastcall, name: "fastcall", generic: false }, |
69 | AbiData { abi: Abi::Vectorcall, name: "vectorcall", generic: false }, | |
6a06907d XL |
70 | AbiData { abi: Abi::Thiscall { unwind: false }, name: "thiscall", generic: false }, |
71 | AbiData { abi: Abi::Thiscall { unwind: true }, name: "thiscall-unwind", generic: false }, | |
dfeec247 XL |
72 | AbiData { abi: Abi::Aapcs, name: "aapcs", generic: false }, |
73 | AbiData { abi: Abi::Win64, name: "win64", generic: false }, | |
74 | AbiData { abi: Abi::SysV64, name: "sysv64", generic: false }, | |
75 | AbiData { abi: Abi::PtxKernel, name: "ptx-kernel", generic: false }, | |
76 | AbiData { abi: Abi::Msp430Interrupt, name: "msp430-interrupt", generic: false }, | |
77 | AbiData { abi: Abi::X86Interrupt, name: "x86-interrupt", generic: false }, | |
78 | AbiData { abi: Abi::AmdGpuKernel, name: "amdgpu-kernel", generic: false }, | |
79 | AbiData { abi: Abi::EfiApi, name: "efiapi", generic: false }, | |
f035d41b XL |
80 | AbiData { abi: Abi::AvrInterrupt, name: "avr-interrupt", generic: false }, |
81 | AbiData { | |
82 | abi: Abi::AvrNonBlockingInterrupt, | |
83 | name: "avr-non-blocking-interrupt", | |
84 | generic: false, | |
85 | }, | |
5869c6ff | 86 | AbiData { abi: Abi::CCmseNonSecureCall, name: "C-cmse-nonsecure-call", generic: false }, |
cdc7bbd5 | 87 | AbiData { abi: Abi::Wasm, name: "wasm", generic: false }, |
223e47cc | 88 | // Cross-platform ABIs |
6a06907d XL |
89 | AbiData { abi: Abi::System { unwind: false }, name: "system", generic: true }, |
90 | AbiData { abi: Abi::System { unwind: true }, name: "system-unwind", generic: true }, | |
dfeec247 XL |
91 | AbiData { abi: Abi::RustIntrinsic, name: "rust-intrinsic", generic: true }, |
92 | AbiData { abi: Abi::RustCall, name: "rust-call", generic: true }, | |
93 | AbiData { abi: Abi::PlatformIntrinsic, name: "platform-intrinsic", generic: true }, | |
94 | AbiData { abi: Abi::Unadjusted, name: "unadjusted", generic: true }, | |
223e47cc LB |
95 | ]; |
96 | ||
1a4d82fc | 97 | /// Returns the ABI with the given name (if any). |
223e47cc | 98 | pub fn lookup(name: &str) -> Option<Abi> { |
1a4d82fc | 99 | AbiDatas.iter().find(|abi_data| name == abi_data.name).map(|&x| x.abi) |
223e47cc LB |
100 | } |
101 | ||
1a4d82fc JJ |
102 | pub fn all_names() -> Vec<&'static str> { |
103 | AbiDatas.iter().map(|d| d.name).collect() | |
223e47cc LB |
104 | } |
105 | ||
970d7e83 | 106 | impl Abi { |
223e47cc | 107 | #[inline] |
b7449926 | 108 | pub fn index(self) -> usize { |
6a06907d XL |
109 | // N.B., this ordering MUST match the AbiDatas array above. |
110 | // (This is ensured by the test indices_are_correct().) | |
111 | use Abi::*; | |
112 | let i = match self { | |
113 | // Cross-platform ABIs | |
114 | Rust => 0, | |
115 | C { unwind: false } => 1, | |
116 | C { unwind: true } => 2, | |
117 | // Platform-specific ABIs | |
118 | Cdecl => 3, | |
119 | Stdcall { unwind: false } => 4, | |
120 | Stdcall { unwind: true } => 5, | |
121 | Fastcall => 6, | |
122 | Vectorcall => 7, | |
123 | Thiscall { unwind: false } => 8, | |
124 | Thiscall { unwind: true } => 9, | |
125 | Aapcs => 10, | |
126 | Win64 => 11, | |
127 | SysV64 => 12, | |
128 | PtxKernel => 13, | |
129 | Msp430Interrupt => 14, | |
130 | X86Interrupt => 15, | |
131 | AmdGpuKernel => 16, | |
132 | EfiApi => 17, | |
133 | AvrInterrupt => 18, | |
134 | AvrNonBlockingInterrupt => 19, | |
135 | CCmseNonSecureCall => 20, | |
cdc7bbd5 | 136 | Wasm => 21, |
6a06907d | 137 | // Cross-platform ABIs |
cdc7bbd5 XL |
138 | System { unwind: false } => 22, |
139 | System { unwind: true } => 23, | |
140 | RustIntrinsic => 24, | |
141 | RustCall => 25, | |
142 | PlatformIntrinsic => 26, | |
143 | Unadjusted => 27, | |
6a06907d XL |
144 | }; |
145 | debug_assert!( | |
146 | AbiDatas | |
147 | .iter() | |
148 | .enumerate() | |
149 | .find(|(_, AbiData { abi, .. })| *abi == self) | |
150 | .map(|(index, _)| index) | |
151 | .expect("abi variant has associated data") | |
152 | == i, | |
153 | "Abi index did not match `AbiDatas` ordering" | |
154 | ); | |
155 | i | |
223e47cc LB |
156 | } |
157 | ||
158 | #[inline] | |
b7449926 | 159 | pub fn data(self) -> &'static AbiData { |
223e47cc LB |
160 | &AbiDatas[self.index()] |
161 | } | |
162 | ||
b7449926 | 163 | pub fn name(self) -> &'static str { |
223e47cc LB |
164 | self.data().name |
165 | } | |
c30ab7b3 | 166 | |
b7449926 | 167 | pub fn generic(self) -> bool { |
c30ab7b3 SL |
168 | self.data().generic |
169 | } | |
223e47cc LB |
170 | } |
171 | ||
85aaf69f | 172 | impl fmt::Display for Abi { |
9fa01778 | 173 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { |
6a06907d XL |
174 | match self { |
175 | abi => write!(f, "\"{}\"", abi.name()), | |
176 | } | |
223e47cc LB |
177 | } |
178 | } |