diff --git a/cranelift/codegen/meta/src/gen_registers.rs b/cranelift/codegen/meta/src/gen_registers.rs index 11d80ff21e..3a75c7147a 100644 --- a/cranelift/codegen/meta/src/gen_registers.rs +++ b/cranelift/codegen/meta/src/gen_registers.rs @@ -10,25 +10,26 @@ fn gen_regbank(fmt: &mut Formatter, reg_bank: &RegBank) { } else { "".to_string() }; - fmt.line("RegBank {"); + fmtln!(fmt, "RegBank {"); fmt.indent(|fmt| { - fmt.line(format!(r#"name: "{}","#, reg_bank.name)); - fmt.line(format!("first_unit: {},", reg_bank.first_unit)); - fmt.line(format!("units: {},", reg_bank.units)); - fmt.line(format!("names: &[{}],", names)); - fmt.line(format!(r#"prefix: "{}","#, reg_bank.prefix)); - fmt.line(format!("first_toprc: {},", reg_bank.toprcs[0].index())); - fmt.line(format!("num_toprcs: {},", reg_bank.toprcs.len())); - fmt.line(format!( + fmtln!(fmt, r#"name: "{}","#, reg_bank.name); + fmtln!(fmt, "first_unit: {},", reg_bank.first_unit); + fmtln!(fmt, "units: {},", reg_bank.units); + fmtln!(fmt, "names: &[{}],", names); + fmtln!(fmt, r#"prefix: "{}","#, reg_bank.prefix); + fmtln!(fmt, "first_toprc: {},", reg_bank.toprcs[0].index()); + fmtln!(fmt, "num_toprcs: {},", reg_bank.toprcs.len()); + fmtln!( + fmt, "pressure_tracking: {},", if reg_bank.pressure_tracking { "true" } else { "false" } - )); + ); }); - fmt.line("},"); + fmtln!(fmt, "},"); } fn gen_regclass(isa: &TargetIsa, reg_class: &RegClass, fmt: &mut Formatter) { @@ -41,63 +42,67 @@ fn gen_regclass(isa: &TargetIsa, reg_class: &RegClass, fmt: &mut Formatter) { .collect(); let mask = mask.join(", "); - fmt.line(format!( + fmtln!( + fmt, "pub static {}_DATA: RegClassData = RegClassData {{", reg_class.name - )); + ); fmt.indent(|fmt| { - fmt.line(format!(r#"name: "{}","#, reg_class.name)); - fmt.line(format!("index: {},", reg_class.index.index())); - fmt.line(format!("width: {},", reg_class.width)); - fmt.line(format!("bank: {},", reg_class.bank.index())); - fmt.line(format!("toprc: {},", reg_class.toprc.index())); - fmt.line(format!("first: {},", reg_bank.first_unit + reg_class.start)); - fmt.line(format!("subclasses: {:#x},", reg_class.subclass_mask())); - fmt.line(format!("mask: [{}],", mask)); - fmt.line("info: &INFO,"); + fmtln!(fmt, r#"name: "{}","#, reg_class.name); + fmtln!(fmt, "index: {},", reg_class.index.index()); + fmtln!(fmt, "width: {},", reg_class.width); + fmtln!(fmt, "bank: {},", reg_class.bank.index()); + fmtln!(fmt, "toprc: {},", reg_class.toprc.index()); + fmtln!(fmt, "first: {},", reg_bank.first_unit + reg_class.start); + fmtln!(fmt, "subclasses: {:#x},", reg_class.subclass_mask()); + fmtln!(fmt, "mask: [{}],", mask); + fmtln!(fmt, "info: &INFO,"); }); - fmt.line("};"); - fmt.line("#[allow(dead_code)]"); - fmt.line(format!( + fmtln!(fmt, "};"); + + fmtln!(fmt, "#[allow(dead_code)]"); + fmtln!( + fmt, "pub static {}: RegClass = &{}_DATA;", - reg_class.name, reg_class.name - )); + reg_class.name, + reg_class.name + ); } fn gen_regbank_units(reg_bank: &RegBank, fmt: &mut Formatter) { for unit in 0..reg_bank.units { let v = unit + reg_bank.first_unit; if (unit as usize) < reg_bank.names.len() { - fmt.line(format!("{} = {},", reg_bank.names[unit as usize], v)); + fmtln!(fmt, "{} = {},", reg_bank.names[unit as usize], v); continue; } - fmt.line(format!("{}{} = {},", reg_bank.prefix, unit, v)); + fmtln!(fmt, "{}{} = {},", reg_bank.prefix, unit, v); } } fn gen_isa(isa: &TargetIsa, fmt: &mut Formatter) { // Emit RegInfo. - fmt.line("pub static INFO: RegInfo = RegInfo {"); + fmtln!(fmt, "pub static INFO: RegInfo = RegInfo {"); fmt.indent(|fmt| { - fmt.line("banks: &["); + fmtln!(fmt, "banks: &["); // Bank descriptors. fmt.indent(|fmt| { for reg_bank in isa.regs.banks.values() { gen_regbank(fmt, ®_bank); } }); - fmt.line("],"); + fmtln!(fmt, "],"); // References to register classes. - fmt.line("classes: &["); + fmtln!(fmt, "classes: &["); fmt.indent(|fmt| { for reg_class in isa.regs.classes.values() { - fmt.line(format!("&{}_DATA,", reg_class.name)); + fmtln!(fmt, "&{}_DATA,", reg_class.name); } }); - fmt.line("],"); + fmtln!(fmt, "],"); }); - fmt.line("};"); + fmtln!(fmt, "};"); // Register class descriptors. for rc in isa.regs.classes.values() { @@ -105,26 +110,26 @@ fn gen_isa(isa: &TargetIsa, fmt: &mut Formatter) { } // Emit constants for all the register units. - fmt.line("#[allow(dead_code, non_camel_case_types)]"); - fmt.line("#[derive(Clone, Copy)]"); - fmt.line("pub enum RU {"); + fmtln!(fmt, "#[allow(dead_code, non_camel_case_types)]"); + fmtln!(fmt, "#[derive(Clone, Copy)]"); + fmtln!(fmt, "pub enum RU {"); fmt.indent(|fmt| { for reg_bank in isa.regs.banks.values() { gen_regbank_units(reg_bank, fmt); } }); - fmt.line("}"); + fmtln!(fmt, "}"); // Emit Into conversion for the RU class. - fmt.line("impl Into for RU {"); + fmtln!(fmt, "impl Into for RU {"); fmt.indent(|fmt| { - fmt.line("fn into(self) -> RegUnit {"); + fmtln!(fmt, "fn into(self) -> RegUnit {"); fmt.indent(|fmt| { - fmt.line("self as RegUnit"); + fmtln!(fmt, "self as RegUnit"); }); - fmt.line("}") + fmtln!(fmt, "}"); }); - fmt.line("}"); + fmtln!(fmt, "}"); } pub fn generate(isa: &TargetIsa, base_filename: &str, out_dir: &str) -> Result<(), error::Error> { diff --git a/cranelift/codegen/meta/src/gen_settings.rs b/cranelift/codegen/meta/src/gen_settings.rs index 183c8643a2..a3c97ebab8 100644 --- a/cranelift/codegen/meta/src/gen_settings.rs +++ b/cranelift/codegen/meta/src/gen_settings.rs @@ -21,84 +21,92 @@ fn gen_constructor(group: &SettingGroup, parent: ParentGroup, fmt: &mut Formatte ParentGroup::None => "builder: Builder", ParentGroup::Shared => "shared: &settings::Flags, builder: Builder", }; - fmt.line("impl Flags {"); + fmtln!(fmt, "impl Flags {"); fmt.indent(|fmt| { fmt.doc_comment(format!("Create flags {} settings group.", group.name)); - fmt.line("#[allow(unused_variables)]"); - fmt.line(format!("pub fn new({}) -> Self {{", args)); + fmtln!(fmt, "#[allow(unused_variables)]"); + fmtln!(fmt, "pub fn new({}) -> Self {{", args); fmt.indent(|fmt| { - fmt.line(format!("let bvec = builder.state_for(\"{}\");", group.name)); - fmt.line(format!( + fmtln!(fmt, "let bvec = builder.state_for(\"{}\");", group.name); + fmtln!( + fmt, "let mut {} = Self {{ bytes: [0; {}] }};", group.name, group.byte_size() - )); - fmt.line(format!( + ); + fmtln!( + fmt, "debug_assert_eq!(bvec.len(), {});", group.settings_size - )); - fmt.line(format!( + ); + fmtln!( + fmt, "{}.bytes[0..{}].copy_from_slice(&bvec);", - group.name, group.settings_size - )); + group.name, + group.settings_size + ); // Now compute the predicates. for p in &group.predicates { fmt.comment(format!("Precompute #{}.", p.number)); - fmt.line(format!("if {} {{", p.render(group))); + fmtln!(fmt, "if {} {{", p.render(group)); fmt.indent(|fmt| { - fmt.line(format!( + fmtln!( + fmt, "{}.bytes[{}] |= 1 << {};", group.name, group.bool_start_byte_offset + p.number / 8, p.number % 8 - )); + ); }); - fmt.line("}"); + fmtln!(fmt, "}"); } - fmt.line(group.name); + fmtln!(fmt, group.name); }); - fmt.line("}"); + fmtln!(fmt, "}"); }); - fmt.line("}"); + fmtln!(fmt, "}"); } /// Emit Display and FromStr implementations for enum settings. fn gen_to_and_from_str(name: &str, values: &[&'static str], fmt: &mut Formatter) { - fmt.line(format!("impl fmt::Display for {} {{", name)); + fmtln!(fmt, "impl fmt::Display for {} {{", name); fmt.indent(|fmt| { - fmt.line("fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {"); + fmtln!( + fmt, + "fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {" + ); fmt.indent(|fmt| { - fmt.line("f.write_str(match *self {"); + fmtln!(fmt, "f.write_str(match *self {"); fmt.indent(|fmt| { for v in values.iter() { - fmt.line(format!("{}::{} => \"{}\",", name, camel_case(v), v)); + fmtln!(fmt, "{}::{} => \"{}\",", name, camel_case(v), v); } }); - fmt.line("})"); + fmtln!(fmt, "})"); }); - fmt.line("}"); + fmtln!(fmt, "}"); }); - fmt.line("}"); + fmtln!(fmt, "}"); - fmt.line(format!("impl str::FromStr for {} {{", name)); + fmtln!(fmt, "impl str::FromStr for {} {{", name); fmt.indent(|fmt| { - fmt.line("type Err = ();"); - fmt.line("fn from_str(s: &str) -> Result {"); + fmtln!(fmt, "type Err = ();"); + fmtln!(fmt, "fn from_str(s: &str) -> Result {"); fmt.indent(|fmt| { - fmt.line("match s {"); + fmtln!(fmt, "match s {"); fmt.indent(|fmt| { for v in values.iter() { - fmt.line(format!("\"{}\" => Ok({}::{}),", v, name, camel_case(v))); + fmtln!(fmt, "\"{}\" => Ok({}::{}),", v, name, camel_case(v)); } - fmt.line("_ => Err(()),"); + fmtln!(fmt, "_ => Err(()),"); }); - fmt.line("}"); + fmtln!(fmt, "}"); }); - fmt.line("}"); + fmtln!(fmt, "}"); }); - fmt.line("}"); + fmtln!(fmt, "}"); } /// Emit real enum for the Enum settings. @@ -111,15 +119,15 @@ fn gen_enum_types(group: &SettingGroup, fmt: &mut Formatter) { let name = camel_case(setting.name); fmt.doc_comment(format!("Values for `{}.{}`.", group.name, setting.name)); - fmt.line("#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]"); - fmt.line(format!("pub enum {} {{", name)); + fmtln!(fmt, "#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]"); + fmtln!(fmt, "pub enum {} {{", name); fmt.indent(|fmt| { for v in values.iter() { fmt.doc_comment(format!("`{}`.", v)); - fmt.line(format!("{},", camel_case(v))); + fmtln!(fmt, "{},", camel_case(v)); } }); - fmt.line("}"); + fmtln!(fmt, "}"); gen_to_and_from_str(&name, values, fmt); } @@ -132,15 +140,15 @@ fn gen_getter(setting: &Setting, fmt: &mut Formatter) { SpecificSetting::Bool(BoolSetting { predicate_number, .. }) => { - fmt.line(format!("pub fn {}(&self) -> bool {{", setting.name)); + fmtln!(fmt, "pub fn {}(&self) -> bool {{", setting.name); fmt.indent(|fmt| { - fmt.line(format!("self.numbered_predicate({})", predicate_number)); + fmtln!(fmt, "self.numbered_predicate({})", predicate_number); }); - fmt.line("}"); + fmtln!(fmt, "}"); } SpecificSetting::Enum(ref values) => { let ty = camel_case(setting.name); - fmt.line(format!("pub fn {}(&self) -> {} {{", setting.name, ty)); + fmtln!(fmt, "pub fn {}(&self) -> {} {{", setting.name, ty); fmt.indent(|fmt| { let mut m = Match::new(format!("self.bytes[{}]", setting.byte_offset)); for (i, v) in values.iter().enumerate() { @@ -153,53 +161,58 @@ fn gen_getter(setting: &Setting, fmt: &mut Formatter) { m.arm("_", vec![], "panic!(\"Invalid enum value\")"); fmt.add_match(m); }); - fmt.line("}"); + fmtln!(fmt, "}"); } SpecificSetting::Num(_) => { - fmt.line(format!("pub fn {}(&self) -> u8 {{", setting.name)); + fmtln!(fmt, "pub fn {}(&self) -> u8 {{", setting.name); fmt.indent(|fmt| { - fmt.line(format!("self.bytes[{}]", setting.byte_offset)); + fmtln!(fmt, "self.bytes[{}]", setting.byte_offset); }); - fmt.line("}"); + fmtln!(fmt, "}"); } } } fn gen_pred_getter(predicate: &Predicate, group: &SettingGroup, fmt: &mut Formatter) { fmt.doc_comment(format!("Computed predicate `{}`.", predicate.render(group))); - fmt.line(format!("pub fn {}(&self) -> bool {{", predicate.name)); + fmtln!(fmt, "pub fn {}(&self) -> bool {{", predicate.name); fmt.indent(|fmt| { - fmt.line(format!("self.numbered_predicate({})", predicate.number)); + fmtln!(fmt, "self.numbered_predicate({})", predicate.number); }); - fmt.line("}"); + fmtln!(fmt, "}"); } /// Emits getters for each setting value. fn gen_getters(group: &SettingGroup, fmt: &mut Formatter) { fmt.doc_comment("User-defined settings."); - fmt.line("#[allow(dead_code)]"); - fmt.line("impl Flags {"); + fmtln!(fmt, "#[allow(dead_code)]"); + fmtln!(fmt, "impl Flags {"); fmt.indent(|fmt| { fmt.doc_comment("Get a view of the boolean predicates."); - fmt.line("pub fn predicate_view(&self) -> ::settings::PredicateView {"); + fmtln!( + fmt, + "pub fn predicate_view(&self) -> ::settings::PredicateView {" + ); fmt.indent(|fmt| { - fmt.line(format!( + fmtln!( + fmt, "::settings::PredicateView::new(&self.bytes[{}..])", group.bool_start_byte_offset - )); + ); }); - fmt.line("}"); + fmtln!(fmt, "}"); if group.settings.len() > 0 { fmt.doc_comment("Dynamic numbered predicate getter."); - fmt.line("fn numbered_predicate(&self, p: usize) -> bool {"); + fmtln!(fmt, "fn numbered_predicate(&self, p: usize) -> bool {"); fmt.indent(|fmt| { - fmt.line(format!( + fmtln!( + fmt, "self.bytes[{} + p / 8] & (1 << (p % 8)) != 0", group.bool_start_byte_offset - )); + ); }); - fmt.line("}"); + fmtln!(fmt, "}"); } for setting in &group.settings { @@ -209,7 +222,7 @@ fn gen_getters(group: &SettingGroup, fmt: &mut Formatter) { gen_pred_getter(&predicate, &group, fmt); } }); - fmt.line("}"); + fmtln!(fmt, "}"); } #[derive(Hash, PartialEq, Eq)] @@ -234,66 +247,66 @@ fn gen_descriptors(group: &SettingGroup, fmt: &mut Formatter) { let mut descriptor_index_map: HashMap = HashMap::new(); // Generate descriptors. - fmt.line(format!( + fmtln!( + fmt, "static DESCRIPTORS: [detail::Descriptor; {}] = [", group.settings.len() + group.presets.len() - )); + ); fmt.indent(|fmt| { for (idx, setting) in group.settings.iter().enumerate() { - fmt.line("detail::Descriptor {"); + fmtln!(fmt, "detail::Descriptor {"); fmt.indent(|fmt| { - fmt.line(format!("name: \"{}\",", setting.name)); - fmt.line(format!("offset: {},", setting.byte_offset)); + fmtln!(fmt, "name: \"{}\",", setting.name); + fmtln!(fmt, "offset: {},", setting.byte_offset); match setting.specific { SpecificSetting::Bool(BoolSetting { bit_offset, .. }) => { - fmt.line(format!( + fmtln!( + fmt, "detail: detail::Detail::Bool {{ bit: {} }},", bit_offset - )); + ); } SpecificSetting::Enum(ref values) => { let offset = enum_table.add(values); - fmt.line(format!( + fmtln!( + fmt, "detail: detail::Detail::Enum {{ last: {}, enumerators: {} }},", values.len() - 1, offset - )); + ); } SpecificSetting::Num(_) => { - fmt.line("detail: detail::Detail::Num,"); + fmtln!(fmt, "detail: detail::Detail::Num,"); } } descriptor_index_map.insert(SettingOrPreset::Setting(setting), idx); }); - fmt.line("},"); + fmtln!(fmt, "},"); } for (idx, preset) in group.presets.iter().enumerate() { - fmt.line("detail::Descriptor {"); + fmtln!(fmt, "detail::Descriptor {"); fmt.indent(|fmt| { - fmt.line(format!("name: \"{}\",", preset.name)); - fmt.line(format!("offset: {},", (idx as u8) * group.settings_size)); - fmt.line("detail: detail::Detail::Preset,"); + fmtln!(fmt, "name: \"{}\",", preset.name); + fmtln!(fmt, "offset: {},", (idx as u8) * group.settings_size); + fmtln!(fmt, "detail: detail::Detail::Preset,"); }); - fmt.line("},"); + fmtln!(fmt, "},"); descriptor_index_map.insert(SettingOrPreset::Preset(preset), idx); } }); - fmt.line("];"); + fmtln!(fmt, "];"); // Generate enumerators. - fmt.line(format!( - "static ENUMERATORS: [&str; {}] = [", - enum_table.len() - )); + fmtln!(fmt, "static ENUMERATORS: [&str; {}] = [", enum_table.len()); fmt.indent(|fmt| { for enum_val in enum_table.iter() { - fmt.line(format!("\"{}\",", enum_val)); + fmtln!(fmt, "\"{}\",", enum_val); } }); - fmt.line("];"); + fmtln!(fmt, "];"); // Generate hash table. let mut hash_entries: Vec = Vec::new(); @@ -312,40 +325,39 @@ fn gen_descriptors(group: &SettingGroup, fmt: &mut Formatter) { .collect::>(), ); let hash_table = generate_table(&hash_entries, |entry| simple_hash(entry.name())); - fmt.line(format!( - "static HASH_TABLE: [u16; {}] = [", - hash_table.len() - )); + fmtln!(fmt, "static HASH_TABLE: [u16; {}] = [", hash_table.len()); fmt.indent(|fmt| { for h in &hash_table { match *h { - Some(setting_or_preset) => fmt.line(format!( + Some(setting_or_preset) => fmtln!( + fmt, "{},", &descriptor_index_map .get(setting_or_preset) .unwrap() .to_string() - )), - None => fmt.line("0xffff,"), + ), + None => fmtln!(fmt, "0xffff,"), } } }); - fmt.line("];"); + fmtln!(fmt, "];"); // Generate presets. - fmt.line(format!( + fmtln!( + fmt, "static PRESETS: [(u8, u8); {}] = [", group.presets.len() - )); + ); fmt.indent(|fmt| { for preset in &group.presets { fmt.comment(preset.name); for (mask, value) in preset.layout(&group) { - fmt.line(format!("(0b{:08b}, 0b{:08b}),", mask, value)); + fmtln!(fmt, "(0b{:08b}, 0b{:08b}),", mask, value); } } }); - fmt.line("];"); + fmtln!(fmt, "];"); } fn gen_template(group: &SettingGroup, fmt: &mut Formatter) { @@ -360,63 +372,70 @@ fn gen_template(group: &SettingGroup, fmt: &mut Formatter) { .collect(); let default_bytes_str = default_bytes.join(", "); - fmt.line("static TEMPLATE: detail::Template = detail::Template {"); + fmtln!( + fmt, + "static TEMPLATE: detail::Template = detail::Template {" + ); fmt.indent(|fmt| { - fmt.line(format!("name: \"{}\",", group.name)); - fmt.line("descriptors: &DESCRIPTORS,"); - fmt.line("enumerators: &ENUMERATORS,"); - fmt.line("hash_table: &HASH_TABLE,"); - fmt.line(format!("defaults: &[{}],", default_bytes_str)); - fmt.line("presets: &PRESETS,"); + fmtln!(fmt, "name: \"{}\",", group.name); + fmtln!(fmt, "descriptors: &DESCRIPTORS,"); + fmtln!(fmt, "enumerators: &ENUMERATORS,"); + fmtln!(fmt, "hash_table: &HASH_TABLE,"); + fmtln!(fmt, "defaults: &[{}],", default_bytes_str); + fmtln!(fmt, "presets: &PRESETS,"); }); - fmt.line("};"); + fmtln!(fmt, "};"); fmt.doc_comment(format!( "Create a `settings::Builder` for the {} settings group.", group.name )); - fmt.line("pub fn builder() -> Builder {"); + fmtln!(fmt, "pub fn builder() -> Builder {"); fmt.indent(|fmt| { - fmt.line("Builder::new(&TEMPLATE)"); + fmtln!(fmt, "Builder::new(&TEMPLATE)"); }); - fmt.line("}"); + fmtln!(fmt, "}"); } fn gen_display(group: &SettingGroup, fmt: &mut Formatter) { - fmt.line("impl fmt::Display for Flags {"); + fmtln!(fmt, "impl fmt::Display for Flags {"); fmt.indent(|fmt| { - fmt.line("fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {"); + fmtln!( + fmt, + "fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {" + ); fmt.indent(|fmt| { - fmt.line(format!("writeln!(f, \"[{}]\")?;", group.name)); - fmt.line("for d in &DESCRIPTORS {"); + fmtln!(fmt, "writeln!(f, \"[{}]\")?;", group.name); + fmtln!(fmt, "for d in &DESCRIPTORS {"); fmt.indent(|fmt| { - fmt.line("if !d.detail.is_preset() {"); + fmtln!(fmt, "if !d.detail.is_preset() {"); fmt.indent(|fmt| { - fmt.line("write!(f, \"{} = \", d.name)?;"); - fmt.line( + fmtln!(fmt, "write!(f, \"{} = \", d.name)?;"); + fmtln!( + fmt, "TEMPLATE.format_toml_value(d.detail, self.bytes[d.offset as usize], f)?;", ); - fmt.line("writeln!(f)?;"); + fmtln!(fmt, "writeln!(f)?;"); }); - fmt.line("}"); + fmtln!(fmt, "}"); }); - fmt.line("}"); - fmt.line("Ok(())"); + fmtln!(fmt, "}"); + fmtln!(fmt, "Ok(())"); }); - fmt.line("}") + fmtln!(fmt, "}") }); - fmt.line("}"); + fmtln!(fmt, "}"); } fn gen_group(group: &SettingGroup, parent: ParentGroup, fmt: &mut Formatter) { // Generate struct. - fmt.line("#[derive(Clone)]"); + fmtln!(fmt, "#[derive(Clone)]"); fmt.doc_comment(format!("Flags group `{}`.", group.name)); - fmt.line("pub struct Flags {"); + fmtln!(fmt, "pub struct Flags {"); fmt.indent(|fmt| { - fmt.line(format!("bytes: [u8; {}],", group.byte_size())); + fmtln!(fmt, "bytes: [u8; {}],", group.byte_size()); }); - fmt.line("}"); + fmtln!(fmt, "}"); gen_constructor(group, parent, fmt); gen_enum_types(group, fmt); diff --git a/cranelift/codegen/meta/src/gen_types.rs b/cranelift/codegen/meta/src/gen_types.rs index 5b48d17a27..0a52eb371e 100644 --- a/cranelift/codegen/meta/src/gen_types.rs +++ b/cranelift/codegen/meta/src/gen_types.rs @@ -22,7 +22,7 @@ fn emit_type(ty: &cdsl_types::ValueType, fmt: &mut srcgen::Formatter) -> Result< })?; fmt.doc_comment(&ty.doc()); - fmt.line(format!("pub const {}: Type = Type({:#x});\n", name, number)); + fmtln!(fmt, "pub const {}: Type = Type({:#x});\n", name, number); Ok(()) } diff --git a/cranelift/codegen/meta/src/lib.rs b/cranelift/codegen/meta/src/lib.rs index b617d31c16..fe65e19d2b 100644 --- a/cranelift/codegen/meta/src/lib.rs +++ b/cranelift/codegen/meta/src/lib.rs @@ -1,5 +1,6 @@ #[macro_use] mod cdsl; +mod srcgen; pub mod error; pub mod isa; @@ -10,7 +11,6 @@ mod gen_types; mod constant_hash; mod shared; -mod srcgen; mod unique_table; pub fn isa_from_arch(arch: &str) -> Result { diff --git a/cranelift/codegen/meta/src/srcgen.rs b/cranelift/codegen/meta/src/srcgen.rs index 4e86e0b8c7..dc7f622940 100644 --- a/cranelift/codegen/meta/src/srcgen.rs +++ b/cranelift/codegen/meta/src/srcgen.rs @@ -3,6 +3,8 @@ //! The `srcgen` module contains generic helper routines and classes for //! generating source code. +#![macro_use] + use std::cmp; use std::collections::{BTreeMap, BTreeSet}; use std::fs; @@ -13,6 +15,18 @@ use crate::error; static SHIFTWIDTH: usize = 4; +/// A macro that simplifies the usage of the Formatter by allowing format +/// strings. +macro_rules! fmtln { + ($fmt:ident, $fmtstring:expr, $($fmtargs:expr),*) => { + $fmt.line(format!($fmtstring, $($fmtargs),*)); + }; + + ($fmt:ident, $arg:expr) => { + $fmt.line($arg); + }; +} + pub struct Formatter { indent: usize, lines: Vec, @@ -104,7 +118,7 @@ impl Formatter { /// Add a comment line. pub fn comment(&mut self, s: impl AsRef) { - self.line(format!("// {}", s.as_ref())); + fmtln!(self, "// {}", s.as_ref()); } /// Add a (multi-line) documentation comment. @@ -123,7 +137,7 @@ impl Formatter { /// Add a match expression. pub fn add_match(&mut self, m: Match) { - self.line(format!("match {} {{", m.expr)); + fmtln!(self, "match {} {{", m.expr); self.indent(|fmt| { for (&(ref fields, ref body), ref names) in m.arms.iter() { // name { fields } | name { fields } => { body } @@ -138,7 +152,7 @@ impl Formatter { }) .collect(); let lhs = conditions.join(" | "); - fmt.line(format!("{} => {{", lhs)); + fmtln!(fmt, "{} => {{", lhs); fmt.indent(|fmt| { fmt.line(body); });