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