[meta] Make Instruction name/doc Strings so they can be automatically generated;

This commit is contained in:
Benjamin Bouvier
2019-04-30 18:14:40 +02:00
parent 22a6823496
commit feb90e376a
3 changed files with 15 additions and 14 deletions

View File

@@ -54,11 +54,11 @@ pub struct PolymorphicInfo {
pub struct InstructionContent { pub struct InstructionContent {
/// Instruction mnemonic, also becomes opcode name. /// Instruction mnemonic, also becomes opcode name.
pub name: &'static str, pub name: String,
pub camel_name: String, pub camel_name: String,
/// Documentation string. /// Documentation string.
doc: &'static str, doc: String,
/// Input operands. This can be a mix of SSA value operands and other operand kinds. /// Input operands. This can be a mix of SSA value operands and other operand kinds.
pub operands_in: Vec<Operand>, pub operands_in: Vec<Operand>,
@@ -115,15 +115,15 @@ impl ops::Deref for Instruction {
} }
impl Instruction { impl Instruction {
pub fn snake_name(&self) -> &'static str { pub fn snake_name(&self) -> &str {
if self.name == "return" { if self.name == "return" {
"return_" "return_"
} else { } else {
self.name &self.name
} }
} }
pub fn doc_comment_first_line(&self) -> &'static str { pub fn doc_comment_first_line(&self) -> &str {
for line in self.doc.split("\n") { for line in self.doc.split("\n") {
let stripped = line.trim(); let stripped = line.trim();
if stripped.len() > 0 { if stripped.len() > 0 {
@@ -162,7 +162,7 @@ impl fmt::Display for Instruction {
fmt.write_str(" = ")?; fmt.write_str(" = ")?;
} }
fmt.write_str(self.name)?; fmt.write_str(&self.name)?;
if self.operands_in.len() > 0 { if self.operands_in.len() > 0 {
let operands_in = self let operands_in = self
@@ -180,8 +180,8 @@ impl fmt::Display for Instruction {
} }
pub struct InstructionBuilder { pub struct InstructionBuilder {
name: &'static str, name: String,
doc: &'static str, doc: String,
operands_in: Option<Vec<Operand>>, operands_in: Option<Vec<Operand>>,
operands_out: Option<Vec<Operand>>, operands_out: Option<Vec<Operand>>,
constraints: Option<Vec<Constraint>>, constraints: Option<Vec<Constraint>>,
@@ -200,10 +200,10 @@ pub struct InstructionBuilder {
} }
impl InstructionBuilder { impl InstructionBuilder {
pub fn new(name: &'static str, doc: &'static str) -> Self { pub fn new<S: Into<String>>(name: S, doc: S) -> Self {
Self { Self {
name, name: name.into(),
doc, doc: doc.into(),
operands_in: None, operands_in: None,
operands_out: None, operands_out: None,
constraints: None, constraints: None,
@@ -310,10 +310,11 @@ impl InstructionBuilder {
// Infer from output operands whether an instruciton clobbers CPU flags or not. // Infer from output operands whether an instruciton clobbers CPU flags or not.
let writes_cpu_flags = operands_out.iter().any(|op| op.is_cpu_flags()); let writes_cpu_flags = operands_out.iter().any(|op| op.is_cpu_flags());
let camel_name = camel_case(&self.name);
Instruction { Instruction {
content: Rc::new(InstructionContent { content: Rc::new(InstructionContent {
name: self.name, name: self.name,
camel_name: camel_case(self.name), camel_name,
doc: self.doc, doc: self.doc,
operands_in, operands_in,
operands_out, operands_out,

View File

@@ -565,7 +565,7 @@ fn gen_opcodes<'a>(
// Generate an opcode hash table for looking up opcodes by name. // Generate an opcode hash table for looking up opcodes by name.
let hash_table = let hash_table =
constant_hash::generate_table(&all_inst, |inst| constant_hash::simple_hash(inst.name)); constant_hash::generate_table(&all_inst, |inst| constant_hash::simple_hash(&inst.name));
fmtln!( fmtln!(
fmt, fmt,
"const OPCODE_HASH_TABLE: [Option<Opcode>; {}] = [", "const OPCODE_HASH_TABLE: [Option<Opcode>; {}] = [",

View File

@@ -241,7 +241,7 @@ fn emit_runtime_typecheck<'a, 'b>(
/// Determine if `node` represents one of the value splitting instructions: `isplit` or `vsplit. /// Determine if `node` represents one of the value splitting instructions: `isplit` or `vsplit.
/// These instructions are lowered specially by the `legalize::split` module. /// These instructions are lowered specially by the `legalize::split` module.
fn is_value_split(def: &Def) -> bool { fn is_value_split(def: &Def) -> bool {
let name = def.apply.inst.name; let name = &def.apply.inst.name;
name == "isplit" || name == "vsplit" name == "isplit" || name == "vsplit"
} }