[meta] Use a ref-counted pointer to an InstructionFormat in instructions;
This avoids a lot of dereferences, and InstructionFormat are immutable once they're created. It removes a lot of code that was keeping the FormatRegistry around, just in case we needed the format. This is more in line with the way we create Instructions, and make it easy to reference InstructionFormats in general.
This commit is contained in:
@@ -1,6 +1,8 @@
|
||||
use std::rc::Rc;
|
||||
|
||||
use cranelift_entity::{entity_impl, PrimaryMap};
|
||||
|
||||
use crate::cdsl::formats::{FormatRegistry, InstructionFormatIndex};
|
||||
use crate::cdsl::formats::InstructionFormat;
|
||||
use crate::cdsl::instructions::InstructionPredicate;
|
||||
use crate::cdsl::regs::RegClassIndex;
|
||||
use crate::cdsl::settings::SettingPredicateNumber;
|
||||
@@ -108,7 +110,7 @@ pub(crate) struct EncodingRecipe {
|
||||
pub name: String,
|
||||
|
||||
/// Associated instruction format.
|
||||
pub format: InstructionFormatIndex,
|
||||
pub format: Rc<InstructionFormat>,
|
||||
|
||||
/// Base number of bytes in the binary encoded instruction.
|
||||
pub base_size: u64,
|
||||
@@ -141,7 +143,7 @@ pub(crate) struct EncodingRecipe {
|
||||
// Implement PartialEq ourselves: take all the fields into account but the name.
|
||||
impl PartialEq for EncodingRecipe {
|
||||
fn eq(&self, other: &Self) -> bool {
|
||||
self.format == other.format
|
||||
Rc::ptr_eq(&self.format, &other.format)
|
||||
&& self.base_size == other.base_size
|
||||
&& self.operands_in == other.operands_in
|
||||
&& self.operands_out == other.operands_out
|
||||
@@ -166,7 +168,7 @@ pub(crate) type Recipes = PrimaryMap<EncodingRecipeNumber, EncodingRecipe>;
|
||||
#[derive(Clone)]
|
||||
pub(crate) struct EncodingRecipeBuilder {
|
||||
pub name: String,
|
||||
format: InstructionFormatIndex,
|
||||
format: Rc<InstructionFormat>,
|
||||
pub base_size: u64,
|
||||
pub operands_in: Option<Vec<OperandConstraint>>,
|
||||
pub operands_out: Option<Vec<OperandConstraint>>,
|
||||
@@ -179,10 +181,10 @@ pub(crate) struct EncodingRecipeBuilder {
|
||||
}
|
||||
|
||||
impl EncodingRecipeBuilder {
|
||||
pub fn new(name: impl Into<String>, format: InstructionFormatIndex, base_size: u64) -> Self {
|
||||
pub fn new(name: impl Into<String>, format: &Rc<InstructionFormat>, base_size: u64) -> Self {
|
||||
Self {
|
||||
name: name.into(),
|
||||
format,
|
||||
format: format.clone(),
|
||||
base_size,
|
||||
operands_in: None,
|
||||
operands_out: None,
|
||||
@@ -250,18 +252,17 @@ impl EncodingRecipeBuilder {
|
||||
self
|
||||
}
|
||||
|
||||
pub fn build(self, formats: &FormatRegistry) -> EncodingRecipe {
|
||||
pub fn build(self) -> EncodingRecipe {
|
||||
let operands_in = self.operands_in.unwrap_or(Vec::new());
|
||||
let operands_out = self.operands_out.unwrap_or(Vec::new());
|
||||
|
||||
// The number of input constraints must match the number of format input operands.
|
||||
if !formats.get(self.format).has_value_list {
|
||||
let format = formats.get(self.format);
|
||||
if !self.format.has_value_list {
|
||||
assert!(
|
||||
operands_in.len() == format.num_value_operands,
|
||||
operands_in.len() == self.format.num_value_operands,
|
||||
format!(
|
||||
"missing operand constraints for recipe {} (format {})",
|
||||
self.name, format.name
|
||||
self.name, self.format.name
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user