1use rustc_abi::{ArmCall, CanonAbi, ExternAbi, InterruptKind, X86Call};
2
3use crate::spec::{Arch, Target};
4
5#[derive(#[automatically_derived]
impl ::core::clone::Clone for AbiMap {
#[inline]
fn clone(&self) -> AbiMap {
AbiMap {
arch: ::core::clone::Clone::clone(&self.arch),
os: ::core::clone::Clone::clone(&self.os),
}
}
}Clone, #[automatically_derived]
impl ::core::fmt::Debug for AbiMap {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
::core::fmt::Formatter::debug_struct_field2_finish(f, "AbiMap",
"arch", &self.arch, "os", &&self.os)
}
}Debug)]
10pub struct AbiMap {
11 arch: ArchKind,
12 os: OsKind,
13}
14
15#[derive(#[automatically_derived]
impl ::core::marker::Copy for AbiMapping { }Copy, #[automatically_derived]
impl ::core::clone::Clone for AbiMapping {
#[inline]
fn clone(&self) -> AbiMapping {
let _: ::core::clone::AssertParamIsClone<CanonAbi>;
*self
}
}Clone, #[automatically_derived]
impl ::core::fmt::Debug for AbiMapping {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
match self {
AbiMapping::Direct(__self_0) =>
::core::fmt::Formatter::debug_tuple_field1_finish(f, "Direct",
&__self_0),
AbiMapping::Deprecated(__self_0) =>
::core::fmt::Formatter::debug_tuple_field1_finish(f,
"Deprecated", &__self_0),
AbiMapping::Invalid =>
::core::fmt::Formatter::write_str(f, "Invalid"),
}
}
}Debug)]
17pub enum AbiMapping {
18 Direct(CanonAbi),
20 Deprecated(CanonAbi),
22 Invalid,
24}
25
26impl AbiMapping {
27 pub fn into_option(self) -> Option<CanonAbi> {
29 match self {
30 Self::Direct(abi) | Self::Deprecated(abi) => Some(abi),
31 Self::Invalid => None,
32 }
33 }
34
35 #[track_caller]
37 pub fn unwrap(self) -> CanonAbi {
38 self.into_option().unwrap()
39 }
40
41 pub fn is_mapped(self) -> bool {
42 self.into_option().is_some()
43 }
44}
45
46impl AbiMap {
47 pub fn from_target(target: &Target) -> Self {
49 let arch = match target.arch {
51 Arch::AArch64 => ArchKind::Aarch64,
52 Arch::AmdGpu => ArchKind::Amdgpu,
53 Arch::Arm => ArchKind::Arm(if target.llvm_target.starts_with("thumbv8m") {
54 ArmVer::ThumbV8M
55 } else {
56 ArmVer::Other
57 }),
58 Arch::Avr => ArchKind::Avr,
59 Arch::LoongArch32 | Arch::LoongArch64 => ArchKind::LoongArch,
60 Arch::Msp430 => ArchKind::Msp430,
61 Arch::Nvptx64 => ArchKind::Nvptx,
62 Arch::RiscV32 | Arch::RiscV64 => ArchKind::Riscv,
63 Arch::X86 => ArchKind::X86,
64 Arch::X86_64 => ArchKind::X86_64,
65 _ => ArchKind::Other,
66 };
67
68 let os = if target.is_like_darwin {
69 OsKind::Apple
70 } else if target.is_like_windows {
71 OsKind::Windows
72 } else if target.is_like_vexos {
73 OsKind::VEXos
74 } else {
75 OsKind::Other
76 };
77
78 AbiMap { arch, os }
79 }
80
81 pub fn canonize_abi(&self, extern_abi: ExternAbi, has_c_varargs: bool) -> AbiMapping {
83 let AbiMap { os, arch } = *self;
84
85 if extern_abi == ExternAbi::Swift {
86 match os {
89 OsKind::Apple => {}
90 _ => return AbiMapping::Invalid,
91 }
92 }
93
94 let canon_abi = match (extern_abi, arch) {
95 (ExternAbi::C { .. }, _) => CanonAbi::C,
97 (ExternAbi::Rust | ExternAbi::RustCall, _) => CanonAbi::Rust,
98 (ExternAbi::Unadjusted, _) => CanonAbi::C,
99
100 (ExternAbi::RustCold, _) if self.os == OsKind::Windows => CanonAbi::Rust,
101 (ExternAbi::RustCold, _) => CanonAbi::RustCold,
102 (ExternAbi::RustPreserveNone, _) => CanonAbi::RustPreserveNone,
103 (ExternAbi::RustTail, _) => CanonAbi::RustTail,
104
105 (ExternAbi::Custom, _) => CanonAbi::Custom,
106
107 (ExternAbi::Swift, _) => CanonAbi::Swift,
108
109 (ExternAbi::System { .. }, ArchKind::X86)
110 if os == OsKind::Windows && !has_c_varargs =>
111 {
112 CanonAbi::X86(X86Call::Stdcall)
113 }
114 (ExternAbi::System { .. }, ArchKind::Arm(..)) if self.os == OsKind::VEXos => {
115 CanonAbi::Arm(ArmCall::Aapcs)
117 }
118 (ExternAbi::System { .. }, _) => CanonAbi::C,
119
120 (ExternAbi::RustInvalid, _) => return AbiMapping::Invalid,
124
125 (ExternAbi::EfiApi, ArchKind::Arm(..)) => CanonAbi::Arm(ArmCall::Aapcs),
126 (ExternAbi::EfiApi, ArchKind::X86_64) => CanonAbi::X86(X86Call::Win64),
127 (
128 ExternAbi::EfiApi,
129 ArchKind::Aarch64 | ArchKind::LoongArch | ArchKind::Riscv | ArchKind::X86,
130 ) => CanonAbi::C,
131 (ExternAbi::EfiApi, _) => return AbiMapping::Invalid,
132
133 (ExternAbi::Aapcs { .. }, ArchKind::Arm(..)) => CanonAbi::Arm(ArmCall::Aapcs),
135 (ExternAbi::Aapcs { .. }, _) => return AbiMapping::Invalid,
136
137 (ExternAbi::CmseNonSecureCall, ArchKind::Arm(ArmVer::ThumbV8M)) => {
138 CanonAbi::Arm(ArmCall::CCmseNonSecureCall)
139 }
140 (ExternAbi::CmseNonSecureEntry, ArchKind::Arm(ArmVer::ThumbV8M)) => {
141 CanonAbi::Arm(ArmCall::CCmseNonSecureEntry)
142 }
143 (ExternAbi::CmseNonSecureCall | ExternAbi::CmseNonSecureEntry, ..) => {
144 return AbiMapping::Invalid;
145 }
146
147 (ExternAbi::PtxKernel, ArchKind::Nvptx) => CanonAbi::GpuKernel,
149 (ExternAbi::GpuKernel, ArchKind::Amdgpu | ArchKind::Nvptx) => CanonAbi::GpuKernel,
150 (ExternAbi::PtxKernel | ExternAbi::GpuKernel, _) => return AbiMapping::Invalid,
151
152 (ExternAbi::Cdecl { .. }, ArchKind::X86) => CanonAbi::C,
154 (ExternAbi::Cdecl { .. }, _) => return AbiMapping::Deprecated(CanonAbi::C),
155
156 (ExternAbi::Fastcall { .. }, ArchKind::X86) => CanonAbi::X86(X86Call::Fastcall),
157 (ExternAbi::Fastcall { .. }, _) if os == OsKind::Windows => {
158 return AbiMapping::Deprecated(CanonAbi::C);
159 }
160 (ExternAbi::Fastcall { .. }, _) => return AbiMapping::Invalid,
161
162 (ExternAbi::Stdcall { .. }, ArchKind::X86) => CanonAbi::X86(X86Call::Stdcall),
163 (ExternAbi::Stdcall { .. }, _) if os == OsKind::Windows => {
164 return AbiMapping::Deprecated(CanonAbi::C);
165 }
166 (ExternAbi::Stdcall { .. }, _) => return AbiMapping::Invalid,
167
168 (ExternAbi::Thiscall { .. }, ArchKind::X86) => CanonAbi::X86(X86Call::Thiscall),
169 (ExternAbi::Thiscall { .. }, _) => return AbiMapping::Invalid,
170
171 (ExternAbi::Vectorcall { .. }, ArchKind::X86 | ArchKind::X86_64) => {
172 CanonAbi::X86(X86Call::Vectorcall)
173 }
174 (ExternAbi::Vectorcall { .. }, _) => return AbiMapping::Invalid,
175
176 (ExternAbi::SysV64 { .. }, ArchKind::X86_64) => CanonAbi::X86(X86Call::SysV64),
177 (ExternAbi::Win64 { .. }, ArchKind::X86_64) => CanonAbi::X86(X86Call::Win64),
178 (ExternAbi::SysV64 { .. } | ExternAbi::Win64 { .. }, _) => return AbiMapping::Invalid,
179
180 (ExternAbi::AvrInterrupt, ArchKind::Avr) => CanonAbi::Interrupt(InterruptKind::Avr),
182 (ExternAbi::AvrNonBlockingInterrupt, ArchKind::Avr) => {
183 CanonAbi::Interrupt(InterruptKind::AvrNonBlocking)
184 }
185 (ExternAbi::Msp430Interrupt, ArchKind::Msp430) => {
186 CanonAbi::Interrupt(InterruptKind::Msp430)
187 }
188 (ExternAbi::RiscvInterruptM, ArchKind::Riscv) => {
189 CanonAbi::Interrupt(InterruptKind::RiscvMachine)
190 }
191 (ExternAbi::RiscvInterruptS, ArchKind::Riscv) => {
192 CanonAbi::Interrupt(InterruptKind::RiscvSupervisor)
193 }
194 (ExternAbi::X86Interrupt, ArchKind::X86 | ArchKind::X86_64) => {
195 CanonAbi::Interrupt(InterruptKind::X86)
196 }
197 (
198 ExternAbi::AvrInterrupt
199 | ExternAbi::AvrNonBlockingInterrupt
200 | ExternAbi::Msp430Interrupt
201 | ExternAbi::RiscvInterruptM
202 | ExternAbi::RiscvInterruptS
203 | ExternAbi::X86Interrupt,
204 _,
205 ) => return AbiMapping::Invalid,
206 };
207
208 AbiMapping::Direct(canon_abi)
209 }
210}
211
212#[derive(#[automatically_derived]
impl ::core::fmt::Debug for ArchKind {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
match self {
ArchKind::Aarch64 =>
::core::fmt::Formatter::write_str(f, "Aarch64"),
ArchKind::Amdgpu =>
::core::fmt::Formatter::write_str(f, "Amdgpu"),
ArchKind::Arm(__self_0) =>
::core::fmt::Formatter::debug_tuple_field1_finish(f, "Arm",
&__self_0),
ArchKind::Avr => ::core::fmt::Formatter::write_str(f, "Avr"),
ArchKind::LoongArch =>
::core::fmt::Formatter::write_str(f, "LoongArch"),
ArchKind::Msp430 =>
::core::fmt::Formatter::write_str(f, "Msp430"),
ArchKind::Nvptx => ::core::fmt::Formatter::write_str(f, "Nvptx"),
ArchKind::Riscv => ::core::fmt::Formatter::write_str(f, "Riscv"),
ArchKind::X86 => ::core::fmt::Formatter::write_str(f, "X86"),
ArchKind::X86_64 =>
::core::fmt::Formatter::write_str(f, "X86_64"),
ArchKind::Other => ::core::fmt::Formatter::write_str(f, "Other"),
}
}
}Debug, #[automatically_derived]
impl ::core::cmp::PartialEq for ArchKind {
#[inline]
fn eq(&self, other: &ArchKind) -> bool {
let __self_discr = ::core::intrinsics::discriminant_value(self);
let __arg1_discr = ::core::intrinsics::discriminant_value(other);
__self_discr == __arg1_discr &&
match (self, other) {
(ArchKind::Arm(__self_0), ArchKind::Arm(__arg1_0)) =>
__self_0 == __arg1_0,
_ => true,
}
}
}PartialEq, #[automatically_derived]
impl ::core::marker::Copy for ArchKind { }Copy, #[automatically_derived]
impl ::core::clone::Clone for ArchKind {
#[inline]
fn clone(&self) -> ArchKind {
let _: ::core::clone::AssertParamIsClone<ArmVer>;
*self
}
}Clone)]
213enum ArchKind {
214 Aarch64,
215 Amdgpu,
216 Arm(ArmVer),
217 Avr,
218 LoongArch,
219 Msp430,
220 Nvptx,
221 Riscv,
222 X86,
223 X86_64,
224 Other,
226}
227
228#[derive(#[automatically_derived]
impl ::core::fmt::Debug for OsKind {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
::core::fmt::Formatter::write_str(f,
match self {
OsKind::Apple => "Apple",
OsKind::Windows => "Windows",
OsKind::VEXos => "VEXos",
OsKind::Other => "Other",
})
}
}Debug, #[automatically_derived]
impl ::core::cmp::PartialEq for OsKind {
#[inline]
fn eq(&self, other: &OsKind) -> bool {
let __self_discr = ::core::intrinsics::discriminant_value(self);
let __arg1_discr = ::core::intrinsics::discriminant_value(other);
__self_discr == __arg1_discr
}
}PartialEq, #[automatically_derived]
impl ::core::marker::Copy for OsKind { }Copy, #[automatically_derived]
impl ::core::clone::Clone for OsKind {
#[inline]
fn clone(&self) -> OsKind { *self }
}Clone)]
229enum OsKind {
230 Apple,
231 Windows,
232 VEXos,
233 Other,
234}
235
236#[derive(#[automatically_derived]
impl ::core::fmt::Debug for ArmVer {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
::core::fmt::Formatter::write_str(f,
match self {
ArmVer::ThumbV8M => "ThumbV8M",
ArmVer::Other => "Other",
})
}
}Debug, #[automatically_derived]
impl ::core::cmp::PartialEq for ArmVer {
#[inline]
fn eq(&self, other: &ArmVer) -> bool {
let __self_discr = ::core::intrinsics::discriminant_value(self);
let __arg1_discr = ::core::intrinsics::discriminant_value(other);
__self_discr == __arg1_discr
}
}PartialEq, #[automatically_derived]
impl ::core::marker::Copy for ArmVer { }Copy, #[automatically_derived]
impl ::core::clone::Clone for ArmVer {
#[inline]
fn clone(&self) -> ArmVer { *self }
}Clone)]
237enum ArmVer {
238 ThumbV8M,
239 Other,
240}