Use InstructionFormat inside InstructionFormatBuilder

This commit is contained in:
bjorn3
2021-10-31 19:01:33 +01:00
parent 2fbd57e9e2
commit e8f3c0c6a9
2 changed files with 14 additions and 30 deletions

View File

@@ -84,32 +84,26 @@ impl InstructionFormat {
} }
} }
pub(crate) struct InstructionFormatBuilder { pub(crate) struct InstructionFormatBuilder(InstructionFormat);
name: &'static str,
num_value_operands: usize,
has_value_list: bool,
imm_fields: Vec<FormatField>,
typevar_operand: Option<usize>,
}
impl InstructionFormatBuilder { impl InstructionFormatBuilder {
pub fn new(name: &'static str) -> Self { pub fn new(name: &'static str) -> Self {
Self { Self(InstructionFormat {
name, name,
num_value_operands: 0, num_value_operands: 0,
has_value_list: false, has_value_list: false,
imm_fields: Vec::new(), imm_fields: Vec::new(),
typevar_operand: None, typevar_operand: None,
} })
} }
pub fn value(mut self) -> Self { pub fn value(mut self) -> Self {
self.num_value_operands += 1; self.0.num_value_operands += 1;
self self
} }
pub fn varargs(mut self) -> Self { pub fn varargs(mut self) -> Self {
self.has_value_list = true; self.0.has_value_list = true;
self self
} }
@@ -118,33 +112,23 @@ impl InstructionFormatBuilder {
kind: operand_kind.clone(), kind: operand_kind.clone(),
member: operand_kind.rust_field_name, member: operand_kind.rust_field_name,
}; };
self.imm_fields.push(field); self.0.imm_fields.push(field);
self self
} }
pub fn typevar_operand(mut self, operand_index: usize) -> Self { pub fn typevar_operand(mut self, operand_index: usize) -> Self {
assert!(self.typevar_operand.is_none()); assert!(self.0.typevar_operand.is_none());
assert!(operand_index < self.num_value_operands); assert!(operand_index < self.0.num_value_operands);
self.typevar_operand = Some(operand_index); self.0.typevar_operand = Some(operand_index);
self self
} }
pub fn build(self) -> Rc<InstructionFormat> { pub fn build(mut self) -> Rc<InstructionFormat> {
let typevar_operand = if self.typevar_operand.is_some() { if self.0.typevar_operand.is_none() && self.0.num_value_operands > 0 {
self.typevar_operand
} else if self.num_value_operands > 0 {
// Default to the first value operand, if there's one. // Default to the first value operand, if there's one.
Some(0) self.0.typevar_operand = Some(0);
} else {
None
}; };
Rc::new(InstructionFormat { Rc::new(self.0)
name: self.name,
num_value_operands: self.num_value_operands,
has_value_list: self.has_value_list,
imm_fields: self.imm_fields,
typevar_operand,
})
} }
} }

View File

@@ -43,7 +43,7 @@ pub(crate) struct InstructionContent {
/// Output operands. The output operands must be SSA values or `variable_args`. /// Output operands. The output operands must be SSA values or `variable_args`.
pub operands_out: Vec<Operand>, pub operands_out: Vec<Operand>,
/// Instruction format, automatically derived from the input operands. /// Instruction format.
pub format: Rc<InstructionFormat>, pub format: Rc<InstructionFormat>,
/// One of the input or output operands is a free type variable. None if the instruction is not /// One of the input or output operands is a free type variable. None if the instruction is not