cranelift_codegen_meta/shared/
formats.rs

1use crate::cdsl::formats::{InstructionFormat, InstructionFormatBuilder as Builder};
2use crate::shared::{entities::EntityRefs, immediates::Immediates};
3use std::rc::Rc;
4
5pub(crate) struct Formats {
6    pub(crate) binary: Rc<InstructionFormat>,
7    pub(crate) binary_imm: Rc<InstructionFormat>,
8    pub(crate) branch: Rc<InstructionFormat>,
9    pub(crate) branch_float: Rc<InstructionFormat>,
10    pub(crate) branch_icmp: Rc<InstructionFormat>,
11    pub(crate) branch_int: Rc<InstructionFormat>,
12    pub(crate) branch_table: Rc<InstructionFormat>,
13    pub(crate) branch_table_base: Rc<InstructionFormat>,
14    pub(crate) branch_table_entry: Rc<InstructionFormat>,
15    pub(crate) call: Rc<InstructionFormat>,
16    pub(crate) call_indirect: Rc<InstructionFormat>,
17    pub(crate) cond_trap: Rc<InstructionFormat>,
18    pub(crate) copy_special: Rc<InstructionFormat>,
19    pub(crate) copy_to_ssa: Rc<InstructionFormat>,
20    pub(crate) extract_lane: Rc<InstructionFormat>,
21    pub(crate) float_compare: Rc<InstructionFormat>,
22    pub(crate) float_cond: Rc<InstructionFormat>,
23    pub(crate) float_cond_trap: Rc<InstructionFormat>,
24    pub(crate) func_addr: Rc<InstructionFormat>,
25    pub(crate) heap_addr: Rc<InstructionFormat>,
26    pub(crate) indirect_jump: Rc<InstructionFormat>,
27    pub(crate) insert_lane: Rc<InstructionFormat>,
28    pub(crate) int_compare: Rc<InstructionFormat>,
29    pub(crate) int_compare_imm: Rc<InstructionFormat>,
30    pub(crate) int_cond: Rc<InstructionFormat>,
31    pub(crate) int_cond_trap: Rc<InstructionFormat>,
32    pub(crate) int_select: Rc<InstructionFormat>,
33    pub(crate) jump: Rc<InstructionFormat>,
34    pub(crate) load: Rc<InstructionFormat>,
35    pub(crate) load_complex: Rc<InstructionFormat>,
36    pub(crate) multiary: Rc<InstructionFormat>,
37    pub(crate) nullary: Rc<InstructionFormat>,
38    pub(crate) reg_fill: Rc<InstructionFormat>,
39    pub(crate) reg_move: Rc<InstructionFormat>,
40    pub(crate) reg_spill: Rc<InstructionFormat>,
41    pub(crate) shuffle: Rc<InstructionFormat>,
42    pub(crate) stack_load: Rc<InstructionFormat>,
43    pub(crate) stack_store: Rc<InstructionFormat>,
44    pub(crate) store: Rc<InstructionFormat>,
45    pub(crate) store_complex: Rc<InstructionFormat>,
46    pub(crate) table_addr: Rc<InstructionFormat>,
47    pub(crate) ternary: Rc<InstructionFormat>,
48    pub(crate) trap: Rc<InstructionFormat>,
49    pub(crate) unary: Rc<InstructionFormat>,
50    pub(crate) unary_bool: Rc<InstructionFormat>,
51    pub(crate) unary_const: Rc<InstructionFormat>,
52    pub(crate) unary_global_value: Rc<InstructionFormat>,
53    pub(crate) unary_ieee32: Rc<InstructionFormat>,
54    pub(crate) unary_ieee64: Rc<InstructionFormat>,
55    pub(crate) unary_imm: Rc<InstructionFormat>,
56}
57
58impl Formats {
59    pub fn new(imm: &Immediates, entities: &EntityRefs) -> Self {
60        Self {
61            unary: Builder::new("Unary").value().build(),
62
63            unary_imm: Builder::new("UnaryImm").imm(&imm.imm64).build(),
64
65            unary_ieee32: Builder::new("UnaryIeee32").imm(&imm.ieee32).build(),
66
67            unary_ieee64: Builder::new("UnaryIeee64").imm(&imm.ieee64).build(),
68
69            unary_bool: Builder::new("UnaryBool").imm(&imm.boolean).build(),
70
71            unary_const: Builder::new("UnaryConst").imm(&imm.pool_constant).build(),
72
73            unary_global_value: Builder::new("UnaryGlobalValue")
74                .imm(&entities.global_value)
75                .build(),
76
77            binary: Builder::new("Binary").value().value().build(),
78
79            binary_imm: Builder::new("BinaryImm").value().imm(&imm.imm64).build(),
80
81            // The select instructions are controlled by the second VALUE operand.
82            // The first VALUE operand is the controlling flag which has a derived type.
83            // The fma instruction has the same constraint on all inputs.
84            ternary: Builder::new("Ternary")
85                .value()
86                .value()
87                .value()
88                .typevar_operand(1)
89                .build(),
90
91            // Catch-all for instructions with many outputs and inputs and no immediate
92            // operands.
93            multiary: Builder::new("MultiAry").varargs().build(),
94
95            nullary: Builder::new("NullAry").build(),
96
97            insert_lane: Builder::new("InsertLane")
98                .value()
99                .imm_with_name("lane", &imm.uimm8)
100                .value()
101                .build(),
102
103            extract_lane: Builder::new("ExtractLane")
104                .value()
105                .imm_with_name("lane", &imm.uimm8)
106                .build(),
107
108            shuffle: Builder::new("Shuffle")
109                .value()
110                .value()
111                .imm_with_name("mask", &imm.uimm128)
112                .build(),
113
114            int_compare: Builder::new("IntCompare")
115                .imm(&imm.intcc)
116                .value()
117                .value()
118                .build(),
119
120            int_compare_imm: Builder::new("IntCompareImm")
121                .imm(&imm.intcc)
122                .value()
123                .imm(&imm.imm64)
124                .build(),
125
126            int_cond: Builder::new("IntCond").imm(&imm.intcc).value().build(),
127
128            float_compare: Builder::new("FloatCompare")
129                .imm(&imm.floatcc)
130                .value()
131                .value()
132                .build(),
133
134            float_cond: Builder::new("FloatCond").imm(&imm.floatcc).value().build(),
135
136            int_select: Builder::new("IntSelect")
137                .imm(&imm.intcc)
138                .value()
139                .value()
140                .value()
141                .build(),
142
143            jump: Builder::new("Jump").imm(&entities.ebb).varargs().build(),
144
145            branch: Builder::new("Branch")
146                .value()
147                .imm(&entities.ebb)
148                .varargs()
149                .build(),
150
151            branch_int: Builder::new("BranchInt")
152                .imm(&imm.intcc)
153                .value()
154                .imm(&entities.ebb)
155                .varargs()
156                .build(),
157
158            branch_float: Builder::new("BranchFloat")
159                .imm(&imm.floatcc)
160                .value()
161                .imm(&entities.ebb)
162                .varargs()
163                .build(),
164
165            branch_icmp: Builder::new("BranchIcmp")
166                .imm(&imm.intcc)
167                .value()
168                .value()
169                .imm(&entities.ebb)
170                .varargs()
171                .build(),
172
173            branch_table: Builder::new("BranchTable")
174                .value()
175                .imm(&entities.ebb)
176                .imm(&entities.jump_table)
177                .build(),
178
179            branch_table_entry: Builder::new("BranchTableEntry")
180                .value()
181                .value()
182                .imm(&imm.uimm8)
183                .imm(&entities.jump_table)
184                .build(),
185
186            branch_table_base: Builder::new("BranchTableBase")
187                .imm(&entities.jump_table)
188                .build(),
189
190            indirect_jump: Builder::new("IndirectJump")
191                .value()
192                .imm(&entities.jump_table)
193                .build(),
194
195            call: Builder::new("Call")
196                .imm(&entities.func_ref)
197                .varargs()
198                .build(),
199
200            call_indirect: Builder::new("CallIndirect")
201                .imm(&entities.sig_ref)
202                .value()
203                .varargs()
204                .build(),
205
206            func_addr: Builder::new("FuncAddr").imm(&entities.func_ref).build(),
207
208            load: Builder::new("Load")
209                .imm(&imm.memflags)
210                .value()
211                .imm(&imm.offset32)
212                .build(),
213
214            load_complex: Builder::new("LoadComplex")
215                .imm(&imm.memflags)
216                .varargs()
217                .imm(&imm.offset32)
218                .build(),
219
220            store: Builder::new("Store")
221                .imm(&imm.memflags)
222                .value()
223                .value()
224                .imm(&imm.offset32)
225                .build(),
226
227            store_complex: Builder::new("StoreComplex")
228                .imm(&imm.memflags)
229                .value()
230                .varargs()
231                .imm(&imm.offset32)
232                .build(),
233
234            stack_load: Builder::new("StackLoad")
235                .imm(&entities.stack_slot)
236                .imm(&imm.offset32)
237                .build(),
238
239            stack_store: Builder::new("StackStore")
240                .value()
241                .imm(&entities.stack_slot)
242                .imm(&imm.offset32)
243                .build(),
244
245            // Accessing a WebAssembly heap.
246            heap_addr: Builder::new("HeapAddr")
247                .imm(&entities.heap)
248                .value()
249                .imm(&imm.uimm32)
250                .build(),
251
252            // Accessing a WebAssembly table.
253            table_addr: Builder::new("TableAddr")
254                .imm(&entities.table)
255                .value()
256                .imm(&imm.offset32)
257                .build(),
258
259            reg_move: Builder::new("RegMove")
260                .value()
261                .imm_with_name("src", &imm.regunit)
262                .imm_with_name("dst", &imm.regunit)
263                .build(),
264
265            copy_special: Builder::new("CopySpecial")
266                .imm_with_name("src", &imm.regunit)
267                .imm_with_name("dst", &imm.regunit)
268                .build(),
269
270            copy_to_ssa: Builder::new("CopyToSsa")
271                .imm_with_name("src", &imm.regunit)
272                .build(),
273
274            reg_spill: Builder::new("RegSpill")
275                .value()
276                .imm_with_name("src", &imm.regunit)
277                .imm_with_name("dst", &entities.stack_slot)
278                .build(),
279
280            reg_fill: Builder::new("RegFill")
281                .value()
282                .imm_with_name("src", &entities.stack_slot)
283                .imm_with_name("dst", &imm.regunit)
284                .build(),
285
286            trap: Builder::new("Trap").imm(&imm.trapcode).build(),
287
288            cond_trap: Builder::new("CondTrap").value().imm(&imm.trapcode).build(),
289
290            int_cond_trap: Builder::new("IntCondTrap")
291                .imm(&imm.intcc)
292                .value()
293                .imm(&imm.trapcode)
294                .build(),
295
296            float_cond_trap: Builder::new("FloatCondTrap")
297                .imm(&imm.floatcc)
298                .value()
299                .imm(&imm.trapcode)
300                .build(),
301        }
302    }
303}