use crate::cdsl::operands::{EnumValues, OperandKind, OperandKindFields};
use std::collections::HashMap;
pub(crate) struct Immediates {
pub imm64: OperandKind,
pub uimm8: OperandKind,
pub uimm32: OperandKind,
pub uimm128: OperandKind,
pub pool_constant: OperandKind,
pub offset32: OperandKind,
pub ieee32: OperandKind,
pub ieee64: OperandKind,
pub boolean: OperandKind,
pub intcc: OperandKind,
pub floatcc: OperandKind,
pub memflags: OperandKind,
pub regunit: 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 {
pub fn new() -> Self {
Self {
imm64: new_imm("imm", "ir::immediates::Imm64").with_doc("A 64-bit immediate integer."),
uimm8: new_imm("imm", "ir::immediates::Uimm8")
.with_doc("An 8-bit immediate unsigned integer."),
uimm32: new_imm("imm", "ir::immediates::Uimm32")
.with_doc("A 32-bit immediate unsigned integer."),
uimm128: new_imm("imm", "ir::Immediate")
.with_doc("A 128-bit immediate unsigned integer."),
pool_constant: new_imm("constant_handle", "ir::Constant")
.with_doc("A constant stored in the constant pool."),
offset32: new_imm("offset", "ir::immediates::Offset32")
.with_doc("A 32-bit immediate signed offset."),
ieee32: new_imm("imm", "ir::immediates::Ieee32")
.with_doc("A 32-bit immediate floating point number."),
ieee64: new_imm("imm", "ir::immediates::Ieee64")
.with_doc("A 64-bit immediate floating point number."),
boolean: new_imm("imm", "bool").with_doc("An immediate boolean."),
intcc: {
let mut intcc_values = HashMap::new();
intcc_values.insert("eq", "Equal");
intcc_values.insert("ne", "NotEqual");
intcc_values.insert("sge", "SignedGreaterThanOrEqual");
intcc_values.insert("sgt", "SignedGreaterThan");
intcc_values.insert("sle", "SignedLessThanOrEqual");
intcc_values.insert("slt", "SignedLessThan");
intcc_values.insert("uge", "UnsignedGreaterThanOrEqual");
intcc_values.insert("ugt", "UnsignedGreaterThan");
intcc_values.insert("ule", "UnsignedLessThanOrEqual");
intcc_values.insert("ult", "UnsignedLessThan");
intcc_values.insert("of", "Overflow");
intcc_values.insert("nof", "NotOverflow");
new_enum("cond", "ir::condcodes::IntCC", intcc_values)
.with_doc("An integer comparison condition code.")
},
floatcc: {
let mut floatcc_values = HashMap::new();
floatcc_values.insert("ord", "Ordered");
floatcc_values.insert("uno", "Unordered");
floatcc_values.insert("eq", "Equal");
floatcc_values.insert("ne", "NotEqual");
floatcc_values.insert("one", "OrderedNotEqual");
floatcc_values.insert("ueq", "UnorderedOrEqual");
floatcc_values.insert("lt", "LessThan");
floatcc_values.insert("le", "LessThanOrEqual");
floatcc_values.insert("gt", "GreaterThan");
floatcc_values.insert("ge", "GreaterThanOrEqual");
floatcc_values.insert("ult", "UnorderedOrLessThan");
floatcc_values.insert("ule", "UnorderedOrLessThanOrEqual");
floatcc_values.insert("ugt", "UnorderedOrGreaterThan");
floatcc_values.insert("uge", "UnorderedOrGreaterThanOrEqual");
new_enum("cond", "ir::condcodes::FloatCC", floatcc_values)
.with_doc("A floating point comparison condition code")
},
memflags: new_imm("flags", "ir::MemFlags").with_doc("Memory operation flags"),
regunit: new_imm("regunit", "isa::RegUnit")
.with_doc("A register unit in the target ISA"),
trapcode: {
let mut trapcode_values = HashMap::new();
trapcode_values.insert("stk_ovf", "StackOverflow");
trapcode_values.insert("heap_oob", "HeapOutOfBounds");
trapcode_values.insert("int_ovf", "IntegerOverflow");
trapcode_values.insert("int_divz", "IntegerDivisionByZero");
new_enum("code", "ir::TrapCode", trapcode_values).with_doc("A trap reason code.")
},
}
}
}