cranelift_codegen_meta/cdsl/
operands.rs1use std::collections::HashMap;
2
3use crate::cdsl::typevar::TypeVar;
4
5#[derive(Clone, Debug)]
19pub(crate) struct Operand {
20 pub name: &'static str,
22
23 pub kind: OperandKind,
25
26 doc: Option<&'static str>,
27}
28
29impl Operand {
30 pub fn new(name: &'static str, kind: impl Into<OperandKind>) -> Self {
31 Self {
32 name,
33 doc: None,
34 kind: kind.into(),
35 }
36 }
37 pub fn with_doc(mut self, doc: &'static str) -> Self {
38 self.doc = Some(doc);
39 self
40 }
41
42 pub fn doc(&self) -> &str {
43 if let Some(doc) = &self.doc {
44 return doc;
45 }
46 match &self.kind.fields {
47 OperandKindFields::TypeVar(tvar) => &tvar.doc,
48 _ => self.kind.doc(),
49 }
50 }
51
52 pub fn is_value(&self) -> bool {
53 matches!(self.kind.fields, OperandKindFields::TypeVar(_))
54 }
55
56 pub fn type_var(&self) -> Option<&TypeVar> {
57 match &self.kind.fields {
58 OperandKindFields::TypeVar(typevar) => Some(typevar),
59 _ => None,
60 }
61 }
62
63 pub fn is_varargs(&self) -> bool {
64 matches!(self.kind.fields, OperandKindFields::VariableArgs)
65 }
66
67 pub fn is_immediate_or_entityref(&self) -> bool {
69 matches!(
70 self.kind.fields,
71 OperandKindFields::ImmEnum(_)
72 | OperandKindFields::ImmValue
73 | OperandKindFields::EntityRef
74 )
75 }
76
77 pub fn is_immediate(&self) -> bool {
79 matches!(
80 self.kind.fields,
81 OperandKindFields::ImmEnum(_) | OperandKindFields::ImmValue
82 )
83 }
84}
85
86pub type EnumValues = HashMap<&'static str, &'static str>;
87
88#[derive(Clone, Debug)]
89pub(crate) enum OperandKindFields {
90 EntityRef,
91 VariableArgs,
92 ImmValue,
93 ImmEnum(EnumValues),
94 TypeVar(TypeVar),
95}
96
97impl OperandKindFields {
98 pub(crate) fn enum_values(&self) -> Option<&EnumValues> {
100 match self {
101 OperandKindFields::ImmEnum(map) => Some(map),
102 _ => None,
103 }
104 }
105}
106
107#[derive(Clone, Debug)]
108pub(crate) struct OperandKind {
109 pub rust_type: &'static str,
111
112 pub rust_field_name: &'static str,
114
115 pub fields: OperandKindFields,
117
118 doc: Option<&'static str>,
119}
120
121impl OperandKind {
122 pub fn new(
123 rust_field_name: &'static str,
124 rust_type: &'static str,
125 fields: OperandKindFields,
126 doc: &'static str,
127 ) -> Self {
128 Self {
129 rust_field_name,
130 rust_type,
131 fields,
132 doc: Some(doc),
133 }
134 }
135 fn doc(&self) -> &str {
136 if let Some(doc) = &self.doc {
137 return doc;
138 }
139 match &self.fields {
140 OperandKindFields::TypeVar(type_var) => &type_var.doc,
141 OperandKindFields::ImmEnum(_)
144 | OperandKindFields::ImmValue
145 | OperandKindFields::EntityRef
146 | OperandKindFields::VariableArgs => unreachable!(),
147 }
148 }
149
150 pub(crate) fn is_block(&self) -> bool {
151 self.rust_type == "ir::BlockCall"
152 }
153}
154
155impl From<&TypeVar> for OperandKind {
156 fn from(type_var: &TypeVar) -> Self {
157 OperandKind {
158 rust_field_name: "value",
159 rust_type: "ir::Value",
160 fields: OperandKindFields::TypeVar(type_var.into()),
161 doc: None,
162 }
163 }
164}
165impl From<&OperandKind> for OperandKind {
166 fn from(kind: &OperandKind) -> Self {
167 kind.clone()
168 }
169}