cranelift_assembler_x64_meta/dsl/
custom.rs

1//! Define customizations available for aspects of the assembler.
2//!
3//! When a customization is applied to an instruction, the generated code will
4//! call the corresponding function in a `custom` module
5//! (`custom::<customization>::<inst>`). E.g., to modify the display of a `NOP`
6//! instruction with format `M`, the generated assembler will call:
7//! `custom::display::nop_m(...)`.
8
9use core::fmt;
10use std::ops::BitOr;
11
12#[derive(PartialEq, Debug)]
13pub enum Customization {
14    /// Modify the disassembly of an instruction.
15    Display,
16    /// Modify how an instruction is emitted into the code buffer.
17    Encode,
18    /// Modify the instruction mnemonic (see [`crate::dsl::Inst::mnemonic`]);
19    /// this customization is irrelevant if [`CustomOperation::Display`] is also
20    /// specified.
21    Mnemonic,
22    /// Modify how a register allocator visits the operands of an instruction.
23    Visit,
24}
25
26impl fmt::Display for Customization {
27    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
28        fmt::Debug::fmt(self, f)
29    }
30}
31
32impl BitOr for Customization {
33    type Output = Custom;
34    fn bitor(self, rhs: Self) -> Self::Output {
35        assert_ne!(self, rhs, "duplicate custom operation: {self:?}");
36        Custom(vec![self, rhs])
37    }
38}
39
40impl BitOr<Customization> for Custom {
41    type Output = Custom;
42    fn bitor(mut self, rhs: Customization) -> Self::Output {
43        assert!(
44            !self.0.contains(&rhs),
45            "duplicate custom operation: {rhs:?}"
46        );
47        self.0.push(rhs);
48        self
49    }
50}
51
52#[derive(PartialEq, Default)]
53pub struct Custom(Vec<Customization>);
54
55impl Custom {
56    #[must_use]
57    pub fn is_empty(&self) -> bool {
58        self.0.is_empty()
59    }
60
61    pub fn iter(&self) -> impl Iterator<Item = &Customization> {
62        self.0.iter()
63    }
64
65    pub fn contains(&self, operation: Customization) -> bool {
66        self.0.contains(&operation)
67    }
68}
69
70impl fmt::Display for Custom {
71    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
72        write!(
73            f,
74            "{}",
75            self.0
76                .iter()
77                .map(ToString::to_string)
78                .collect::<Vec<_>>()
79                .join(" | ")
80        )
81    }
82}
83
84impl From<Customization> for Custom {
85    fn from(operation: Customization) -> Self {
86        Custom(vec![operation])
87    }
88}