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_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 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 #[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 #[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}