]> git.proxmox.com Git - rustc.git/blob - src/librustc_target/spec/abi.rs
New upstream version 1.47.0+dfsg1
[rustc.git] / src / librustc_target / spec / abi.rs
1 use std::fmt;
2
3 use rustc_macros::HashStable_Generic;
4
5 #[cfg(test)]
6 mod tests;
7
8 #[derive(PartialEq, Eq, PartialOrd, Ord, Hash, Clone, Copy, Debug)]
9 #[derive(HashStable_Generic, Encodable, Decodable)]
10 pub enum Abi {
11 // N.B., this ordering MUST match the AbiDatas array below.
12 // (This is ensured by the test indices_are_correct().)
13
14 // Multiplatform / generic ABIs
15 //
16 // These ABIs come first because every time we add a new ABI, we
17 // have to re-bless all the hashing tests. These are used in many
18 // places, so giving them stable values reduces test churn. The
19 // specific values are meaningless.
20 Rust = 0,
21 C = 1,
22
23 // Single platform ABIs
24 Cdecl,
25 Stdcall,
26 Fastcall,
27 Vectorcall,
28 Thiscall,
29 Aapcs,
30 Win64,
31 SysV64,
32 PtxKernel,
33 Msp430Interrupt,
34 X86Interrupt,
35 AmdGpuKernel,
36 EfiApi,
37 AvrInterrupt,
38 AvrNonBlockingInterrupt,
39
40 // Multiplatform / generic ABIs
41 System,
42 RustIntrinsic,
43 RustCall,
44 PlatformIntrinsic,
45 Unadjusted,
46 }
47
48 #[derive(Copy, Clone)]
49 pub struct AbiData {
50 abi: Abi,
51
52 /// Name of this ABI as we like it called.
53 name: &'static str,
54
55 /// A generic ABI is supported on all platforms.
56 generic: bool,
57 }
58
59 #[allow(non_upper_case_globals)]
60 const AbiDatas: &[AbiData] = &[
61 // Cross-platform ABIs
62 AbiData { abi: Abi::Rust, name: "Rust", generic: true },
63 AbiData { abi: Abi::C, name: "C", generic: true },
64 // Platform-specific ABIs
65 AbiData { abi: Abi::Cdecl, name: "cdecl", generic: false },
66 AbiData { abi: Abi::Stdcall, name: "stdcall", generic: false },
67 AbiData { abi: Abi::Fastcall, name: "fastcall", generic: false },
68 AbiData { abi: Abi::Vectorcall, name: "vectorcall", generic: false },
69 AbiData { abi: Abi::Thiscall, name: "thiscall", generic: false },
70 AbiData { abi: Abi::Aapcs, name: "aapcs", generic: false },
71 AbiData { abi: Abi::Win64, name: "win64", generic: false },
72 AbiData { abi: Abi::SysV64, name: "sysv64", generic: false },
73 AbiData { abi: Abi::PtxKernel, name: "ptx-kernel", generic: false },
74 AbiData { abi: Abi::Msp430Interrupt, name: "msp430-interrupt", generic: false },
75 AbiData { abi: Abi::X86Interrupt, name: "x86-interrupt", generic: false },
76 AbiData { abi: Abi::AmdGpuKernel, name: "amdgpu-kernel", generic: false },
77 AbiData { abi: Abi::EfiApi, name: "efiapi", generic: false },
78 AbiData { abi: Abi::AvrInterrupt, name: "avr-interrupt", generic: false },
79 AbiData {
80 abi: Abi::AvrNonBlockingInterrupt,
81 name: "avr-non-blocking-interrupt",
82 generic: false,
83 },
84 // Cross-platform ABIs
85 AbiData { abi: Abi::System, name: "system", generic: true },
86 AbiData { abi: Abi::RustIntrinsic, name: "rust-intrinsic", generic: true },
87 AbiData { abi: Abi::RustCall, name: "rust-call", generic: true },
88 AbiData { abi: Abi::PlatformIntrinsic, name: "platform-intrinsic", generic: true },
89 AbiData { abi: Abi::Unadjusted, name: "unadjusted", generic: true },
90 ];
91
92 /// Returns the ABI with the given name (if any).
93 pub fn lookup(name: &str) -> Option<Abi> {
94 AbiDatas.iter().find(|abi_data| name == abi_data.name).map(|&x| x.abi)
95 }
96
97 pub fn all_names() -> Vec<&'static str> {
98 AbiDatas.iter().map(|d| d.name).collect()
99 }
100
101 impl Abi {
102 #[inline]
103 pub fn index(self) -> usize {
104 self as usize
105 }
106
107 #[inline]
108 pub fn data(self) -> &'static AbiData {
109 &AbiDatas[self.index()]
110 }
111
112 pub fn name(self) -> &'static str {
113 self.data().name
114 }
115
116 pub fn generic(self) -> bool {
117 self.data().generic
118 }
119 }
120
121 impl fmt::Display for Abi {
122 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
123 write!(f, "\"{}\"", self.name())
124 }
125 }