10 /* Possible reachable status */
11 enum locationreachable
{
12 LOCATION_UNREACHABLE
= 0, /* Location is not reachable by any means */
13 LOCATION_REACHABLE
, /* Location is reachable by some path */
14 LOCATION_DELAY_SLOT
/* Location is a delay slot of a reachable branch/jump */
17 /* If an error was detected one a location */
19 ERROR_NONE
= 0, /* No error */
20 ERROR_INVALID_OPCODE
, /* Opcode is not recognized */
21 ERROR_DELAY_SLOT
, /* Branch/jump inside a delay slot */
22 ERROR_TARGET_OUTSIDE_FILE
, /* Branch/jump target outside the code */
23 ERROR_ILLEGAL_BRANCH
/* Branch with a condition that can never occur, such as `bne $0, $0, target' */
26 /* Represents a location in the code */
28 uint32 opc
; /* The opcode (little-endian) */
29 uint32 address
; /* The virtual address of the location */
31 const struct allegrex_instruction
*insn
; /* The decoded instruction or null (illegal opcode) */
32 struct location
*target
; /* A possible target of a branch/jump */
34 list references
; /* Number of references to this target inside the same subroutine */
35 int branchalways
; /* True if this location is a branch that always occurs */
36 enum locationreachable reachable
; /* Reachable status */
37 enum locationerror error
; /* Error status */
39 struct subroutine
*sub
; /* Owner subroutine */
40 struct basicblock
*block
; /* Basic block mark (used when extracting basic blocks) */
41 struct codeswitch
*cswitch
; /* Code switch mark */
44 /* Represents a switch in the code */
46 struct prx_reloc
*jumpreloc
;
47 struct prx_reloc
*switchreloc
;
48 struct location
*location
; /* The location that loads the base address of the switch */
49 struct location
*jumplocation
; /* The location of the jump instruction */
50 list references
; /* A list of possible target locations (without repeating) */
51 int count
; /* How many possible targets this switch have */
52 int checked
; /* Is this switch valid? */
55 /* Subroutine decompilation status */
56 #define SUBROUTINE_EXTRACTED 1
57 #define SUBROUTINE_CFG_EXTRACTED 2
61 struct code
*code
; /* The owner code of this subroutine */
62 struct prx_function
*export
; /* Is this a function export? */
63 struct prx_function
*import
; /* Is this a function import? */
65 struct location
*begin
; /* Where the subroutine begins */
66 struct location
*end
; /* Where the subroutine ends */
68 struct basicblock
*startblock
; /* Points to the first basic block of this subroutine */
69 struct basicblock
*endblock
; /* Points to the last basic block of this subroutine */
70 list blocks
; /* A list of the basic blocks of this subroutine */
71 list dfsblocks
, revdfsblocks
; /* Blocks ordered in DFS and Reverse-DFS order */
73 list whereused
; /* A list of basic blocks calling this subroutine */
79 int haserror
, status
; /* Subroutine decompilation status */
83 /* Represents a pair of integers */
89 /* Abstract node in DFS and DOM trees (or reverse DFS and DOM trees) */
90 struct basicblocknode
{
91 int dfsnum
; /* The Depth-First search number */
92 struct intpair domdfsnum
; /* To determine ancestry information in the dominator tree */
93 struct basicblocknode
*dominator
; /* The dominator node */
94 struct basicblocknode
*parent
; /* The parent node (in the depth-first search) */
95 element blockel
; /* An element inside the list (dfsblocks or revdfsblocks) */
96 list children
; /* Children in the DFS tree */
97 list domchildren
; /* Children in the dominator tree */
98 list frontier
; /* The dominator frontier */
101 /* The type of the basic block */
102 enum basicblocktype
{
103 BLOCK_START
= 0, /* The first basic block in a subroutine */
104 BLOCK_SIMPLE
, /* A simple block */
105 BLOCK_CALL
, /* A block that represents a call */
106 BLOCK_END
/* The last basic block */
109 /* The basic block */
111 enum basicblocktype type
; /* The type of the basic block *?
112 element blockel; /* An element inside the list sub->blocks */
115 struct location
*begin
; /* The start of the simple block */
116 struct location
*end
; /* The end of the simple block */
117 struct location
*jumploc
; /* The jump/branch location inside the block */
120 struct subroutine
*calltarget
; /* The target of the call */
124 uint32 reg_gen
[2], reg_kill
[2];
125 uint32 reg_live_in
[2], reg_live_out
[2];
127 struct subroutine
*sub
; /* The owner subroutine */
129 struct basicblocknode node
; /* Node info for DFS and DOM trees */
130 struct basicblocknode revnode
; /* Node info for the reverse DFS and DOM trees */
132 list inrefs
, outrefs
; /* A list of in- and out-edges of this block */
134 struct loopstructure
*loopst
;
135 struct ifstructure
*ifst
;
137 int haslabel
, identsize
;
153 struct basicblock
*from
, *to
;
154 element fromel
, toel
;
158 #define REGISTER_LINK 31
159 #define REGISTER_LO 32
160 #define REGISTER_HI 33
161 #define NUM_REGISTERS 34
173 struct variable
*variable
;
184 VARIABLE_CONSTANTUNK
,
190 enum variabletype type
;
193 struct operation
*def
;
209 enum operationtype type
;
210 enum allegrex_insn insn
;
211 struct location
*begin
;
212 struct location
*end
;
213 struct basicblock
*block
;
227 struct loopstructure
{
229 struct basicblock
*start
;
230 struct basicblock
*end
;
236 struct basicblock
*end
;
245 uint32 baddr
, numopc
;
246 struct location
*base
;
247 struct location
*end
;
252 fixedpool switchpool
;
254 fixedpool blockspool
;
264 struct code
* code_analyse (struct prx
*p
);
265 void code_free (struct code
*c
);
267 int decode_instructions (struct code
*c
);
268 uint32
location_gpr_used (struct location
*loc
);
269 uint32
location_gpr_defined (struct location
*loc
);
270 int location_branch_may_swap (struct location
*branch
);
272 void extract_switches (struct code
*c
);
273 void extract_subroutines (struct code
*c
);
275 void extract_cfg (struct subroutine
*sub
);
277 int cfg_dfs (struct subroutine
*sub
, int reverse
);
279 int dom_isancestor (struct basicblocknode
*ancestor
, struct basicblocknode
*node
);
280 struct basicblocknode
*dom_common (struct basicblocknode
*n1
, struct basicblocknode
*n2
);
281 void cfg_dominance (struct subroutine
*sub
, int reverse
);
282 void cfg_frontier (struct subroutine
*sub
, int reverse
);
284 void reset_marks (struct subroutine
*sub
);
285 void extract_structures (struct subroutine
*sub
);
287 void build_ssa (struct subroutine
*sub
);
288 void extract_variables (struct subroutine
*sub
);
291 #endif /* __CODE_H */