Cranelift: Introduce the return_call and return_call_indirect instructions (#5679)

* Cranelift: Introduce the `tail` calling convention

This is an unstable-ABI calling convention that we will eventually use to
support Wasm tail calls.

Co-Authored-By: Jamey Sharp <jsharp@fastly.com>

* Cranelift: Introduce the `return_call` and `return_call_indirect` instructions

These will be used to implement tail calls for Wasm and any other language
targeting CLIF. The `return_call_indirect` instruction differs from the Wasm
instruction of the same name by taking a native address callee rather than a
Wasm function index.

Co-Authored-By: Jamey Sharp <jsharp@fastly.com>

* Cranelift: Implement verification rules for `return_call[_indirect]`

They must:

* have the same return types between the caller and callee,
* have the same calling convention between caller and callee,
* and that calling convention must support tail calls.

Co-Authored-By: Jamey Sharp <jsharp@fastly.com>

* cargo fmt

---------

Co-authored-by: Jamey Sharp <jsharp@fastly.com>
This commit is contained in:
Nick Fitzgerald
2023-02-01 13:20:35 -08:00
committed by GitHub
parent ffbbfbffce
commit bdfb746548
8 changed files with 298 additions and 101 deletions

View File

@@ -14,6 +14,8 @@ pub enum CallConv {
Fast,
/// Smallest caller code size, not ABI-stable.
Cold,
/// Supports tail calls, not ABI-stable.
Tail,
/// System V-style convention used on many platforms.
SystemV,
/// Windows "fastcall" convention, also used for x64 and ARM.
@@ -64,6 +66,14 @@ impl CallConv {
}
}
/// Does this calling convention support tail calls?
pub fn supports_tail_calls(&self) -> bool {
match self {
CallConv::Tail => true,
_ => false,
}
}
/// Is the calling convention extending the Windows Fastcall ABI?
pub fn extends_windows_fastcall(self) -> bool {
match self {
@@ -94,6 +104,7 @@ impl fmt::Display for CallConv {
f.write_str(match *self {
Self::Fast => "fast",
Self::Cold => "cold",
Self::Tail => "tail",
Self::SystemV => "system_v",
Self::WindowsFastcall => "windows_fastcall",
Self::AppleAarch64 => "apple_aarch64",
@@ -111,6 +122,7 @@ impl str::FromStr for CallConv {
match s {
"fast" => Ok(Self::Fast),
"cold" => Ok(Self::Cold),
"tail" => Ok(Self::Tail),
"system_v" => Ok(Self::SystemV),
"windows_fastcall" => Ok(Self::WindowsFastcall),
"apple_aarch64" => Ok(Self::AppleAarch64),

View File

@@ -708,6 +708,7 @@ impl ABIMachineSpec for X64ABIMachineSpec {
regs: &[Writable<RealReg>],
) -> Vec<Writable<RealReg>> {
let mut regs: Vec<Writable<RealReg>> = match call_conv {
CallConv::Tail => unimplemented!(),
CallConv::Fast | CallConv::Cold | CallConv::SystemV | CallConv::WasmtimeSystemV => regs
.iter()
.cloned()
@@ -823,6 +824,7 @@ fn get_intreg_for_retval(
retval_idx: usize,
) -> Option<Reg> {
match call_conv {
CallConv::Tail => unimplemented!(),
CallConv::Fast | CallConv::Cold | CallConv::SystemV => match intreg_idx {
0 => Some(regs::rax()),
1 => Some(regs::rdx()),
@@ -851,6 +853,7 @@ fn get_fltreg_for_retval(
retval_idx: usize,
) -> Option<Reg> {
match call_conv {
CallConv::Tail => unimplemented!(),
CallConv::Fast | CallConv::Cold | CallConv::SystemV => match fltreg_idx {
0 => Some(regs::xmm0()),
1 => Some(regs::xmm1()),