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