winch(x64): Improve ABI support in trampolines (#6204)
This commit improves ABI support in Winch's trampolines mainly by: * Adding support for the `fastcall` calling convention. * By storing/restoring callee-saved registers. One of the explicit goals of this change is to make tests available in the x86_64 target as a whole and remove the need exclude the windows target. This commit also introduces a `CallingConvention` enum, to better reflect the subset of calling conventions that are supported by Winch.
This commit is contained in:
@@ -70,6 +70,60 @@ pub(crate) enum LookupError {
|
||||
SupportDisabled,
|
||||
}
|
||||
|
||||
/// Calling conventions supported by Winch. Winch supports the `Wasmtime*`
|
||||
/// variations of the system's ABI calling conventions and an internal default
|
||||
/// calling convention.
|
||||
///
|
||||
/// This enum is a reduced subset of the calling conventions defined in
|
||||
/// [cranelift_codegen::isa::CallConv]. Introducing this enum makes it easier
|
||||
/// to enforce the invariant of all the calling conventions supported by Winch.
|
||||
pub enum CallingConvention {
|
||||
/// See [cranelift_codegen::isa::CallConv::WasmtimeSystemV]
|
||||
WasmtimeSystemV,
|
||||
/// See [cranelift_codegen::isa::CallConv::WasmtimeFastcall]
|
||||
WasmtimeFastcall,
|
||||
/// See [cranelift_codegen::isa::CallConv::WasmtimeAppleAarch64]
|
||||
WasmtimeAppleAarch64,
|
||||
/// The default calling convention for Winch. It largely follows SystemV
|
||||
/// for parameter and result handling. This calling convention is part of
|
||||
/// Winch's default ABI [crate::abi::ABI].
|
||||
Default,
|
||||
}
|
||||
|
||||
impl CallingConvention {
|
||||
/// Returns true if the current calling convention is `WasmtimeFastcall`.
|
||||
fn is_fastcall(&self) -> bool {
|
||||
match &self {
|
||||
CallingConvention::WasmtimeFastcall => true,
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns true if the current calling convention is `WasmtimeSystemV`.
|
||||
fn is_systemv(&self) -> bool {
|
||||
match &self {
|
||||
CallingConvention::WasmtimeSystemV => true,
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns true if the current calling convention is `WasmtimeAppleAarch64`.
|
||||
fn is_apple_aarch64(&self) -> bool {
|
||||
match &self {
|
||||
CallingConvention::WasmtimeAppleAarch64 => true,
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns true if the current calling convention is `Default`.
|
||||
fn is_default(&self) -> bool {
|
||||
match &self {
|
||||
CallingConvention::Default => true,
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// A trait representing commonalities between the supported
|
||||
/// instruction set architectures.
|
||||
pub trait TargetIsa: Send + Sync {
|
||||
@@ -100,10 +154,21 @@ pub trait TargetIsa: Send + Sync {
|
||||
) -> Result<MachBufferFinalized<Final>>;
|
||||
|
||||
/// Get the default calling convention of the underlying target triple.
|
||||
fn call_conv(&self) -> CallConv {
|
||||
fn default_call_conv(&self) -> CallConv {
|
||||
CallConv::triple_default(&self.triple())
|
||||
}
|
||||
|
||||
/// Derive Wasmtime's calling convention from the triple's default
|
||||
/// calling convention.
|
||||
fn wasmtime_call_conv(&self) -> CallingConvention {
|
||||
match self.default_call_conv() {
|
||||
CallConv::AppleAarch64 => CallingConvention::WasmtimeAppleAarch64,
|
||||
CallConv::SystemV => CallingConvention::WasmtimeSystemV,
|
||||
CallConv::WindowsFastcall => CallingConvention::WasmtimeFastcall,
|
||||
cc => unimplemented!("calling convention: {:?}", cc),
|
||||
}
|
||||
}
|
||||
|
||||
/// Get the endianess of the underlying target triple.
|
||||
fn endianness(&self) -> target_lexicon::Endianness {
|
||||
self.triple().endianness().unwrap()
|
||||
@@ -131,7 +196,7 @@ impl Debug for &dyn TargetIsa {
|
||||
f,
|
||||
"Target ISA {{ triple: {:?}, calling convention: {:?} }}",
|
||||
self.triple(),
|
||||
self.call_conv()
|
||||
self.default_call_conv()
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user