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::SpirV => ArchKind::Spirv,
64 Arch::Wasm32 | Arch::Wasm64 => ArchKind::Wasm,
65 Arch::X86 => ArchKind::X86,
66 Arch::X86_64 => ArchKind::X86_64,
67 _ => ArchKind::Other,
68 };
69
70 let os = if target.is_like_darwin {
71 OsKind::Apple
72 } else if target.is_like_windows {
73 OsKind::Windows
74 } else if target.is_like_vexos {
75 OsKind::VEXos
76 } else {
77 OsKind::Other
78 };
79
80 AbiMap { arch, os }
81 }
82
83 pub fn canonize_abi(&self, extern_abi: ExternAbi, has_c_varargs: bool) -> AbiMapping {
85 let AbiMap { os, arch } = *self;
86
87 if extern_abi == ExternAbi::Swift {
88 match os {
91 OsKind::Apple => {}
92 _ => return AbiMapping::Invalid,
93 }
94 }
95
96 let canon_abi = match (extern_abi, arch) {
97 (ExternAbi::C { .. }, _) => CanonAbi::C,
99 (ExternAbi::Rust | ExternAbi::RustCall, _) => CanonAbi::Rust,
100 (ExternAbi::Unadjusted, _) => CanonAbi::C,
101
102 (ExternAbi::RustCold, _) if self.os == OsKind::Windows => CanonAbi::Rust,
103 (ExternAbi::RustCold, _) => CanonAbi::RustCold,
104 (ExternAbi::RustPreserveNone, _) => CanonAbi::RustPreserveNone,
105 (ExternAbi::RustTail, _) => CanonAbi::RustTail,
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::Custom, ArchKind::Wasm | ArchKind::Spirv) => return AbiMapping::Invalid,
126 (ExternAbi::Custom, _) => CanonAbi::Custom,
127
128 (ExternAbi::EfiApi, ArchKind::Arm(..)) => CanonAbi::Arm(ArmCall::Aapcs),
129 (ExternAbi::EfiApi, ArchKind::X86_64) => CanonAbi::X86(X86Call::Win64),
130 (
131 ExternAbi::EfiApi,
132 ArchKind::Aarch64 | ArchKind::LoongArch | ArchKind::Riscv | ArchKind::X86,
133 ) => CanonAbi::C,
134 (ExternAbi::EfiApi, _) => return AbiMapping::Invalid,
135
136 (ExternAbi::Aapcs { .. }, ArchKind::Arm(..)) => CanonAbi::Arm(ArmCall::Aapcs),
138 (ExternAbi::Aapcs { .. }, _) => return AbiMapping::Invalid,
139
140 (ExternAbi::CmseNonSecureCall, ArchKind::Arm(ArmVer::ThumbV8M)) => {
141 CanonAbi::Arm(ArmCall::CCmseNonSecureCall)
142 }
143 (ExternAbi::CmseNonSecureEntry, ArchKind::Arm(ArmVer::ThumbV8M)) => {
144 CanonAbi::Arm(ArmCall::CCmseNonSecureEntry)
145 }
146 (ExternAbi::CmseNonSecureCall | ExternAbi::CmseNonSecureEntry, ..) => {
147 return AbiMapping::Invalid;
148 }
149
150 (ExternAbi::PtxKernel, ArchKind::Nvptx) => CanonAbi::GpuKernel,
152 (ExternAbi::GpuKernel, ArchKind::Amdgpu | ArchKind::Nvptx) => CanonAbi::GpuKernel,
153 (ExternAbi::PtxKernel | ExternAbi::GpuKernel, _) => return AbiMapping::Invalid,
154
155 (ExternAbi::Cdecl { .. }, ArchKind::X86) => CanonAbi::C,
157 (ExternAbi::Cdecl { .. }, _) => return AbiMapping::Deprecated(CanonAbi::C),
158
159 (ExternAbi::Fastcall { .. }, ArchKind::X86) => CanonAbi::X86(X86Call::Fastcall),
160 (ExternAbi::Fastcall { .. }, _) if os == OsKind::Windows => {
161 return AbiMapping::Deprecated(CanonAbi::C);
162 }
163 (ExternAbi::Fastcall { .. }, _) => return AbiMapping::Invalid,
164
165 (ExternAbi::Stdcall { .. }, ArchKind::X86) => CanonAbi::X86(X86Call::Stdcall),
166 (ExternAbi::Stdcall { .. }, _) if os == OsKind::Windows => {
167 return AbiMapping::Deprecated(CanonAbi::C);
168 }
169 (ExternAbi::Stdcall { .. }, _) => return AbiMapping::Invalid,
170
171 (ExternAbi::Thiscall { .. }, ArchKind::X86) => CanonAbi::X86(X86Call::Thiscall),
172 (ExternAbi::Thiscall { .. }, _) => return AbiMapping::Invalid,
173
174 (ExternAbi::Vectorcall { .. }, ArchKind::X86 | ArchKind::X86_64) => {
175 CanonAbi::X86(X86Call::Vectorcall)
176 }
177 (ExternAbi::Vectorcall { .. }, _) => return AbiMapping::Invalid,
178
179 (ExternAbi::SysV64 { .. }, ArchKind::X86_64) => CanonAbi::X86(X86Call::SysV64),
180 (ExternAbi::Win64 { .. }, ArchKind::X86_64) => CanonAbi::X86(X86Call::Win64),
181 (ExternAbi::SysV64 { .. } | ExternAbi::Win64 { .. }, _) => return AbiMapping::Invalid,
182
183 (ExternAbi::AvrInterrupt, ArchKind::Avr) => CanonAbi::Interrupt(InterruptKind::Avr),
185 (ExternAbi::AvrNonBlockingInterrupt, ArchKind::Avr) => {
186 CanonAbi::Interrupt(InterruptKind::AvrNonBlocking)
187 }
188 (ExternAbi::Msp430Interrupt, ArchKind::Msp430) => {
189 CanonAbi::Interrupt(InterruptKind::Msp430)
190 }
191 (ExternAbi::RiscvInterruptM, ArchKind::Riscv) => {
192 CanonAbi::Interrupt(InterruptKind::RiscvMachine)
193 }
194 (ExternAbi::RiscvInterruptS, ArchKind::Riscv) => {
195 CanonAbi::Interrupt(InterruptKind::RiscvSupervisor)
196 }
197 (ExternAbi::X86Interrupt, ArchKind::X86 | ArchKind::X86_64) => {
198 CanonAbi::Interrupt(InterruptKind::X86)
199 }
200 (
201 ExternAbi::AvrInterrupt
202 | ExternAbi::AvrNonBlockingInterrupt
203 | ExternAbi::Msp430Interrupt
204 | ExternAbi::RiscvInterruptM
205 | ExternAbi::RiscvInterruptS
206 | ExternAbi::X86Interrupt,
207 _,
208 ) => return AbiMapping::Invalid,
209 };
210
211 AbiMapping::Direct(canon_abi)
212 }
213}
214
215#[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::Wasm => ::core::fmt::Formatter::write_str(f, "Wasm"),
ArchKind::Spirv => ::core::fmt::Formatter::write_str(f, "Spirv"),
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)]
216enum ArchKind {
217 Aarch64,
218 Amdgpu,
219 Arm(ArmVer),
220 Avr,
221 LoongArch,
222 Msp430,
223 Nvptx,
224 Riscv,
225 X86,
226 X86_64,
227 Wasm,
228 Spirv,
229 Other,
231}
232
233#[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)]
234enum OsKind {
235 Apple,
236 Windows,
237 VEXos,
238 Other,
239}
240
241#[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)]
242enum ArmVer {
243 ThumbV8M,
244 Other,
245}