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_impls(f, insts);
16 generate_inst_display_impl(f, insts);
17
18 f.empty_line();
20 for inst in insts {
21 inst.generate_struct(f);
22 inst.generate_struct_impl(f);
23 inst.generate_display_impl(f);
24 inst.generate_from_impl(f);
25 f.empty_line();
26 }
27
28 dsl::Feature::generate_macro(f);
30}
31
32fn generate_inst_enum(f: &mut Formatter, insts: &[dsl::Inst]) {
34 fmtln!(f, "#[doc(hidden)]");
35 generate_derive(f);
36 generate_derive_arbitrary_bounds(f);
37 f.add_block("pub enum Inst<R: Registers>", |f| {
38 for inst in insts {
39 let variant_name = inst.name();
40 let struct_name = inst.struct_name_with_generic();
41 fmtln!(f, "{variant_name}({struct_name}),");
42 }
43 });
44}
45
46fn match_variants(f: &mut Formatter, insts: &[dsl::Inst], invoke: &str) {
49 f.add_block("match self", |f| {
50 for inst in insts.iter().map(|i| i.name()) {
51 fmtln!(f, "Self::{inst}(i) => i.{invoke},");
52 }
53 });
54}
55
56fn generate_inst_display_impl(f: &mut Formatter, insts: &[dsl::Inst]) {
58 f.add_block("impl<R: Registers> std::fmt::Display for Inst<R>", |f| {
59 f.add_block(
60 "fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result",
61 |f| {
62 match_variants(f, insts, "fmt(f)");
63 },
64 );
65 });
66}
67
68fn generate_inst_impls(f: &mut Formatter, insts: &[dsl::Inst]) {
69 f.add_block("impl<R: Registers> Inst<R>", |f| {
70 f.add_block("pub fn encode(&self, b: &mut impl CodeSink)", |f| {
71 match_variants(f, insts, "encode(b)");
72 });
73 f.add_block(
74 "pub fn visit(&mut self, v: &mut impl RegisterVisitor<R>)",
75 |f| {
76 match_variants(f, insts, "visit(v)");
77 },
78 );
79 f.add_block(
80 "pub fn is_available(&self, f: &impl AvailableFeatures) -> bool",
81 |f| {
82 match_variants(f, insts, "is_available(f)");
83 },
84 );
85 f.add_block("pub fn features(&self) -> &'static Features", |f| {
86 match_variants(f, insts, "features()");
87 });
88 f.add_block("pub fn num_registers_available(&self) -> usize", |f| {
89 match_variants(f, insts, "num_registers_available()");
90 });
91 });
92}
93
94fn generate_derive(f: &mut Formatter) {
96 fmtln!(f, "#[derive(Copy, Clone, Debug)]");
97 fmtln!(
98 f,
99 "#[cfg_attr(any(test, feature = \"fuzz\"), derive(arbitrary::Arbitrary))]"
100 );
101}
102
103fn generate_derive_arbitrary_bounds(f: &mut Formatter) {
106 fmtln!(
107 f,
108 "#[cfg_attr(any(test, feature = \"fuzz\"), arbitrary(bound = \"R: crate::fuzz::RegistersArbitrary\"))]"
109 );
110}