cranelift_assembler_x64_meta/
generate.rs1mod features;
4mod format;
5mod inst;
6mod operand;
7
8use crate::dsl;
9use cranelift_srcgen::{Formatter, fmtln};
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 f.add_block("pub enum Inst<R: Registers>", |f| {
40 for inst in insts {
41 let variant_name = inst.name();
42 let struct_name = inst.struct_name_with_generic();
43 fmtln!(f, "{variant_name}({struct_name}),");
44 }
45 });
46}
47
48fn generate_derive(f: &mut Formatter) {
50 fmtln!(f, "#[derive(Copy, Clone, Debug)]");
51 fmtln!(
52 f,
53 "#[cfg_attr(any(test, feature = \"fuzz\"), derive(arbitrary::Arbitrary))]"
54 );
55}
56
57fn generate_derive_arbitrary_bounds(f: &mut Formatter) {
60 fmtln!(
61 f,
62 "#[cfg_attr(any(test, feature = \"fuzz\"), arbitrary(bound = \"R: crate::fuzz::RegistersArbitrary\"))]"
63 );
64}
65
66fn generate_inst_display_impl(f: &mut Formatter, insts: &[dsl::Inst]) {
68 f.add_block("impl<R: Registers> std::fmt::Display for Inst<R>", |f| {
69 f.add_block(
70 "fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result",
71 |f| {
72 f.add_block("match self", |f| {
73 for inst in insts {
74 let variant_name = inst.name();
75 fmtln!(f, "Self::{variant_name}(i) => i.fmt(f),");
76 }
77 });
78 },
79 );
80 });
81}
82
83fn generate_inst_encode_impl(f: &mut Formatter, insts: &[dsl::Inst]) {
85 f.add_block("impl<R: Registers> Inst<R>", |f| {
86 f.add_block("pub fn encode(&self, b: &mut impl CodeSink)", |f| {
87 f.add_block("match self", |f| {
88 for inst in insts {
89 let variant_name = inst.name();
90 fmtln!(f, "Self::{variant_name}(i) => i.encode(b),");
91 }
92 });
93 });
94 });
95}
96
97fn generate_inst_visit_impl(f: &mut Formatter, insts: &[dsl::Inst]) {
99 fmtln!(f, "impl<R: Registers> Inst<R> {{");
100 f.indent(|f| {
101 fmtln!(
102 f,
103 "pub fn visit(&mut self, v: &mut impl RegisterVisitor<R>) {{"
104 );
105 f.indent(|f| {
106 fmtln!(f, "match self {{");
107 f.indent_push();
108 for inst in insts {
109 let variant_name = inst.name();
110 fmtln!(f, "Self::{variant_name}(i) => i.visit(v),");
111 }
112 f.indent_pop();
113 fmtln!(f, "}}");
114 });
115 fmtln!(f, "}}");
116 });
117 fmtln!(f, "}}");
118}
119
120fn generate_inst_features_impl(f: &mut Formatter, insts: &[dsl::Inst]) {
122 f.add_block("impl<R: Registers> Inst<R>", |f| {
123 f.add_block("pub fn features(&self) -> Vec<Feature>", |f| {
124 f.add_block("match self", |f| {
125 for inst in insts {
126 let variant_name = inst.name();
127 fmtln!(f, "Self::{variant_name}(i) => i.features(),");
128 }
129 });
130 });
131 });
132}