[meta] Remove the OperandKindBuilder;
And replace it by constructors in OperandKind. There's a single optional parameter function `set_doc` that remains, and didn't justify the whole OperandKindBuilder concept to exist.
This commit is contained in:
@@ -49,6 +49,7 @@ pub(crate) struct InstructionFormat {
|
|||||||
pub(crate) struct FormatStructure {
|
pub(crate) struct FormatStructure {
|
||||||
pub num_value_operands: usize,
|
pub num_value_operands: usize,
|
||||||
pub has_value_list: bool,
|
pub has_value_list: bool,
|
||||||
|
/// Tuples of (Rust field name / Rust type) for each immediate field.
|
||||||
pub imm_field_names: Vec<(&'static str, &'static str)>,
|
pub imm_field_names: Vec<(&'static str, &'static str)>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1296,7 +1296,7 @@ impl Into<InstSpec> for BoundInstruction {
|
|||||||
mod test {
|
mod test {
|
||||||
use super::*;
|
use super::*;
|
||||||
use crate::cdsl::formats::InstructionFormatBuilder;
|
use crate::cdsl::formats::InstructionFormatBuilder;
|
||||||
use crate::cdsl::operands::{OperandKindBuilder, OperandKindFields};
|
use crate::cdsl::operands::{OperandKind, OperandKindFields};
|
||||||
use crate::cdsl::typevar::TypeSetBuilder;
|
use crate::cdsl::typevar::TypeSetBuilder;
|
||||||
use crate::shared::types::Int::{I32, I64};
|
use crate::shared::types::Int::{I32, I64};
|
||||||
|
|
||||||
@@ -1304,7 +1304,7 @@ mod test {
|
|||||||
// Pretend the index string is &'static.
|
// Pretend the index string is &'static.
|
||||||
let name = Box::leak(index.to_string().into_boxed_str());
|
let name = Box::leak(index.to_string().into_boxed_str());
|
||||||
// Format's name / rust_type don't matter here.
|
// Format's name / rust_type don't matter here.
|
||||||
let kind = OperandKindBuilder::new(name, name, field).build();
|
let kind = OperandKind::new(name, name, field);
|
||||||
let operand = Operand::new(name, kind);
|
let operand = Operand::new(name, kind);
|
||||||
operand
|
operand
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -100,7 +100,7 @@ impl Operand {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
type EnumValues = HashMap<&'static str, &'static str>;
|
pub type EnumValues = HashMap<&'static str, &'static str>;
|
||||||
|
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
pub(crate) enum OperandKindFields {
|
pub(crate) enum OperandKindFields {
|
||||||
@@ -126,6 +126,23 @@ pub(crate) struct OperandKind {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl OperandKind {
|
impl OperandKind {
|
||||||
|
pub fn new(
|
||||||
|
rust_field_name: &'static str,
|
||||||
|
rust_type: &'static str,
|
||||||
|
fields: OperandKindFields,
|
||||||
|
) -> Self {
|
||||||
|
Self {
|
||||||
|
rust_field_name,
|
||||||
|
rust_type,
|
||||||
|
fields,
|
||||||
|
doc: None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
pub fn with_doc(mut self, doc: &'static str) -> Self {
|
||||||
|
assert!(self.doc.is_none());
|
||||||
|
self.doc = Some(doc);
|
||||||
|
self
|
||||||
|
}
|
||||||
fn doc(&self) -> Option<&str> {
|
fn doc(&self) -> Option<&str> {
|
||||||
if let Some(doc) = &self.doc {
|
if let Some(doc) = &self.doc {
|
||||||
return Some(doc);
|
return Some(doc);
|
||||||
@@ -142,12 +159,11 @@ impl OperandKind {
|
|||||||
|
|
||||||
impl Into<OperandKind> for &TypeVar {
|
impl Into<OperandKind> for &TypeVar {
|
||||||
fn into(self) -> OperandKind {
|
fn into(self) -> OperandKind {
|
||||||
OperandKindBuilder::new(
|
OperandKind::new(
|
||||||
"value",
|
"value",
|
||||||
"ir::Value",
|
"ir::Value",
|
||||||
OperandKindFields::TypeVar(self.into()),
|
OperandKindFields::TypeVar(self.into()),
|
||||||
)
|
)
|
||||||
.build()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
impl Into<OperandKind> for &OperandKind {
|
impl Into<OperandKind> for &OperandKind {
|
||||||
@@ -155,58 +171,3 @@ impl Into<OperandKind> for &OperandKind {
|
|||||||
self.clone()
|
self.clone()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) struct OperandKindBuilder {
|
|
||||||
rust_field_name: &'static str,
|
|
||||||
rust_type: &'static str,
|
|
||||||
fields: OperandKindFields,
|
|
||||||
doc: Option<&'static str>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl OperandKindBuilder {
|
|
||||||
pub fn new(
|
|
||||||
rust_field_name: &'static str,
|
|
||||||
rust_type: &'static str,
|
|
||||||
fields: OperandKindFields,
|
|
||||||
) -> Self {
|
|
||||||
Self {
|
|
||||||
rust_field_name,
|
|
||||||
rust_type,
|
|
||||||
fields,
|
|
||||||
doc: None,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
pub fn new_imm(rust_field_name: &'static str, rust_type: &'static str) -> Self {
|
|
||||||
Self {
|
|
||||||
rust_field_name,
|
|
||||||
rust_type,
|
|
||||||
fields: OperandKindFields::ImmValue,
|
|
||||||
doc: None,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
pub fn new_enum(
|
|
||||||
rust_field_name: &'static str,
|
|
||||||
rust_type: &'static str,
|
|
||||||
values: EnumValues,
|
|
||||||
) -> Self {
|
|
||||||
Self {
|
|
||||||
rust_field_name,
|
|
||||||
rust_type,
|
|
||||||
fields: OperandKindFields::ImmEnum(values),
|
|
||||||
doc: None,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
pub fn with_doc(mut self, doc: &'static str) -> Self {
|
|
||||||
assert!(self.doc.is_none());
|
|
||||||
self.doc = Some(doc);
|
|
||||||
self
|
|
||||||
}
|
|
||||||
pub fn build(self) -> OperandKind {
|
|
||||||
OperandKind {
|
|
||||||
rust_type: self.rust_type,
|
|
||||||
fields: self.fields,
|
|
||||||
rust_field_name: self.rust_field_name,
|
|
||||||
doc: self.doc,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -1,4 +1,9 @@
|
|||||||
use crate::cdsl::operands::{OperandKind, OperandKindBuilder as Builder, OperandKindFields};
|
use crate::cdsl::operands::{OperandKind, OperandKindFields};
|
||||||
|
|
||||||
|
/// Small helper to initialize an OperandBuilder with the right kind, for a given name and doc.
|
||||||
|
fn new(format_field_name: &'static str, rust_type: &'static str, doc: &'static str) -> OperandKind {
|
||||||
|
OperandKind::new(format_field_name, rust_type, OperandKindFields::EntityRef).with_doc(doc)
|
||||||
|
}
|
||||||
|
|
||||||
pub(crate) struct EntityRefs {
|
pub(crate) struct EntityRefs {
|
||||||
/// A reference to an extended basic block in the same function.
|
/// A reference to an extended basic block in the same function.
|
||||||
@@ -35,43 +40,34 @@ pub(crate) struct EntityRefs {
|
|||||||
impl EntityRefs {
|
impl EntityRefs {
|
||||||
pub fn new() -> Self {
|
pub fn new() -> Self {
|
||||||
Self {
|
Self {
|
||||||
ebb: create(
|
ebb: new(
|
||||||
"destination",
|
"destination",
|
||||||
"ir::Ebb",
|
"ir::Ebb",
|
||||||
"An extended basic block in the same function.",
|
"An extended basic block in the same function.",
|
||||||
)
|
),
|
||||||
.build(),
|
stack_slot: new("stack_slot", "ir::StackSlot", "A stack slot"),
|
||||||
|
|
||||||
stack_slot: create("stack_slot", "ir::StackSlot", "A stack slot").build(),
|
global_value: new("global_value", "ir::GlobalValue", "A global value."),
|
||||||
|
|
||||||
global_value: create("global_value", "ir::GlobalValue", "A global value.").build(),
|
sig_ref: new("sig_ref", "ir::SigRef", "A function signature."),
|
||||||
|
|
||||||
sig_ref: create("sig_ref", "ir::SigRef", "A function signature.").build(),
|
func_ref: new("func_ref", "ir::FuncRef", "An external function."),
|
||||||
|
|
||||||
func_ref: create("func_ref", "ir::FuncRef", "An external function.").build(),
|
jump_table: new("table", "ir::JumpTable", "A jump table."),
|
||||||
|
|
||||||
jump_table: create("table", "ir::JumpTable", "A jump table.").build(),
|
heap: new("heap", "ir::Heap", "A heap."),
|
||||||
|
|
||||||
heap: create("heap", "ir::Heap", "A heap.").build(),
|
table: new("table", "ir::Table", "A table."),
|
||||||
|
|
||||||
table: create("table", "ir::Table", "A table.").build(),
|
varargs: OperandKind::new("", "&[Value]", OperandKindFields::VariableArgs).with_doc(
|
||||||
|
r#"
|
||||||
varargs: Builder::new("", "&[Value]", OperandKindFields::VariableArgs)
|
|
||||||
.with_doc(
|
|
||||||
r#"
|
|
||||||
A variable size list of `value` operands.
|
A variable size list of `value` operands.
|
||||||
|
|
||||||
Use this to represent arguments passed to a function call, arguments
|
Use this to represent arguments passed to a function call, arguments
|
||||||
passed to an extended basic block, or a variable number of results
|
passed to an extended basic block, or a variable number of results
|
||||||
returned from an instruction.
|
returned from an instruction.
|
||||||
"#,
|
"#,
|
||||||
)
|
),
|
||||||
.build(),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Small helper to initialize an OperandBuilder with the right kind, for a given name and doc.
|
|
||||||
fn create(format_field_name: &'static str, rust_type: &'static str, doc: &'static str) -> Builder {
|
|
||||||
Builder::new(format_field_name, rust_type, OperandKindFields::EntityRef).with_doc(doc)
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
use crate::cdsl::operands::{OperandKind, OperandKindBuilder as Builder};
|
use crate::cdsl::operands::{EnumValues, OperandKind, OperandKindFields};
|
||||||
|
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
|
|
||||||
@@ -73,45 +73,40 @@ pub(crate) struct Immediates {
|
|||||||
pub trapcode: OperandKind,
|
pub trapcode: OperandKind,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn new_imm(format_field_name: &'static str, rust_type: &'static str) -> OperandKind {
|
||||||
|
OperandKind::new(format_field_name, rust_type, OperandKindFields::ImmValue)
|
||||||
|
}
|
||||||
|
fn new_enum(
|
||||||
|
format_field_name: &'static str,
|
||||||
|
rust_type: &'static str,
|
||||||
|
values: EnumValues,
|
||||||
|
) -> OperandKind {
|
||||||
|
OperandKind::new(
|
||||||
|
format_field_name,
|
||||||
|
rust_type,
|
||||||
|
OperandKindFields::ImmEnum(values),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
impl Immediates {
|
impl Immediates {
|
||||||
pub fn new() -> Self {
|
pub fn new() -> Self {
|
||||||
Self {
|
Self {
|
||||||
imm64: Builder::new_imm("imm", "ir::immediates::Imm64")
|
imm64: new_imm("imm", "ir::immediates::Imm64").with_doc("A 64-bit immediate integer."),
|
||||||
.with_doc("A 64-bit immediate integer.")
|
uimm8: new_imm("imm", "ir::immediates::Uimm8")
|
||||||
.build(),
|
.with_doc("An 8-bit immediate unsigned integer."),
|
||||||
|
uimm32: new_imm("imm", "ir::immediates::Uimm32")
|
||||||
uimm8: Builder::new_imm("imm", "ir::immediates::Uimm8")
|
.with_doc("A 32-bit immediate unsigned integer."),
|
||||||
.with_doc("An 8-bit immediate unsigned integer.")
|
uimm128: new_imm("imm", "ir::Immediate")
|
||||||
.build(),
|
.with_doc("A 128-bit immediate unsigned integer."),
|
||||||
|
pool_constant: new_imm("constant_handle", "ir::Constant")
|
||||||
uimm32: Builder::new_imm("imm", "ir::immediates::Uimm32")
|
.with_doc("A constant stored in the constant pool."),
|
||||||
.with_doc("A 32-bit immediate unsigned integer.")
|
offset32: new_imm("offset", "ir::immediates::Offset32")
|
||||||
.build(),
|
.with_doc("A 32-bit immediate signed offset."),
|
||||||
|
ieee32: new_imm("imm", "ir::immediates::Ieee32")
|
||||||
uimm128: Builder::new_imm("imm", "ir::Immediate")
|
.with_doc("A 32-bit immediate floating point number."),
|
||||||
.with_doc("A 128-bit immediate unsigned integer.")
|
ieee64: new_imm("imm", "ir::immediates::Ieee64")
|
||||||
.build(),
|
.with_doc("A 64-bit immediate floating point number."),
|
||||||
|
boolean: new_imm("imm", "bool").with_doc("An immediate boolean."),
|
||||||
pool_constant: Builder::new_imm("constant_handle", "ir::Constant")
|
|
||||||
.with_doc("A constant stored in the constant pool.")
|
|
||||||
.build(),
|
|
||||||
|
|
||||||
offset32: Builder::new_imm("offset", "ir::immediates::Offset32")
|
|
||||||
.with_doc("A 32-bit immediate signed offset.")
|
|
||||||
.build(),
|
|
||||||
|
|
||||||
ieee32: Builder::new_imm("imm", "ir::immediates::Ieee32")
|
|
||||||
.with_doc("A 32-bit immediate floating point number.")
|
|
||||||
.build(),
|
|
||||||
|
|
||||||
ieee64: Builder::new_imm("imm", "ir::immediates::Ieee64")
|
|
||||||
.with_doc("A 64-bit immediate floating point number.")
|
|
||||||
.build(),
|
|
||||||
|
|
||||||
boolean: Builder::new_imm("imm", "bool")
|
|
||||||
.with_doc("An immediate boolean.")
|
|
||||||
.build(),
|
|
||||||
|
|
||||||
intcc: {
|
intcc: {
|
||||||
let mut intcc_values = HashMap::new();
|
let mut intcc_values = HashMap::new();
|
||||||
intcc_values.insert("eq", "Equal");
|
intcc_values.insert("eq", "Equal");
|
||||||
@@ -126,9 +121,8 @@ impl Immediates {
|
|||||||
intcc_values.insert("ult", "UnsignedLessThan");
|
intcc_values.insert("ult", "UnsignedLessThan");
|
||||||
intcc_values.insert("of", "Overflow");
|
intcc_values.insert("of", "Overflow");
|
||||||
intcc_values.insert("nof", "NotOverflow");
|
intcc_values.insert("nof", "NotOverflow");
|
||||||
Builder::new_enum("cond", "ir::condcodes::IntCC", intcc_values)
|
new_enum("cond", "ir::condcodes::IntCC", intcc_values)
|
||||||
.with_doc("An integer comparison condition code.")
|
.with_doc("An integer comparison condition code.")
|
||||||
.build()
|
|
||||||
},
|
},
|
||||||
|
|
||||||
floatcc: {
|
floatcc: {
|
||||||
@@ -147,28 +141,20 @@ impl Immediates {
|
|||||||
floatcc_values.insert("ule", "UnorderedOrLessThanOrEqual");
|
floatcc_values.insert("ule", "UnorderedOrLessThanOrEqual");
|
||||||
floatcc_values.insert("ugt", "UnorderedOrGreaterThan");
|
floatcc_values.insert("ugt", "UnorderedOrGreaterThan");
|
||||||
floatcc_values.insert("uge", "UnorderedOrGreaterThanOrEqual");
|
floatcc_values.insert("uge", "UnorderedOrGreaterThanOrEqual");
|
||||||
Builder::new_enum("cond", "ir::condcodes::FloatCC", floatcc_values)
|
new_enum("cond", "ir::condcodes::FloatCC", floatcc_values)
|
||||||
.with_doc("A floating point comparison condition code")
|
.with_doc("A floating point comparison condition code")
|
||||||
.build()
|
|
||||||
},
|
},
|
||||||
|
|
||||||
memflags: Builder::new_imm("flags", "ir::MemFlags")
|
memflags: new_imm("flags", "ir::MemFlags").with_doc("Memory operation flags"),
|
||||||
.with_doc("Memory operation flags")
|
regunit: new_imm("regunit", "isa::RegUnit")
|
||||||
.build(),
|
.with_doc("A register unit in the target ISA"),
|
||||||
|
|
||||||
regunit: Builder::new_imm("regunit", "isa::RegUnit")
|
|
||||||
.with_doc("A register unit in the target ISA")
|
|
||||||
.build(),
|
|
||||||
|
|
||||||
trapcode: {
|
trapcode: {
|
||||||
let mut trapcode_values = HashMap::new();
|
let mut trapcode_values = HashMap::new();
|
||||||
trapcode_values.insert("stk_ovf", "StackOverflow");
|
trapcode_values.insert("stk_ovf", "StackOverflow");
|
||||||
trapcode_values.insert("heap_oob", "HeapOutOfBounds");
|
trapcode_values.insert("heap_oob", "HeapOutOfBounds");
|
||||||
trapcode_values.insert("int_ovf", "IntegerOverflow");
|
trapcode_values.insert("int_ovf", "IntegerOverflow");
|
||||||
trapcode_values.insert("int_divz", "IntegerDivisionByZero");
|
trapcode_values.insert("int_divz", "IntegerDivisionByZero");
|
||||||
Builder::new_enum("code", "ir::TrapCode", trapcode_values)
|
new_enum("code", "ir::TrapCode", trapcode_values).with_doc("A trap reason code.")
|
||||||
.with_doc("A trap reason code.")
|
|
||||||
.build()
|
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user