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