Skip to content

Commit 895cf95

Browse files
Add AbiMapping for encoding permissive mappings
1 parent 2beb5a4 commit 895cf95

File tree

2 files changed

+42
-14
lines changed

2 files changed

+42
-14
lines changed

compiler/rustc_target/src/spec/abi_map.rs

Lines changed: 41 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,38 @@ use crate::spec::Target;
66
///
77
/// A maybe-transitional structure circa 2025 for hosting future experiments in
88
/// encapsulating arch-specific ABI lowering details to make them more testable.
9-
#[derive(Clone)]
9+
#[derive(Clone, Debug)]
1010
pub struct AbiMap {
1111
arch: Arch,
1212
os: OsKind,
1313
}
1414

15+
#[derive(Copy, Clone, Debug)]
16+
pub enum AbiMapping {
17+
/// this ABI is exactly mapped for this platform
18+
Direct(CanonAbi),
19+
/// a "permissive" ABI mapping generalized from other platforms
20+
Permissive(CanonAbi),
21+
Invalid,
22+
}
23+
24+
impl AbiMapping {
25+
pub fn into_option(self) -> Option<CanonAbi> {
26+
match self {
27+
Self::Direct(abi) | Self::Permissive(abi) => Some(abi),
28+
Self::Invalid => None,
29+
}
30+
}
31+
32+
pub fn unwrap(self) -> CanonAbi {
33+
self.into_option().unwrap()
34+
}
35+
36+
pub fn is_mapped(self) -> bool {
37+
self.into_option().is_some()
38+
}
39+
}
40+
1541
impl AbiMap {
1642
pub fn from_target(target: &Target) -> Self {
1743
// the purpose of this little exercise is to force listing what affects these mappings
@@ -32,7 +58,7 @@ impl AbiMap {
3258
AbiMap { arch, os }
3359
}
3460

35-
pub fn canonize_abi(&self, extern_abi: ExternAbi, has_c_varargs: bool) -> Option<CanonAbi> {
61+
pub fn canonize_abi(&self, extern_abi: ExternAbi, has_c_varargs: bool) -> AbiMapping {
3662
let AbiMap { os, arch } = *self;
3763

3864
let canon_abi = match (extern_abi, arch) {
@@ -53,43 +79,45 @@ impl AbiMap {
5379
(ExternAbi::EfiApi, Arch::Arm(..)) => CanonAbi::Arm(ArmCall::Aapcs),
5480
(ExternAbi::EfiApi, Arch::X86_64) => CanonAbi::X86(X86Call::Win64),
5581
(ExternAbi::EfiApi, Arch::Aarch64 | Arch::Riscv | Arch::X86) => CanonAbi::C,
56-
(ExternAbi::EfiApi, _) => return None,
82+
(ExternAbi::EfiApi, _) => return AbiMapping::Invalid,
5783

5884
(ExternAbi::Aapcs { .. }, Arch::Arm(..)) => CanonAbi::Arm(ArmCall::Aapcs),
59-
(ExternAbi::Aapcs { .. }, _) => return None,
85+
(ExternAbi::Aapcs { .. }, _) => return AbiMapping::Invalid,
6086

6187
(ExternAbi::CCmseNonSecureCall, Arch::Arm(ArmVer::ThumbV8M)) => {
6288
CanonAbi::Arm(ArmCall::CCmseNonSecureCall)
6389
}
6490
(ExternAbi::CCmseNonSecureEntry, Arch::Arm(ArmVer::ThumbV8M)) => {
6591
CanonAbi::Arm(ArmCall::CCmseNonSecureEntry)
6692
}
67-
(ExternAbi::CCmseNonSecureCall | ExternAbi::CCmseNonSecureEntry, ..) => return None,
93+
(ExternAbi::CCmseNonSecureCall | ExternAbi::CCmseNonSecureEntry, ..) => {
94+
return AbiMapping::Invalid;
95+
}
6896

6997
(ExternAbi::Fastcall { .. }, Arch::X86) => CanonAbi::X86(X86Call::Fastcall),
7098
(ExternAbi::Fastcall { .. }, _) if os == OsKind::Windows => CanonAbi::C,
71-
(ExternAbi::Fastcall { .. }, _) => return None,
99+
(ExternAbi::Fastcall { .. }, _) => return AbiMapping::Invalid,
72100

73101
(ExternAbi::Stdcall { .. }, Arch::X86) => CanonAbi::X86(X86Call::Stdcall),
74102
(ExternAbi::Stdcall { .. }, _) if os == OsKind::Windows => CanonAbi::C,
75-
(ExternAbi::Stdcall { .. }, _) => return None,
103+
(ExternAbi::Stdcall { .. }, _) => return AbiMapping::Invalid,
76104

77105
(ExternAbi::Thiscall { .. }, Arch::X86) => CanonAbi::X86(X86Call::Thiscall),
78-
(ExternAbi::Thiscall { .. }, _) => return None,
106+
(ExternAbi::Thiscall { .. }, _) => return AbiMapping::Invalid,
79107

80108
(ExternAbi::Vectorcall { .. }, Arch::X86 | Arch::X86_64) => {
81109
CanonAbi::X86(X86Call::Vectorcall)
82110
}
83111
(ExternAbi::Vectorcall { .. }, _) if os == OsKind::Windows => CanonAbi::C,
84-
(ExternAbi::Vectorcall { .. }, _) => return None,
112+
(ExternAbi::Vectorcall { .. }, _) => return AbiMapping::Invalid,
85113

86114
(ExternAbi::SysV64 { .. }, Arch::X86_64) => CanonAbi::X86(X86Call::SysV64),
87115
(ExternAbi::Win64 { .. }, Arch::X86_64) => CanonAbi::X86(X86Call::Win64),
88-
(ExternAbi::SysV64 { .. } | ExternAbi::Win64 { .. }, _) => return None,
116+
(ExternAbi::SysV64 { .. } | ExternAbi::Win64 { .. }, _) => return AbiMapping::Invalid,
89117

90118
(ExternAbi::PtxKernel, Arch::Nvptx) => CanonAbi::GpuKernel,
91119
(ExternAbi::GpuKernel, Arch::Amdgpu | Arch::Nvptx) => CanonAbi::GpuKernel,
92-
(ExternAbi::PtxKernel | ExternAbi::GpuKernel, _) => return None,
120+
(ExternAbi::PtxKernel | ExternAbi::GpuKernel, _) => return AbiMapping::Invalid,
93121

94122
(ExternAbi::AvrInterrupt, Arch::Avr) => CanonAbi::Interrupt(InterruptKind::Avr),
95123
(ExternAbi::AvrNonBlockingInterrupt, Arch::Avr) => {
@@ -115,10 +143,10 @@ impl AbiMap {
115143
| ExternAbi::RiscvInterruptS
116144
| ExternAbi::X86Interrupt,
117145
_,
118-
) => return None,
146+
) => return AbiMapping::Invalid,
119147
};
120148

121-
Some(canon_abi)
149+
AbiMapping::Direct(canon_abi)
122150
}
123151
}
124152

compiler/rustc_target/src/spec/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2917,7 +2917,7 @@ impl DerefMut for Target {
29172917
impl Target {
29182918
pub fn is_abi_supported(&self, abi: ExternAbi) -> bool {
29192919
let abi_map = AbiMap::from_target(self);
2920-
abi_map.canonize_abi(abi, false).is_some()
2920+
abi_map.canonize_abi(abi, false).is_mapped()
29212921
}
29222922

29232923
/// Minimum integer size in bits that this target can perform atomic

0 commit comments

Comments
 (0)