cranelift_codegen/isa/
call_conv.rs1use crate::settings::{self, LibcallCallConv};
2use core::fmt;
3use core::str;
4use target_lexicon::{CallingConvention, Triple};
5
6#[cfg(feature = "enable-serde")]
7use serde::{Deserialize, Serialize};
8
9#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
11#[cfg_attr(feature = "enable-serde", derive(Serialize, Deserialize))]
12pub enum CallConv {
13 Fast,
15 Cold,
17 Tail,
19 SystemV,
21 WindowsFastcall,
23 AppleAarch64,
25 Probestack,
27 WasmtimeSystemV,
33 WasmtimeFastcall,
37 WasmtimeAppleAarch64,
41}
42
43impl CallConv {
44 pub fn triple_default(triple: &Triple) -> Self {
46 match triple.default_calling_convention() {
47 Ok(CallingConvention::SystemV) | Err(()) => Self::SystemV,
50 Ok(CallingConvention::AppleAarch64) => Self::AppleAarch64,
51 Ok(CallingConvention::WindowsFastcall) => Self::WindowsFastcall,
52 Ok(unimp) => unimplemented!("calling convention: {:?}", unimp),
53 }
54 }
55
56 pub fn for_libcall(flags: &settings::Flags, default_call_conv: CallConv) -> Self {
58 match flags.libcall_call_conv() {
59 LibcallCallConv::IsaDefault => default_call_conv,
60 LibcallCallConv::Fast => Self::Fast,
61 LibcallCallConv::Cold => Self::Cold,
62 LibcallCallConv::SystemV => Self::SystemV,
63 LibcallCallConv::WindowsFastcall => Self::WindowsFastcall,
64 LibcallCallConv::AppleAarch64 => Self::AppleAarch64,
65 LibcallCallConv::Probestack => Self::Probestack,
66 }
67 }
68
69 pub fn supports_tail_calls(&self) -> bool {
71 match self {
72 CallConv::Tail => true,
73 _ => false,
74 }
75 }
76
77 pub fn extends_windows_fastcall(self) -> bool {
79 match self {
80 Self::WindowsFastcall | Self::WasmtimeFastcall => true,
81 _ => false,
82 }
83 }
84
85 pub fn extends_apple_aarch64(self) -> bool {
87 match self {
88 Self::AppleAarch64 | Self::WasmtimeAppleAarch64 => true,
89 _ => false,
90 }
91 }
92
93 pub fn extends_wasmtime(self) -> bool {
95 match self {
96 Self::WasmtimeSystemV | Self::WasmtimeFastcall | Self::WasmtimeAppleAarch64 => true,
97 _ => false,
98 }
99 }
100}
101
102impl fmt::Display for CallConv {
103 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
104 f.write_str(match *self {
105 Self::Fast => "fast",
106 Self::Cold => "cold",
107 Self::Tail => "tail",
108 Self::SystemV => "system_v",
109 Self::WindowsFastcall => "windows_fastcall",
110 Self::AppleAarch64 => "apple_aarch64",
111 Self::Probestack => "probestack",
112 Self::WasmtimeSystemV => "wasmtime_system_v",
113 Self::WasmtimeFastcall => "wasmtime_fastcall",
114 Self::WasmtimeAppleAarch64 => "wasmtime_apple_aarch64",
115 })
116 }
117}
118
119impl str::FromStr for CallConv {
120 type Err = ();
121 fn from_str(s: &str) -> Result<Self, Self::Err> {
122 match s {
123 "fast" => Ok(Self::Fast),
124 "cold" => Ok(Self::Cold),
125 "tail" => Ok(Self::Tail),
126 "system_v" => Ok(Self::SystemV),
127 "windows_fastcall" => Ok(Self::WindowsFastcall),
128 "apple_aarch64" => Ok(Self::AppleAarch64),
129 "probestack" => Ok(Self::Probestack),
130 "wasmtime_system_v" => Ok(Self::WasmtimeSystemV),
131 "wasmtime_fastcall" => Ok(Self::WasmtimeFastcall),
132 "wasmtime_apple_aarch64" => Ok(Self::WasmtimeAppleAarch64),
133 _ => Err(()),
134 }
135 }
136}