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_table: Rc<InstructionFormat>,
12     pub(crate) brif: Rc<InstructionFormat>,
13     pub(crate) call: Rc<InstructionFormat>,
14     pub(crate) call_indirect: Rc<InstructionFormat>,
15     pub(crate) try_call: Rc<InstructionFormat>,
16     pub(crate) try_call_indirect: Rc<InstructionFormat>,
17     pub(crate) cond_trap: Rc<InstructionFormat>,
18     pub(crate) float_compare: Rc<InstructionFormat>,
19     pub(crate) func_addr: Rc<InstructionFormat>,
20     pub(crate) int_compare: Rc<InstructionFormat>,
21     pub(crate) int_compare_imm: Rc<InstructionFormat>,
22     pub(crate) int_add_trap: Rc<InstructionFormat>,
23     pub(crate) jump: Rc<InstructionFormat>,
24     pub(crate) load: Rc<InstructionFormat>,
25     pub(crate) load_no_offset: Rc<InstructionFormat>,
26     pub(crate) multiary: Rc<InstructionFormat>,
27     pub(crate) nullary: Rc<InstructionFormat>,
28     pub(crate) shuffle: Rc<InstructionFormat>,
29     pub(crate) stack_load: Rc<InstructionFormat>,
30     pub(crate) stack_store: Rc<InstructionFormat>,
31     pub(crate) dynamic_stack_load: Rc<InstructionFormat>,
32     pub(crate) dynamic_stack_store: Rc<InstructionFormat>,
33     pub(crate) store: Rc<InstructionFormat>,
34     pub(crate) store_no_offset: Rc<InstructionFormat>,
35     pub(crate) ternary: Rc<InstructionFormat>,
36     pub(crate) ternary_imm8: Rc<InstructionFormat>,
37     pub(crate) trap: Rc<InstructionFormat>,
38     pub(crate) unary: Rc<InstructionFormat>,
39     pub(crate) unary_const: Rc<InstructionFormat>,
40     pub(crate) unary_global_value: Rc<InstructionFormat>,
41     pub(crate) unary_ieee16: Rc<InstructionFormat>,
42     pub(crate) unary_ieee32: Rc<InstructionFormat>,
43     pub(crate) unary_ieee64: Rc<InstructionFormat>,
44     pub(crate) unary_imm: Rc<InstructionFormat>,
45 }
46 
47 impl Formats {
48     pub fn new(imm: &Immediates, entities: &EntityRefs) -> Self {
49         Self {
50             unary: Builder::new("Unary").value().build(),
51 
52             unary_imm: Builder::new("UnaryImm").imm(&imm.imm64).build(),
53 
54             unary_ieee16: Builder::new("UnaryIeee16").imm(&imm.ieee16).build(),
55 
56             unary_ieee32: Builder::new("UnaryIeee32").imm(&imm.ieee32).build(),
57 
58             unary_ieee64: Builder::new("UnaryIeee64").imm(&imm.ieee64).build(),
59 
60             unary_const: Builder::new("UnaryConst").imm(&imm.pool_constant).build(),
61 
62             unary_global_value: Builder::new("UnaryGlobalValue")
63                 .imm(&entities.global_value)
64                 .build(),
65 
66             binary: Builder::new("Binary").value().value().build(),
67 
68             binary_imm8: Builder::new("BinaryImm8").value().imm(&imm.uimm8).build(),
69 
70             binary_imm64: Builder::new("BinaryImm64").value().imm(&imm.imm64).build(),
71 
72             // The select instructions are controlled by the second VALUE operand.
73             // The first VALUE operand is the controlling flag which has a derived type.
74             // The fma instruction has the same constraint on all inputs.
75             ternary: Builder::new("Ternary")
76                 .value()
77                 .value()
78                 .value()
79                 .typevar_operand(1)
80                 .build(),
81 
82             ternary_imm8: Builder::new("TernaryImm8")
83                 .value()
84                 .imm(&imm.uimm8)
85                 .value()
86                 .build(),
87 
88             // Catch-all for instructions with many outputs and inputs and no immediate
89             // operands.
90             multiary: Builder::new("MultiAry").varargs().build(),
91 
92             nullary: Builder::new("NullAry").build(),
93 
94             shuffle: Builder::new("Shuffle")
95                 .value()
96                 .value()
97                 .imm(&imm.uimm128)
98                 .build(),
99 
100             int_compare: Builder::new("IntCompare")
101                 .imm(&imm.intcc)
102                 .value()
103                 .value()
104                 .build(),
105 
106             int_compare_imm: Builder::new("IntCompareImm")
107                 .imm(&imm.intcc)
108                 .value()
109                 .imm(&imm.imm64)
110                 .build(),
111 
112             float_compare: Builder::new("FloatCompare")
113                 .imm(&imm.floatcc)
114                 .value()
115                 .value()
116                 .build(),
117 
118             jump: Builder::new("Jump").block().build(),
119 
120             brif: Builder::new("Brif").value().block().block().build(),
121 
122             branch_table: Builder::new("BranchTable")
123                 .value()
124                 .imm(&entities.jump_table)
125                 .build(),
126 
127             call: Builder::new("Call")
128                 .imm(&entities.func_ref)
129                 .varargs()
130                 .build(),
131 
132             call_indirect: Builder::new("CallIndirect")
133                 .imm(&entities.sig_ref)
134                 .value()
135                 .varargs()
136                 .build(),
137 
138             try_call: Builder::new("TryCall")
139                 .imm(&entities.func_ref)
140                 .varargs()
141                 .imm(&&entities.exception_table)
142                 .build(),
143 
144             try_call_indirect: Builder::new("TryCallIndirect")
145                 .value()
146                 .varargs()
147                 .imm(&&entities.exception_table)
148                 .build(),
149 
150             func_addr: Builder::new("FuncAddr").imm(&entities.func_ref).build(),
151 
152             atomic_rmw: Builder::new("AtomicRmw")
153                 .imm(&imm.memflags)
154                 .imm(&imm.atomic_rmw_op)
155                 .value()
156                 .value()
157                 .build(),
158 
159             atomic_cas: Builder::new("AtomicCas")
160                 .imm(&imm.memflags)
161                 .value()
162                 .value()
163                 .value()
164                 .typevar_operand(2)
165                 .build(),
166 
167             load: Builder::new("Load")
168                 .imm(&imm.memflags)
169                 .value()
170                 .imm(&imm.offset32)
171                 .build(),
172 
173             load_no_offset: Builder::new("LoadNoOffset")
174                 .imm(&imm.memflags)
175                 .value()
176                 .build(),
177 
178             store: Builder::new("Store")
179                 .imm(&imm.memflags)
180                 .value()
181                 .value()
182                 .imm(&imm.offset32)
183                 .build(),
184 
185             store_no_offset: Builder::new("StoreNoOffset")
186                 .imm(&imm.memflags)
187                 .value()
188                 .value()
189                 .build(),
190 
191             stack_load: Builder::new("StackLoad")
192                 .imm(&entities.stack_slot)
193                 .imm(&imm.offset32)
194                 .build(),
195 
196             stack_store: Builder::new("StackStore")
197                 .value()
198                 .imm(&entities.stack_slot)
199                 .imm(&imm.offset32)
200                 .build(),
201 
202             dynamic_stack_load: Builder::new("DynamicStackLoad")
203                 .imm(&entities.dynamic_stack_slot)
204                 .build(),
205 
206             dynamic_stack_store: Builder::new("DynamicStackStore")
207                 .value()
208                 .imm(&entities.dynamic_stack_slot)
209                 .build(),
210 
211             trap: Builder::new("Trap").imm(&imm.trapcode).build(),
212 
213             cond_trap: Builder::new("CondTrap").value().imm(&imm.trapcode).build(),
214 
215             int_add_trap: Builder::new("IntAddTrap")
216                 .value()
217                 .value()
218                 .imm(&imm.trapcode)
219                 .build(),
220         }
221     }
222 }
223