cranelift_codegen_meta/shared/
immediates.rs

1use crate::cdsl::operands::{EnumValues, OperandKind, OperandKindFields};
2
3use std::collections::HashMap;
4
5pub(crate) struct Immediates {
6    /// A 64-bit immediate integer operand.
7    ///
8    /// This type of immediate integer can interact with SSA values with any IntType type.
9    pub imm64: OperandKind,
10
11    /// An unsigned 8-bit immediate integer operand.
12    ///
13    /// This small operand is used to indicate lane indexes in SIMD vectors and immediate bit
14    /// counts on shift instructions.
15    pub uimm8: OperandKind,
16
17    /// A 32-bit immediate signed offset.
18    ///
19    /// This is used to represent an immediate address offset in load/store instructions.
20    pub offset32: OperandKind,
21
22    /// A 16-bit immediate floating point operand.
23    ///
24    /// IEEE 754-2008 binary16 interchange format.
25    pub ieee16: OperandKind,
26
27    /// A 32-bit immediate floating point operand.
28    ///
29    /// IEEE 754-2008 binary32 interchange format.
30    pub ieee32: OperandKind,
31
32    /// A 64-bit immediate floating point operand.
33    ///
34    /// IEEE 754-2008 binary64 interchange format.
35    pub ieee64: OperandKind,
36
37    /// A condition code for comparing integer values.
38    ///
39    /// This enumerated operand kind is used for the `icmp` instruction and corresponds to the
40    /// condcodes::IntCC` Rust type.
41    pub intcc: OperandKind,
42
43    /// A condition code for comparing floating point values.
44    ///
45    /// This enumerated operand kind is used for the `fcmp` instruction and corresponds to the
46    /// `condcodes::FloatCC` Rust type.
47    pub floatcc: OperandKind,
48
49    /// Flags for memory operations like `load` and `store`.
50    pub memflags: OperandKind,
51
52    /// A trap code indicating the reason for trapping.
53    ///
54    /// The Rust enum type also has a `User(u16)` variant for user-provided trap codes.
55    pub trapcode: OperandKind,
56
57    /// A code indicating the arithmetic operation to perform in an atomic_rmw memory access.
58    pub atomic_rmw_op: OperandKind,
59}
60
61fn new_imm(
62    format_field_name: &'static str,
63    rust_type: &'static str,
64    doc: &'static str,
65) -> OperandKind {
66    OperandKind::new(
67        format_field_name,
68        rust_type,
69        OperandKindFields::ImmValue,
70        doc,
71    )
72}
73fn new_enum(
74    format_field_name: &'static str,
75    rust_type: &'static str,
76    values: EnumValues,
77    doc: &'static str,
78) -> OperandKind {
79    OperandKind::new(
80        format_field_name,
81        rust_type,
82        OperandKindFields::ImmEnum(values),
83        doc,
84    )
85}
86
87impl Immediates {
88    pub fn new() -> Self {
89        Self {
90            imm64: new_imm(
91                "imm",
92                "ir::immediates::Imm64",
93                "A 64-bit immediate integer.",
94            ),
95            uimm8: new_imm(
96                "imm",
97                "ir::immediates::Uimm8",
98                "An 8-bit immediate unsigned integer.",
99            ),
100            offset32: new_imm(
101                "offset",
102                "ir::immediates::Offset32",
103                "A 32-bit immediate signed offset.",
104            ),
105            ieee16: new_imm(
106                "imm",
107                "ir::immediates::Ieee16",
108                "A 16-bit immediate floating point number.",
109            ),
110            ieee32: new_imm(
111                "imm",
112                "ir::immediates::Ieee32",
113                "A 32-bit immediate floating point number.",
114            ),
115            ieee64: new_imm(
116                "imm",
117                "ir::immediates::Ieee64",
118                "A 64-bit immediate floating point number.",
119            ),
120            intcc: {
121                let mut intcc_values = HashMap::new();
122                intcc_values.insert("eq", "Equal");
123                intcc_values.insert("ne", "NotEqual");
124                intcc_values.insert("sge", "SignedGreaterThanOrEqual");
125                intcc_values.insert("sgt", "SignedGreaterThan");
126                intcc_values.insert("sle", "SignedLessThanOrEqual");
127                intcc_values.insert("slt", "SignedLessThan");
128                intcc_values.insert("uge", "UnsignedGreaterThanOrEqual");
129                intcc_values.insert("ugt", "UnsignedGreaterThan");
130                intcc_values.insert("ule", "UnsignedLessThanOrEqual");
131                intcc_values.insert("ult", "UnsignedLessThan");
132                new_enum(
133                    "cond",
134                    "ir::condcodes::IntCC",
135                    intcc_values,
136                    "An integer comparison condition code.",
137                )
138            },
139
140            floatcc: {
141                let mut floatcc_values = HashMap::new();
142                floatcc_values.insert("ord", "Ordered");
143                floatcc_values.insert("uno", "Unordered");
144                floatcc_values.insert("eq", "Equal");
145                floatcc_values.insert("ne", "NotEqual");
146                floatcc_values.insert("one", "OrderedNotEqual");
147                floatcc_values.insert("ueq", "UnorderedOrEqual");
148                floatcc_values.insert("lt", "LessThan");
149                floatcc_values.insert("le", "LessThanOrEqual");
150                floatcc_values.insert("gt", "GreaterThan");
151                floatcc_values.insert("ge", "GreaterThanOrEqual");
152                floatcc_values.insert("ult", "UnorderedOrLessThan");
153                floatcc_values.insert("ule", "UnorderedOrLessThanOrEqual");
154                floatcc_values.insert("ugt", "UnorderedOrGreaterThan");
155                floatcc_values.insert("uge", "UnorderedOrGreaterThanOrEqual");
156                new_enum(
157                    "cond",
158                    "ir::condcodes::FloatCC",
159                    floatcc_values,
160                    "A floating point comparison condition code",
161                )
162            },
163
164            memflags: new_imm("flags", "ir::MemFlags", "Memory operation flags"),
165
166            trapcode: {
167                let mut trapcode_values = HashMap::new();
168                trapcode_values.insert("stk_ovf", "STACK_OVERFLOW");
169                trapcode_values.insert("heap_oob", "HEAP_OUT_OF_BOUNDS");
170                trapcode_values.insert("int_ovf", "INTEGER_OVERFLOW");
171                trapcode_values.insert("int_divz", "INTEGER_DIVISION_BY_ZERO");
172                trapcode_values.insert("bad_toint", "BAD_CONVERSION_TO_INTEGER");
173                new_enum(
174                    "code",
175                    "ir::TrapCode",
176                    trapcode_values,
177                    "A trap reason code.",
178                )
179            },
180            atomic_rmw_op: {
181                let mut atomic_rmw_op_values = HashMap::new();
182                atomic_rmw_op_values.insert("add", "Add");
183                atomic_rmw_op_values.insert("sub", "Sub");
184                atomic_rmw_op_values.insert("and", "And");
185                atomic_rmw_op_values.insert("nand", "Nand");
186                atomic_rmw_op_values.insert("or", "Or");
187                atomic_rmw_op_values.insert("xor", "Xor");
188                atomic_rmw_op_values.insert("xchg", "Xchg");
189                atomic_rmw_op_values.insert("umin", "Umin");
190                atomic_rmw_op_values.insert("umax", "Umax");
191                atomic_rmw_op_values.insert("smin", "Smin");
192                atomic_rmw_op_values.insert("smax", "Smax");
193                new_enum(
194                    "op",
195                    "ir::AtomicRmwOp",
196                    atomic_rmw_op_values,
197                    "Atomic Read-Modify-Write Ops",
198                )
199            },
200        }
201    }
202}