Skip to main content

binaryninja/high_level_il/
lift.rs

1use super::operation::*;
2use super::{HighLevelExpressionIndex, HighLevelILFunction, HighLevelInstructionIndex};
3use std::fmt::{Debug, Formatter};
4
5use crate::architecture::CoreIntrinsic;
6use crate::rc::Ref;
7use crate::variable::{ConstantData, PossibleValueSet, SSAVariable, Variable};
8
9#[derive(Clone, Debug)]
10pub enum HighLevelILLiftedOperand {
11    ConstantData(ConstantData),
12    Expr(HighLevelILLiftedInstruction),
13    ExprList(Vec<HighLevelILLiftedInstruction>),
14    Float(f64),
15    Int(u64),
16    IntList(Vec<u64>),
17    Intrinsic(CoreIntrinsic),
18    Label(GotoLabel),
19    MemberIndex(Option<usize>),
20    PossibleValueSet(PossibleValueSet),
21    Var(Variable),
22    VarSsa(SSAVariable),
23    VarSsaList(Vec<SSAVariable>),
24}
25
26// TODO: UGH, if your gonna call it expr_idx, call the instruction and expression!!!!!
27// TODO: We dont even need to say instruction in the type!
28// TODO: IF you want to have an instruction type, there needs to be a separate expression type
29// TODO: See the lowlevelil module.
30#[derive(Clone, PartialEq)]
31pub struct HighLevelILLiftedInstruction {
32    pub function: Ref<HighLevelILFunction>,
33    pub address: u64,
34    pub instr_index: HighLevelInstructionIndex,
35    pub expr_index: HighLevelExpressionIndex,
36    pub size: usize,
37    pub kind: HighLevelILLiftedInstructionKind,
38}
39
40#[derive(Clone, Debug, PartialEq)]
41pub enum HighLevelILLiftedInstructionKind {
42    Nop,
43    Break,
44    Continue,
45    Noret,
46    Unreachable,
47    Bp,
48    Undef,
49    Unimpl,
50    Adc(LiftedBinaryOpCarry),
51    Sbb(LiftedBinaryOpCarry),
52    Rlc(LiftedBinaryOpCarry),
53    Rrc(LiftedBinaryOpCarry),
54    Add(LiftedBinaryOp),
55    Sub(LiftedBinaryOp),
56    And(LiftedBinaryOp),
57    Or(LiftedBinaryOp),
58    Xor(LiftedBinaryOp),
59    Lsl(LiftedBinaryOp),
60    Lsr(LiftedBinaryOp),
61    Asr(LiftedBinaryOp),
62    Rol(LiftedBinaryOp),
63    Ror(LiftedBinaryOp),
64    Mul(LiftedBinaryOp),
65    MuluDp(LiftedBinaryOp),
66    MulsDp(LiftedBinaryOp),
67    Divu(LiftedBinaryOp),
68    DivuDp(LiftedBinaryOp),
69    Divs(LiftedBinaryOp),
70    DivsDp(LiftedBinaryOp),
71    Modu(LiftedBinaryOp),
72    ModuDp(LiftedBinaryOp),
73    Mods(LiftedBinaryOp),
74    ModsDp(LiftedBinaryOp),
75    MinSigned(LiftedBinaryOp),
76    MaxSigned(LiftedBinaryOp),
77    MinUnsigned(LiftedBinaryOp),
78    MaxUnsigned(LiftedBinaryOp),
79    CmpE(LiftedBinaryOp),
80    CmpNe(LiftedBinaryOp),
81    CmpSlt(LiftedBinaryOp),
82    CmpUlt(LiftedBinaryOp),
83    CmpSle(LiftedBinaryOp),
84    CmpUle(LiftedBinaryOp),
85    CmpSge(LiftedBinaryOp),
86    CmpUge(LiftedBinaryOp),
87    CmpSgt(LiftedBinaryOp),
88    CmpUgt(LiftedBinaryOp),
89    TestBit(LiftedBinaryOp),
90    AddOverflow(LiftedBinaryOp),
91    Fadd(LiftedBinaryOp),
92    Fsub(LiftedBinaryOp),
93    Fmul(LiftedBinaryOp),
94    Fdiv(LiftedBinaryOp),
95    FcmpE(LiftedBinaryOp),
96    FcmpNe(LiftedBinaryOp),
97    FcmpLt(LiftedBinaryOp),
98    FcmpLe(LiftedBinaryOp),
99    FcmpGe(LiftedBinaryOp),
100    FcmpGt(LiftedBinaryOp),
101    FcmpO(LiftedBinaryOp),
102    FcmpUo(LiftedBinaryOp),
103    ArrayIndex(LiftedArrayIndex),
104    ArrayIndexSsa(LiftedArrayIndexSsa),
105    Assert(LiftedAssert),
106    AssertSsa(LiftedAssertSsa),
107    Assign(LiftedAssign),
108    AssignMemSsa(LiftedAssignMemSsa),
109    AssignUnpack(LiftedAssignUnpack),
110    AssignUnpackMemSsa(LiftedAssignUnpackMemSsa),
111    Block(LiftedBlock),
112    Call(LiftedCall),
113    Tailcall(LiftedCall),
114    CallSsa(LiftedCallSsa),
115    Case(LiftedCase),
116    Const(Const),
117    ConstPtr(Const),
118    Import(Const),
119    ConstData(LiftedConstData),
120    Deref(LiftedUnaryOp),
121    AddressOf(LiftedUnaryOp),
122    PassByRef(LiftedUnaryOp),
123    ReturnByRef(LiftedUnaryOp),
124    Neg(LiftedUnaryOp),
125    Not(LiftedUnaryOp),
126    Bswap(LiftedUnaryOp),
127    Popcnt(LiftedUnaryOp),
128    Clz(LiftedUnaryOp),
129    Ctz(LiftedUnaryOp),
130    Rbit(LiftedUnaryOp),
131    Cls(LiftedUnaryOp),
132    Abs(LiftedUnaryOp),
133    Sx(LiftedUnaryOp),
134    Zx(LiftedUnaryOp),
135    LowPart(LiftedUnaryOp),
136    BoolToInt(LiftedUnaryOp),
137    UnimplMem(LiftedUnaryOp),
138    Fsqrt(LiftedUnaryOp),
139    Fneg(LiftedUnaryOp),
140    Fabs(LiftedUnaryOp),
141    FloatToInt(LiftedUnaryOp),
142    IntToFloat(LiftedUnaryOp),
143    FloatConv(LiftedUnaryOp),
144    RoundToInt(LiftedUnaryOp),
145    Floor(LiftedUnaryOp),
146    Ceil(LiftedUnaryOp),
147    Ftrunc(LiftedUnaryOp),
148    DerefFieldSsa(LiftedDerefFieldSsa),
149    DerefSsa(LiftedDerefSsa),
150    ExternPtr(ExternPtr),
151    FloatConst(FloatConst),
152    For(LiftedForLoop),
153    ForSsa(LiftedForLoopSsa),
154    ForceVer(ForceVer),
155    ForceVerSsa(ForceVerSsa),
156    Goto(LiftedLabel),
157    Label(LiftedLabel),
158    If(LiftedIf),
159    Intrinsic(LiftedIntrinsic),
160    IntrinsicSsa(LiftedIntrinsicSsa),
161    Jump(LiftedJump),
162    MemPhi(LiftedMemPhi),
163    Ret(LiftedRet),
164    Split(LiftedSplit),
165    StructField(LiftedStructField),
166    DerefField(LiftedStructField),
167    StructInit(LiftedStructInit),
168    StructInitField(LiftedStructField),
169    Switch(LiftedSwitch),
170    Syscall(LiftedSyscall),
171    SyscallSsa(LiftedSyscallSsa),
172    Trap(Trap),
173    VarDeclare(Var),
174    Var(Var),
175    VarInit(LiftedVarInit),
176    VarInitSsa(LiftedVarInitSsa),
177    VarPhi(LiftedVarPhi),
178    VarSsa(VarSsa),
179    VarSsaPartial(VarSsaPartial),
180    While(LiftedWhile),
181    DoWhile(LiftedWhile),
182    WhileSsa(LiftedWhileSsa),
183    DoWhileSsa(LiftedWhileSsa),
184}
185
186impl HighLevelILLiftedInstruction {
187    pub fn name(&self) -> &'static str {
188        use HighLevelILLiftedInstructionKind::*;
189        match self.kind {
190            Nop => "Nop",
191            Break => "Break",
192            Continue => "Continue",
193            Noret => "Noret",
194            Unreachable => "Unreachable",
195            Bp => "Bp",
196            Undef => "Undef",
197            Unimpl => "Unimpl",
198            Adc(_) => "Adc",
199            Sbb(_) => "Sbb",
200            Rlc(_) => "Rlc",
201            Rrc(_) => "Rrc",
202            Add(_) => "Add",
203            Sub(_) => "Sub",
204            And(_) => "And",
205            Or(_) => "Or",
206            Xor(_) => "Xor",
207            Lsl(_) => "Lsl",
208            Lsr(_) => "Lsr",
209            Asr(_) => "Asr",
210            Rol(_) => "Rol",
211            Ror(_) => "Ror",
212            Mul(_) => "Mul",
213            MuluDp(_) => "MuluDp",
214            MulsDp(_) => "MulsDp",
215            Divu(_) => "Divu",
216            DivuDp(_) => "DivuDp",
217            Divs(_) => "Divs",
218            DivsDp(_) => "DivsDp",
219            Modu(_) => "Modu",
220            ModuDp(_) => "ModuDp",
221            Mods(_) => "Mods",
222            ModsDp(_) => "ModsDp",
223            MinSigned(_) => "MinSigned",
224            MaxSigned(_) => "MaxSigned",
225            MinUnsigned(_) => "MinUnsigned",
226            MaxUnsigned(_) => "MaxUnsigned",
227            CmpE(_) => "CmpE",
228            CmpNe(_) => "CmpNe",
229            CmpSlt(_) => "CmpSlt",
230            CmpUlt(_) => "CmpUlt",
231            CmpSle(_) => "CmpSle",
232            CmpUle(_) => "CmpUle",
233            CmpSge(_) => "CmpSge",
234            CmpUge(_) => "CmpUge",
235            CmpSgt(_) => "CmpSgt",
236            CmpUgt(_) => "CmpUgt",
237            TestBit(_) => "TestBit",
238            AddOverflow(_) => "AddOverflow",
239            Fadd(_) => "Fadd",
240            Fsub(_) => "Fsub",
241            Fmul(_) => "Fmul",
242            Fdiv(_) => "Fdiv",
243            FcmpE(_) => "FcmpE",
244            FcmpNe(_) => "FcmpNe",
245            FcmpLt(_) => "FcmpLt",
246            FcmpLe(_) => "FcmpLe",
247            FcmpGe(_) => "FcmpGe",
248            FcmpGt(_) => "FcmpGt",
249            FcmpO(_) => "FcmpO",
250            FcmpUo(_) => "FcmpUo",
251            ArrayIndex(_) => "ArrayIndex",
252            ArrayIndexSsa(_) => "ArrayIndexSsa",
253            Assert(_) => "Assert",
254            AssertSsa(_) => "AssertSsa",
255            Assign(_) => "Assign",
256            AssignMemSsa(_) => "AssignMemSsa",
257            AssignUnpack(_) => "AssignUnpack",
258            AssignUnpackMemSsa(_) => "AssignUnpackMemSsa",
259            Block(_) => "Block",
260            Call(_) => "Call",
261            Tailcall(_) => "Tailcall",
262            CallSsa(_) => "CallSsa",
263            Case(_) => "Case",
264            Const(_) => "Const",
265            ConstPtr(_) => "ConstPtr",
266            Import(_) => "Import",
267            ConstData(_) => "ConstData",
268            Deref(_) => "Deref",
269            AddressOf(_) => "AddressOf",
270            PassByRef(_) => "PassByRef",
271            ReturnByRef(_) => "ReturnByRef",
272            Neg(_) => "Neg",
273            Not(_) => "Not",
274            Bswap(_) => "Bswap",
275            Popcnt(_) => "Popcnt",
276            Clz(_) => "Clz",
277            Ctz(_) => "Ctz",
278            Rbit(_) => "Rbit",
279            Cls(_) => "Cls",
280            Abs(_) => "Abs",
281            Sx(_) => "Sx",
282            Zx(_) => "Zx",
283            LowPart(_) => "LowPart",
284            BoolToInt(_) => "BoolToInt",
285            UnimplMem(_) => "UnimplMem",
286            Fsqrt(_) => "Fsqrt",
287            Fneg(_) => "Fneg",
288            Fabs(_) => "Fabs",
289            FloatToInt(_) => "FloatToInt",
290            IntToFloat(_) => "IntToFloat",
291            FloatConv(_) => "FloatConv",
292            RoundToInt(_) => "RoundToInt",
293            Floor(_) => "Floor",
294            Ceil(_) => "Ceil",
295            Ftrunc(_) => "Ftrunc",
296            DerefFieldSsa(_) => "DerefFieldSsa",
297            DerefSsa(_) => "DerefSsa",
298            ExternPtr(_) => "ExternPtr",
299            FloatConst(_) => "FloatConst",
300            For(_) => "For",
301            ForSsa(_) => "ForSsa",
302            ForceVer(_) => "ForceVer",
303            ForceVerSsa(_) => "ForceVerSsa",
304            Goto(_) => "Goto",
305            Label(_) => "Label",
306            If(_) => "If",
307            Intrinsic(_) => "Intrinsic",
308            IntrinsicSsa(_) => "IntrinsicSsa",
309            Jump(_) => "Jump",
310            MemPhi(_) => "MemPhi",
311            Ret(_) => "Ret",
312            Split(_) => "Split",
313            StructField(_) => "StructField",
314            DerefField(_) => "DerefField",
315            StructInit(_) => "StructInit",
316            StructInitField(_) => "StructInitField",
317            Switch(_) => "Switch",
318            Syscall(_) => "Syscall",
319            SyscallSsa(_) => "SyscallSsa",
320            Trap(_) => "Trap",
321            VarDeclare(_) => "VarDeclare",
322            Var(_) => "Var",
323            VarInit(_) => "VarInit",
324            VarInitSsa(_) => "VarInitSsa",
325            VarPhi(_) => "VarPhi",
326            VarSsa(_) => "VarSsa",
327            VarSsaPartial(_) => "VarSsaPartial",
328            While(_) => "While",
329            DoWhile(_) => "DoWhile",
330            WhileSsa(_) => "WhileSsa",
331            DoWhileSsa(_) => "DoWhileSsa",
332        }
333    }
334
335    pub fn operands(&self) -> Vec<(&'static str, HighLevelILLiftedOperand)> {
336        use HighLevelILLiftedInstructionKind::*;
337        use HighLevelILLiftedOperand as Operand;
338        match &self.kind {
339            Nop | Break | Continue | Noret | Unreachable | Bp | Undef | Unimpl => vec![],
340            Adc(op) | Sbb(op) | Rlc(op) | Rrc(op) => vec![
341                ("left", Operand::Expr(*op.left.clone())),
342                ("right", Operand::Expr(*op.right.clone())),
343                ("carry", Operand::Expr(*op.carry.clone())),
344            ],
345            Add(op) | Sub(op) | And(op) | Or(op) | Xor(op) | Lsl(op) | Lsr(op) | Asr(op)
346            | Rol(op) | Ror(op) | Mul(op) | MuluDp(op) | MulsDp(op) | Divu(op) | DivuDp(op)
347            | Divs(op) | DivsDp(op) | Modu(op) | ModuDp(op) | Mods(op) | ModsDp(op)
348            | MinSigned(op) | MaxSigned(op) | MinUnsigned(op) | MaxUnsigned(op) | CmpE(op)
349            | CmpNe(op) | CmpSlt(op) | CmpUlt(op) | CmpSle(op) | CmpUle(op) | CmpSge(op)
350            | CmpUge(op) | CmpSgt(op) | CmpUgt(op) | TestBit(op) | AddOverflow(op) | Fadd(op)
351            | Fsub(op) | Fmul(op) | Fdiv(op) | FcmpE(op) | FcmpNe(op) | FcmpLt(op) | FcmpLe(op)
352            | FcmpGe(op) | FcmpGt(op) | FcmpO(op) | FcmpUo(op) => vec![
353                ("left", Operand::Expr(*op.left.clone())),
354                ("right", Operand::Expr(*op.right.clone())),
355            ],
356            ArrayIndex(op) => vec![
357                ("src", Operand::Expr(*op.src.clone())),
358                ("index", Operand::Expr(*op.index.clone())),
359            ],
360            ArrayIndexSsa(op) => vec![
361                ("src", Operand::Expr(*op.src.clone())),
362                ("src_memory", Operand::Int(op.src_memory)),
363                ("index", Operand::Expr(*op.index.clone())),
364            ],
365            Assert(op) => vec![
366                ("src", Operand::Var(op.src)),
367                (
368                    "constraint",
369                    Operand::PossibleValueSet(op.constraint.clone()),
370                ),
371            ],
372            AssertSsa(op) => vec![
373                ("src", Operand::VarSsa(op.src)),
374                (
375                    "constraint",
376                    Operand::PossibleValueSet(op.constraint.clone()),
377                ),
378            ],
379            Assign(op) => vec![
380                ("dest", Operand::Expr(*op.dest.clone())),
381                ("src", Operand::Expr(*op.src.clone())),
382            ],
383            AssignMemSsa(op) => vec![
384                ("dest", Operand::Expr(*op.dest.clone())),
385                ("dest_memory", Operand::Int(op.dest_memory)),
386                ("src", Operand::Expr(*op.src.clone())),
387                ("src_memory", Operand::Int(op.src_memory)),
388            ],
389            AssignUnpack(op) => vec![
390                ("dest", Operand::ExprList(op.dest.clone())),
391                ("src", Operand::Expr(*op.src.clone())),
392            ],
393            AssignUnpackMemSsa(op) => vec![
394                ("dest", Operand::ExprList(op.dest.clone())),
395                ("dest_memory", Operand::Int(op.dest_memory)),
396                ("src", Operand::Expr(*op.src.clone())),
397                ("src_memory", Operand::Int(op.src_memory)),
398            ],
399            Block(op) => vec![("body", Operand::ExprList(op.body.clone()))],
400            Call(op) | Tailcall(op) => vec![
401                ("dest", Operand::Expr(*op.dest.clone())),
402                ("params", Operand::ExprList(op.params.clone())),
403            ],
404            CallSsa(op) => vec![
405                ("dest", Operand::Expr(*op.dest.clone())),
406                ("params", Operand::ExprList(op.params.clone())),
407                ("dest_memory", Operand::Int(op.dest_memory)),
408                ("src_memory", Operand::Int(op.src_memory)),
409            ],
410            Case(op) => vec![
411                ("values", Operand::ExprList(op.values.clone())),
412                ("body", Operand::Expr(*op.body.clone())),
413            ],
414            Const(op) | ConstPtr(op) | Import(op) => vec![("constant", Operand::Int(op.constant))],
415            ConstData(op) => vec![(
416                "constant_data",
417                Operand::ConstantData(op.constant_data.clone()),
418            )],
419            Deref(op) | AddressOf(op) | PassByRef(op) | ReturnByRef(op) | Neg(op) | Not(op)
420            | Bswap(op) | Popcnt(op) | Clz(op) | Ctz(op) | Rbit(op) | Cls(op) | Abs(op)
421            | Sx(op) | Zx(op) | LowPart(op) | BoolToInt(op) | UnimplMem(op) | Fsqrt(op)
422            | Fneg(op) | Fabs(op) | FloatToInt(op) | IntToFloat(op) | FloatConv(op)
423            | RoundToInt(op) | Floor(op) | Ceil(op) | Ftrunc(op) => {
424                vec![("src", Operand::Expr(*op.src.clone()))]
425            }
426            DerefFieldSsa(op) => vec![
427                ("src", Operand::Expr(*op.src.clone())),
428                ("src_memory", Operand::Int(op.src_memory)),
429                ("offset", Operand::Int(op.offset)),
430                ("member_index", Operand::MemberIndex(op.member_index)),
431            ],
432            DerefSsa(op) => vec![
433                ("src", Operand::Expr(*op.src.clone())),
434                ("src_memory", Operand::Int(op.src_memory)),
435            ],
436            ExternPtr(op) => vec![
437                ("constant", Operand::Int(op.constant)),
438                ("offset", Operand::Int(op.offset)),
439            ],
440            FloatConst(op) => vec![("constant", Operand::Float(op.constant))],
441            For(op) => vec![
442                ("init", Operand::Expr(*op.init.clone())),
443                ("condition", Operand::Expr(*op.condition.clone())),
444                ("update", Operand::Expr(*op.update.clone())),
445                ("body", Operand::Expr(*op.body.clone())),
446            ],
447            ForSsa(op) => vec![
448                ("init", Operand::Expr(*op.init.clone())),
449                ("condition_phi", Operand::Expr(*op.condition_phi.clone())),
450                ("condition", Operand::Expr(*op.condition.clone())),
451                ("update", Operand::Expr(*op.update.clone())),
452                ("body", Operand::Expr(*op.body.clone())),
453            ],
454            ForceVer(op) => vec![
455                ("dest", Operand::Var(op.dest)),
456                ("src", Operand::Var(op.src)),
457            ],
458            ForceVerSsa(op) => vec![
459                ("dest", Operand::VarSsa(op.dest)),
460                ("src", Operand::VarSsa(op.src)),
461            ],
462            Goto(op) | Label(op) => vec![("target", Operand::Label(op.target.clone()))],
463            If(op) => vec![
464                ("condition", Operand::Expr(*op.condition.clone())),
465                ("cond_true", Operand::Expr(*op.cond_true.clone())),
466                ("cond_false", Operand::Expr(*op.cond_false.clone())),
467            ],
468            Intrinsic(op) => vec![
469                ("intrinsic", Operand::Intrinsic(op.intrinsic)),
470                ("params", Operand::ExprList(op.params.clone())),
471            ],
472            IntrinsicSsa(op) => vec![
473                ("intrinsic", Operand::Intrinsic(op.intrinsic)),
474                ("params", Operand::ExprList(op.params.clone())),
475                ("dest_memory", Operand::Int(op.dest_memory)),
476                ("src_memory", Operand::Int(op.src_memory)),
477            ],
478            Jump(op) => vec![("dest", Operand::Expr(*op.dest.clone()))],
479            MemPhi(op) => vec![
480                ("dest", Operand::Int(op.dest)),
481                ("src", Operand::IntList(op.src.clone())),
482            ],
483            Ret(op) => vec![("src", Operand::ExprList(op.src.clone()))],
484            Split(op) => vec![
485                ("high", Operand::Expr(*op.high.clone())),
486                ("low", Operand::Expr(*op.low.clone())),
487            ],
488            StructField(op) | DerefField(op) => vec![
489                ("src", Operand::Expr(*op.src.clone())),
490                ("offset", Operand::Int(op.offset)),
491                ("member_index", Operand::MemberIndex(op.member_index)),
492            ],
493            StructInit(op) => vec![("fields", Operand::ExprList(op.fields.clone()))],
494            StructInitField(op) => vec![
495                ("offset", Operand::Int(op.offset)),
496                ("member_index", Operand::MemberIndex(op.member_index)),
497                ("src", Operand::Expr(*op.src.clone())),
498            ],
499            Switch(op) => vec![
500                ("condition", Operand::Expr(*op.condition.clone())),
501                ("default", Operand::Expr(*op.default.clone())),
502                ("cases", Operand::ExprList(op.cases.clone())),
503            ],
504            Syscall(op) => vec![("params", Operand::ExprList(op.params.clone()))],
505            SyscallSsa(op) => vec![
506                ("params", Operand::ExprList(op.params.clone())),
507                ("dest_memory", Operand::Int(op.dest_memory)),
508                ("src_memory", Operand::Int(op.src_memory)),
509            ],
510            Trap(op) => vec![("vector", Operand::Int(op.vector))],
511            VarDeclare(op) | Var(op) => vec![("var", Operand::Var(op.var))],
512            VarInit(op) => vec![
513                ("dest", Operand::Var(op.dest)),
514                ("src", Operand::Expr(*op.src.clone())),
515            ],
516            VarInitSsa(op) => vec![
517                ("dest", Operand::VarSsa(op.dest)),
518                ("src", Operand::Expr(*op.src.clone())),
519            ],
520            VarPhi(op) => vec![
521                ("dest", Operand::VarSsa(op.dest)),
522                ("src", Operand::VarSsaList(op.src.clone())),
523            ],
524            VarSsa(op) => vec![("var", Operand::VarSsa(op.var))],
525            VarSsaPartial(op) => vec![
526                ("dest", Operand::VarSsa(op.dest)),
527                ("prev", Operand::VarSsa(op.prev)),
528            ],
529            While(op) => vec![
530                ("condition", Operand::Expr(*op.condition.clone())),
531                ("body", Operand::Expr(*op.body.clone())),
532            ],
533            DoWhile(op) => vec![
534                ("body", Operand::Expr(*op.body.clone())),
535                ("condition", Operand::Expr(*op.condition.clone())),
536            ],
537            WhileSsa(op) => vec![
538                ("condition_phi", Operand::Expr(*op.condition_phi.clone())),
539                ("condition", Operand::Expr(*op.condition.clone())),
540                ("body", Operand::Expr(*op.body.clone())),
541            ],
542            DoWhileSsa(op) => vec![
543                ("body", Operand::Expr(*op.body.clone())),
544                ("condition_phi", Operand::Expr(*op.condition_phi.clone())),
545                ("condition", Operand::Expr(*op.condition.clone())),
546            ],
547        }
548    }
549}
550
551impl Debug for HighLevelILLiftedInstruction {
552    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
553        f.debug_struct("HighLevelILLiftedInstruction")
554            .field("address", &self.address)
555            .field("expr_index", &self.expr_index)
556            .field("size", &self.size)
557            .field("kind", &self.kind)
558            .finish()
559    }
560}