1 use crate::cdsl::operands::{EnumValues, OperandKind, OperandKindFields};
2 
3 use std::collections::HashMap;
4 
5 pub(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 
new_imm( format_field_name: &'static str, rust_type: &'static str, doc: &'static str, ) -> OperandKind61 fn 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 }
new_enum( format_field_name: &'static str, rust_type: &'static str, values: EnumValues, doc: &'static str, ) -> OperandKind73 fn 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 
87 impl Immediates {
new() -> Self88     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 }
203