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
104 (ExternAbi::Custom, _) => CanonAbi::Custom,
105
106 (ExternAbi::Swift, _) => CanonAbi::Swift,
107
108 (ExternAbi::System { .. }, ArchKind::X86)
109 if os == OsKind::Windows && !has_c_varargs =>
110 {
111 CanonAbi::X86(X86Call::Stdcall)
112 }
113 (ExternAbi::System { .. }, ArchKind::Arm(..)) if self.os == OsKind::VEXos => {
114 CanonAbi::Arm(ArmCall::Aapcs)
116 }
117 (ExternAbi::System { .. }, _) => CanonAbi::C,
118
119 (ExternAbi::RustInvalid, _) => return AbiMapping::Invalid,
123
124 (ExternAbi::EfiApi, ArchKind::Arm(..)) => CanonAbi::Arm(ArmCall::Aapcs),
125 (ExternAbi::EfiApi, ArchKind::X86_64) => CanonAbi::X86(X86Call::Win64),
126 (
127 ExternAbi::EfiApi,
128 ArchKind::Aarch64 | ArchKind::LoongArch | ArchKind::Riscv | ArchKind::X86,
129 ) => CanonAbi::C,
130 (ExternAbi::EfiApi, _) => return AbiMapping::Invalid,
131
132 (ExternAbi::Aapcs { .. }, ArchKind::Arm(..)) => CanonAbi::Arm(ArmCall::Aapcs),
134 (ExternAbi::Aapcs { .. }, _) => return AbiMapping::Invalid,
135
136 (ExternAbi::CmseNonSecureCall, ArchKind::Arm(ArmVer::ThumbV8M)) => {
137 CanonAbi::Arm(ArmCall::CCmseNonSecureCall)
138 }
139 (ExternAbi::CmseNonSecureEntry, ArchKind::Arm(ArmVer::ThumbV8M)) => {
140 CanonAbi::Arm(ArmCall::CCmseNonSecureEntry)
141 }
142 (ExternAbi::CmseNonSecureCall | ExternAbi::CmseNonSecureEntry, ..) => {
143 return AbiMapping::Invalid;
144 }
145
146 (ExternAbi::PtxKernel, ArchKind::Nvptx) => CanonAbi::GpuKernel,
148 (ExternAbi::GpuKernel, ArchKind::Amdgpu | ArchKind::Nvptx) => CanonAbi::GpuKernel,
149 (ExternAbi::PtxKernel | ExternAbi::GpuKernel, _) => return AbiMapping::Invalid,
150
151 (ExternAbi::Cdecl { .. }, ArchKind::X86) => CanonAbi::C,
153 (ExternAbi::Cdecl { .. }, _) => return AbiMapping::Deprecated(CanonAbi::C),
154
155 (ExternAbi::Fastcall { .. }, ArchKind::X86) => CanonAbi::X86(X86Call::Fastcall),
156 (ExternAbi::Fastcall { .. }, _) if os == OsKind::Windows => {
157 return AbiMapping::Deprecated(CanonAbi::C);
158 }
159 (ExternAbi::Fastcall { .. }, _) => return AbiMapping::Invalid,
160
161 (ExternAbi::Stdcall { .. }, ArchKind::X86) => CanonAbi::X86(X86Call::Stdcall),
162 (ExternAbi::Stdcall { .. }, _) if os == OsKind::Windows => {
163 return AbiMapping::Deprecated(CanonAbi::C);
164 }
165 (ExternAbi::Stdcall { .. }, _) => return AbiMapping::Invalid,
166
167 (ExternAbi::Thiscall { .. }, ArchKind::X86) => CanonAbi::X86(X86Call::Thiscall),
168 (ExternAbi::Thiscall { .. }, _) => return AbiMapping::Invalid,
169
170 (ExternAbi::Vectorcall { .. }, ArchKind::X86 | ArchKind::X86_64) => {
171 CanonAbi::X86(X86Call::Vectorcall)
172 }
173 (ExternAbi::Vectorcall { .. }, _) => return AbiMapping::Invalid,
174
175 (ExternAbi::SysV64 { .. }, ArchKind::X86_64) => CanonAbi::X86(X86Call::SysV64),
176 (ExternAbi::Win64 { .. }, ArchKind::X86_64) => CanonAbi::X86(X86Call::Win64),
177 (ExternAbi::SysV64 { .. } | ExternAbi::Win64 { .. }, _) => return AbiMapping::Invalid,
178
179 (ExternAbi::AvrInterrupt, ArchKind::Avr) => CanonAbi::Interrupt(InterruptKind::Avr),
181 (ExternAbi::AvrNonBlockingInterrupt, ArchKind::Avr) => {
182 CanonAbi::Interrupt(InterruptKind::AvrNonBlocking)
183 }
184 (ExternAbi::Msp430Interrupt, ArchKind::Msp430) => {
185 CanonAbi::Interrupt(InterruptKind::Msp430)
186 }
187 (ExternAbi::RiscvInterruptM, ArchKind::Riscv) => {
188 CanonAbi::Interrupt(InterruptKind::RiscvMachine)
189 }
190 (ExternAbi::RiscvInterruptS, ArchKind::Riscv) => {
191 CanonAbi::Interrupt(InterruptKind::RiscvSupervisor)
192 }
193 (ExternAbi::X86Interrupt, ArchKind::X86 | ArchKind::X86_64) => {
194 CanonAbi::Interrupt(InterruptKind::X86)
195 }
196 (
197 ExternAbi::AvrInterrupt
198 | ExternAbi::AvrNonBlockingInterrupt
199 | ExternAbi::Msp430Interrupt
200 | ExternAbi::RiscvInterruptM
201 | ExternAbi::RiscvInterruptS
202 | ExternAbi::X86Interrupt,
203 _,
204 ) => return AbiMapping::Invalid,
205 };
206
207 AbiMapping::Direct(canon_abi)
208 }
209}
210
211#[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)]
212enum ArchKind {
213 Aarch64,
214 Amdgpu,
215 Arm(ArmVer),
216 Avr,
217 LoongArch,
218 Msp430,
219 Nvptx,
220 Riscv,
221 X86,
222 X86_64,
223 Other,
225}
226
227#[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)]
228enum OsKind {
229 Apple,
230 Windows,
231 VEXos,
232 Other,
233}
234
235#[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)]
236enum ArmVer {
237 ThumbV8M,
238 Other,
239}