1use super::operation::*;
2use super::{MediumLevelExpressionIndex, MediumLevelILFunction, MediumLevelInstructionIndex};
3use crate::architecture::CoreIntrinsic;
4use crate::rc::Ref;
5use crate::variable::{ConstantData, SSAVariable, Variable};
6use std::collections::BTreeMap;
7use std::fmt::{Debug, Formatter};
8
9#[derive(Clone, Debug)]
10pub enum MediumLevelILLiftedOperand {
11 ConstantData(ConstantData),
12 Intrinsic(CoreIntrinsic),
13 Expr(MediumLevelILLiftedInstruction),
14 ExprList(Vec<MediumLevelILLiftedInstruction>),
15 Float(f64),
16 Int(u64),
17 IntList(Vec<u64>),
18 TargetMap(BTreeMap<u64, MediumLevelInstructionIndex>),
19 Var(Variable),
20 VarList(Vec<Variable>),
21 VarSsa(SSAVariable),
22 VarSsaList(Vec<SSAVariable>),
23 InstructionIndex(MediumLevelInstructionIndex),
24}
25
26#[derive(Clone, PartialEq)]
27pub struct MediumLevelILLiftedInstruction {
28 pub function: Ref<MediumLevelILFunction>,
29 pub address: u64,
30 pub instr_index: MediumLevelInstructionIndex,
31 pub expr_index: MediumLevelExpressionIndex,
32 pub size: usize,
33 pub kind: MediumLevelILLiftedInstructionKind,
34}
35
36impl Debug for MediumLevelILLiftedInstruction {
37 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
38 f.debug_struct("MediumLevelILLiftedInstruction")
39 .field("address", &self.address)
40 .field("instr_index", &self.instr_index)
41 .field("expr_index", &self.expr_index)
42 .field("size", &self.size)
43 .field("kind", &self.kind)
44 .finish()
45 }
46}
47
48#[derive(Clone, Debug, PartialEq)]
49pub enum MediumLevelILLiftedInstructionKind {
50 Nop,
51 Noret,
52 Bp,
53 Undef,
54 Unimpl,
55 If(LiftedIf),
56 FloatConst(FloatConst),
57 Const(Constant),
58 ConstPtr(Constant),
59 Import(Constant),
60 ExternPtr(ExternPtr),
61 ConstData(LiftedConstData),
62 Jump(LiftedJump),
63 RetHint(LiftedJump),
64 StoreSsa(LiftedStoreSsa),
65 StoreStructSsa(LiftedStoreStructSsa),
66 StoreStruct(LiftedStoreStruct),
67 Store(LiftedStore),
68 JumpTo(LiftedJumpTo),
69 Goto(Goto),
70 FreeVarSlot(FreeVarSlot),
71 SetVarField(LiftedSetVarField),
72 SetVar(LiftedSetVar),
73 FreeVarSlotSsa(FreeVarSlotSsa),
74 SetVarSsaField(LiftedSetVarSsaField),
75 SetVarAliasedField(LiftedSetVarSsaField),
76 SetVarAliased(LiftedSetVarAliased),
77 SetVarSsa(LiftedSetVarSsa),
78 VarPhi(LiftedVarPhi),
79 MemPhi(LiftedMemPhi),
80 VarSplit(VarSplit),
81 SetVarSplit(LiftedSetVarSplit),
82 VarSplitSsa(VarSplitSsa),
83 SetVarSplitSsa(LiftedSetVarSplitSsa),
84 Add(LiftedBinaryOp),
85 Sub(LiftedBinaryOp),
86 And(LiftedBinaryOp),
87 Or(LiftedBinaryOp),
88 Xor(LiftedBinaryOp),
89 Lsl(LiftedBinaryOp),
90 Lsr(LiftedBinaryOp),
91 Asr(LiftedBinaryOp),
92 Rol(LiftedBinaryOp),
93 Ror(LiftedBinaryOp),
94 Mul(LiftedBinaryOp),
95 MuluDp(LiftedBinaryOp),
96 MulsDp(LiftedBinaryOp),
97 Divu(LiftedBinaryOp),
98 DivuDp(LiftedBinaryOp),
99 Divs(LiftedBinaryOp),
100 DivsDp(LiftedBinaryOp),
101 Modu(LiftedBinaryOp),
102 ModuDp(LiftedBinaryOp),
103 Mods(LiftedBinaryOp),
104 ModsDp(LiftedBinaryOp),
105 MinSigned(LiftedBinaryOp),
106 MaxSigned(LiftedBinaryOp),
107 MinUnsigned(LiftedBinaryOp),
108 MaxUnsigned(LiftedBinaryOp),
109 CmpE(LiftedBinaryOp),
110 CmpNe(LiftedBinaryOp),
111 CmpSlt(LiftedBinaryOp),
112 CmpUlt(LiftedBinaryOp),
113 CmpSle(LiftedBinaryOp),
114 CmpUle(LiftedBinaryOp),
115 CmpSge(LiftedBinaryOp),
116 CmpUge(LiftedBinaryOp),
117 CmpSgt(LiftedBinaryOp),
118 CmpUgt(LiftedBinaryOp),
119 TestBit(LiftedBinaryOp),
120 AddOverflow(LiftedBinaryOp),
121 FcmpE(LiftedBinaryOp),
122 FcmpNe(LiftedBinaryOp),
123 FcmpLt(LiftedBinaryOp),
124 FcmpLe(LiftedBinaryOp),
125 FcmpGe(LiftedBinaryOp),
126 FcmpGt(LiftedBinaryOp),
127 FcmpO(LiftedBinaryOp),
128 FcmpUo(LiftedBinaryOp),
129 Fadd(LiftedBinaryOp),
130 Fsub(LiftedBinaryOp),
131 Fmul(LiftedBinaryOp),
132 Fdiv(LiftedBinaryOp),
133 Adc(LiftedBinaryOpCarry),
134 Sbb(LiftedBinaryOpCarry),
135 Rlc(LiftedBinaryOpCarry),
136 Rrc(LiftedBinaryOpCarry),
137 Call(LiftedCall),
138 CallOutput(LiftedCallOutput),
139 CallParam(LiftedCallParam),
140 CallOutputSsa(LiftedCallOutputSsa),
141 CallParamSsa(LiftedCallParamSsa),
142 Tailcall(LiftedCall),
143 Intrinsic(LiftedIntrinsic),
144 Syscall(LiftedSyscallCall),
145 IntrinsicSsa(LiftedIntrinsicSsa),
146 MemoryIntrinsicSsa(LiftedMemoryIntrinsicSsa),
147 MemoryIntrinsicOutputSsa(LiftedMemoryIntrinsicOutputSsa),
148 CallSsa(LiftedCallSsa),
149 TailcallSsa(LiftedCallSsa),
150 CallUntypedSsa(LiftedCallUntypedSsa),
151 TailcallUntypedSsa(LiftedCallUntypedSsa),
152 SyscallSsa(LiftedSyscallSsa),
153 SyscallUntypedSsa(LiftedSyscallUntypedSsa),
154 CallUntyped(LiftedCallUntyped),
155 TailcallUntyped(LiftedCallUntyped),
156 SyscallUntyped(LiftedSyscallUntyped),
157 SeparateParamList(LiftedSeparateParamList),
158 SharedParamSlot(LiftedSharedParamSlot),
159 Neg(LiftedUnaryOp),
160 Not(LiftedUnaryOp),
161 Bswap(LiftedUnaryOp),
162 Popcnt(LiftedUnaryOp),
163 Clz(LiftedUnaryOp),
164 Ctz(LiftedUnaryOp),
165 Rbit(LiftedUnaryOp),
166 Cls(LiftedUnaryOp),
167 Abs(LiftedUnaryOp),
168 Sx(LiftedUnaryOp),
169 Zx(LiftedUnaryOp),
170 LowPart(LiftedUnaryOp),
171 BoolToInt(LiftedUnaryOp),
172 UnimplMem(LiftedUnaryOp),
173 Fsqrt(LiftedUnaryOp),
174 Fneg(LiftedUnaryOp),
175 Fabs(LiftedUnaryOp),
176 FloatToInt(LiftedUnaryOp),
177 IntToFloat(LiftedUnaryOp),
178 FloatConv(LiftedUnaryOp),
179 RoundToInt(LiftedUnaryOp),
180 Floor(LiftedUnaryOp),
181 Ceil(LiftedUnaryOp),
182 Ftrunc(LiftedUnaryOp),
183 Load(LiftedUnaryOp),
184 LoadStruct(LiftedLoadStruct),
185 LoadStructSsa(LiftedLoadStructSsa),
186 LoadSsa(LiftedLoadSsa),
187 Ret(LiftedRet),
188 Var(Var),
189 VarOutput(VarOutput),
190 VarOutputField(VarOutputField),
191 StoreOutput(LiftedStoreOutput),
192 AddressOf(Var),
193 PassByRef(LiftedUnaryOp),
194 ReturnByRef(LiftedUnaryOp),
195 VarField(Field),
196 AddressOfField(Field),
197 VarSsa(VarSsa),
198 VarAliased(VarSsa),
199 VarSsaField(VarSsaField),
200 VarAliasedField(VarSsaField),
201 VarOutputSsa(VarOutputSsa),
202 VarOutputSsaField(VarOutputSsaField),
203 VarOutputAliased(VarOutputAliased),
204 VarOutputAliasedField(VarOutputAliasedField),
205 Trap(Trap),
206 BlockToExpand(LiftedBlockToExpand),
207 NotYetImplemented,
210}
211
212impl MediumLevelILLiftedInstruction {
213 pub fn name(&self) -> &'static str {
214 use MediumLevelILLiftedInstructionKind::*;
215 match self.kind {
216 Nop => "Nop",
217 Noret => "Noret",
218 Bp => "Bp",
219 Undef => "Undef",
220 Unimpl => "Unimpl",
221 NotYetImplemented => "NotYetImplemented",
222 If(_) => "If",
223 FloatConst(_) => "FloatConst",
224 Const(_) => "Const",
225 ConstPtr(_) => "ConstPtr",
226 Import(_) => "Import",
227 ExternPtr(_) => "ExternPtr",
228 ConstData(_) => "ConstData",
229 Jump(_) => "Jump",
230 RetHint(_) => "RetHint",
231 StoreSsa(_) => "StoreSsa",
232 StoreStructSsa(_) => "StoreStructSsa",
233 StoreStruct(_) => "StoreStruct",
234 Store(_) => "Store",
235 JumpTo(_) => "JumpTo",
236 Goto(_) => "Goto",
237 FreeVarSlot(_) => "FreeVarSlot",
238 SetVarField(_) => "SetVarField",
239 SetVar(_) => "SetVar",
240 FreeVarSlotSsa(_) => "FreeVarSlotSsa",
241 SetVarSsaField(_) => "SetVarSsaField",
242 SetVarAliasedField(_) => "SetVarAliasedField",
243 SetVarAliased(_) => "SetVarAliased",
244 SetVarSsa(_) => "SetVarSsa",
245 VarPhi(_) => "VarPhi",
246 MemPhi(_) => "MemPhi",
247 VarSplit(_) => "VarSplit",
248 SetVarSplit(_) => "SetVarSplit",
249 VarSplitSsa(_) => "VarSplitSsa",
250 SetVarSplitSsa(_) => "SetVarSplitSsa",
251 Add(_) => "Add",
252 Sub(_) => "Sub",
253 And(_) => "And",
254 Or(_) => "Or",
255 Xor(_) => "Xor",
256 Lsl(_) => "Lsl",
257 Lsr(_) => "Lsr",
258 Asr(_) => "Asr",
259 Rol(_) => "Rol",
260 Ror(_) => "Ror",
261 Mul(_) => "Mul",
262 MuluDp(_) => "MuluDp",
263 MulsDp(_) => "MulsDp",
264 Divu(_) => "Divu",
265 DivuDp(_) => "DivuDp",
266 Divs(_) => "Divs",
267 DivsDp(_) => "DivsDp",
268 Modu(_) => "Modu",
269 ModuDp(_) => "ModuDp",
270 Mods(_) => "Mods",
271 ModsDp(_) => "ModsDp",
272 MinSigned(_) => "MinSigned",
273 MaxSigned(_) => "MaxSigned",
274 MinUnsigned(_) => "MinUnsigned",
275 MaxUnsigned(_) => "MaxUnsigned",
276 CmpE(_) => "CmpE",
277 CmpNe(_) => "CmpNe",
278 CmpSlt(_) => "CmpSlt",
279 CmpUlt(_) => "CmpUlt",
280 CmpSle(_) => "CmpSle",
281 CmpUle(_) => "CmpUle",
282 CmpSge(_) => "CmpSge",
283 CmpUge(_) => "CmpUge",
284 CmpSgt(_) => "CmpSgt",
285 CmpUgt(_) => "CmpUgt",
286 TestBit(_) => "TestBit",
287 AddOverflow(_) => "AddOverflow",
288 FcmpE(_) => "FcmpE",
289 FcmpNe(_) => "FcmpNe",
290 FcmpLt(_) => "FcmpLt",
291 FcmpLe(_) => "FcmpLe",
292 FcmpGe(_) => "FcmpGe",
293 FcmpGt(_) => "FcmpGt",
294 FcmpO(_) => "FcmpO",
295 FcmpUo(_) => "FcmpUo",
296 Fadd(_) => "Fadd",
297 Fsub(_) => "Fsub",
298 Fmul(_) => "Fmul",
299 Fdiv(_) => "Fdiv",
300 Adc(_) => "Adc",
301 Sbb(_) => "Sbb",
302 Rlc(_) => "Rlc",
303 Rrc(_) => "Rrc",
304 Call(_) => "Call",
305 CallOutput(_) => "CallOutput",
306 CallParam(_) => "CallParam",
307 CallOutputSsa(_) => "CallOutputSsa",
308 CallParamSsa(_) => "CallParamSsa",
309 Tailcall(_) => "Tailcall",
310 Syscall(_) => "Syscall",
311 Intrinsic(_) => "Intrinsic",
312 IntrinsicSsa(_) => "IntrinsicSsa",
313 MemoryIntrinsicSsa(_) => "MemoryIntrinsicSsa",
314 MemoryIntrinsicOutputSsa(_) => "MemoryIntrinsicOutputSsa",
315 CallSsa(_) => "CallSsa",
316 TailcallSsa(_) => "TailcallSsa",
317 CallUntypedSsa(_) => "CallUntypedSsa",
318 TailcallUntypedSsa(_) => "TailcallUntypedSsa",
319 SyscallSsa(_) => "SyscallSsa",
320 SyscallUntypedSsa(_) => "SyscallUntypedSsa",
321 CallUntyped(_) => "CallUntyped",
322 TailcallUntyped(_) => "TailcallUntyped",
323 SyscallUntyped(_) => "SyscallUntyped",
324 SeparateParamList(_) => "SeparateParamList",
325 SharedParamSlot(_) => "SharedParamSlot",
326 VarOutput(_) => "VarOutput",
327 VarOutputField(_) => "VarOutputField",
328 StoreOutput(_) => "StoreOutput",
329 Neg(_) => "Neg",
330 Not(_) => "Not",
331 Bswap(_) => "Bswap",
332 Popcnt(_) => "Popcnt",
333 Clz(_) => "Clz",
334 Ctz(_) => "Ctz",
335 Rbit(_) => "Rbit",
336 Cls(_) => "Cls",
337 Abs(_) => "Abs",
338 Sx(_) => "Sx",
339 Zx(_) => "Zx",
340 LowPart(_) => "LowPart",
341 BoolToInt(_) => "BoolToInt",
342 UnimplMem(_) => "UnimplMem",
343 Fsqrt(_) => "Fsqrt",
344 Fneg(_) => "Fneg",
345 Fabs(_) => "Fabs",
346 FloatToInt(_) => "FloatToInt",
347 IntToFloat(_) => "IntToFloat",
348 FloatConv(_) => "FloatConv",
349 RoundToInt(_) => "RoundToInt",
350 Floor(_) => "Floor",
351 Ceil(_) => "Ceil",
352 Ftrunc(_) => "Ftrunc",
353 Load(_) => "Load",
354 LoadStruct(_) => "LoadStruct",
355 LoadStructSsa(_) => "LoadStructSsa",
356 LoadSsa(_) => "LoadSsa",
357 Ret(_) => "Ret",
358 Var(_) => "Var",
359 AddressOf(_) => "AddressOf",
360 PassByRef(_) => "PassByRef",
361 ReturnByRef(_) => "ReturnByRef",
362 VarField(_) => "VarField",
363 AddressOfField(_) => "AddressOfField",
364 VarSsa(_) => "VarSsa",
365 VarAliased(_) => "VarAliased",
366 VarSsaField(_) => "VarSsaField",
367 VarAliasedField(_) => "VarAliasedField",
368 VarOutputSsa(_) => "VarOutputSsa",
369 VarOutputSsaField(_) => "VarOutputSsaField",
370 VarOutputAliased(_) => "VarOutputAliased",
371 VarOutputAliasedField(_) => "VarOutputAliasedField",
372 Trap(_) => "Trap",
373 BlockToExpand(_) => "BlockToExpand",
374 }
375 }
376
377 pub fn operands(&self) -> Vec<(&'static str, MediumLevelILLiftedOperand)> {
378 use MediumLevelILLiftedInstructionKind::*;
379 use MediumLevelILLiftedOperand as Operand;
380 match &self.kind {
381 Nop | Noret | Bp | Undef | Unimpl | NotYetImplemented => vec![],
382 If(op) => vec![
383 ("condition", Operand::Expr(*op.condition.clone())),
384 ("dest_true", Operand::InstructionIndex(op.dest_true)),
385 ("dest_false", Operand::InstructionIndex(op.dest_false)),
386 ],
387 FloatConst(op) => vec![("constant", Operand::Float(op.constant))],
388 Const(op) | ConstPtr(op) | Import(op) => vec![("constant", Operand::Int(op.constant))],
389 ExternPtr(op) => vec![
390 ("constant", Operand::Int(op.constant)),
391 ("offset", Operand::Int(op.offset)),
392 ],
393 ConstData(op) => vec![(
394 "constant_data",
395 Operand::ConstantData(op.constant_data.clone()),
396 )],
397 Jump(op) | RetHint(op) => vec![("dest", Operand::Expr(*op.dest.clone()))],
398 StoreSsa(op) => vec![
399 ("dest", Operand::Expr(*op.dest.clone())),
400 ("dest_memory", Operand::Int(op.dest_memory)),
401 ("src_memory", Operand::Int(op.src_memory)),
402 ("src", Operand::Expr(*op.src.clone())),
403 ],
404 StoreStructSsa(op) => vec![
405 ("dest", Operand::Expr(*op.dest.clone())),
406 ("offset", Operand::Int(op.offset)),
407 ("dest_memory", Operand::Int(op.dest_memory)),
408 ("src_memory", Operand::Int(op.src_memory)),
409 ("src", Operand::Expr(*op.src.clone())),
410 ],
411 StoreStruct(op) => vec![
412 ("dest", Operand::Expr(*op.dest.clone())),
413 ("offset", Operand::Int(op.offset)),
414 ("src", Operand::Expr(*op.src.clone())),
415 ],
416 Store(op) => vec![
417 ("dest", Operand::Expr(*op.dest.clone())),
418 ("src", Operand::Expr(*op.src.clone())),
419 ],
420 JumpTo(op) => vec![
421 ("dest", Operand::Expr(*op.dest.clone())),
422 ("targets", Operand::TargetMap(op.targets.clone())),
423 ],
424 Goto(op) => vec![("dest", Operand::InstructionIndex(op.dest))],
425 FreeVarSlot(op) => vec![("dest", Operand::Var(op.dest))],
426 SetVarField(op) => vec![
427 ("dest", Operand::Var(op.dest)),
428 ("offset", Operand::Int(op.offset)),
429 ("src", Operand::Expr(*op.src.clone())),
430 ],
431 SetVar(op) => vec![
432 ("dest", Operand::Var(op.dest)),
433 ("src", Operand::Expr(*op.src.clone())),
434 ],
435 FreeVarSlotSsa(op) => vec![
436 ("dest", Operand::VarSsa(op.dest)),
437 ("prev", Operand::VarSsa(op.prev)),
438 ],
439 SetVarSsaField(op) | SetVarAliasedField(op) => vec![
440 ("dest", Operand::VarSsa(op.dest)),
441 ("prev", Operand::VarSsa(op.prev)),
442 ("offset", Operand::Int(op.offset)),
443 ("src", Operand::Expr(*op.src.clone())),
444 ],
445 SetVarAliased(op) => vec![
446 ("dest", Operand::VarSsa(op.dest)),
447 ("prev", Operand::VarSsa(op.prev)),
448 ("src", Operand::Expr(*op.src.clone())),
449 ],
450 SetVarSsa(op) => vec![
451 ("dest", Operand::VarSsa(op.dest)),
452 ("src", Operand::Expr(*op.src.clone())),
453 ],
454 VarPhi(op) => vec![
455 ("dest", Operand::VarSsa(op.dest)),
456 ("src", Operand::VarSsaList(op.src.clone())),
457 ],
458 MemPhi(op) => vec![
459 ("dest_memory", Operand::Int(op.dest_memory)),
460 ("src_memory", Operand::IntList(op.src_memory.clone())),
461 ],
462 VarSplit(op) => vec![
463 ("high", Operand::Var(op.high)),
464 ("low", Operand::Var(op.low)),
465 ],
466 SetVarSplit(op) => vec![
467 ("high", Operand::Var(op.high)),
468 ("low", Operand::Var(op.low)),
469 ("src", Operand::Expr(*op.src.clone())),
470 ],
471 VarSplitSsa(op) => vec![
472 ("high", Operand::VarSsa(op.high)),
473 ("low", Operand::VarSsa(op.low)),
474 ],
475 SetVarSplitSsa(op) => vec![
476 ("high", Operand::VarSsa(op.high)),
477 ("low", Operand::VarSsa(op.low)),
478 ("src", Operand::Expr(*op.src.clone())),
479 ],
480 Add(op) | Sub(op) | And(op) | Or(op) | Xor(op) | Lsl(op) | Lsr(op) | Asr(op)
481 | Rol(op) | Ror(op) | Mul(op) | MuluDp(op) | MulsDp(op) | Divu(op) | DivuDp(op)
482 | Divs(op) | DivsDp(op) | Modu(op) | ModuDp(op) | Mods(op) | ModsDp(op)
483 | MinSigned(op) | MaxSigned(op) | MinUnsigned(op) | MaxUnsigned(op) | CmpE(op)
484 | CmpNe(op) | CmpSlt(op) | CmpUlt(op) | CmpSle(op) | CmpUle(op) | CmpSge(op)
485 | CmpUge(op) | CmpSgt(op) | CmpUgt(op) | TestBit(op) | AddOverflow(op) | FcmpE(op)
486 | FcmpNe(op) | FcmpLt(op) | FcmpLe(op) | FcmpGe(op) | FcmpGt(op) | FcmpO(op)
487 | FcmpUo(op) | Fadd(op) | Fsub(op) | Fmul(op) | Fdiv(op) => vec![
488 ("left", Operand::Expr(*op.left.clone())),
489 ("right", Operand::Expr(*op.right.clone())),
490 ],
491 Adc(op) | Sbb(op) | Rlc(op) | Rrc(op) => vec![
492 ("left", Operand::Expr(*op.left.clone())),
493 ("right", Operand::Expr(*op.right.clone())),
494 ("carry", Operand::Expr(*op.carry.clone())),
495 ],
496 Call(op) | Tailcall(op) => vec![
497 ("output", Operand::ExprList(op.output.clone())),
498 ("dest", Operand::Expr(*op.dest.clone())),
499 ("params", Operand::ExprList(op.params.clone())),
500 ],
501 CallOutput(op) => vec![("output", Operand::VarList(op.output.clone()))],
502 CallParam(op) => vec![("params", Operand::ExprList(op.params.clone()))],
503 CallOutputSsa(op) => vec![
504 ("output", Operand::VarSsaList(op.output.clone())),
505 ("dest_memory", Operand::Int(op.dest_memory)),
506 ],
507 CallParamSsa(op) => vec![
508 ("params", Operand::ExprList(op.params.clone())),
509 ("src_memory", Operand::Int(op.src_memory)),
510 ],
511 Syscall(op) => vec![
512 ("output", Operand::ExprList(op.output.clone())),
513 ("params", Operand::ExprList(op.params.clone())),
514 ],
515 Intrinsic(op) => vec![
516 ("output", Operand::VarList(op.output.clone())),
517 ("intrinsic", Operand::Intrinsic(op.intrinsic)),
518 ("params", Operand::ExprList(op.params.clone())),
519 ],
520 IntrinsicSsa(op) => vec![
521 ("output", Operand::VarSsaList(op.output.clone())),
522 ("intrinsic", Operand::Intrinsic(op.intrinsic)),
523 ("params", Operand::ExprList(op.params.clone())),
524 ],
525 MemoryIntrinsicSsa(op) => vec![
526 ("output", Operand::Expr(*op.output.clone())),
527 ("intrinsic", Operand::Intrinsic(op.intrinsic)),
528 ("params", Operand::ExprList(op.params.clone())),
529 ("src_memory", Operand::Int(op.src_memory)),
530 ],
531 MemoryIntrinsicOutputSsa(op) => vec![
532 ("dest_memory", Operand::Int(op.dest_memory)),
533 ("output", Operand::VarSsaList(op.output.clone())),
534 ],
535 CallSsa(op) | TailcallSsa(op) => vec![
536 ("output", Operand::ExprList(op.output.clone())),
537 ("dest", Operand::Expr(*op.dest.clone())),
538 ("params", Operand::ExprList(op.params.clone())),
539 ("src_memory", Operand::Int(op.src_memory)),
540 ],
541 CallUntypedSsa(op) | TailcallUntypedSsa(op) => vec![
542 ("output", Operand::ExprList(op.output.clone())),
543 ("dest", Operand::Expr(*op.dest.clone())),
544 ("params", Operand::ExprList(op.params.clone())),
545 ("stack", Operand::Expr(*op.stack.clone())),
546 ],
547 SyscallSsa(op) => vec![
548 ("output", Operand::ExprList(op.output.clone())),
549 ("params", Operand::ExprList(op.params.clone())),
550 ("src_memory", Operand::Int(op.src_memory)),
551 ],
552 SyscallUntypedSsa(op) => vec![
553 ("output", Operand::ExprList(op.output.clone())),
554 ("params", Operand::ExprList(op.params.clone())),
555 ("stack", Operand::Expr(*op.stack.clone())),
556 ],
557 CallUntyped(op) | TailcallUntyped(op) => vec![
558 ("output", Operand::ExprList(op.output.clone())),
559 ("dest", Operand::Expr(*op.dest.clone())),
560 ("params", Operand::ExprList(op.params.clone())),
561 ("stack", Operand::Expr(*op.stack.clone())),
562 ],
563 SyscallUntyped(op) => vec![
564 ("output", Operand::ExprList(op.output.clone())),
565 ("params", Operand::ExprList(op.params.clone())),
566 ("stack", Operand::Expr(*op.stack.clone())),
567 ],
568 Neg(op) | Not(op) | Bswap(op) | Popcnt(op) | Clz(op) | Ctz(op) | Rbit(op) | Cls(op)
569 | Abs(op) | Sx(op) | Zx(op) | LowPart(op) | BoolToInt(op) | UnimplMem(op)
570 | Fsqrt(op) | Fneg(op) | Fabs(op) | FloatToInt(op) | IntToFloat(op) | FloatConv(op)
571 | RoundToInt(op) | Floor(op) | Ceil(op) | Ftrunc(op) | Load(op) => {
572 vec![("src", Operand::Expr(*op.src.clone()))]
573 }
574 LoadStruct(op) => vec![
575 ("src", Operand::Expr(*op.src.clone())),
576 ("offset", Operand::Int(op.offset)),
577 ],
578 LoadStructSsa(op) => vec![
579 ("src", Operand::Expr(*op.src.clone())),
580 ("offset", Operand::Int(op.offset)),
581 ("src_memory", Operand::Int(op.src_memory)),
582 ],
583 LoadSsa(op) => vec![
584 ("src", Operand::Expr(*op.src.clone())),
585 ("src_memory", Operand::Int(op.src_memory)),
586 ],
587 Ret(op) => vec![("src", Operand::ExprList(op.src.clone()))],
588 SeparateParamList(op) => vec![("params", Operand::ExprList(op.params.clone()))],
589 SharedParamSlot(op) => vec![("params", Operand::ExprList(op.params.clone()))],
590 Var(op) | AddressOf(op) => vec![("src", Operand::Var(op.src))],
591 VarOutput(op) => vec![("dest", Operand::Var(op.dest))],
592 VarOutputField(op) => vec![
593 ("dest", Operand::Var(op.dest)),
594 ("offset", Operand::Int(op.offset)),
595 ],
596 StoreOutput(op) => vec![("dest", Operand::Expr(*op.dest.clone()))],
597 PassByRef(op) => vec![("src", Operand::Expr(*op.src.clone()))],
598 ReturnByRef(op) => vec![("src", Operand::Expr(*op.src.clone()))],
599 VarField(op) | AddressOfField(op) => vec![
600 ("src", Operand::Var(op.src)),
601 ("offset", Operand::Int(op.offset)),
602 ],
603 VarSsa(op) | VarAliased(op) => vec![("src", Operand::VarSsa(op.src))],
604 VarSsaField(op) | VarAliasedField(op) => vec![
605 ("src", Operand::VarSsa(op.src)),
606 ("offset", Operand::Int(op.offset)),
607 ],
608 VarOutputSsa(op) => vec![("dest", Operand::VarSsa(op.dest))],
609 VarOutputSsaField(op) => vec![
610 ("dest", Operand::VarSsa(op.dest)),
611 ("prev", Operand::VarSsa(op.prev)),
612 ("offset", Operand::Int(op.offset)),
613 ],
614 VarOutputAliased(op) => vec![
615 ("dest", Operand::VarSsa(op.dest)),
616 ("prev", Operand::VarSsa(op.prev)),
617 ],
618 VarOutputAliasedField(op) => vec![
619 ("dest", Operand::VarSsa(op.dest)),
620 ("prev", Operand::VarSsa(op.prev)),
621 ("offset", Operand::Int(op.offset)),
622 ],
623 Trap(op) => vec![("vector", Operand::Int(op.vector))],
624 BlockToExpand(op) => vec![("exprs", Operand::ExprList(op.exprs.clone()))],
625 }
626 }
627}