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 fprintf (out
, "block%d:\n", block
->node
.dfsnum
);
43 if (block
->type
== BLOCK_SIMPLE
){
45 loc
= block
->info
.simple
.begin
;
47 fprintf (out
, " %s\n", allegrex_disassemble (loc
->opc
, loc
->address
, TRUE
));
48 if (loc
++ == block
->info
.simple
.end
) break;
53 if (block
->status
& BLOCK_STAT_ISSWITCHTARGET
) {
54 ref
= list_head (block
->inrefs
);
56 edge
= element_getvalue (ref
);
57 if (edge
->from
->status
& BLOCK_STAT_ISSWITCH
) {
58 ident_line (out
, identsize
);
59 fprintf (out
, "case %d:\n", edge
->fromnum
);
61 ref
= element_next (ref
);
65 if (block
->status
& BLOCK_STAT_HASLABEL
) {
67 ident_line (out
, identsize
);
68 fprintf (out
, "label%d:\n", block
->node
.dfsnum
);
71 if (block
->st
->start
== block
&& block
->st
->type
== CONTROL_LOOP
) {
73 ident_line (out
, identsize
);
74 fprintf (out
, "while (1) {\n");
78 print_block (out
, block
, identsize
+ 1, revcond
);
80 if (block
->status
& BLOCK_STAT_ISSWITCH
) {
82 ident_line (out
, identsize
+ 1);
83 fprintf (out
, "switch () {\n");
86 if (revcond
) ref
= list_head (block
->outrefs
);
87 else ref
= list_tail (block
->outrefs
);
90 edge
= element_getvalue (ref
);
91 if (edge
->type
!= EDGE_CASE
&& edge
->type
!= EDGE_NEXT
&&
92 edge
->type
!= EDGE_IFEXIT
&& edge
->type
!= EDGE_UNKNOWN
) {
93 ident_line (out
, identsize
+ 1);
94 if (first
&& list_size (block
->outrefs
) == 2 &&
95 !(block
->status
& BLOCK_STAT_ISSWITCH
) && edge
->type
!= EDGE_IFENTER
)
101 fprintf (out
, "break;\n");
104 fprintf (out
, "continue;\n");
108 fprintf (out
, "goto label%d;\n", edge
->to
->node
.dfsnum
);
114 if (!edge
->to
->mark1
)
115 print_block_recursive (out
, edge
->to
);
118 print_block_recursive (out
, edge
->to
);
121 fprintf (out
, "{\n");
122 print_block_recursive (out
, edge
->to
);
123 ident_line (out
, identsize
+ 1);
124 fprintf (out
, "}\n");
128 if (revcond
) ref
= element_next (ref
);
129 else ref
= element_previous (ref
);
131 if ((block
->status
& BLOCK_STAT_HASELSE
) && ref
) {
132 ident_line (out
, identsize
+ 1);
133 fprintf (out
, "else\n");
139 if (block
->ifst
->hasendgoto
) {
140 ident_line (out
, identsize
+ 1);
141 fprintf (out
, "goto label%d;\n", block
->ifst
->end
->node
.dfsnum
);
142 } else if (block
->ifst
->info
.ifctrl
.endfollow
) {
143 print_block_recursive (out
, block
->ifst
->end
);
147 if (block
->status
& BLOCK_STAT_ISSWITCH
) {
148 ident_line (out
, identsize
+ 1);
149 fprintf (out
, "}\n");
152 if (block
->st
->start
== block
&& block
->st
->type
== CONTROL_LOOP
) {
153 ident_line (out
, identsize
);
154 fprintf (out
, "}\n");
155 if (block
->st
->hasendgoto
) {
156 ident_line (out
, identsize
);
157 fprintf (out
, "goto label%d;\n", block
->st
->end
->node
.dfsnum
);
159 print_block_recursive (out
, block
->st
->end
);
166 void print_subroutine (FILE *out
, struct subroutine
*sub
)
168 if (sub
->import
) { return; }
170 fprintf (out
, "/**\n * Subroutine at address 0x%08X\n", sub
->begin
->address
);
171 fprintf (out
, " */\n");
172 print_subroutine_declaration (out
, sub
);
173 fprintf (out
, "\n{\n");
176 struct location
*loc
;
177 for (loc
= sub
->begin
; ; loc
++) {
178 fprintf (out
, "%s\n", allegrex_disassemble (loc
->opc
, loc
->address
, TRUE
));
179 if (loc
== sub
->end
) break;
185 el
= list_head (sub
->blocks
);
187 struct basicblock
*block
= element_getvalue (el
);
189 print_block_recursive (out
, block
);
190 el
= element_next (el
);
193 fprintf (out
, "}\n\n");
197 void print_source (FILE *out
, struct code
*c
, char *headerfilename
)
202 fprintf (out
, "#include <pspsdk.h>\n");
203 fprintf (out
, "#include \"%s\"\n\n", headerfilename
);
205 for (i
= 0; i
< c
->file
->modinfo
->numimports
; i
++) {
206 struct prx_import
*imp
= &c
->file
->modinfo
->imports
[i
];
208 fprintf (out
, "/*\n * Imports from library: %s\n */\n", imp
->name
);
209 for (j
= 0; j
< imp
->nfuncs
; j
++) {
210 struct prx_function
*func
= &imp
->funcs
[j
];
212 fprintf (out
, "extern ");
213 print_subroutine_declaration (out
, func
->pfunc
);
214 fprintf (out
, ";\n");
220 el
= list_head (c
->subroutines
);
222 struct subroutine
*sub
;
223 sub
= element_getvalue (el
);
225 print_subroutine (out
, sub
);
226 el
= element_next (el
);
232 void print_header (FILE *out
, struct code
*c
, char *headerfilename
)
238 while (pos
< sizeof (buffer
) - 1) {
239 char c
= headerfilename
[pos
];
241 if (c
== '.') c
= '_';
242 else c
= toupper (c
);
247 fprintf (out
, "#ifndef __%s\n", buffer
);
248 fprintf (out
, "#define __%s\n\n", buffer
);
250 for (i
= 0; i
< c
->file
->modinfo
->numexports
; i
++) {
251 struct prx_export
*exp
= &c
->file
->modinfo
->exports
[i
];
253 fprintf (out
, "/*\n * Exports from library: %s\n */\n", exp
->name
);
254 for (j
= 0; j
< exp
->nfuncs
; j
++) {
255 struct prx_function
*func
= &exp
->funcs
[j
];
257 fprintf (out
, "void %s (void);\n",func
->name
);
259 fprintf (out
, "void %s_%08X (void);\n", exp
->name
, func
->nid
);
265 fprintf (out
, "#endif /* __%s */\n", buffer
);
269 int print_code (struct code
*c
, char *prxname
)
276 get_base_name (prxname
, basename
, sizeof (basename
));
277 sprintf (buffer
, "%s.c", basename
);
279 cout
= fopen (buffer
, "w");
281 xerror (__FILE__
": can't open file for writing `%s'", buffer
);
285 sprintf (buffer
, "%s.h", basename
);
286 hout
= fopen (buffer
, "w");
288 xerror (__FILE__
": can't open file for writing `%s'", buffer
);
293 print_header (hout
, c
, buffer
);
294 print_source (cout
, c
, buffer
);