cranelift_assembler_x64_meta/generate/
operand.rs

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