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 | imm64 => {
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 | rbx | cl | rcx | dx | edx | rdx => {
18                let enc = match self.location {
19                    al | ax | eax | rax => "{ gpr::enc::RAX }",
20                    rbx => "{ gpr::enc::RBX }",
21                    cl | rcx => "{ gpr::enc::RCX }",
22                    dx | edx | rdx => "{ gpr::enc::RDX }",
23                    _ => unreachable!(),
24                };
25                format!("Fixed<R::{mut_}Gpr, {enc}>")
26            }
27            r8 | r16 | r32 | r32a | r32b | r64 | r64a | r64b => format!("Gpr<R::{mut_}Gpr>"),
28            rm8 | rm16 | rm32 | rm64 => format!("GprMem<R::{mut_}Gpr, R::ReadGpr>"),
29            xmm1 | xmm2 | xmm3 => {
30                format!("Xmm<R::{mut_}Xmm>")
31            }
32            xmm_m16 | xmm_m32 | xmm_m64 | xmm_m128 => {
33                format!("XmmMem<R::{mut_}Xmm, R::ReadGpr>")
34            }
35            m8 | m16 | m32 | m64 | m128 => format!("Amode<R::ReadGpr>"),
36            xmm0 => format!("Fixed<R::{mut_}Xmm, {{ xmm::enc::XMM0 }}>"),
37        }
38    }
39}
40
41impl dsl::Location {
42    /// `self.<operand>.to_string(...)`
43    #[must_use]
44    pub fn generate_to_string(&self, extension: dsl::Extension) -> String {
45        use dsl::Location::*;
46        match self {
47            imm8 | imm16 | imm32 | imm64 => {
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 | r32a | r32b | r64 | r64a | r64b | rm8 | rm16 | rm32 | rm64 => {
56                match self.generate_size() {
57                    Some(size) => format!("self.{self}.to_string({size})"),
58                    None => unreachable!(),
59                }
60            }
61            al | ax | eax | rax | rbx | cl | rcx | dx | edx | rdx | xmm0 => {
62                match self.generate_size() {
63                    Some(size) => format!("self.{self}.to_string(Some({size}))"),
64                    None => format!("self.{self}.to_string(None)"),
65                }
66            }
67            xmm_m16 | xmm_m32 | xmm_m64 | xmm1 | xmm2 | xmm3 | xmm_m128 | m8 | m16 | m32 | m64
68            | m128 => {
69                format!("self.{self}.to_string()")
70            }
71        }
72    }
73
74    /// `Size::<operand size>`
75    #[must_use]
76    fn generate_size(&self) -> Option<&str> {
77        use dsl::Location::*;
78        match self {
79            imm8 | imm16 | imm32 | imm64 => None,
80            al | cl | r8 | rm8 => Some("Size::Byte"),
81            ax | dx | r16 | rm16 => Some("Size::Word"),
82            eax | edx | r32 | r32a | r32b | rm32 => Some("Size::Doubleword"),
83            rax | rbx | rcx | rdx | r64 | r64a | r64b | rm64 => Some("Size::Quadword"),
84            m8 | m16 | m32 | m64 | m128 => {
85                panic!("no need to generate a size for memory-only access")
86            }
87            xmm1 | xmm2 | xmm3 | xmm_m16 | xmm_m32 | xmm_m64 | xmm_m128 | xmm0 => None,
88        }
89    }
90}
91
92impl dsl::Mutability {
93    #[must_use]
94    pub fn generate_camel_case(&self) -> &str {
95        match self {
96            dsl::Mutability::Read => "Read",
97            dsl::Mutability::ReadWrite => "ReadWrite",
98            dsl::Mutability::Write => "Write",
99        }
100    }
101
102    #[must_use]
103    pub fn generate_snake_case(&self) -> &str {
104        match self {
105            dsl::Mutability::Read => "read",
106            dsl::Mutability::ReadWrite => "read_write",
107            dsl::Mutability::Write => "write",
108        }
109    }
110}
111
112impl dsl::Extension {
113    /// `Extension::...`
114    #[must_use]
115    pub fn generate_variant(&self) -> &str {
116        use dsl::Extension::*;
117        match self {
118            None => "Extension::None",
119            SignExtendWord => "Extension::SignExtendWord",
120            SignExtendLong => "Extension::SignExtendLong",
121            SignExtendQuad => "Extension::SignExtendQuad",
122        }
123    }
124}