cranelift_assembler_x64_meta/generate/
operand.rs1use 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 #[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 #[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 #[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 #[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}