[meta] Make Instruction name/doc Strings so they can be automatically generated;
This commit is contained in:
@@ -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,
|
||||||
|
|||||||
@@ -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>; {}] = [",
|
||||||
|
|||||||
@@ -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"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user