[meta] Add Instruction helpers and change its representation to make it easily copiable;
- adds helpers used by other parts of the code - allows cheap copies by having Instruction be a lightweight ref-cloned wrapper of the actual instruction's content.
This commit is contained in:
@@ -1,10 +1,15 @@
|
|||||||
use crate::cdsl::camel_case;
|
use crate::cdsl::camel_case;
|
||||||
use crate::cdsl::formats::{FormatRegistry, InstructionFormat, InstructionFormatIndex};
|
use crate::cdsl::formats::{
|
||||||
|
FormatField, FormatRegistry, InstructionFormat, InstructionFormatIndex,
|
||||||
|
};
|
||||||
use crate::cdsl::operands::Operand;
|
use crate::cdsl::operands::Operand;
|
||||||
use crate::cdsl::type_inference::Constraint;
|
use crate::cdsl::type_inference::Constraint;
|
||||||
|
use crate::cdsl::types::ValueType;
|
||||||
use crate::cdsl::typevar::TypeVar;
|
use crate::cdsl::typevar::TypeVar;
|
||||||
|
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
|
use std::ops;
|
||||||
|
use std::rc::Rc;
|
||||||
use std::slice;
|
use std::slice;
|
||||||
|
|
||||||
/// Every instruction must belong to exactly one instruction group. A given
|
/// Every instruction must belong to exactly one instruction group. A given
|
||||||
@@ -32,6 +37,13 @@ impl InstructionGroup {
|
|||||||
pub fn iter(&self) -> slice::Iter<Instruction> {
|
pub fn iter(&self) -> slice::Iter<Instruction> {
|
||||||
self.instructions.iter()
|
self.instructions.iter()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn by_name(&self, name: &'static str) -> &Instruction {
|
||||||
|
self.instructions
|
||||||
|
.iter()
|
||||||
|
.find(|inst| inst.name == name)
|
||||||
|
.expect(&format!("unexisting instruction with name {}", name))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct PolymorphicInfo {
|
pub struct PolymorphicInfo {
|
||||||
@@ -40,7 +52,7 @@ pub struct PolymorphicInfo {
|
|||||||
pub other_typevars: Vec<TypeVar>,
|
pub other_typevars: Vec<TypeVar>,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct Instruction {
|
pub struct InstructionContent {
|
||||||
/// Instruction mnemonic, also becomes opcode name.
|
/// Instruction mnemonic, also becomes opcode name.
|
||||||
pub name: &'static str,
|
pub name: &'static str,
|
||||||
pub camel_name: String,
|
pub camel_name: String,
|
||||||
@@ -53,7 +65,7 @@ pub struct Instruction {
|
|||||||
/// 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-specific TypeConstraints.
|
/// Instruction-specific TypeConstraints.
|
||||||
_constraints: Vec<Constraint>,
|
pub constraints: Vec<Constraint>,
|
||||||
|
|
||||||
/// Instruction format, automatically derived from the input operands.
|
/// Instruction format, automatically derived from the input operands.
|
||||||
pub format: InstructionFormatIndex,
|
pub format: InstructionFormatIndex,
|
||||||
@@ -90,6 +102,18 @@ pub struct Instruction {
|
|||||||
pub writes_cpu_flags: bool,
|
pub writes_cpu_flags: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Clone)]
|
||||||
|
pub struct Instruction {
|
||||||
|
content: Rc<InstructionContent>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ops::Deref for Instruction {
|
||||||
|
type Target = InstructionContent;
|
||||||
|
fn deref(&self) -> &Self::Target {
|
||||||
|
&*self.content
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl Instruction {
|
impl Instruction {
|
||||||
pub fn snake_name(&self) -> &'static str {
|
pub fn snake_name(&self) -> &'static str {
|
||||||
if self.name == "return" {
|
if self.name == "return" {
|
||||||
@@ -108,6 +132,17 @@ impl Instruction {
|
|||||||
}
|
}
|
||||||
""
|
""
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn all_typevars(&self) -> Vec<&TypeVar> {
|
||||||
|
match &self.polymorphic_info {
|
||||||
|
Some(poly) => {
|
||||||
|
let mut result = vec![&poly.ctrl_typevar];
|
||||||
|
result.extend(&poly.other_typevars);
|
||||||
|
result
|
||||||
|
}
|
||||||
|
None => Vec::new(),
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl fmt::Display for Instruction {
|
impl fmt::Display for Instruction {
|
||||||
@@ -272,12 +307,13 @@ impl InstructionBuilder {
|
|||||||
let writes_cpu_flags = operands_out.iter().any(|op| op.is_cpu_flags());
|
let writes_cpu_flags = operands_out.iter().any(|op| op.is_cpu_flags());
|
||||||
|
|
||||||
Instruction {
|
Instruction {
|
||||||
|
content: Rc::new(InstructionContent {
|
||||||
name: self.name,
|
name: self.name,
|
||||||
camel_name: camel_case(self.name),
|
camel_name: camel_case(self.name),
|
||||||
doc: self.doc,
|
doc: self.doc,
|
||||||
operands_in,
|
operands_in,
|
||||||
operands_out,
|
operands_out,
|
||||||
_constraints: self.constraints.unwrap_or_else(Vec::new),
|
constraints: self.constraints.unwrap_or_else(Vec::new),
|
||||||
format: format_index,
|
format: format_index,
|
||||||
polymorphic_info,
|
polymorphic_info,
|
||||||
value_opnums,
|
value_opnums,
|
||||||
@@ -294,10 +330,17 @@ impl InstructionBuilder {
|
|||||||
can_trap: self.can_trap,
|
can_trap: self.can_trap,
|
||||||
other_side_effects: self.other_side_effects,
|
other_side_effects: self.other_side_effects,
|
||||||
writes_cpu_flags,
|
writes_cpu_flags,
|
||||||
|
}),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Clone)]
|
||||||
|
pub struct BoundInstruction {
|
||||||
|
pub inst: Instruction,
|
||||||
|
pub value_types: Vec<ValueType>,
|
||||||
|
}
|
||||||
|
|
||||||
/// Check if this instruction is polymorphic, and verify its use of type variables.
|
/// Check if this instruction is polymorphic, and verify its use of type variables.
|
||||||
fn verify_polymorphic(
|
fn verify_polymorphic(
|
||||||
operands_in: &Vec<Operand>,
|
operands_in: &Vec<Operand>,
|
||||||
|
|||||||
@@ -134,7 +134,7 @@ pub struct OperandKind {
|
|||||||
/// The camel-cased name of an operand kind is also the Rust type used to represent it.
|
/// The camel-cased name of an operand kind is also the Rust type used to represent it.
|
||||||
pub rust_type: String,
|
pub rust_type: String,
|
||||||
|
|
||||||
fields: OperandKindFields,
|
pub fields: OperandKindFields,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl OperandKind {
|
impl OperandKind {
|
||||||
|
|||||||
Reference in New Issue
Block a user