cranelift_assembler_x64_meta/
generate.rs1mod features;
4mod format;
5mod inst;
6mod operand;
7
8use crate::dsl;
9use cranelift_srcgen::{fmtln, Formatter};
10
11pub fn rust_assembler(f: &mut Formatter, insts: &[dsl::Inst]) {
13 generate_inst_enum(f, insts);
15 generate_inst_display_impl(f, insts);
16 generate_inst_encode_impl(f, insts);
17 generate_inst_visit_impl(f, insts);
18 generate_inst_features_impl(f, insts);
19
20 f.empty_line();
22 for inst in insts {
23 inst.generate_struct(f);
24 inst.generate_struct_impl(f);
25 inst.generate_display_impl(f);
26 inst.generate_from_impl(f);
27 f.empty_line();
28 }
29
30 dsl::Feature::generate_enum(f);
32}
33
34fn generate_inst_enum(f: &mut Formatter, insts: &[dsl::Inst]) {
36 fmtln!(f, "#[doc(hidden)]");
37 generate_derive(f);
38 generate_derive_arbitrary_bounds(f);
39 fmtln!(f, "pub enum Inst<R: Registers> {{");
40 f.indent_push();
41 for inst in insts {
42 let variant_name = inst.name();
43 let struct_name = inst.struct_name_with_generic();
44 fmtln!(f, "{variant_name}({struct_name}),");
45 }
46 f.indent_pop();
47 fmtln!(f, "}}");
48}
49
50fn generate_derive(f: &mut Formatter) {
52 fmtln!(f, "#[derive(Clone, Debug)]");
53 fmtln!(f, "#[cfg_attr(any(test, feature = \"fuzz\"), derive(arbitrary::Arbitrary))]");
54}
55
56fn generate_derive_arbitrary_bounds(f: &mut Formatter) {
59 fmtln!(f,
60 "#[cfg_attr(any(test, feature = \"fuzz\"), arbitrary(bound = \"R: crate::fuzz::RegistersArbitrary\"))]"
61 );
62}
63
64fn generate_inst_display_impl(f: &mut Formatter, insts: &[dsl::Inst]) {
66 fmtln!(f, "impl<R: Registers> std::fmt::Display for Inst<R> {{");
67 f.indent(|f| {
68 fmtln!(f, "fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {{");
69 f.indent(|f| {
70 fmtln!(f, "match self {{");
71 f.indent_push();
72 for inst in insts {
73 let variant_name = inst.name();
74 fmtln!(f, "Self::{variant_name}(i) => write!(f, \"{{i}}\"),");
75 }
76 f.indent_pop();
77 fmtln!(f, "}}");
78 });
79 fmtln!(f, "}}");
80 });
81 fmtln!(f, "}}");
82}
83
84fn generate_inst_encode_impl(f: &mut Formatter, insts: &[dsl::Inst]) {
86 fmtln!(f, "impl<R: Registers> Inst<R> {{");
87 f.indent(|f| {
88 fmtln!(f, "pub fn encode(&self, b: &mut impl CodeSink, o: &impl KnownOffsetTable) {{");
89 f.indent(|f| {
90 fmtln!(f, "match self {{");
91 f.indent_push();
92 for inst in insts {
93 let variant_name = inst.name();
94 fmtln!(f, "Self::{variant_name}(i) => i.encode(b, o),");
95 }
96 f.indent_pop();
97 fmtln!(f, "}}");
98 });
99 fmtln!(f, "}}");
100 });
101 fmtln!(f, "}}");
102}
103
104fn generate_inst_visit_impl(f: &mut Formatter, insts: &[dsl::Inst]) {
106 fmtln!(f, "impl<R: Registers> Inst<R> {{");
107 f.indent(|f| {
108 fmtln!(f, "pub fn visit(&mut self, v: &mut impl RegisterVisitor<R>) {{");
109 f.indent(|f| {
110 fmtln!(f, "match self {{");
111 f.indent_push();
112 for inst in insts {
113 let variant_name = inst.name();
114 fmtln!(f, "Self::{variant_name}(i) => i.visit(v),");
115 }
116 f.indent_pop();
117 fmtln!(f, "}}");
118 });
119 fmtln!(f, "}}");
120 });
121 fmtln!(f, "}}");
122}
123
124fn generate_inst_features_impl(f: &mut Formatter, insts: &[dsl::Inst]) {
126 fmtln!(f, "impl<R: Registers> Inst<R> {{");
127 f.indent(|f| {
128 fmtln!(f, "#[must_use]");
129 fmtln!(f, "pub fn features(&self) -> Vec<Feature> {{");
130 f.indent(|f| {
131 fmtln!(f, "match self {{");
132 f.indent_push();
133 for inst in insts {
134 let variant_name = inst.name();
135 fmtln!(f, "Self::{variant_name}(i) => i.features(),");
136 }
137 f.indent_pop();
138 fmtln!(f, "}}");
139 });
140 fmtln!(f, "}}");
141 });
142 fmtln!(f, "}}");
143}