1use crate::{Number, NumberNonZeroUnsigned, NumberUnsigned, Span};
2
3use super::{
4 disassembly, pcode_macro::PcodeMacroCallId, BitrangeId, ContextId,
5 InstNext, InstStart, SpaceId, TableId, TokenFieldId, UserFunctionId,
6 VarnodeId,
7};
8
9#[derive(Clone, Debug)]
10pub struct Execution {
11 pub(crate) blocks: Box<[Block]>,
12 pub(crate) variables: Box<[Variable]>,
13
14 pub entry_block: BlockId,
16}
17
18#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
19pub struct BlockId(pub(crate) usize);
20
21#[derive(Clone, Debug)]
22pub struct Block {
23 pub name: Option<Box<str>>,
25 pub next: Option<BlockId>,
26 pub statements: Box<[Statement]>,
27}
28
29#[derive(Clone, Debug)]
30pub enum Statement {
31 Delayslot(NumberUnsigned),
32 Export(Export),
33 CpuBranch(CpuBranch),
34 LocalGoto(LocalGoto),
35 UserCall(UserCall),
36 MacroCall(MacroCall),
37 Build(Build),
38 Declare(VariableId),
39 Assignment(Assignment),
40 MemWrite(MemWrite),
41}
42
43#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
44pub struct VariableId(pub(crate) usize);
45
46#[derive(Clone, Debug)]
47pub struct Variable {
48 pub(crate) name: Box<str>,
49 pub len_bits: NumberNonZeroUnsigned,
50 pub location: Option<Span>,
51}
52
53#[derive(Clone, Debug)]
54pub enum Expr {
55 Value(ExprElement),
56 Op(ExprBinaryOp),
57}
58
59#[derive(Clone, Debug)]
60pub struct ExprBinaryOp {
61 pub location: Span,
62 pub len_bits: NumberNonZeroUnsigned,
63 pub op: Binary,
64 pub left: Box<Expr>,
65 pub right: Box<Expr>,
66}
67
68#[derive(Clone, Debug)]
69pub enum ExprElement {
70 Value(ReadValue),
71 UserCall(UserCall),
72 Reference(Reference),
73 Op(ExprUnaryOp),
74 New(ExprNew),
75 CPool(ExprCPool),
76}
77
78#[derive(Clone, Debug)]
79pub struct Reference {
80 pub location: Span,
81 pub len_bits: NumberNonZeroUnsigned,
82 pub value: ReferencedValue,
83}
84
85#[derive(Clone, Debug)]
86pub struct ExprUnaryOp {
87 pub location: Span,
88 pub output_bits: NumberNonZeroUnsigned,
89 pub op: Unary,
90 pub input: Box<Expr>,
91}
92
93#[derive(Clone, Debug)]
94pub struct ExprNew {
95 pub location: Span,
96 pub first: Box<Expr>,
97 pub second: Option<Box<Expr>>,
98}
99
100#[derive(Clone, Debug)]
101pub struct ExprCPool {
102 pub location: Span,
103 pub params: Box<[Expr]>,
104}
105
106#[derive(Clone, Debug)]
107pub struct UserCall {
108 pub location: Span,
109 pub function: UserFunctionId,
110 pub params: Box<[Expr]>,
111}
112
113#[derive(Clone, Debug)]
114pub enum ReadValue {
115 Int(ExprNumber),
116 TokenField(ExprTokenField),
117 InstStart(ExprInstStart),
118 InstNext(ExprInstNext),
119 Varnode(ExprVarnode),
120 Context(ExprContext),
121 Bitrange(ExprBitrange),
122 Table(ExprTable),
123 DisVar(ExprDisVar),
124 ExeVar(ExprExeVar),
125}
126
127#[derive(Clone, Debug)]
128pub struct ExprNumber {
129 pub location: Span,
130 pub len_bits: NumberNonZeroUnsigned,
131 pub number: Number,
132}
133
134#[derive(Clone, Debug)]
135pub struct ExprTokenField {
136 pub location: Span,
137 pub id: TokenFieldId,
138}
139
140#[derive(Clone, Debug)]
141pub struct ExprInstStart {
142 pub location: Span,
143 pub data: InstStart,
144}
145
146#[derive(Clone, Debug)]
147pub struct ExprInstNext {
148 pub location: Span,
149 pub data: InstNext,
150}
151
152#[derive(Clone, Debug)]
153pub struct ExprVarnode {
154 pub location: Span,
155 pub id: VarnodeId,
156}
157
158#[derive(Clone, Debug)]
159pub struct ExprContext {
160 pub location: Span,
161 pub id: ContextId,
162}
163
164#[derive(Clone, Debug)]
165pub struct ExprBitrange {
166 pub location: Span,
167 pub id: BitrangeId,
168}
169
170#[derive(Clone, Debug)]
171pub struct ExprTable {
172 pub location: Span,
173 pub id: TableId,
174}
175
176#[derive(Clone, Debug)]
177pub struct ExprDisVar {
178 pub location: Span,
179 pub len_bits: NumberNonZeroUnsigned,
180 pub id: disassembly::VariableId,
181}
182
183#[derive(Clone, Debug)]
184pub struct ExprExeVar {
185 pub location: Span,
186 pub id: VariableId,
187}
188
189#[derive(Clone, Debug)]
190pub enum ReferencedValue {
191 TokenField(ExprTokenField),
193 InstStart(ExprInstStart),
194 InstNext(ExprInstNext),
195 Table(ExprTable),
196}
197
198#[derive(Clone, Debug)]
199pub struct CpuBranch {
200 pub cond: Option<Expr>,
201 pub call: BranchCall,
202 pub direct: bool,
203 pub dst: Expr,
204}
205
206#[derive(Clone, Debug, Copy)]
207pub enum BranchCall {
208 Goto,
209 Call,
210 Return,
211}
212
213#[derive(Clone, Debug)]
214pub struct LocalGoto {
215 pub cond: Option<Expr>,
216 pub dst: BlockId,
217}
218
219#[derive(Clone, Debug)]
220pub enum WriteValue {
221 Varnode(ExprVarnode),
222 Bitrange(ExprBitrange),
223 TokenField(ExprTokenField),
225 TableExport(ExprTable),
226 Local(ExprExeVar),
227}
228
229#[derive(Clone, Debug)]
230pub struct Assignment {
231 pub location: Span,
232 pub var: WriteValue,
233 pub op: Option<Truncate>,
234 pub right: Expr,
235}
236
237#[derive(Clone, Debug)]
238pub struct MemWrite {
239 pub addr: Expr,
240 pub mem: MemoryLocation,
241 pub right: Expr,
242}
243
244#[derive(Clone, Debug)]
245pub struct WriteAddr {
246 pub space: MemoryLocation,
247 pub expr: Expr,
248}
249
250#[derive(Clone, Debug)]
251pub struct Build {
252 pub table: ExprTable,
253}
254
255#[derive(Clone, Debug)]
256pub struct MacroCall {
257 pub params: Box<[Expr]>,
258 pub function: PcodeMacroCallId,
259}
260
261#[derive(Clone, Debug)]
262pub enum ExportConst {
263 DisVar(disassembly::VariableId),
264 TokenField(TokenFieldId),
266 Context(ContextId),
268 Table(TableId),
270 ExeVar(VariableId),
271}
272
273#[derive(Clone, Debug)]
274pub enum Export {
275 Const {
277 len_bits: NumberNonZeroUnsigned,
279 location: Span,
281 export: ExportConst,
283 },
284 Value(Expr),
286 Reference { addr: Expr, memory: MemoryLocation },
288}
289
290#[derive(Clone, Debug)]
291pub struct MemoryLocation {
292 pub space: SpaceId,
293 pub len_bytes: NumberNonZeroUnsigned,
294}
295
296#[derive(Clone, Copy, Debug)]
297pub struct Truncate {
298 pub lsb: NumberUnsigned,
299 pub len_bits: NumberNonZeroUnsigned,
300}
301
302#[derive(Clone, Debug)]
303pub enum Unary {
304 Truncate(Truncate),
307 Dereference(MemoryLocation),
308 Negation,
310 BitNegation,
311 Negative,
312 FloatNegative,
313 Popcount,
314 Lzcount,
315 Zext,
316 Sext,
317 FloatNan,
318 FloatAbs,
319 FloatSqrt,
320 Int2Float,
321 Float2Float,
322 SignTrunc,
323 FloatCeil,
324 FloatFloor,
325 FloatRound,
326}
327
328#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord)]
329pub enum Binary {
330 Mult,
332 Div,
333 SigDiv,
334 Rem,
335 FloatDiv,
336 FloatMult,
337 Add,
338 Sub,
339 FloatAdd,
340 FloatSub,
341 Lsl,
342 Lsr,
343 Asr,
344 BitAnd,
345 BitXor,
346 BitOr,
347 SigLess,
349 SigGreater,
350 SigRem,
351 SigLessEq,
352 SigGreaterEq,
353 Less,
354 Greater,
355 LessEq,
356 GreaterEq,
357 FloatLess,
358 FloatGreater,
359 FloatLessEq,
360 FloatGreaterEq,
361 And,
362 Xor,
363 Or,
364 Eq,
365 Ne,
366 FloatEq,
367 FloatNe,
368 Carry,
370 SCarry,
371 SBorrow,
372}
373
374impl Variable {
375 pub fn name(&self) -> &str {
376 &self.name
377 }
378}
379
380impl Execution {
381 pub fn variable(&self, id: VariableId) -> &Variable {
382 &self.variables[id.0]
383 }
384 pub fn block(&self, id: BlockId) -> &Block {
385 &self.blocks[id.0]
386 }
387 pub fn export(&self) -> Option<&Export> {
388 todo!();
389 }
390}