cranelift_assembler_x64_meta/generate/
operand.rs

1use crate::dsl;
2
3impl dsl::Operand {
4    #[must_use]
5    pub fn generate_type(&self) -> Option<String> {
6        use dsl::OperandKind::*;
7        match self.location.kind() {
8            FixedReg(_) => None,
9            Imm(loc) => {
10                let bits = loc.bits();
11                if self.extension.is_sign_extended() {
12                    Some(format!("Simm{bits}"))
13                } else {
14                    Some(format!("Imm{bits}"))
15                }
16            }
17            Reg(r) => match r.bits() {
18                128 => Some(format!("Xmm<R::{}Xmm>", self.mutability.generate_type())),
19                _ => Some(format!("Gpr<R::{}Gpr>", self.mutability.generate_type())),
20            },
21            RegMem(rm) => match rm.bits() {
22                128 => Some(format!("XmmMem<R::{}Xmm, R::ReadGpr>", self.mutability.generate_type())),
23                _ => Some(format!("GprMem<R::{}Gpr, R::ReadGpr>", self.mutability.generate_type())),
24            },
25        }
26    }
27}
28
29impl dsl::Location {
30    /// `self.<operand>.to_string(...)`
31    #[must_use]
32    pub fn generate_to_string(&self, extension: dsl::Extension) -> String {
33        use dsl::Location::*;
34        match self {
35            al => "\"%al\"".into(),
36            ax => "\"%ax\"".into(),
37            eax => "\"%eax\"".into(),
38            rax => "\"%rax\"".into(),
39            cl => "\"%cl\"".into(),
40            imm8 | imm16 | imm32 => {
41                if extension.is_sign_extended() {
42                    let variant = extension.generate_variant();
43                    format!("self.{self}.to_string({variant})")
44                } else {
45                    format!("self.{self}.to_string()")
46                }
47            }
48            r8 | r16 | r32 | r64 | rm8 | rm16 | rm32 | rm64 => match self.generate_size() {
49                Some(size) => format!("self.{self}.to_string({size})"),
50                None => unreachable!(),
51            },
52            xmm | rm128 => format!("self.{self}.to_string()"),
53        }
54    }
55
56    /// `Size::<operand size>`
57    #[must_use]
58    fn generate_size(&self) -> Option<&str> {
59        use dsl::Location::*;
60        match self {
61            al | ax | eax | rax | cl | imm8 | imm16 | imm32 => None,
62            r8 | rm8 => Some("Size::Byte"),
63            r16 | rm16 => Some("Size::Word"),
64            r32 | rm32 => Some("Size::Doubleword"),
65            r64 | rm64 => Some("Size::Quadword"),
66            xmm | rm128 => panic!("no need to generate a size for XMM-sized access"),
67        }
68    }
69
70    /// `Gpr(regs::...)`
71    #[must_use]
72    pub fn generate_fixed_reg(&self) -> Option<&str> {
73        use dsl::Location::*;
74        match self {
75            al | ax | eax | rax => Some("gpr::enc::RAX"),
76            cl => Some("gpr::enc::RCX"),
77            imm8 | imm16 | imm32 | r8 | r16 | r32 | r64 | xmm | rm8 | rm16 | rm32 | rm64 | rm128 => None,
78        }
79    }
80}
81
82impl dsl::Mutability {
83    #[must_use]
84    pub fn generate_regalloc_call(&self) -> &str {
85        match self {
86            dsl::Mutability::Read => "read",
87            dsl::Mutability::ReadWrite => "read_write",
88        }
89    }
90
91    #[must_use]
92    pub fn generate_type(&self) -> &str {
93        match self {
94            dsl::Mutability::Read => "Read",
95            dsl::Mutability::ReadWrite => "ReadWrite",
96        }
97    }
98
99    #[must_use]
100    pub fn generate_xmm_regalloc_call(&self) -> &str {
101        match self {
102            dsl::Mutability::Read => "read_xmm",
103            dsl::Mutability::ReadWrite => "read_write_xmm",
104        }
105    }
106}
107
108impl dsl::Extension {
109    /// `Extension::...`
110    #[must_use]
111    pub fn generate_variant(&self) -> &str {
112        use dsl::Extension::*;
113        match self {
114            None => "Extension::None",
115            SignExtendWord => "Extension::SignExtendWord",
116            SignExtendLong => "Extension::SignExtendLong",
117            SignExtendQuad => "Extension::SignExtendQuad",
118        }
119    }
120}