2 * Author: Humberto Naves (hsnaves@gmail.com)
13 void print_block (FILE *out
, struct basicblock
*block
, int identsize
, int reversecond
)
18 if (reversecond
) options
|= OPTS_REVERSECOND
;
19 opel
= list_head (block
->operations
);
21 struct operation
*op
= element_getvalue (opel
);
22 if (!(op
->status
& OP_STAT_DEFERRED
)) {
23 if (op
!= block
->jumpop
)
24 print_operation (out
, op
, identsize
, options
);
26 opel
= element_next (opel
);
29 print_operation (out
, block
->jumpop
, identsize
, options
);
33 void print_block_recursive (FILE *out
, struct basicblock
*block
)
36 struct basicedge
*edge
;
37 int identsize
= block
->st
->identsize
;
38 int revcond
= block
->status
& BLOCK_STAT_REVCOND
;
39 int first
= TRUE
, isloop
= FALSE
;
41 if (g_verbosity
> 1) {
42 ident_line (out
, identsize
+ 1);
43 fprintf (out
, "/** Block %d\n", block
->node
.dfsnum
);
44 if (block
->type
== BLOCK_SIMPLE
){
46 loc
= block
->info
.simple
.begin
;
48 ident_line (out
, identsize
+ 1);
49 fprintf (out
, " * %s\n", allegrex_disassemble (loc
->opc
, loc
->address
, TRUE
));
50 if (loc
++ == block
->info
.simple
.end
) break;
53 ident_line (out
, identsize
+ 1);
54 fprintf (out
, " */\n");
57 if (block
->status
& BLOCK_STAT_ISSWITCHTARGET
) {
58 ref
= list_head (block
->inrefs
);
60 edge
= element_getvalue (ref
);
61 if (edge
->from
->status
& BLOCK_STAT_ISSWITCH
) {
62 ident_line (out
, identsize
);
63 fprintf (out
, "case %d:\n", edge
->fromnum
);
65 ref
= element_next (ref
);
69 if (block
->status
& BLOCK_STAT_HASLABEL
) {
71 ident_line (out
, identsize
);
72 fprintf (out
, "label%d:\n", block
->node
.dfsnum
);
75 if (block
->st
->start
== block
&& block
->st
->type
== CONTROL_LOOP
) {
77 ident_line (out
, identsize
);
78 fprintf (out
, "while (1) {\n");
82 print_block (out
, block
, identsize
+ 1, revcond
);
84 if (block
->status
& BLOCK_STAT_ISSWITCH
) {
86 ident_line (out
, identsize
+ 1);
87 fprintf (out
, "switch () {\n");
90 if (revcond
) ref
= list_head (block
->outrefs
);
91 else ref
= list_tail (block
->outrefs
);
94 edge
= element_getvalue (ref
);
102 ident_line (out
, identsize
+ 1);
103 if (first
&& list_size (block
->outrefs
) == 2 &&
104 !(block
->status
& BLOCK_STAT_ISSWITCH
) && edge
->type
!= EDGE_IFENTER
)
116 switch (edge
->type
) {
118 fprintf (out
, "break;\n");
121 fprintf (out
, "continue;\n");
125 fprintf (out
, "goto label%d;\n", edge
->to
->node
.dfsnum
);
131 if (!edge
->to
->mark1
)
132 print_block_recursive (out
, edge
->to
);
136 print_block_recursive (out
, edge
->to
);
139 fprintf (out
, "{\n");
140 print_block_recursive (out
, edge
->to
);
141 ident_line (out
, identsize
+ 1);
142 fprintf (out
, "}\n");
146 if (revcond
) ref
= element_next (ref
);
147 else ref
= element_previous (ref
);
149 if ((block
->status
& BLOCK_STAT_HASELSE
) && ref
) {
150 ident_line (out
, identsize
+ 1);
151 fprintf (out
, "else\n");
157 if (block
->ifst
->hasendgoto
) {
158 ident_line (out
, identsize
+ 1);
159 fprintf (out
, "goto label%d;\n", block
->ifst
->end
->node
.dfsnum
);
160 } else if (block
->ifst
->endfollow
) {
161 print_block_recursive (out
, block
->ifst
->end
);
165 if (block
->status
& BLOCK_STAT_ISSWITCH
) {
166 ident_line (out
, identsize
+ 1);
167 fprintf (out
, "}\n");
170 if (block
->st
->start
== block
&& block
->st
->type
== CONTROL_LOOP
) {
171 ident_line (out
, identsize
);
172 fprintf (out
, "}\n");
173 if (block
->st
->hasendgoto
) {
174 ident_line (out
, identsize
);
175 fprintf (out
, "goto label%d;\n", block
->st
->end
->node
.dfsnum
);
176 } else if (block
->st
->endfollow
) {
177 print_block_recursive (out
, block
->st
->end
);
184 void print_subroutine (FILE *out
, struct subroutine
*sub
)
186 if (sub
->import
) { return; }
188 fprintf (out
, "/**\n * Subroutine at address 0x%08X\n", sub
->begin
->address
);
189 fprintf (out
, " */\n");
190 print_subroutine_declaration (out
, sub
);
191 fprintf (out
, "\n{\n");
194 struct location
*loc
;
195 for (loc
= sub
->begin
; ; loc
++) {
196 fprintf (out
, "%s\n", allegrex_disassemble (loc
->opc
, loc
->address
, TRUE
));
197 if (loc
== sub
->end
) break;
203 el
= list_head (sub
->blocks
);
205 struct basicblock
*block
= element_getvalue (el
);
207 print_block_recursive (out
, block
);
208 el
= element_next (el
);
211 fprintf (out
, "}\n\n");
215 void print_source (FILE *out
, struct code
*c
, char *headerfilename
)
220 fprintf (out
, "#include <pspsdk.h>\n");
221 fprintf (out
, "#include \"%s\"\n\n", headerfilename
);
223 for (i
= 0; i
< c
->file
->modinfo
->numimports
; i
++) {
224 struct prx_import
*imp
= &c
->file
->modinfo
->imports
[i
];
226 fprintf (out
, "/*\n * Imports from library: %s\n */\n", imp
->name
);
227 for (j
= 0; j
< imp
->nfuncs
; j
++) {
228 struct prx_function
*func
= &imp
->funcs
[j
];
230 fprintf (out
, "extern ");
231 print_subroutine_declaration (out
, func
->pfunc
);
232 fprintf (out
, ";\n");
238 el
= list_head (c
->subroutines
);
240 struct subroutine
*sub
;
241 sub
= element_getvalue (el
);
243 print_subroutine (out
, sub
);
244 el
= element_next (el
);
250 void print_header (FILE *out
, struct code
*c
, char *headerfilename
)
256 while (pos
< sizeof (buffer
) - 1) {
257 char c
= headerfilename
[pos
];
259 if (c
== '.') c
= '_';
260 else c
= toupper (c
);
265 fprintf (out
, "#ifndef __%s\n", buffer
);
266 fprintf (out
, "#define __%s\n\n", buffer
);
268 for (i
= 0; i
< c
->file
->modinfo
->numexports
; i
++) {
269 struct prx_export
*exp
= &c
->file
->modinfo
->exports
[i
];
271 fprintf (out
, "/*\n * Exports from library: %s\n */\n", exp
->name
);
272 for (j
= 0; j
< exp
->nfuncs
; j
++) {
273 struct prx_function
*func
= &exp
->funcs
[j
];
275 fprintf (out
, "void %s (void);\n",func
->name
);
277 fprintf (out
, "void %s_%08X (void);\n", exp
->name
, func
->nid
);
283 fprintf (out
, "#endif /* __%s */\n", buffer
);
287 int print_code (struct code
*c
, char *prxname
)
294 get_base_name (prxname
, basename
, sizeof (basename
));
295 sprintf (buffer
, "%s.c", basename
);
297 cout
= fopen (buffer
, "w");
299 xerror (__FILE__
": can't open file for writing `%s'", buffer
);
303 sprintf (buffer
, "%s.h", basename
);
304 hout
= fopen (buffer
, "w");
306 xerror (__FILE__
": can't open file for writing `%s'", buffer
);
311 print_header (hout
, c
, buffer
);
312 print_source (cout
, c
, buffer
);