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_windows {
69 OsKind::Windows
70 } else if target.is_like_vexos {
71 OsKind::VEXos
72 } else {
73 OsKind::Other
74 };
75
76 AbiMap { arch, os }
77 }
78
79 pub fn canonize_abi(&self, extern_abi: ExternAbi, has_c_varargs: bool) -> AbiMapping {
81 let AbiMap { os, arch } = *self;
82
83 let canon_abi = match (extern_abi, arch) {
84 (ExternAbi::C { .. }, _) => CanonAbi::C,
86 (ExternAbi::Rust | ExternAbi::RustCall, _) => CanonAbi::Rust,
87 (ExternAbi::Unadjusted, _) => CanonAbi::C,
88
89 (ExternAbi::RustCold, _) if self.os == OsKind::Windows => CanonAbi::Rust,
90 (ExternAbi::RustCold, _) => CanonAbi::RustCold,
91 (ExternAbi::RustPreserveNone, _) => CanonAbi::RustPreserveNone,
92
93 (ExternAbi::Custom, _) => CanonAbi::Custom,
94
95 (ExternAbi::System { .. }, ArchKind::X86)
96 if os == OsKind::Windows && !has_c_varargs =>
97 {
98 CanonAbi::X86(X86Call::Stdcall)
99 }
100 (ExternAbi::System { .. }, ArchKind::Arm(..)) if self.os == OsKind::VEXos => {
101 CanonAbi::Arm(ArmCall::Aapcs)
103 }
104 (ExternAbi::System { .. }, _) => CanonAbi::C,
105
106 (ExternAbi::RustInvalid, _) => return AbiMapping::Invalid,
110
111 (ExternAbi::EfiApi, ArchKind::Arm(..)) => CanonAbi::Arm(ArmCall::Aapcs),
112 (ExternAbi::EfiApi, ArchKind::X86_64) => CanonAbi::X86(X86Call::Win64),
113 (
114 ExternAbi::EfiApi,
115 ArchKind::Aarch64 | ArchKind::LoongArch | ArchKind::Riscv | ArchKind::X86,
116 ) => CanonAbi::C,
117 (ExternAbi::EfiApi, _) => return AbiMapping::Invalid,
118
119 (ExternAbi::Aapcs { .. }, ArchKind::Arm(..)) => CanonAbi::Arm(ArmCall::Aapcs),
121 (ExternAbi::Aapcs { .. }, _) => return AbiMapping::Invalid,
122
123 (ExternAbi::CmseNonSecureCall, ArchKind::Arm(ArmVer::ThumbV8M)) => {
124 CanonAbi::Arm(ArmCall::CCmseNonSecureCall)
125 }
126 (ExternAbi::CmseNonSecureEntry, ArchKind::Arm(ArmVer::ThumbV8M)) => {
127 CanonAbi::Arm(ArmCall::CCmseNonSecureEntry)
128 }
129 (ExternAbi::CmseNonSecureCall | ExternAbi::CmseNonSecureEntry, ..) => {
130 return AbiMapping::Invalid;
131 }
132
133 (ExternAbi::PtxKernel, ArchKind::Nvptx) => CanonAbi::GpuKernel,
135 (ExternAbi::GpuKernel, ArchKind::Amdgpu | ArchKind::Nvptx) => CanonAbi::GpuKernel,
136 (ExternAbi::PtxKernel | ExternAbi::GpuKernel, _) => return AbiMapping::Invalid,
137
138 (ExternAbi::Cdecl { .. }, ArchKind::X86) => CanonAbi::C,
140 (ExternAbi::Cdecl { .. }, _) => return AbiMapping::Deprecated(CanonAbi::C),
141
142 (ExternAbi::Fastcall { .. }, ArchKind::X86) => CanonAbi::X86(X86Call::Fastcall),
143 (ExternAbi::Fastcall { .. }, _) if os == OsKind::Windows => {
144 return AbiMapping::Deprecated(CanonAbi::C);
145 }
146 (ExternAbi::Fastcall { .. }, _) => return AbiMapping::Invalid,
147
148 (ExternAbi::Stdcall { .. }, ArchKind::X86) => CanonAbi::X86(X86Call::Stdcall),
149 (ExternAbi::Stdcall { .. }, _) if os == OsKind::Windows => {
150 return AbiMapping::Deprecated(CanonAbi::C);
151 }
152 (ExternAbi::Stdcall { .. }, _) => return AbiMapping::Invalid,
153
154 (ExternAbi::Thiscall { .. }, ArchKind::X86) => CanonAbi::X86(X86Call::Thiscall),
155 (ExternAbi::Thiscall { .. }, _) => return AbiMapping::Invalid,
156
157 (ExternAbi::Vectorcall { .. }, ArchKind::X86 | ArchKind::X86_64) => {
158 CanonAbi::X86(X86Call::Vectorcall)
159 }
160 (ExternAbi::Vectorcall { .. }, _) => return AbiMapping::Invalid,
161
162 (ExternAbi::SysV64 { .. }, ArchKind::X86_64) => CanonAbi::X86(X86Call::SysV64),
163 (ExternAbi::Win64 { .. }, ArchKind::X86_64) => CanonAbi::X86(X86Call::Win64),
164 (ExternAbi::SysV64 { .. } | ExternAbi::Win64 { .. }, _) => return AbiMapping::Invalid,
165
166 (ExternAbi::AvrInterrupt, ArchKind::Avr) => CanonAbi::Interrupt(InterruptKind::Avr),
168 (ExternAbi::AvrNonBlockingInterrupt, ArchKind::Avr) => {
169 CanonAbi::Interrupt(InterruptKind::AvrNonBlocking)
170 }
171 (ExternAbi::Msp430Interrupt, ArchKind::Msp430) => {
172 CanonAbi::Interrupt(InterruptKind::Msp430)
173 }
174 (ExternAbi::RiscvInterruptM, ArchKind::Riscv) => {
175 CanonAbi::Interrupt(InterruptKind::RiscvMachine)
176 }
177 (ExternAbi::RiscvInterruptS, ArchKind::Riscv) => {
178 CanonAbi::Interrupt(InterruptKind::RiscvSupervisor)
179 }
180 (ExternAbi::X86Interrupt, ArchKind::X86 | ArchKind::X86_64) => {
181 CanonAbi::Interrupt(InterruptKind::X86)
182 }
183 (
184 ExternAbi::AvrInterrupt
185 | ExternAbi::AvrNonBlockingInterrupt
186 | ExternAbi::Msp430Interrupt
187 | ExternAbi::RiscvInterruptM
188 | ExternAbi::RiscvInterruptS
189 | ExternAbi::X86Interrupt,
190 _,
191 ) => return AbiMapping::Invalid,
192 };
193
194 AbiMapping::Direct(canon_abi)
195 }
196}
197
198#[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)]
199enum ArchKind {
200 Aarch64,
201 Amdgpu,
202 Arm(ArmVer),
203 Avr,
204 LoongArch,
205 Msp430,
206 Nvptx,
207 Riscv,
208 X86,
209 X86_64,
210 Other,
212}
213
214#[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::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)]
215enum OsKind {
216 Windows,
217 VEXos,
218 Other,
219}
220
221#[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)]
222enum ArmVer {
223 ThumbV8M,
224 Other,
225}