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