10 void print_block (FILE *out
, struct basicblock
*block
, int reversecond
)
13 struct operation
*jumpop
= NULL
;
16 if (reversecond
) options
|= OPTS_REVERSECOND
;
17 opel
= list_head (block
->operations
);
19 struct operation
*op
= element_getvalue (opel
);
20 if (!(op
->status
& OPERATION_DEFERRED
)) {
21 if (op
->type
== OP_INSTRUCTION
) {
22 if (op
->info
.iop
.loc
->insn
->flags
& (INSN_JUMP
| INSN_BRANCH
))
26 print_operation (out
, op
, block
->identsize
+ 1, options
);
28 opel
= element_next (opel
);
31 print_operation (out
, jumpop
, block
->identsize
+ 1, options
);
35 void print_block_recursive (FILE *out
, struct basicblock
*block
, int verbosity
)
37 struct basicedge
*edge
;
38 int reversecond
= FALSE
, haselse
= FALSE
;
43 if (block
->haslabel
) {
45 ident_line (out
, block
->identsize
);
46 fprintf (out
, "label%d:\n", block
->node
.dfsnum
);
50 if (block
->loopst
->start
== block
) {
51 ident_line (out
, block
->identsize
);
52 fprintf (out
, "loop {\n");
57 ident_line (out
, block
->identsize
+ 1);
58 fprintf (out
, "/* Block %d ", block
->node
.dfsnum
);
59 if (block
->type
== BLOCK_SIMPLE
) {
60 fprintf (out
, "Address 0x%08X ", block
->info
.simple
.begin
->address
);
62 fprintf (out
, "*/\n");
66 struct basicedge
*edge1
, *edge2
;
68 edge1
= list_headvalue (block
->outrefs
);
69 edge2
= list_tailvalue (block
->outrefs
);
71 if (edge1
->type
!= EDGE_IFEXIT
&&
72 edge2
->type
!= EDGE_IFEXIT
) {
75 if (edge2
->type
== EDGE_IFEXIT
)
80 print_block (out
, block
, reversecond
);
84 ref
= list_tail (block
->outrefs
);
86 ref
= list_head (block
->outrefs
);
89 edge
= element_getvalue (ref
);
91 if (edge
->type
== EDGE_FOLLOW
) {
93 ident_line (out
, block
->identsize
+ 1);
96 print_block_recursive (out
, edge
->to
, verbosity
);
98 ident_line (out
, block
->identsize
+ 1);
101 } else if (edge
->type
!= EDGE_IFEXIT
) {
102 int identsize
= block
->identsize
+ 1;
103 if (block
->st
) identsize
++;
104 ident_line (out
, identsize
);
105 switch (edge
->type
) {
106 case EDGE_GOTO
: fprintf (out
, "goto label%d;\n", edge
->to
->node
.dfsnum
); break;
107 case EDGE_BREAK
: fprintf (out
, "break;\n"); break;
108 case EDGE_CONTINUE
: fprintf (out
, "continue;\n"); break;
115 ref
= element_previous (ref
);
117 ref
= element_next (ref
);
119 if (ref
&& haselse
) {
120 ident_line (out
, block
->identsize
+ 1);
121 fprintf (out
, "else\n");
127 if (block
->st
->end
&& block
->st
->info
.ifctrl
.isoutermost
) {
128 if (block
->st
->hasendgoto
) {
129 ident_line (out
, block
->identsize
+ 1);
130 fprintf (out
, "goto label%d;\n", block
->st
->end
->node
.dfsnum
);
132 print_block_recursive (out
, block
->st
->end
, verbosity
);
138 if (block
->loopst
->start
== block
) {
139 ident_line (out
, block
->identsize
);
140 fprintf (out
, "}\n");
141 if (block
->loopst
->end
) {
142 if (block
->loopst
->hasendgoto
) {
143 ident_line (out
, block
->identsize
);
144 fprintf (out
, "goto label%d;\n", block
->loopst
->end
->node
.dfsnum
);
146 print_block_recursive (out
, block
->loopst
->end
, verbosity
);
154 void print_subroutine (FILE *out
, struct subroutine
*sub
, int verbosity
)
156 if (sub
->import
) { return; }
158 fprintf (out
, "/**\n * Subroutine at address 0x%08X\n", sub
->begin
->address
);
159 if (verbosity
> 1 && !sub
->haserror
) {
160 struct location
*loc
= sub
->begin
;
161 for (loc
= sub
->begin
; ; loc
++) {
162 fprintf (out
, " * %s\n", allegrex_disassemble (loc
->opc
, loc
->address
, TRUE
));
163 if (loc
== sub
->end
) break;
166 fprintf (out
, " */\n");
167 print_subroutine_declaration (out
, sub
);
168 fprintf (out
, "\n{\n");
171 struct location
*loc
;
172 for (loc
= sub
->begin
; ; loc
++) {
173 fprintf (out
, "%s\n", allegrex_disassemble (loc
->opc
, loc
->address
, TRUE
));
174 if (loc
== sub
->end
) break;
180 el
= list_head (sub
->blocks
);
182 struct basicblock
*block
= element_getvalue (el
);
184 print_block_recursive (out
, block
, verbosity
);
185 el
= element_next (el
);
188 fprintf (out
, "}\n\n");
192 void print_source (FILE *out
, struct code
*c
, char *headerfilename
, int verbosity
)
197 fprintf (out
, "#include <pspsdk.h>\n");
198 fprintf (out
, "#include \"%s\"\n\n", headerfilename
);
200 for (i
= 0; i
< c
->file
->modinfo
->numimports
; i
++) {
201 struct prx_import
*imp
= &c
->file
->modinfo
->imports
[i
];
203 fprintf (out
, "/*\n * Imports from library: %s\n */\n", imp
->name
);
204 for (j
= 0; j
< imp
->nfuncs
; j
++) {
205 struct prx_function
*func
= &imp
->funcs
[j
];
207 fprintf (out
, "extern ");
208 print_subroutine_declaration (out
, func
->pfunc
);
209 fprintf (out
, ";\n");
215 el
= list_head (c
->subroutines
);
217 struct subroutine
*sub
;
218 sub
= element_getvalue (el
);
220 print_subroutine (out
, sub
, verbosity
);
221 el
= element_next (el
);
227 void print_header (FILE *out
, struct code
*c
, char *headerfilename
)
233 while (pos
< sizeof (buffer
) - 1) {
234 char c
= headerfilename
[pos
];
236 if (c
== '.') c
= '_';
237 else c
= toupper (c
);
242 fprintf (out
, "#ifndef __%s\n", buffer
);
243 fprintf (out
, "#define __%s\n\n", buffer
);
245 for (i
= 0; i
< c
->file
->modinfo
->numexports
; i
++) {
246 struct prx_export
*exp
= &c
->file
->modinfo
->exports
[i
];
248 fprintf (out
, "/*\n * Exports from library: %s\n */\n", exp
->name
);
249 for (j
= 0; j
< exp
->nfuncs
; j
++) {
250 struct prx_function
*func
= &exp
->funcs
[j
];
252 fprintf (out
, "void %s (void);\n",func
->name
);
254 fprintf (out
, "void %s_%08X (void);\n", exp
->name
, func
->nid
);
260 fprintf (out
, "#endif /* __%s */\n", buffer
);
264 int print_code (struct code
*c
, char *prxname
, int verbosity
)
271 get_base_name (prxname
, basename
, sizeof (basename
));
272 sprintf (buffer
, "%s.c", basename
);
274 cout
= fopen (buffer
, "w");
276 xerror (__FILE__
": can't open file for writing `%s'", buffer
);
280 sprintf (buffer
, "%s.h", basename
);
281 hout
= fopen (buffer
, "w");
283 xerror (__FILE__
": can't open file for writing `%s'", buffer
);
288 print_header (hout
, c
, buffer
);
289 print_source (cout
, c
, buffer
, verbosity
);