cranelift_assembler_x64_meta/generate/
operand.rs1use 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_m8 | 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 #[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 xmm1 | xmm2 | xmm3 | xmm_m8 | xmm_m16 | xmm_m32 | xmm_m64 | xmm_m128 | m8 | m16
68 | m32 | m64 | m128 => {
69 format!("self.{self}.to_string()")
70 }
71 }
72 }
73
74 #[must_use]
77 pub fn generate_to_string_xed(&self, _extension: dsl::Extension) -> Option<String> {
78 use dsl::Location::*;
79 match self {
80 rm8 | rm16 | rm32 | rm64 => {
81 let size = self.generate_size().expect("r/m operands have a size");
82 Some(format!("self.{self}.to_string_xed({size})"))
83 }
84 xmm_m8 | xmm_m16 | xmm_m32 | xmm_m64 | xmm_m128 => {
85 Some(format!("self.{self}.to_string_xed()"))
86 }
87 m8 | m16 | m32 | m64 | m128 => Some(format!("alloc::format!(\"{{:#}}\", self.{self})")),
88 _ => None,
89 }
90 }
91
92 #[must_use]
94 fn generate_size(&self) -> Option<&str> {
95 use dsl::Location::*;
96 match self {
97 imm8 | imm16 | imm32 | imm64 => None,
98 al | cl | r8 | rm8 => Some("Size::Byte"),
99 ax | dx | r16 | rm16 => Some("Size::Word"),
100 eax | edx | r32 | r32a | r32b | rm32 => Some("Size::Doubleword"),
101 rax | rbx | rcx | rdx | r64 | r64a | r64b | rm64 => Some("Size::Quadword"),
102 m8 | m16 | m32 | m64 | m128 => {
103 panic!("no need to generate a size for memory-only access")
104 }
105 xmm1 | xmm2 | xmm3 | xmm_m8 | xmm_m16 | xmm_m32 | xmm_m64 | xmm_m128 | xmm0 => None,
106 }
107 }
108}
109
110impl dsl::Mutability {
111 #[must_use]
112 pub fn generate_camel_case(&self) -> &str {
113 match self {
114 dsl::Mutability::Read => "Read",
115 dsl::Mutability::ReadWrite => "ReadWrite",
116 dsl::Mutability::Write => "Write",
117 }
118 }
119
120 #[must_use]
121 pub fn generate_snake_case(&self) -> &str {
122 match self {
123 dsl::Mutability::Read => "read",
124 dsl::Mutability::ReadWrite => "read_write",
125 dsl::Mutability::Write => "write",
126 }
127 }
128}
129
130impl dsl::Extension {
131 #[must_use]
133 pub fn generate_variant(&self) -> &str {
134 use dsl::Extension::*;
135 match self {
136 None => "Extension::None",
137 SignExtendWord => "Extension::SignExtendWord",
138 SignExtendLong => "Extension::SignExtendLong",
139 SignExtendQuad => "Extension::SignExtendQuad",
140 }
141 }
142}