cranelift_codegen_meta/cdsl/
formats.rs1use crate::cdsl::operands::OperandKind;
2use std::fmt;
3use std::rc::Rc;
4
5#[derive(Debug)]
10pub(crate) struct FormatField {
11 pub kind: OperandKind,
13
14 pub member: &'static str,
16}
17
18#[derive(Debug)]
30pub(crate) struct InstructionFormat {
31 pub name: &'static str,
34
35 pub num_value_operands: usize,
36
37 pub has_value_list: bool,
38
39 pub imm_fields: Vec<FormatField>,
40
41 pub num_block_operands: usize,
42
43 pub num_raw_block_operands: usize,
44
45 pub typevar_operand: Option<usize>,
49}
50
51#[derive(Hash, PartialEq, Eq)]
53pub(crate) struct FormatStructure {
54 pub num_value_operands: usize,
55 pub has_value_list: bool,
56 pub num_block_operands: usize,
57 pub num_raw_block_operands: usize,
58 pub imm_field_names: Vec<(&'static str, &'static str)>,
60}
61
62impl fmt::Display for InstructionFormat {
63 fn fmt(&self, fmt: &mut fmt::Formatter) -> Result<(), fmt::Error> {
64 let imm_args = self
65 .imm_fields
66 .iter()
67 .map(|field| format!("{}: {}", field.member, field.kind.rust_type))
68 .collect::<Vec<_>>()
69 .join(", ");
70 fmt.write_fmt(format_args!(
71 "{}(imms=({}), vals={}, blocks={}, raw_blocks={})",
72 self.name,
73 imm_args,
74 self.num_value_operands,
75 self.num_block_operands,
76 self.num_raw_block_operands,
77 ))?;
78 Ok(())
79 }
80}
81
82impl InstructionFormat {
83 pub fn structure(&self) -> FormatStructure {
85 FormatStructure {
86 num_value_operands: self.num_value_operands,
87 has_value_list: self.has_value_list,
88 num_block_operands: self.num_block_operands,
89 num_raw_block_operands: self.num_raw_block_operands,
90 imm_field_names: self
91 .imm_fields
92 .iter()
93 .map(|field| (field.kind.rust_field_name, field.kind.rust_type))
94 .collect::<Vec<_>>(),
95 }
96 }
97}
98
99pub(crate) struct InstructionFormatBuilder(InstructionFormat);
100
101impl InstructionFormatBuilder {
102 pub fn new(name: &'static str) -> Self {
103 Self(InstructionFormat {
104 name,
105 num_value_operands: 0,
106 has_value_list: false,
107 num_block_operands: 0,
108 num_raw_block_operands: 0,
109 imm_fields: Vec::new(),
110 typevar_operand: None,
111 })
112 }
113
114 pub fn value(mut self) -> Self {
115 self.0.num_value_operands += 1;
116 self
117 }
118
119 pub fn varargs(mut self) -> Self {
120 self.0.has_value_list = true;
121 self
122 }
123
124 pub fn block(mut self) -> Self {
125 self.0.num_block_operands += 1;
126 self
127 }
128
129 pub fn raw_block(mut self) -> Self {
130 self.0.num_raw_block_operands += 1;
131 self
132 }
133
134 pub fn imm(mut self, operand_kind: &OperandKind) -> Self {
135 let field = FormatField {
136 kind: operand_kind.clone(),
137 member: operand_kind.rust_field_name,
138 };
139 self.0.imm_fields.push(field);
140 self
141 }
142
143 pub fn typevar_operand(mut self, operand_index: usize) -> Self {
144 assert!(self.0.typevar_operand.is_none());
145 assert!(operand_index < self.0.num_value_operands);
146 self.0.typevar_operand = Some(operand_index);
147 self
148 }
149
150 pub fn build(mut self) -> Rc<InstructionFormat> {
151 if self.0.typevar_operand.is_none() && self.0.num_value_operands > 0 {
152 self.0.typevar_operand = Some(0);
154 };
155
156 Rc::new(self.0)
157 }
158}