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 Switch(LiftedSwitch),
163 Syscall(LiftedSyscall),
164 SyscallSsa(LiftedSyscallSsa),
165 Trap(Trap),
166 VarDeclare(Var),
167 Var(Var),
168 VarInit(LiftedVarInit),
169 VarInitSsa(LiftedVarInitSsa),
170 VarPhi(LiftedVarPhi),
171 VarSsa(VarSsa),
172 VarSsaPartial(VarSsaPartial),
173 While(LiftedWhile),
174 DoWhile(LiftedWhile),
175 WhileSsa(LiftedWhileSsa),
176 DoWhileSsa(LiftedWhileSsa),
177}
178
179impl HighLevelILLiftedInstruction {
180 pub fn name(&self) -> &'static str {
181 use HighLevelILLiftedInstructionKind::*;
182 match self.kind {
183 Nop => "Nop",
184 Break => "Break",
185 Continue => "Continue",
186 Noret => "Noret",
187 Unreachable => "Unreachable",
188 Bp => "Bp",
189 Undef => "Undef",
190 Unimpl => "Unimpl",
191 Adc(_) => "Adc",
192 Sbb(_) => "Sbb",
193 Rlc(_) => "Rlc",
194 Rrc(_) => "Rrc",
195 Add(_) => "Add",
196 Sub(_) => "Sub",
197 And(_) => "And",
198 Or(_) => "Or",
199 Xor(_) => "Xor",
200 Lsl(_) => "Lsl",
201 Lsr(_) => "Lsr",
202 Asr(_) => "Asr",
203 Rol(_) => "Rol",
204 Ror(_) => "Ror",
205 Mul(_) => "Mul",
206 MuluDp(_) => "MuluDp",
207 MulsDp(_) => "MulsDp",
208 Divu(_) => "Divu",
209 DivuDp(_) => "DivuDp",
210 Divs(_) => "Divs",
211 DivsDp(_) => "DivsDp",
212 Modu(_) => "Modu",
213 ModuDp(_) => "ModuDp",
214 Mods(_) => "Mods",
215 ModsDp(_) => "ModsDp",
216 MinSigned(_) => "MinSigned",
217 MaxSigned(_) => "MaxSigned",
218 MinUnsigned(_) => "MinUnsigned",
219 MaxUnsigned(_) => "MaxUnsigned",
220 CmpE(_) => "CmpE",
221 CmpNe(_) => "CmpNe",
222 CmpSlt(_) => "CmpSlt",
223 CmpUlt(_) => "CmpUlt",
224 CmpSle(_) => "CmpSle",
225 CmpUle(_) => "CmpUle",
226 CmpSge(_) => "CmpSge",
227 CmpUge(_) => "CmpUge",
228 CmpSgt(_) => "CmpSgt",
229 CmpUgt(_) => "CmpUgt",
230 TestBit(_) => "TestBit",
231 AddOverflow(_) => "AddOverflow",
232 Fadd(_) => "Fadd",
233 Fsub(_) => "Fsub",
234 Fmul(_) => "Fmul",
235 Fdiv(_) => "Fdiv",
236 FcmpE(_) => "FcmpE",
237 FcmpNe(_) => "FcmpNe",
238 FcmpLt(_) => "FcmpLt",
239 FcmpLe(_) => "FcmpLe",
240 FcmpGe(_) => "FcmpGe",
241 FcmpGt(_) => "FcmpGt",
242 FcmpO(_) => "FcmpO",
243 FcmpUo(_) => "FcmpUo",
244 ArrayIndex(_) => "ArrayIndex",
245 ArrayIndexSsa(_) => "ArrayIndexSsa",
246 Assign(_) => "Assign",
247 AssignMemSsa(_) => "AssignMemSsa",
248 AssignUnpack(_) => "AssignUnpack",
249 AssignUnpackMemSsa(_) => "AssignUnpackMemSsa",
250 Block(_) => "Block",
251 Call(_) => "Call",
252 Tailcall(_) => "Tailcall",
253 CallSsa(_) => "CallSsa",
254 Case(_) => "Case",
255 Const(_) => "Const",
256 ConstPtr(_) => "ConstPtr",
257 Import(_) => "Import",
258 ConstData(_) => "ConstData",
259 Deref(_) => "Deref",
260 AddressOf(_) => "AddressOf",
261 PassByRef(_) => "PassByRef",
262 ReturnByRef(_) => "ReturnByRef",
263 Neg(_) => "Neg",
264 Not(_) => "Not",
265 Bswap(_) => "Bswap",
266 Popcnt(_) => "Popcnt",
267 Clz(_) => "Clz",
268 Ctz(_) => "Ctz",
269 Rbit(_) => "Rbit",
270 Cls(_) => "Cls",
271 Abs(_) => "Abs",
272 Sx(_) => "Sx",
273 Zx(_) => "Zx",
274 LowPart(_) => "LowPart",
275 BoolToInt(_) => "BoolToInt",
276 UnimplMem(_) => "UnimplMem",
277 Fsqrt(_) => "Fsqrt",
278 Fneg(_) => "Fneg",
279 Fabs(_) => "Fabs",
280 FloatToInt(_) => "FloatToInt",
281 IntToFloat(_) => "IntToFloat",
282 FloatConv(_) => "FloatConv",
283 RoundToInt(_) => "RoundToInt",
284 Floor(_) => "Floor",
285 Ceil(_) => "Ceil",
286 Ftrunc(_) => "Ftrunc",
287 DerefFieldSsa(_) => "DerefFieldSsa",
288 DerefSsa(_) => "DerefSsa",
289 ExternPtr(_) => "ExternPtr",
290 FloatConst(_) => "FloatConst",
291 For(_) => "For",
292 ForSsa(_) => "ForSsa",
293 Goto(_) => "Goto",
294 Label(_) => "Label",
295 If(_) => "If",
296 Intrinsic(_) => "Intrinsic",
297 IntrinsicSsa(_) => "IntrinsicSsa",
298 Jump(_) => "Jump",
299 MemPhi(_) => "MemPhi",
300 Ret(_) => "Ret",
301 Split(_) => "Split",
302 StructField(_) => "StructField",
303 DerefField(_) => "DerefField",
304 Switch(_) => "Switch",
305 Syscall(_) => "Syscall",
306 SyscallSsa(_) => "SyscallSsa",
307 Trap(_) => "Trap",
308 VarDeclare(_) => "VarDeclare",
309 Var(_) => "Var",
310 VarInit(_) => "VarInit",
311 VarInitSsa(_) => "VarInitSsa",
312 VarPhi(_) => "VarPhi",
313 VarSsa(_) => "VarSsa",
314 VarSsaPartial(_) => "VarSsaPartial",
315 While(_) => "While",
316 DoWhile(_) => "DoWhile",
317 WhileSsa(_) => "WhileSsa",
318 DoWhileSsa(_) => "DoWhileSsa",
319 }
320 }
321
322 pub fn operands(&self) -> Vec<(&'static str, HighLevelILLiftedOperand)> {
323 use HighLevelILLiftedInstructionKind::*;
324 use HighLevelILLiftedOperand as Operand;
325 match &self.kind {
326 Nop | Break | Continue | Noret | Unreachable | Bp | Undef | Unimpl => vec![],
327 Adc(op) | Sbb(op) | Rlc(op) | Rrc(op) => vec![
328 ("left", Operand::Expr(*op.left.clone())),
329 ("right", Operand::Expr(*op.right.clone())),
330 ("carry", Operand::Expr(*op.carry.clone())),
331 ],
332 Add(op) | Sub(op) | And(op) | Or(op) | Xor(op) | Lsl(op) | Lsr(op) | Asr(op)
333 | Rol(op) | Ror(op) | Mul(op) | MuluDp(op) | MulsDp(op) | Divu(op) | DivuDp(op)
334 | Divs(op) | DivsDp(op) | Modu(op) | ModuDp(op) | Mods(op) | ModsDp(op)
335 | MinSigned(op) | MaxSigned(op) | MinUnsigned(op) | MaxUnsigned(op) | CmpE(op)
336 | CmpNe(op) | CmpSlt(op) | CmpUlt(op) | CmpSle(op) | CmpUle(op) | CmpSge(op)
337 | CmpUge(op) | CmpSgt(op) | CmpUgt(op) | TestBit(op) | AddOverflow(op) | Fadd(op)
338 | Fsub(op) | Fmul(op) | Fdiv(op) | FcmpE(op) | FcmpNe(op) | FcmpLt(op) | FcmpLe(op)
339 | FcmpGe(op) | FcmpGt(op) | FcmpO(op) | FcmpUo(op) => vec![
340 ("left", Operand::Expr(*op.left.clone())),
341 ("right", Operand::Expr(*op.right.clone())),
342 ],
343 ArrayIndex(op) => vec![
344 ("src", Operand::Expr(*op.src.clone())),
345 ("index", Operand::Expr(*op.index.clone())),
346 ],
347 ArrayIndexSsa(op) => vec![
348 ("src", Operand::Expr(*op.src.clone())),
349 ("src_memory", Operand::Int(op.src_memory)),
350 ("index", Operand::Expr(*op.index.clone())),
351 ],
352 Assign(op) => vec![
353 ("dest", Operand::Expr(*op.dest.clone())),
354 ("src", Operand::Expr(*op.src.clone())),
355 ],
356 AssignMemSsa(op) => vec![
357 ("dest", Operand::Expr(*op.dest.clone())),
358 ("dest_memory", Operand::Int(op.dest_memory)),
359 ("src", Operand::Expr(*op.src.clone())),
360 ("src_memory", Operand::Int(op.src_memory)),
361 ],
362 AssignUnpack(op) => vec![
363 ("dest", Operand::ExprList(op.dest.clone())),
364 ("src", Operand::Expr(*op.src.clone())),
365 ],
366 AssignUnpackMemSsa(op) => vec![
367 ("dest", Operand::ExprList(op.dest.clone())),
368 ("dest_memory", Operand::Int(op.dest_memory)),
369 ("src", Operand::Expr(*op.src.clone())),
370 ("src_memory", Operand::Int(op.src_memory)),
371 ],
372 Block(op) => vec![("body", Operand::ExprList(op.body.clone()))],
373 Call(op) | Tailcall(op) => vec![
374 ("dest", Operand::Expr(*op.dest.clone())),
375 ("params", Operand::ExprList(op.params.clone())),
376 ],
377 CallSsa(op) => vec![
378 ("dest", Operand::Expr(*op.dest.clone())),
379 ("params", Operand::ExprList(op.params.clone())),
380 ("dest_memory", Operand::Int(op.dest_memory)),
381 ("src_memory", Operand::Int(op.src_memory)),
382 ],
383 Case(op) => vec![
384 ("values", Operand::ExprList(op.values.clone())),
385 ("body", Operand::Expr(*op.body.clone())),
386 ],
387 Const(op) | ConstPtr(op) | Import(op) => vec![("constant", Operand::Int(op.constant))],
388 ConstData(op) => vec![(
389 "constant_data",
390 Operand::ConstantData(op.constant_data.clone()),
391 )],
392 Deref(op) | AddressOf(op) | PassByRef(op) | ReturnByRef(op) | Neg(op) | Not(op)
393 | Bswap(op) | Popcnt(op) | Clz(op) | Ctz(op) | Rbit(op) | Cls(op) | Abs(op)
394 | Sx(op) | Zx(op) | LowPart(op) | BoolToInt(op) | UnimplMem(op) | Fsqrt(op)
395 | Fneg(op) | Fabs(op) | FloatToInt(op) | IntToFloat(op) | FloatConv(op)
396 | RoundToInt(op) | Floor(op) | Ceil(op) | Ftrunc(op) => {
397 vec![("src", Operand::Expr(*op.src.clone()))]
398 }
399 DerefFieldSsa(op) => vec![
400 ("src", Operand::Expr(*op.src.clone())),
401 ("src_memory", Operand::Int(op.src_memory)),
402 ("offset", Operand::Int(op.offset)),
403 ("member_index", Operand::MemberIndex(op.member_index)),
404 ],
405 DerefSsa(op) => vec![
406 ("src", Operand::Expr(*op.src.clone())),
407 ("src_memory", Operand::Int(op.src_memory)),
408 ],
409 ExternPtr(op) => vec![
410 ("constant", Operand::Int(op.constant)),
411 ("offset", Operand::Int(op.offset)),
412 ],
413 FloatConst(op) => vec![("constant", Operand::Float(op.constant))],
414 For(op) => vec![
415 ("init", Operand::Expr(*op.init.clone())),
416 ("condition", Operand::Expr(*op.condition.clone())),
417 ("update", Operand::Expr(*op.update.clone())),
418 ("body", Operand::Expr(*op.body.clone())),
419 ],
420 ForSsa(op) => vec![
421 ("init", Operand::Expr(*op.init.clone())),
422 ("condition_phi", Operand::Expr(*op.condition_phi.clone())),
423 ("condition", Operand::Expr(*op.condition.clone())),
424 ("update", Operand::Expr(*op.update.clone())),
425 ("body", Operand::Expr(*op.body.clone())),
426 ],
427 Goto(op) | Label(op) => vec![("target", Operand::Label(op.target.clone()))],
428 If(op) => vec![
429 ("condition", Operand::Expr(*op.condition.clone())),
430 ("cond_true", Operand::Expr(*op.cond_true.clone())),
431 ("cond_false", Operand::Expr(*op.cond_false.clone())),
432 ],
433 Intrinsic(op) => vec![
434 ("intrinsic", Operand::Intrinsic(op.intrinsic)),
435 ("params", Operand::ExprList(op.params.clone())),
436 ],
437 IntrinsicSsa(op) => vec![
438 ("intrinsic", Operand::Intrinsic(op.intrinsic)),
439 ("params", Operand::ExprList(op.params.clone())),
440 ("dest_memory", Operand::Int(op.dest_memory)),
441 ("src_memory", Operand::Int(op.src_memory)),
442 ],
443 Jump(op) => vec![("dest", Operand::Expr(*op.dest.clone()))],
444 MemPhi(op) => vec![
445 ("dest", Operand::Int(op.dest)),
446 ("src", Operand::IntList(op.src.clone())),
447 ],
448 Ret(op) => vec![("src", Operand::ExprList(op.src.clone()))],
449 Split(op) => vec![
450 ("high", Operand::Expr(*op.high.clone())),
451 ("low", Operand::Expr(*op.low.clone())),
452 ],
453 StructField(op) | DerefField(op) => vec![
454 ("src", Operand::Expr(*op.src.clone())),
455 ("offset", Operand::Int(op.offset)),
456 ("member_index", Operand::MemberIndex(op.member_index)),
457 ],
458 Switch(op) => vec![
459 ("condition", Operand::Expr(*op.condition.clone())),
460 ("default", Operand::Expr(*op.default.clone())),
461 ("cases", Operand::ExprList(op.cases.clone())),
462 ],
463 Syscall(op) => vec![("params", Operand::ExprList(op.params.clone()))],
464 SyscallSsa(op) => vec![
465 ("params", Operand::ExprList(op.params.clone())),
466 ("dest_memory", Operand::Int(op.dest_memory)),
467 ("src_memory", Operand::Int(op.src_memory)),
468 ],
469 Trap(op) => vec![("vector", Operand::Int(op.vector))],
470 VarDeclare(op) | Var(op) => vec![("var", Operand::Var(op.var))],
471 VarInit(op) => vec![
472 ("dest", Operand::Var(op.dest)),
473 ("src", Operand::Expr(*op.src.clone())),
474 ],
475 VarInitSsa(op) => vec![
476 ("dest", Operand::VarSsa(op.dest)),
477 ("src", Operand::Expr(*op.src.clone())),
478 ],
479 VarPhi(op) => vec![
480 ("dest", Operand::VarSsa(op.dest)),
481 ("src", Operand::VarSsaList(op.src.clone())),
482 ],
483 VarSsa(op) => vec![("var", Operand::VarSsa(op.var))],
484 VarSsaPartial(op) => vec![
485 ("dest", Operand::VarSsa(op.dest)),
486 ("prev", Operand::VarSsa(op.prev)),
487 ],
488 While(op) | DoWhile(op) => vec![
489 ("condition", Operand::Expr(*op.condition.clone())),
490 ("body", Operand::Expr(*op.body.clone())),
491 ],
492 WhileSsa(op) | DoWhileSsa(op) => vec![
493 ("condition_phi", Operand::Expr(*op.condition_phi.clone())),
494 ("condition", Operand::Expr(*op.condition.clone())),
495 ("body", Operand::Expr(*op.body.clone())),
496 ],
497 }
498 }
499}
500
501impl Debug for HighLevelILLiftedInstruction {
502 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
503 f.debug_struct("HighLevelILLiftedInstruction")
504 .field("address", &self.address)
505 .field("expr_index", &self.expr_index)
506 .field("size", &self.size)
507 .field("kind", &self.kind)
508 .finish()
509 }
510}