cranelift_codegen/isa/
call_conv.rs1use crate::ir::types;
2use crate::ir::Type;
3use crate::settings::{self, LibcallCallConv};
4use core::fmt;
5use core::str;
6use target_lexicon::{CallingConvention, Triple};
7
8#[cfg(feature = "enable-serde")]
9use serde_derive::{Deserialize, Serialize};
10
11#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
13#[cfg_attr(feature = "enable-serde", derive(Serialize, Deserialize))]
14pub enum CallConv {
15 Fast,
17 Cold,
19 Tail,
34 SystemV,
36 WindowsFastcall,
38 AppleAarch64,
40 Probestack,
42 Winch,
48}
49
50impl CallConv {
51 pub fn triple_default(triple: &Triple) -> Self {
53 match triple.default_calling_convention() {
54 Ok(CallingConvention::SystemV) | Err(()) => Self::SystemV,
57 Ok(CallingConvention::AppleAarch64) => Self::AppleAarch64,
58 Ok(CallingConvention::WindowsFastcall) => Self::WindowsFastcall,
59 Ok(unimp) => unimplemented!("calling convention: {:?}", unimp),
60 }
61 }
62
63 pub fn for_libcall(flags: &settings::Flags, default_call_conv: CallConv) -> Self {
65 match flags.libcall_call_conv() {
66 LibcallCallConv::IsaDefault => default_call_conv,
67 LibcallCallConv::Fast => Self::Fast,
68 LibcallCallConv::Cold => Self::Cold,
69 LibcallCallConv::SystemV => Self::SystemV,
70 LibcallCallConv::WindowsFastcall => Self::WindowsFastcall,
71 LibcallCallConv::AppleAarch64 => Self::AppleAarch64,
72 LibcallCallConv::Probestack => Self::Probestack,
73 }
74 }
75
76 pub fn supports_tail_calls(&self) -> bool {
78 match self {
79 CallConv::Tail => true,
80 _ => false,
81 }
82 }
83
84 pub fn supports_exceptions(&self) -> bool {
86 match self {
87 CallConv::Tail | CallConv::SystemV => true,
88 _ => false,
89 }
90 }
91
92 pub fn exception_payload_types(&self, pointer_ty: Type) -> &[Type] {
94 match self {
95 CallConv::Tail | CallConv::SystemV => match pointer_ty {
96 types::I32 => &[types::I32, types::I32],
97 types::I64 => &[types::I64, types::I64],
98 _ => unreachable!(),
99 },
100 _ => &[],
101 }
102 }
103}
104
105impl fmt::Display for CallConv {
106 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
107 f.write_str(match *self {
108 Self::Fast => "fast",
109 Self::Cold => "cold",
110 Self::Tail => "tail",
111 Self::SystemV => "system_v",
112 Self::WindowsFastcall => "windows_fastcall",
113 Self::AppleAarch64 => "apple_aarch64",
114 Self::Probestack => "probestack",
115 Self::Winch => "winch",
116 })
117 }
118}
119
120impl str::FromStr for CallConv {
121 type Err = ();
122 fn from_str(s: &str) -> Result<Self, Self::Err> {
123 match s {
124 "fast" => Ok(Self::Fast),
125 "cold" => Ok(Self::Cold),
126 "tail" => Ok(Self::Tail),
127 "system_v" => Ok(Self::SystemV),
128 "windows_fastcall" => Ok(Self::WindowsFastcall),
129 "apple_aarch64" => Ok(Self::AppleAarch64),
130 "probestack" => Ok(Self::Probestack),
131 "winch" => Ok(Self::Winch),
132 _ => Err(()),
133 }
134 }
135}