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 typevar_operand: Option<usize>,
47}
48
49#[derive(Hash, PartialEq, Eq)]
51pub(crate) struct FormatStructure {
52 pub num_value_operands: usize,
53 pub has_value_list: bool,
54 pub num_block_operands: usize,
55 pub imm_field_names: Vec<(&'static str, &'static str)>,
57}
58
59impl fmt::Display for InstructionFormat {
60 fn fmt(&self, fmt: &mut fmt::Formatter) -> Result<(), fmt::Error> {
61 let imm_args = self
62 .imm_fields
63 .iter()
64 .map(|field| format!("{}: {}", field.member, field.kind.rust_type))
65 .collect::<Vec<_>>()
66 .join(", ");
67 fmt.write_fmt(format_args!(
68 "{}(imms=({}), vals={}, blocks={})",
69 self.name, imm_args, self.num_value_operands, self.num_block_operands,
70 ))?;
71 Ok(())
72 }
73}
74
75impl InstructionFormat {
76 pub fn structure(&self) -> FormatStructure {
78 FormatStructure {
79 num_value_operands: self.num_value_operands,
80 has_value_list: self.has_value_list,
81 num_block_operands: self.num_block_operands,
82 imm_field_names: self
83 .imm_fields
84 .iter()
85 .map(|field| (field.kind.rust_field_name, field.kind.rust_type))
86 .collect::<Vec<_>>(),
87 }
88 }
89}
90
91pub(crate) struct InstructionFormatBuilder(InstructionFormat);
92
93impl InstructionFormatBuilder {
94 pub fn new(name: &'static str) -> Self {
95 Self(InstructionFormat {
96 name,
97 num_value_operands: 0,
98 has_value_list: false,
99 num_block_operands: 0,
100 imm_fields: Vec::new(),
101 typevar_operand: None,
102 })
103 }
104
105 pub fn value(mut self) -> Self {
106 self.0.num_value_operands += 1;
107 self
108 }
109
110 pub fn varargs(mut self) -> Self {
111 self.0.has_value_list = true;
112 self
113 }
114
115 pub fn block(mut self) -> Self {
116 self.0.num_block_operands += 1;
117 self
118 }
119
120 pub fn imm(mut self, operand_kind: &OperandKind) -> Self {
121 let field = FormatField {
122 kind: operand_kind.clone(),
123 member: operand_kind.rust_field_name,
124 };
125 self.0.imm_fields.push(field);
126 self
127 }
128
129 pub fn typevar_operand(mut self, operand_index: usize) -> Self {
130 assert!(self.0.typevar_operand.is_none());
131 assert!(operand_index < self.0.num_value_operands);
132 self.0.typevar_operand = Some(operand_index);
133 self
134 }
135
136 pub fn build(mut self) -> Rc<InstructionFormat> {
137 if self.0.typevar_operand.is_none() && self.0.num_value_operands > 0 {
138 self.0.typevar_operand = Some(0);
140 };
141
142 Rc::new(self.0)
143 }
144}