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