1use alloc::{collections::BTreeMap, format};
2use core::fmt;
3
4use openvm_stark_backend::p3_field::{ExtensionField, PrimeField32};
5
6use super::A0;
7
8#[derive(Debug, Clone)]
9pub enum AsmInstruction<F, EF> {
10 LoadFI(i32, i32, F, F, F),
14
15 LoadEI(i32, i32, F, F, F),
20
21 StoreFI(i32, i32, F, F, F),
25
26 StoreEI(i32, i32, F, F, F),
31
32 ImmF(i32, F),
34
35 CopyF(i32, i32),
37
38 AddF(i32, i32, i32),
40
41 AddFI(i32, i32, F),
43
44 SubF(i32, i32, i32),
46
47 SubFI(i32, i32, F),
49
50 SubFIN(i32, F, i32),
52
53 MulF(i32, i32, i32),
55
56 MulFI(i32, i32, F),
58
59 DivF(i32, i32, i32),
61
62 DivFI(i32, i32, F),
64
65 DivFIN(i32, F, i32),
67
68 AddE(i32, i32, i32),
70
71 SubE(i32, i32, i32),
73
74 MulE(i32, i32, i32),
76
77 DivE(i32, i32, i32),
79
80 Jump(i32, F),
82
83 Bne(F, i32, i32),
85
86 BneI(F, i32, F),
88
89 Beq(F, i32, i32),
91
92 BeqI(F, i32, F),
94
95 BneE(F, i32, i32),
97
98 BneEI(F, i32, EF),
100
101 BeqE(F, i32, i32),
103
104 BeqEI(F, i32, EF),
106
107 Trap,
109
110 Halt,
112
113 Poseidon2Permute(i32, i32),
117 Poseidon2Compress(i32, i32, i32),
120
121 FriReducedOpening(i32, i32, i32, i32, i32, i32, i32),
123
124 VerifyBatchFelt(i32, i32, i32, i32, i32, i32),
127
128 VerifyBatchExt(i32, i32, i32, i32, i32, i32),
131
132 RangeCheck(i32, i32, i32),
135
136 PrintV(i32),
138
139 PrintF(i32),
141
142 PrintE(i32),
144
145 HintInputVec(),
147 HintFelt(),
149
150 HintBits(i32, u32),
155
156 HintLoad(),
157
158 StoreHintWordI(i32, F),
160
161 StoreHintExtI(i32, F),
163
164 Publish(i32, i32),
166
167 CycleTrackerStart(),
168 CycleTrackerEnd(),
169}
170
171impl<F: PrimeField32, EF: ExtensionField<F>> AsmInstruction<F, EF> {
172 pub fn j(label: F) -> Self {
173 AsmInstruction::Jump(A0, label)
174 }
175
176 pub fn fmt(&self, labels: &BTreeMap<F, String>, f: &mut fmt::Formatter) -> fmt::Result {
177 match self {
178 AsmInstruction::LoadFI(dst, src, var_index, size, offset) => {
179 write!(
180 f,
181 "lwi ({dst})fp, ({src})fp, {var_index}, {size}, {offset}"
182 )
183 }
184 AsmInstruction::LoadEI(dst, src, var_index, size, offset) => {
185 write!(
186 f,
187 "lei ({dst})fp, ({src})fp, {var_index}, {size}, {offset}"
188 )
189 }
190 AsmInstruction::StoreFI(dst, src, var_index, size, offset) => {
191 write!(
192 f,
193 "swi ({dst})fp, ({src})fp, {var_index}, {size}, {offset}"
194 )
195 }
196 AsmInstruction::StoreEI(dst, src, var_index, size, offset) => {
197 write!(
198 f,
199 "sei ({dst})fp, ({src})fp, {var_index}, {size}, {offset}"
200 )
201 }
202 AsmInstruction::ImmF(dst, src) => {
203 write!(f, "imm ({dst})fp, ({src})")
204 }
205 AsmInstruction::CopyF(dst, src) => {
206 write!(f, "copy ({dst})fp, ({src})")
207 }
208 AsmInstruction::AddF(dst, lhs, rhs) => {
209 write!(f, "add ({dst})fp, ({lhs})fp, ({rhs})fp")
210 }
211 AsmInstruction::AddFI(dst, lhs, rhs) => {
212 write!(f, "addi ({dst})fp, ({lhs})fp, {rhs}")
213 }
214 AsmInstruction::SubF(dst, lhs, rhs) => {
215 write!(f, "sub ({dst})fp, ({lhs})fp, ({rhs})fp")
216 }
217 AsmInstruction::SubFI(dst, lhs, rhs) => {
218 write!(f, "subi ({dst})fp, ({lhs})fp, {rhs}")
219 }
220 AsmInstruction::SubFIN(dst, lhs, rhs) => {
221 write!(f, "subin ({dst})fp, {lhs}, ({rhs})fp")
222 }
223 AsmInstruction::MulF(dst, lhs, rhs) => {
224 write!(f, "mul ({dst})fp, ({lhs})fp, ({rhs})fp")
225 }
226 AsmInstruction::MulFI(dst, lhs, rhs) => {
227 write!(f, "muli ({dst})fp, ({lhs})fp, {rhs}")
228 }
229 AsmInstruction::DivF(dst, lhs, rhs) => {
230 write!(f, "div ({dst})fp, ({lhs})fp, ({rhs})fp")
231 }
232 AsmInstruction::DivFI(dst, lhs, rhs) => {
233 write!(f, "divi ({dst})fp, ({lhs})fp, {rhs}")
234 }
235 AsmInstruction::DivFIN(dst, lhs, rhs) => {
236 write!(f, "divi ({dst})fp, {lhs}, ({rhs})fp")
237 }
238 AsmInstruction::AddE(dst, lhs, rhs) => {
239 write!(f, "eadd ({dst})fp, ({lhs})fp, ({rhs})fp")
240 }
241 AsmInstruction::SubE(dst, lhs, rhs) => {
242 write!(f, "esub ({dst})fp, ({lhs})fp, ({rhs})fp")
243 }
244 AsmInstruction::MulE(dst, lhs, rhs) => {
245 write!(f, "emul ({dst})fp, ({lhs})fp, ({rhs})fp")
246 }
247 AsmInstruction::DivE(dst, lhs, rhs) => {
248 write!(f, "ediv ({dst})fp, ({lhs})fp, ({rhs})fp")
249 }
250 AsmInstruction::Jump(dst, label) => {
251 write!(
252 f,
253 "j ({})fp, {}",
254 dst,
255 labels.get(label).unwrap_or(&format!(".L{label}"))
256 )
257 }
258 AsmInstruction::Bne(label, lhs, rhs) => {
259 write!(
260 f,
261 "bne {}, ({})fp, ({})fp",
262 labels.get(label).unwrap_or(&format!(".L{label}")),
263 lhs,
264 rhs
265 )
266 }
267 AsmInstruction::BneI(label, lhs, rhs) => {
268 write!(
269 f,
270 "bnei {}, ({})fp, {}",
271 labels.get(label).unwrap_or(&format!(".L{label}")),
272 lhs,
273 rhs
274 )
275 }
276 AsmInstruction::Beq(label, lhs, rhs) => {
277 write!(
278 f,
279 "beq {}, ({})fp, ({})fp",
280 labels.get(label).unwrap_or(&format!(".L{label}")),
281 lhs,
282 rhs
283 )
284 }
285 AsmInstruction::BeqI(label, lhs, rhs) => {
286 write!(
287 f,
288 "beqi {}, ({})fp, {}",
289 labels.get(label).unwrap_or(&format!(".L{label}")),
290 lhs,
291 rhs
292 )
293 }
294 AsmInstruction::BneE(label, lhs, rhs) => {
295 write!(
296 f,
297 "ebne {}, ({})fp, ({})fp",
298 labels.get(label).unwrap_or(&format!(".L{label}")),
299 lhs,
300 rhs
301 )
302 }
303 AsmInstruction::BneEI(label, lhs, rhs) => {
304 write!(
305 f,
306 "ebnei {}, ({})fp, {}",
307 labels.get(label).unwrap_or(&format!(".L{label}")),
308 lhs,
309 rhs
310 )
311 }
312 AsmInstruction::BeqE(label, lhs, rhs) => {
313 write!(
314 f,
315 "ebeq {}, ({})fp, ({})fp",
316 labels.get(label).unwrap_or(&format!(".L{label}")),
317 lhs,
318 rhs
319 )
320 }
321 AsmInstruction::BeqEI(label, lhs, rhs) => {
322 write!(
323 f,
324 "ebeqi {}, ({})fp, {}",
325 labels.get(label).unwrap_or(&format!(".L{label}")),
326 lhs,
327 rhs
328 )
329 }
330 AsmInstruction::Trap => write!(f, "trap"),
331 AsmInstruction::Halt => write!(f, "halt"),
332 AsmInstruction::HintBits(src, len) => write!(f, "hint_bits ({src})fp, {len}"),
333 AsmInstruction::Poseidon2Permute(dst, lhs) => {
334 write!(f, "poseidon2_permute ({dst})fp, ({lhs})fp")
335 }
336 AsmInstruction::Poseidon2Compress(result, src1, src2) => {
337 write!(f, "poseidon2_compress ({result})fp, ({src1})fp, ({src2})fp")
338 }
339 AsmInstruction::PrintF(dst) => {
340 write!(f, "print_f ({dst})fp")
341 }
342 AsmInstruction::PrintV(dst) => {
343 write!(f, "print_v ({dst})fp")
344 }
345 AsmInstruction::PrintE(dst) => {
346 write!(f, "print_e ({dst})fp")
347 }
348 AsmInstruction::HintInputVec() => write!(f, "hint_vec"),
349 AsmInstruction::HintFelt() => write!(f, "hint_felt"),
350 AsmInstruction::StoreHintWordI(dst, offset) => {
351 write!(f, "shintw ({dst})fp {offset}")
352 }
353 AsmInstruction::StoreHintExtI(dst, offset) => {
354 write!(f, "shinte ({dst})fp {offset}")
355 }
356 AsmInstruction::HintLoad() => write!(f, "hint_load"),
357 AsmInstruction::Publish(val, index) => {
358 write!(f, "commit ({val})fp ({index})fp")
359 }
360 AsmInstruction::CycleTrackerStart() => {
361 write!(f, "cycle_tracker_start")
362 }
363 AsmInstruction::CycleTrackerEnd() => {
364 write!(f, "cycle_tracker_end")
365 }
366 AsmInstruction::FriReducedOpening(a, b, length, alpha, res, hint_id, is_init) => {
367 write!(
368 f,
369 "fri_mat_opening ({a})fp, ({b})fp, ({length})fp, ({alpha})fp, ({res})fp, ({hint_id})fp, ({is_init})fp"
370 )
371 }
372 AsmInstruction::VerifyBatchFelt(dim, opened, opened_length, sibling, index, commit) => {
373 write!(
374 f,
375 "verify_batch_felt ({dim})fp, ({opened})fp, ({opened_length})fp, ({sibling})fp, ({index})fp, ({commit})fp"
376 )
377 }
378 AsmInstruction::VerifyBatchExt(dim, opened, opened_length, sibling, index, commit) => {
379 write!(
380 f,
381 "verify_batch_ext ({dim})fp, ({opened})fp, ({opened_length})fp, ({sibling})fp, ({index})fp, ({commit})fp"
382 )
383 }
384 AsmInstruction::RangeCheck(fp, lo_bits, hi_bits) => {
385 write!(f, "range_check_fp ({fp})fp, ({lo_bits}), ({hi_bits})")
386 }
387 }
388 }
389}