9 void get_base_name (char *filename
, char *basename
, size_t len
)
13 temp
= strrchr (filename
, '/');
14 if (temp
) filename
= &temp
[1];
16 strncpy (basename
, filename
, len
- 1);
17 basename
[len
- 1] = '\0';
18 temp
= strchr (basename
, '.');
19 if (temp
) *temp
= '\0';
22 void ident_line (FILE *out
, int size
)
25 for (i
= 0; i
< size
; i
++)
30 void print_subroutine_name (FILE *out
, struct subroutine
*sub
)
33 if (sub
->export
->name
) {
34 fprintf (out
, "%s", sub
->export
->name
);
36 fprintf (out
, "%s_%08X", sub
->export
->libname
, sub
->export
->nid
);
38 } else if (sub
->import
) {
39 if (sub
->import
->name
) {
40 fprintf (out
, "%s", sub
->import
->name
);
42 fprintf (out
, "%s_%08X", sub
->import
->libname
, sub
->import
->nid
);
45 fprintf (out
, "sub_%05X", sub
->begin
->address
);
49 void print_subroutine_declaration (FILE *out
, struct subroutine
*sub
)
52 if (sub
->numregout
> 0)
53 fprintf (out
, "int ");
55 fprintf (out
, "void ");
57 print_subroutine_name (out
, sub
);
60 for (i
= 0; i
< sub
->numregargs
; i
++) {
61 if (i
!= 0) fprintf (out
, ", ");
62 fprintf (out
, "int arg%d", i
+ 1);
67 void print_value (FILE *out
, struct value
*val
)
70 case VAL_CONSTANT
: fprintf (out
, "0x%08X", val
->val
.intval
); break;
72 switch (val
->val
.variable
->type
) {
74 if (val
->val
.variable
->name
.val
.intval
>= REGISTER_GPR_A0
&&
75 val
->val
.variable
->name
.val
.intval
<= REGISTER_GPR_T3
) {
76 fprintf (out
, "arg%d", val
->val
.variable
->name
.val
.intval
- REGISTER_GPR_A0
+ 1);
78 print_value (out
, &val
->val
.variable
->name
);
82 fprintf (out
, "local%d", val
->val
.variable
->info
);
85 fprintf (out
, "0x%08X", val
->val
.variable
->info
);
88 if (val
->val
.variable
->def
->type
!= OP_MOVE
)
90 print_operation (out
, val
->val
.variable
->def
, 0, TRUE
);
91 if (val
->val
.variable
->def
->type
!= OP_MOVE
)
95 print_value (out
, &val
->val
.variable
->name
);
96 fprintf (out
, "/* Invalid block %d %d */",
97 val
->val
.variable
->def
->block
->node
.dfsnum
,
98 val
->val
.variable
->def
->type
);
103 if (val
->val
.intval
== REGISTER_HI
) fprintf (out
, "hi");
104 else if (val
->val
.intval
== REGISTER_LO
) fprintf (out
, "lo");
105 else fprintf (out
, "%s", gpr_names
[val
->val
.intval
]);
108 fprintf (out
, "UNK");
113 void print_asm_reglist (FILE *out
, list regs
, int identsize
, int options
)
118 ident_line (out
, identsize
);
119 fprintf (out
, " : ");
121 el
= list_head (regs
);
123 struct value
*val
= element_getvalue (el
);
124 if (el
!= list_head (regs
))
126 fprintf (out
, "\"=r\"(");
127 print_value (out
, val
);
129 el
= element_next (el
);
134 void print_asm (FILE *out
, struct operation
*op
, int identsize
, int options
)
136 struct location
*loc
;
138 ident_line (out
, identsize
);
139 fprintf (out
, "__asm__ (");
140 for (loc
= op
->info
.asmop
.begin
; ; loc
++) {
141 if (loc
!= op
->info
.asmop
.begin
) {
143 ident_line (out
, identsize
);
146 fprintf (out
, "\"%s\"", allegrex_disassemble (loc
->opc
, loc
->address
, FALSE
));
147 if (loc
== op
->info
.asmop
.end
) break;
149 if (list_size (op
->results
) != 0 || list_size (op
->operands
) != 0) {
150 print_asm_reglist (out
, op
->results
, identsize
, options
);
151 if (list_size (op
->operands
) != 0) {
152 print_asm_reglist (out
, op
->operands
, identsize
, options
);
156 fprintf (out
, ");\n");
160 void print_binaryop (FILE *out
, struct operation
*op
, const char *opsymbol
, int options
)
162 if (!(options
& OPTS_DEFERRED
)) {
163 print_value (out
, list_headvalue (op
->results
));
164 fprintf (out
, " = ");
166 print_value (out
, list_headvalue (op
->operands
));
167 fprintf (out
, " %s ", opsymbol
);
168 print_value (out
, list_tailvalue (op
->operands
));
171 void print_complexop (FILE *out
, struct operation
*op
, const char *opsymbol
, int options
)
175 if (list_size (op
->results
) != 0 && !(options
& OPTS_DEFERRED
)) {
176 print_value (out
, list_headvalue (op
->results
));
177 fprintf (out
, " = ");
180 fprintf (out
, "%s (", opsymbol
);
181 el
= list_head (op
->operands
);
184 val
= element_getvalue (el
);
185 if (val
->type
== VAL_SSAVAR
) {
186 if (val
->val
.variable
->type
== SSAVAR_INVALID
) break;
188 if (el
!= list_head (op
->operands
))
190 print_value (out
, val
);
191 el
= element_next (el
);
196 void print_call (FILE *out
, struct operation
*op
, int options
)
200 if (list_size (op
->info
.callop
.retvalues
) != 0 && !(options
& OPTS_DEFERRED
)) {
201 el
= list_head (op
->info
.callop
.retvalues
);
203 print_value (out
, list_tailvalue (op
->results
));
205 el
= element_next (el
);
210 if (op
->block
->info
.call
.calltarget
) {
211 print_subroutine_name (out
, op
->block
->info
.call
.calltarget
);
213 fprintf (out
, "CALL");
218 el
= list_head (op
->info
.callop
.arguments
);
221 val
= element_getvalue (el
);
222 if (val
->type
== VAL_SSAVAR
) {
223 if (val
->val
.variable
->type
== SSAVAR_INVALID
) break;
225 if (el
!= list_head (op
->info
.callop
.arguments
))
227 print_value (out
, val
);
228 el
= element_next (el
);
234 void print_ext (FILE *out
, struct operation
*op
, int options
)
236 struct value
*val1
, *val2
, *val3
;
240 el
= list_head (op
->operands
);
241 val1
= element_getvalue (el
); el
= element_next (el
);
242 val2
= element_getvalue (el
); el
= element_next (el
);
243 val3
= element_getvalue (el
);
245 mask
= 0xFFFFFFFF >> (32 - val3
->val
.intval
);
246 if (!(options
& OPTS_DEFERRED
)) {
247 print_value (out
, list_headvalue (op
->results
));
248 fprintf (out
, " = ");
252 print_value (out
, val1
);
253 fprintf (out
, " >> %d)", val2
->val
.intval
);
254 fprintf (out
, " & 0x%08X", mask
);
258 void print_ins (FILE *out
, struct operation
*op
, int options
)
260 struct value
*val1
, *val2
, *val3
, *val4
;
264 el
= list_head (op
->operands
);
265 val1
= element_getvalue (el
); el
= element_next (el
);
266 val2
= element_getvalue (el
); el
= element_next (el
);
267 val3
= element_getvalue (el
); el
= element_next (el
);
268 val4
= element_getvalue (el
);
270 mask
= 0xFFFFFFFF >> (32 - val4
->val
.intval
);
271 if (!(options
& OPTS_DEFERRED
)) {
272 print_value (out
, list_headvalue (op
->results
));
273 fprintf (out
, " = ");
277 print_value (out
, val2
);
278 fprintf (out
, " & 0x%08X) | (", ~(mask
<< val3
->val
.intval
));
279 print_value (out
, val1
);
280 fprintf (out
, " & 0x%08X)", mask
);
284 void print_nor (FILE *out
, struct operation
*op
, int options
)
286 struct value
*val1
, *val2
;
289 val1
= list_headvalue (op
->operands
);
290 val2
= list_tailvalue (op
->operands
);
292 if (val1
->val
.intval
== 0 || val2
->val
.intval
== 0) {
294 if (val1
->val
.intval
== 0) val1
= val2
;
297 if (!(options
& OPTS_DEFERRED
)) {
298 print_value (out
, list_headvalue (op
->results
));
299 fprintf (out
, " = ");
304 print_value (out
, val1
);
305 fprintf (out
, " | ");
306 print_value (out
, val2
);
310 print_value (out
, val1
);
315 void print_movnz (FILE *out
, struct operation
*op
, int ismovn
, int options
)
317 struct value
*val1
, *val2
, *val3
;
318 struct value
*result
;
321 el
= list_head (op
->operands
);
322 val1
= element_getvalue (el
); el
= element_next (el
);
323 val2
= element_getvalue (el
); el
= element_next (el
);
324 val3
= element_getvalue (el
);
325 result
= list_headvalue (op
->results
);
327 if (!(options
& OPTS_DEFERRED
)) {
328 print_value (out
, result
);
329 fprintf (out
, " = ");
336 print_value (out
, val2
);
337 fprintf (out
, ") ? ");
338 print_value (out
, val1
);
339 fprintf (out
, " : ");
340 print_value (out
, val3
);
344 void print_slt (FILE *out
, struct operation
*op
, int isunsigned
, int options
)
346 struct value
*val1
, *val2
;
347 struct value
*result
;
350 el
= list_head (op
->operands
);
351 val1
= element_getvalue (el
); el
= element_next (el
);
352 val2
= element_getvalue (el
);
353 result
= list_headvalue (op
->results
);
355 if (!(options
& OPTS_DEFERRED
)) {
356 print_value (out
, result
);
357 fprintf (out
, " = ");
362 print_value (out
, val1
);
363 fprintf (out
, " < ");
364 print_value (out
, val2
);
369 void print_signextend (FILE *out
, struct operation
*op
, int isbyte
, int options
)
371 if (!(options
& OPTS_DEFERRED
)) {
372 print_value (out
, list_headvalue (op
->results
));
373 fprintf (out
, " = ");
377 fprintf (out
, "(char) ");
379 fprintf (out
, "(short) ");
381 print_value (out
, list_headvalue (op
->operands
));
385 void print_memory_address (FILE *out
, struct operation
*op
, int size
, int isunsigned
, int options
)
392 if (isunsigned
) type
= "unsigned char *";
393 else type
= "char *";
394 } else if (size
== 1) {
395 if (isunsigned
) type
= "unsigned short *";
396 else type
= "short *";
397 } else if (size
== 2) {
401 val
= list_headvalue (op
->operands
);
402 if (val
->type
== VAL_SSAVAR
) {
403 if (val
->val
.variable
->type
== SSAVAR_CONSTANT
) {
404 address
= val
->val
.variable
->type
;
405 val
= list_tailvalue (op
->operands
);
406 address
+= val
->val
.intval
;
407 fprintf (out
, "*((%s) 0x%08X)", type
, address
);
412 fprintf (out
, "((%s) ", type
);
413 print_value (out
, val
);
414 val
= list_tailvalue (op
->operands
);
415 fprintf (out
, ")[%d]", val
->val
.intval
>> size
);
419 void print_load (FILE *out
, struct operation
*op
, int size
, int isunsigned
, int options
)
421 if (!(options
& OPTS_DEFERRED
)) {
422 print_value (out
, list_headvalue (op
->results
));
423 fprintf (out
, " = ");
425 print_memory_address (out
, op
, size
, isunsigned
, options
);
429 void print_store (FILE *out
, struct operation
*op
, int size
, int isunsigned
, int options
)
431 struct value
*val
= element_getvalue (element_next (list_head (op
->operands
)));
432 print_memory_address (out
, op
, size
, isunsigned
, options
);
433 fprintf (out
, " = ");
434 print_value (out
, val
);
438 void print_condition (FILE *out
, struct operation
*op
, int options
)
440 fprintf (out
, "if (");
441 if (options
& OPTS_REVERSECOND
) fprintf (out
, "!(");
442 print_value (out
, list_headvalue (op
->operands
));
443 switch (op
->info
.iop
.insn
) {
445 fprintf (out
, " != ");
448 fprintf (out
, " == ");
452 fprintf (out
, " >= 0");
455 fprintf (out
, " > 0");
458 fprintf (out
, " <= 0");
462 fprintf (out
, " < 0");
467 if (list_size (op
->operands
) == 2)
468 print_value (out
, list_tailvalue (op
->operands
));
470 if (options
& OPTS_REVERSECOND
) fprintf (out
, ")");
476 void print_operation (FILE *out
, struct operation
*op
, int identsize
, int options
)
478 struct location
*loc
;
479 int nosemicolon
= FALSE
;
481 if (op
->type
== OP_ASM
) {
482 print_asm (out
, op
, identsize
, options
);
486 if (op
->type
== OP_INSTRUCTION
) {
487 if (op
->info
.iop
.loc
->insn
->flags
& (INSN_JUMP
))
489 } else if (op
->type
== OP_NOP
|| op
->type
== OP_START
||
490 op
->type
== OP_END
|| op
->type
== OP_PHI
) {
494 loc
= op
->info
.iop
.loc
;
495 if (op
->type
== OP_INSTRUCTION
) {
496 if (loc
->branchalways
) return;
499 ident_line (out
, identsize
);
500 if (op
->type
== OP_INSTRUCTION
) {
501 switch (op
->info
.iop
.insn
) {
502 case I_ADD
: print_binaryop (out
, op
, "+", options
); break;
503 case I_ADDU
: print_binaryop (out
, op
, "+", options
); break;
504 case I_SUB
: print_binaryop (out
, op
, "-", options
); break;
505 case I_SUBU
: print_binaryop (out
, op
, "-", options
); break;
506 case I_XOR
: print_binaryop (out
, op
, "^", options
); break;
507 case I_AND
: print_binaryop (out
, op
, "&", options
); break;
508 case I_OR
: print_binaryop (out
, op
, "|", options
); break;
509 case I_SRAV
: print_binaryop (out
, op
, ">>", options
); break;
510 case I_SRLV
: print_binaryop (out
, op
, ">>", options
); break;
511 case I_SLLV
: print_binaryop (out
, op
, "<<", options
); break;
512 case I_INS
: print_ins (out
, op
, options
); break;
513 case I_EXT
: print_ext (out
, op
, options
); break;
514 case I_MIN
: print_complexop (out
, op
, "MIN", options
); break;
515 case I_MAX
: print_complexop (out
, op
, "MAX", options
); break;
516 case I_BITREV
: print_complexop (out
, op
, "BITREV", options
); break;
517 case I_CLZ
: print_complexop (out
, op
, "CLZ", options
); break;
518 case I_CLO
: print_complexop (out
, op
, "CLO", options
); break;
519 case I_NOR
: print_nor (out
, op
, options
); break;
520 case I_MOVN
: print_movnz (out
, op
, TRUE
, options
); break;
521 case I_MOVZ
: print_movnz (out
, op
, FALSE
, options
); break;
522 case I_SLT
: print_slt (out
, op
, FALSE
, options
); break;
523 case I_SLTU
: print_slt (out
, op
, TRUE
, options
); break;
524 case I_LW
: print_load (out
, op
, 2, FALSE
, options
); break;
525 case I_LB
: print_load (out
, op
, 0, FALSE
, options
); break;
526 case I_LBU
: print_load (out
, op
, 0, TRUE
, options
); break;
527 case I_LH
: print_load (out
, op
, 1, FALSE
, options
); break;
528 case I_LHU
: print_load (out
, op
, 1, TRUE
, options
); break;
529 case I_LL
: print_complexop (out
, op
, "LL", options
); break;
530 case I_LWL
: print_complexop (out
, op
, "LWL", options
); break;
531 case I_LWR
: print_complexop (out
, op
, "LWR", options
); break;
532 case I_SW
: print_store (out
, op
, 2, FALSE
, options
); break;
533 case I_SH
: print_store (out
, op
, 1, FALSE
, options
); break;
534 case I_SB
: print_store (out
, op
, 0, FALSE
, options
); break;
535 case I_SC
: print_complexop (out
, op
, "SC", options
); break;
536 case I_SWL
: print_complexop (out
, op
, "SWL", options
); break;
537 case I_SWR
: print_complexop (out
, op
, "SWR", options
); break;
538 case I_SEB
: print_signextend (out
, op
, TRUE
, options
); break;
539 case I_SEH
: print_signextend (out
, op
, TRUE
, options
); break;
541 if (loc
->insn
->flags
& INSN_BRANCH
) {
542 print_condition (out
, op
, options
);
547 } else if (op
->type
== OP_MOVE
) {
549 print_value (out
, list_headvalue (op
->results
));
550 fprintf (out
, " = ");
552 print_value (out
, list_headvalue (op
->operands
));
553 } else if (op
->type
== OP_CALL
) {
554 print_call (out
, op
, options
);
557 if (!(options
& OPTS_DEFERRED
)) {
558 if (nosemicolon
) fprintf (out
, "\n");
559 else fprintf (out
, ";\n");