]> git.proxmox.com Git - rustc.git/blame - compiler/rustc_target/src/spec/abi.rs
New upstream version 1.54.0+dfsg1
[rustc.git] / compiler / rustc_target / src / spec / abi.rs
CommitLineData
1a4d82fc
JJ
1use std::fmt;
2
60c5eb7d
XL
3use rustc_macros::HashStable_Generic;
4
416331ca
XL
5#[cfg(test)]
6mod tests;
7
3dfed10e
XL
8#[derive(PartialEq, Eq, PartialOrd, Ord, Hash, Clone, Copy, Debug)]
9#[derive(HashStable_Generic, Encodable, Decodable)]
223e47cc 10pub 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 48pub 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 59const 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 98pub 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
102pub fn all_names() -> Vec<&'static str> {
103 AbiDatas.iter().map(|d| d.name).collect()
223e47cc
LB
104}
105
970d7e83 106impl 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 172impl 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}