2 * Author: Humberto Naves (hsnaves@gmail.com)
13 void print_block (FILE *out
, struct basicblock
*block
, int identsize
, int reversecond
)
16 struct operation
*jumpop
= NULL
;
19 if (reversecond
) options
|= OPTS_REVERSECOND
;
20 opel
= list_head (block
->operations
);
22 struct operation
*op
= element_getvalue (opel
);
23 if (!(op
->status
& OP_STAT_DEFERRED
)) {
24 if (op
->type
== OP_INSTRUCTION
) {
25 if (op
->info
.iop
.loc
->insn
->flags
& (INSN_JUMP
| INSN_BRANCH
))
29 print_operation (out
, op
, identsize
, options
);
31 opel
= element_next (opel
);
34 print_operation (out
, jumpop
, identsize
, options
);
38 void print_block_recursive (FILE *out
, struct basicblock
*block
)
41 struct basicedge
*edge
;
42 int identsize
= block
->st
->identsize
;
43 int revcond
= block
->status
& BLOCK_STAT_REVCOND
;
44 int first
= TRUE
, isloop
= FALSE
;
46 if (block
->status
& BLOCK_STAT_ISSWITCHTARGET
) {
47 ref
= list_head (block
->inrefs
);
49 edge
= element_getvalue (ref
);
50 if (edge
->from
->status
& BLOCK_STAT_ISSWITCH
) {
51 ident_line (out
, identsize
);
52 fprintf (out
, "case %d:\n", edge
->fromnum
);
54 ref
= element_next (ref
);
58 if (block
->status
& BLOCK_STAT_HASLABEL
) {
60 ident_line (out
, identsize
);
61 fprintf (out
, "label%d:\n", block
->node
.dfsnum
);
64 if (block
->st
->start
== block
&& block
->st
->type
== CONTROL_LOOP
) {
66 ident_line (out
, identsize
);
67 fprintf (out
, "while (1) {\n");
71 print_block (out
, block
, identsize
+ 1, revcond
);
73 if (block
->status
& BLOCK_STAT_ISSWITCH
) {
75 ident_line (out
, identsize
+ 1);
76 fprintf (out
, "switch () {\n");
79 if (revcond
) ref
= list_head (block
->outrefs
);
80 else ref
= list_tail (block
->outrefs
);
83 edge
= element_getvalue (ref
);
84 if (edge
->type
!= EDGE_CASE
&& edge
->type
!= EDGE_NEXT
&&
85 edge
->type
!= EDGE_IFEXIT
&& edge
->type
!= EDGE_UNKNOWN
) {
86 ident_line (out
, identsize
+ 1);
87 if (first
&& list_size (block
->outrefs
) == 2 &&
88 !(block
->status
& BLOCK_STAT_ISSWITCH
) && edge
->type
!= EDGE_IFENTER
)
94 fprintf (out
, "break;\n");
97 fprintf (out
, "continue;\n");
101 fprintf (out
, "goto label%d;\n", edge
->to
->node
.dfsnum
);
107 if (!edge
->to
->mark1
)
108 print_block_recursive (out
, edge
->to
);
111 print_block_recursive (out
, edge
->to
);
114 fprintf (out
, "{\n");
115 print_block_recursive (out
, edge
->to
);
116 ident_line (out
, identsize
+ 1);
117 fprintf (out
, "}\n");
121 if (revcond
) ref
= element_next (ref
);
122 else ref
= element_previous (ref
);
124 if ((block
->status
& BLOCK_STAT_HASELSE
) && ref
) {
125 ident_line (out
, identsize
+ 1);
126 fprintf (out
, "else\n");
132 if (block
->ifst
->hasendgoto
) {
133 ident_line (out
, identsize
+ 1);
134 fprintf (out
, "goto label%d;\n", block
->ifst
->end
->node
.dfsnum
);
135 } else if (block
->ifst
->info
.ifctrl
.endfollow
) {
136 print_block_recursive (out
, block
->ifst
->end
);
140 if (block
->status
& BLOCK_STAT_ISSWITCH
) {
141 ident_line (out
, identsize
+ 1);
142 fprintf (out
, "}\n");
145 if (block
->st
->start
== block
&& block
->st
->type
== CONTROL_LOOP
) {
146 ident_line (out
, identsize
);
147 fprintf (out
, "}\n");
148 if (block
->st
->hasendgoto
) {
149 ident_line (out
, identsize
);
150 fprintf (out
, "goto label%d;\n", block
->st
->end
->node
.dfsnum
);
152 print_block_recursive (out
, block
->st
->end
);
159 void print_subroutine (FILE *out
, struct subroutine
*sub
)
161 if (sub
->import
) { return; }
163 fprintf (out
, "/**\n * Subroutine at address 0x%08X\n", sub
->begin
->address
);
164 fprintf (out
, " */\n");
165 print_subroutine_declaration (out
, sub
);
166 fprintf (out
, "\n{\n");
169 struct location
*loc
;
170 for (loc
= sub
->begin
; ; loc
++) {
171 fprintf (out
, "%s\n", allegrex_disassemble (loc
->opc
, loc
->address
, TRUE
));
172 if (loc
== sub
->end
) break;
178 el
= list_head (sub
->blocks
);
180 struct basicblock
*block
= element_getvalue (el
);
182 print_block_recursive (out
, block
);
183 el
= element_next (el
);
186 fprintf (out
, "}\n\n");
190 void print_source (FILE *out
, struct code
*c
, char *headerfilename
)
195 fprintf (out
, "#include <pspsdk.h>\n");
196 fprintf (out
, "#include \"%s\"\n\n", headerfilename
);
198 for (i
= 0; i
< c
->file
->modinfo
->numimports
; i
++) {
199 struct prx_import
*imp
= &c
->file
->modinfo
->imports
[i
];
201 fprintf (out
, "/*\n * Imports from library: %s\n */\n", imp
->name
);
202 for (j
= 0; j
< imp
->nfuncs
; j
++) {
203 struct prx_function
*func
= &imp
->funcs
[j
];
205 fprintf (out
, "extern ");
206 print_subroutine_declaration (out
, func
->pfunc
);
207 fprintf (out
, ";\n");
213 el
= list_head (c
->subroutines
);
215 struct subroutine
*sub
;
216 sub
= element_getvalue (el
);
218 print_subroutine (out
, sub
);
219 el
= element_next (el
);
225 void print_header (FILE *out
, struct code
*c
, char *headerfilename
)
231 while (pos
< sizeof (buffer
) - 1) {
232 char c
= headerfilename
[pos
];
234 if (c
== '.') c
= '_';
235 else c
= toupper (c
);
240 fprintf (out
, "#ifndef __%s\n", buffer
);
241 fprintf (out
, "#define __%s\n\n", buffer
);
243 for (i
= 0; i
< c
->file
->modinfo
->numexports
; i
++) {
244 struct prx_export
*exp
= &c
->file
->modinfo
->exports
[i
];
246 fprintf (out
, "/*\n * Exports from library: %s\n */\n", exp
->name
);
247 for (j
= 0; j
< exp
->nfuncs
; j
++) {
248 struct prx_function
*func
= &exp
->funcs
[j
];
250 fprintf (out
, "void %s (void);\n",func
->name
);
252 fprintf (out
, "void %s_%08X (void);\n", exp
->name
, func
->nid
);
258 fprintf (out
, "#endif /* __%s */\n", buffer
);
262 int print_code (struct code
*c
, char *prxname
)
269 get_base_name (prxname
, basename
, sizeof (basename
));
270 sprintf (buffer
, "%s.c", basename
);
272 cout
= fopen (buffer
, "w");
274 xerror (__FILE__
": can't open file for writing `%s'", buffer
);
278 sprintf (buffer
, "%s.h", basename
);
279 hout
= fopen (buffer
, "w");
281 xerror (__FILE__
": can't open file for writing `%s'", buffer
);
286 print_header (hout
, c
, buffer
);
287 print_source (cout
, c
, buffer
);