summaryrefslogtreecommitdiffstats
path: root/third_party/rust/cranelift-codegen-meta/src/shared/immediates.rs
diff options
context:
space:
mode:
Diffstat (limited to 'third_party/rust/cranelift-codegen-meta/src/shared/immediates.rs')
-rw-r--r--third_party/rust/cranelift-codegen-meta/src/shared/immediates.rs175
1 files changed, 175 insertions, 0 deletions
diff --git a/third_party/rust/cranelift-codegen-meta/src/shared/immediates.rs b/third_party/rust/cranelift-codegen-meta/src/shared/immediates.rs
new file mode 100644
index 0000000000..0aa4129daf
--- /dev/null
+++ b/third_party/rust/cranelift-codegen-meta/src/shared/immediates.rs
@@ -0,0 +1,175 @@
+use crate::cdsl::operands::{EnumValues, OperandKind, OperandKindFields};
+
+use std::collections::HashMap;
+
+pub(crate) struct Immediates {
+ /// A 64-bit immediate integer operand.
+ ///
+ /// This type of immediate integer can interact with SSA values with any IntType type.
+ pub imm64: OperandKind,
+
+ /// An unsigned 8-bit immediate integer operand.
+ ///
+ /// This small operand is used to indicate lane indexes in SIMD vectors and immediate bit
+ /// counts on shift instructions.
+ pub uimm8: OperandKind,
+
+ /// An unsigned 32-bit immediate integer operand.
+ pub uimm32: OperandKind,
+
+ /// An unsigned 128-bit immediate integer operand.
+ ///
+ /// This operand is used to pass entire 128-bit vectors as immediates to instructions like
+ /// const.
+ pub uimm128: OperandKind,
+
+ /// A constant stored in the constant pool.
+ ///
+ /// This operand is used to pass constants to instructions like vconst while storing the
+ /// actual bytes in the constant pool.
+ pub pool_constant: OperandKind,
+
+ /// A 32-bit immediate signed offset.
+ ///
+ /// This is used to represent an immediate address offset in load/store instructions.
+ pub offset32: OperandKind,
+
+ /// A 32-bit immediate floating point operand.
+ ///
+ /// IEEE 754-2008 binary32 interchange format.
+ pub ieee32: OperandKind,
+
+ /// A 64-bit immediate floating point operand.
+ ///
+ /// IEEE 754-2008 binary64 interchange format.
+ pub ieee64: OperandKind,
+
+ /// An immediate boolean operand.
+ ///
+ /// This type of immediate boolean can interact with SSA values with any BoolType type.
+ pub boolean: OperandKind,
+
+ /// A condition code for comparing integer values.
+ ///
+ /// This enumerated operand kind is used for the `icmp` instruction and corresponds to the
+ /// condcodes::IntCC` Rust type.
+ pub intcc: OperandKind,
+
+ /// A condition code for comparing floating point values.
+ ///
+ /// This enumerated operand kind is used for the `fcmp` instruction and corresponds to the
+ /// `condcodes::FloatCC` Rust type.
+ pub floatcc: OperandKind,
+
+ /// Flags for memory operations like `load` and `store`.
+ pub memflags: OperandKind,
+
+ /// A register unit in the current target ISA.
+ pub regunit: OperandKind,
+
+ /// A trap code indicating the reason for trapping.
+ ///
+ /// The Rust enum type also has a `User(u16)` variant for user-provided trap codes.
+ pub trapcode: OperandKind,
+
+ /// A code indicating the arithmetic operation to perform in an atomic_rmw memory access.
+ pub atomic_rmw_op: 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.")
+ },
+ atomic_rmw_op: {
+ let mut atomic_rmw_op_values = HashMap::new();
+ atomic_rmw_op_values.insert("add", "Add");
+ atomic_rmw_op_values.insert("sub", "Sub");
+ atomic_rmw_op_values.insert("and", "And");
+ atomic_rmw_op_values.insert("or", "Or");
+ atomic_rmw_op_values.insert("xor", "Xor");
+ atomic_rmw_op_values.insert("xchg", "Xchg");
+ new_enum("op", "ir::AtomicRmwOp", atomic_rmw_op_values)
+ .with_doc("Atomic Read-Modify-Write Ops")
+ },
+ }
+ }
+}