compiler: simplify TargetOptions ABI functions
`adjust_abi` is not needed and `is_abi_supported` can be a 1-liner.
This commit is contained in:
@@ -697,7 +697,6 @@ impl<'a, Ty> FnAbi<'a, Ty> {
|
|||||||
"sparc" => sparc::compute_abi_info(cx, self),
|
"sparc" => sparc::compute_abi_info(cx, self),
|
||||||
"sparc64" => sparc64::compute_abi_info(cx, self),
|
"sparc64" => sparc64::compute_abi_info(cx, self),
|
||||||
"nvptx64" => {
|
"nvptx64" => {
|
||||||
let abi = cx.target_spec().adjust_abi(abi, self.c_variadic);
|
|
||||||
if abi == ExternAbi::PtxKernel || abi == ExternAbi::GpuKernel {
|
if abi == ExternAbi::PtxKernel || abi == ExternAbi::GpuKernel {
|
||||||
nvptx64::compute_ptx_kernel_abi_info(cx, self)
|
nvptx64::compute_ptx_kernel_abi_info(cx, self)
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -2915,114 +2915,9 @@ impl DerefMut for Target {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Target {
|
impl Target {
|
||||||
/// Given a function ABI, turn it into the correct ABI for this target.
|
|
||||||
pub fn adjust_abi(&self, abi: ExternAbi, c_variadic: bool) -> ExternAbi {
|
|
||||||
use ExternAbi::*;
|
|
||||||
match abi {
|
|
||||||
// On Windows, `extern "system"` behaves like msvc's `__stdcall`.
|
|
||||||
// `__stdcall` only applies on x86 and on non-variadic functions:
|
|
||||||
// https://learn.microsoft.com/en-us/cpp/cpp/stdcall?view=msvc-170
|
|
||||||
System { unwind } => {
|
|
||||||
if self.is_like_windows && self.arch == "x86" && !c_variadic {
|
|
||||||
Stdcall { unwind }
|
|
||||||
} else {
|
|
||||||
C { unwind }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
EfiApi => {
|
|
||||||
if self.arch == "arm" {
|
|
||||||
Aapcs { unwind: false }
|
|
||||||
} else if self.arch == "x86_64" {
|
|
||||||
Win64 { unwind: false }
|
|
||||||
} else {
|
|
||||||
C { unwind: false }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// See commentary in `is_abi_supported`.
|
|
||||||
Stdcall { unwind } | Thiscall { unwind } | Fastcall { unwind } => {
|
|
||||||
if self.arch == "x86" { abi } else { C { unwind } }
|
|
||||||
}
|
|
||||||
Vectorcall { unwind } => {
|
|
||||||
if ["x86", "x86_64"].contains(&&*self.arch) {
|
|
||||||
abi
|
|
||||||
} else {
|
|
||||||
C { unwind }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// The Windows x64 calling convention we use for `extern "Rust"`
|
|
||||||
// <https://learn.microsoft.com/en-us/cpp/build/x64-software-conventions#register-volatility-and-preservation>
|
|
||||||
// expects the callee to save `xmm6` through `xmm15`, but `PreserveMost`
|
|
||||||
// (that we use by default for `extern "rust-cold"`) doesn't save any of those.
|
|
||||||
// So to avoid bloating callers, just use the Rust convention here.
|
|
||||||
RustCold if self.is_like_windows && self.arch == "x86_64" => Rust,
|
|
||||||
|
|
||||||
abi => abi,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn is_abi_supported(&self, abi: ExternAbi) -> bool {
|
pub fn is_abi_supported(&self, abi: ExternAbi) -> bool {
|
||||||
use ExternAbi::*;
|
let abi_map = AbiMap::from_target(self);
|
||||||
match abi {
|
abi_map.canonize_abi(abi, false).is_mapped()
|
||||||
Rust | C { .. } | System { .. } | RustCall | Unadjusted | Cdecl { .. } | RustCold => {
|
|
||||||
true
|
|
||||||
}
|
|
||||||
EfiApi => {
|
|
||||||
["arm", "aarch64", "riscv32", "riscv64", "x86", "x86_64"].contains(&&self.arch[..])
|
|
||||||
}
|
|
||||||
X86Interrupt => ["x86", "x86_64"].contains(&&self.arch[..]),
|
|
||||||
Aapcs { .. } => "arm" == self.arch,
|
|
||||||
CCmseNonSecureCall | CCmseNonSecureEntry => {
|
|
||||||
["thumbv8m.main-none-eabi", "thumbv8m.main-none-eabihf", "thumbv8m.base-none-eabi"]
|
|
||||||
.contains(&&self.llvm_target[..])
|
|
||||||
}
|
|
||||||
Win64 { .. } | SysV64 { .. } => self.arch == "x86_64",
|
|
||||||
PtxKernel => self.arch == "nvptx64",
|
|
||||||
GpuKernel => ["amdgpu", "nvptx64"].contains(&&self.arch[..]),
|
|
||||||
Msp430Interrupt => self.arch == "msp430",
|
|
||||||
RiscvInterruptM | RiscvInterruptS => ["riscv32", "riscv64"].contains(&&self.arch[..]),
|
|
||||||
AvrInterrupt | AvrNonBlockingInterrupt => self.arch == "avr",
|
|
||||||
Thiscall { .. } => self.arch == "x86",
|
|
||||||
// On windows these fall-back to platform native calling convention (C) when the
|
|
||||||
// architecture is not supported.
|
|
||||||
//
|
|
||||||
// This is I believe a historical accident that has occurred as part of Microsoft
|
|
||||||
// striving to allow most of the code to "just" compile when support for 64-bit x86
|
|
||||||
// was added and then later again, when support for ARM architectures was added.
|
|
||||||
//
|
|
||||||
// This is well documented across MSDN. Support for this in Rust has been added in
|
|
||||||
// #54576. This makes much more sense in context of Microsoft's C++ than it does in
|
|
||||||
// Rust, but there isn't much leeway remaining here to change it back at the time this
|
|
||||||
// comment has been written.
|
|
||||||
//
|
|
||||||
// Following are the relevant excerpts from the MSDN documentation.
|
|
||||||
//
|
|
||||||
// > The __vectorcall calling convention is only supported in native code on x86 and
|
|
||||||
// x64 processors that include Streaming SIMD Extensions 2 (SSE2) and above.
|
|
||||||
// > ...
|
|
||||||
// > On ARM machines, __vectorcall is accepted and ignored by the compiler.
|
|
||||||
//
|
|
||||||
// -- https://docs.microsoft.com/en-us/cpp/cpp/vectorcall?view=msvc-160
|
|
||||||
//
|
|
||||||
// > On ARM and x64 processors, __stdcall is accepted and ignored by the compiler;
|
|
||||||
//
|
|
||||||
// -- https://docs.microsoft.com/en-us/cpp/cpp/stdcall?view=msvc-160
|
|
||||||
//
|
|
||||||
// > In most cases, keywords or compiler switches that specify an unsupported
|
|
||||||
// > convention on a particular platform are ignored, and the platform default
|
|
||||||
// > convention is used.
|
|
||||||
//
|
|
||||||
// -- https://docs.microsoft.com/en-us/cpp/cpp/argument-passing-and-naming-conventions
|
|
||||||
Stdcall { .. } | Fastcall { .. } | Vectorcall { .. } if self.is_like_windows => true,
|
|
||||||
// Outside of Windows we want to only support these calling conventions for the
|
|
||||||
// architectures for which these calling conventions are actually well defined.
|
|
||||||
Stdcall { .. } | Fastcall { .. } if self.arch == "x86" => true,
|
|
||||||
Vectorcall { .. } if ["x86", "x86_64"].contains(&&self.arch[..]) => true,
|
|
||||||
// Reject these calling conventions everywhere else.
|
|
||||||
Stdcall { .. } | Fastcall { .. } | Vectorcall { .. } => false,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Minimum integer size in bits that this target can perform atomic
|
/// Minimum integer size in bits that this target can perform atomic
|
||||||
|
|||||||
Reference in New Issue
Block a user