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