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_value (FILE *out
, struct value
*val
)
52 case VAL_CONSTANT
: fprintf (out
, "0x%08X", val
->val
.intval
); break;
54 switch (val
->val
.variable
->type
) {
55 case VARIABLE_ARGUMENT
:
56 if (val
->val
.variable
->name
.val
.intval
>= REGISTER_GPR_A0
&&
57 val
->val
.variable
->name
.val
.intval
<= REGISTER_GPR_T3
) {
58 fprintf (out
, "arg%d", val
->val
.variable
->name
.val
.intval
- REGISTER_GPR_A0
+ 1);
60 print_value (out
, &val
->val
.variable
->name
);
64 fprintf (out
, "local%d", val
->val
.variable
->info
);
66 case VARIABLE_CONSTANT
:
67 fprintf (out
, "0x%08X", val
->val
.variable
->info
);
70 if (val
->val
.variable
->def
->type
!= OP_MOVE
)
72 print_operation (out
, val
->val
.variable
->def
, 0, TRUE
);
73 if (val
->val
.variable
->def
->type
!= OP_MOVE
)
77 print_value (out
, &val
->val
.variable
->name
);
78 fprintf (out
, "/* Invalid block %d %d */",
79 val
->val
.variable
->def
->block
->node
.dfsnum
,
80 val
->val
.variable
->def
->type
);
85 if (val
->val
.intval
== REGISTER_HI
) fprintf (out
, "hi");
86 else if (val
->val
.intval
== REGISTER_LO
) fprintf (out
, "lo");
87 else fprintf (out
, "%s", gpr_names
[val
->val
.intval
]);
95 void print_asm_reglist (FILE *out
, list regs
, int identsize
, int options
)
100 ident_line (out
, identsize
);
101 fprintf (out
, " : ");
103 el
= list_head (regs
);
105 struct value
*val
= element_getvalue (el
);
106 if (el
!= list_head (regs
))
108 fprintf (out
, "\"=r\"(");
109 print_value (out
, val
);
111 el
= element_next (el
);
116 void print_asm (FILE *out
, struct operation
*op
, int identsize
, int options
)
118 struct location
*loc
;
120 ident_line (out
, identsize
);
121 fprintf (out
, "__asm__ (");
122 for (loc
= op
->info
.asmop
.begin
; ; loc
++) {
123 if (loc
!= op
->info
.asmop
.begin
) {
125 ident_line (out
, identsize
);
128 fprintf (out
, "\"%s\"", allegrex_disassemble (loc
->opc
, loc
->address
, FALSE
));
129 if (loc
== op
->info
.asmop
.end
) break;
131 if (list_size (op
->results
) != 0 || list_size (op
->operands
) != 0) {
132 print_asm_reglist (out
, op
->results
, identsize
, options
);
133 if (list_size (op
->operands
) != 0) {
134 print_asm_reglist (out
, op
->operands
, identsize
, options
);
138 fprintf (out
, ");\n");
142 void print_binaryop (FILE *out
, struct operation
*op
, const char *opsymbol
, int options
)
144 if (!(options
& OPTS_DEFERRED
)) {
145 print_value (out
, list_headvalue (op
->results
));
146 fprintf (out
, " = ");
148 print_value (out
, list_headvalue (op
->operands
));
149 fprintf (out
, " %s ", opsymbol
);
150 print_value (out
, list_tailvalue (op
->operands
));
153 void print_complexop (FILE *out
, struct operation
*op
, const char *opsymbol
, int options
)
157 if (list_size (op
->results
) != 0 && !(options
& OPTS_DEFERRED
)) {
158 print_value (out
, list_headvalue (op
->results
));
159 fprintf (out
, " = ");
162 fprintf (out
, "%s (", opsymbol
);
163 el
= list_head (op
->operands
);
166 val
= element_getvalue (el
);
167 if (val
->type
== VAL_VARIABLE
) {
168 if (val
->val
.variable
->type
== VARIABLE_INVALID
) break;
170 if (el
!= list_head (op
->operands
))
172 print_value (out
, val
);
173 el
= element_next (el
);
178 void print_call (FILE *out
, struct operation
*op
, int options
)
182 if (list_size (op
->info
.callop
.retvalues
) != 0 && !(options
& OPTS_DEFERRED
)) {
183 el
= list_head (op
->info
.callop
.retvalues
);
185 print_value (out
, list_tailvalue (op
->results
));
187 el
= element_next (el
);
192 if (op
->block
->info
.call
.calltarget
) {
193 print_subroutine_name (out
, op
->block
->info
.call
.calltarget
);
195 fprintf (out
, "CALL");
200 el
= list_head (op
->info
.callop
.arguments
);
203 val
= element_getvalue (el
);
204 if (val
->type
== VAL_VARIABLE
) {
205 if (val
->val
.variable
->type
== VARIABLE_INVALID
) break;
207 if (el
!= list_head (op
->info
.callop
.arguments
))
209 print_value (out
, val
);
210 el
= element_next (el
);
216 void print_ext (FILE *out
, struct operation
*op
, int options
)
218 struct value
*val1
, *val2
, *val3
;
222 el
= list_head (op
->operands
);
223 val1
= element_getvalue (el
); el
= element_next (el
);
224 val2
= element_getvalue (el
); el
= element_next (el
);
225 val3
= element_getvalue (el
);
227 mask
= 0xFFFFFFFF >> (32 - val3
->val
.intval
);
228 if (!(options
& OPTS_DEFERRED
)) {
229 print_value (out
, list_headvalue (op
->results
));
230 fprintf (out
, " = ");
234 print_value (out
, val1
);
235 fprintf (out
, " >> %d)", val2
->val
.intval
);
236 fprintf (out
, " & 0x%08X", mask
);
240 void print_ins (FILE *out
, struct operation
*op
, int options
)
242 struct value
*val1
, *val2
, *val3
, *val4
;
246 el
= list_head (op
->operands
);
247 val1
= element_getvalue (el
); el
= element_next (el
);
248 val2
= element_getvalue (el
); el
= element_next (el
);
249 val3
= element_getvalue (el
); el
= element_next (el
);
250 val4
= element_getvalue (el
);
252 mask
= 0xFFFFFFFF >> (32 - val4
->val
.intval
);
253 if (!(options
& OPTS_DEFERRED
)) {
254 print_value (out
, list_headvalue (op
->results
));
255 fprintf (out
, " = ");
259 print_value (out
, val2
);
260 fprintf (out
, " & 0x%08X) | (", ~(mask
<< val3
->val
.intval
));
261 print_value (out
, val1
);
262 fprintf (out
, " & 0x%08X)", mask
);
266 void print_nor (FILE *out
, struct operation
*op
, int options
)
268 struct value
*val1
, *val2
;
271 val1
= list_headvalue (op
->operands
);
272 val2
= list_tailvalue (op
->operands
);
274 if (val1
->val
.intval
== 0 || val2
->val
.intval
== 0) {
276 if (val1
->val
.intval
== 0) val1
= val2
;
279 if (!(options
& OPTS_DEFERRED
)) {
280 print_value (out
, list_headvalue (op
->results
));
281 fprintf (out
, " = ");
286 print_value (out
, val1
);
287 fprintf (out
, " | ");
288 print_value (out
, val2
);
292 print_value (out
, val1
);
297 void print_movnz (FILE *out
, struct operation
*op
, int ismovn
, int options
)
299 struct value
*val1
, *val2
, *val3
;
300 struct value
*result
;
303 el
= list_head (op
->operands
);
304 val1
= element_getvalue (el
); el
= element_next (el
);
305 val2
= element_getvalue (el
); el
= element_next (el
);
306 val3
= element_getvalue (el
);
307 result
= list_headvalue (op
->results
);
309 if (!(options
& OPTS_DEFERRED
)) {
310 print_value (out
, result
);
311 fprintf (out
, " = ");
318 print_value (out
, val2
);
319 fprintf (out
, ") ? ");
320 print_value (out
, val1
);
321 fprintf (out
, " : ");
322 print_value (out
, val3
);
326 void print_slt (FILE *out
, struct operation
*op
, int isunsigned
, int options
)
328 struct value
*val1
, *val2
;
329 struct value
*result
;
332 el
= list_head (op
->operands
);
333 val1
= element_getvalue (el
); el
= element_next (el
);
334 val2
= element_getvalue (el
);
335 result
= list_headvalue (op
->results
);
337 if (!(options
& OPTS_DEFERRED
)) {
338 print_value (out
, result
);
339 fprintf (out
, " = ");
344 print_value (out
, val1
);
345 fprintf (out
, " < ");
346 print_value (out
, val2
);
351 void print_signextend (FILE *out
, struct operation
*op
, int isbyte
, int options
)
353 if (!(options
& OPTS_DEFERRED
)) {
354 print_value (out
, list_headvalue (op
->results
));
355 fprintf (out
, " = ");
359 fprintf (out
, "(char) ");
361 fprintf (out
, "(short) ");
363 print_value (out
, list_headvalue (op
->operands
));
367 void print_memory_address (FILE *out
, struct operation
*op
, int size
, int isunsigned
, int options
)
374 if (isunsigned
) type
= "unsigned char *";
375 else type
= "char *";
376 } else if (size
== 1) {
377 if (isunsigned
) type
= "unsigned short *";
378 else type
= "short *";
379 } else if (size
== 2) {
383 val
= list_headvalue (op
->operands
);
384 if (val
->type
== VAL_VARIABLE
) {
385 if (val
->val
.variable
->type
== VARIABLE_CONSTANT
) {
386 address
= val
->val
.variable
->type
;
387 val
= list_tailvalue (op
->operands
);
388 address
+= val
->val
.intval
;
389 fprintf (out
, "*((%s) 0x%08X)", type
, address
);
394 fprintf (out
, "((%s) ", type
);
395 print_value (out
, val
);
396 val
= list_tailvalue (op
->operands
);
397 fprintf (out
, ")[%d]", val
->val
.intval
>> size
);
401 void print_load (FILE *out
, struct operation
*op
, int size
, int isunsigned
, int options
)
403 if (!(options
& OPTS_DEFERRED
)) {
404 print_value (out
, list_headvalue (op
->results
));
405 fprintf (out
, " = ");
407 print_memory_address (out
, op
, size
, isunsigned
, options
);
411 void print_store (FILE *out
, struct operation
*op
, int size
, int isunsigned
, int options
)
413 struct value
*val
= element_getvalue (element_next (list_head (op
->operands
)));
414 print_memory_address (out
, op
, size
, isunsigned
, options
);
415 fprintf (out
, " = ");
416 print_value (out
, val
);
420 void print_condition (FILE *out
, struct operation
*op
, int options
)
422 fprintf (out
, "if (");
423 if (options
& OPTS_REVERSECOND
) fprintf (out
, "!(");
424 print_value (out
, list_headvalue (op
->operands
));
425 switch (op
->info
.iop
.insn
) {
427 fprintf (out
, " != ");
430 fprintf (out
, " == ");
434 fprintf (out
, " >= 0");
437 fprintf (out
, " > 0");
440 fprintf (out
, " <= 0");
444 fprintf (out
, " < 0");
449 if (list_size (op
->operands
) == 2)
450 print_value (out
, list_tailvalue (op
->operands
));
452 if (options
& OPTS_REVERSECOND
) fprintf (out
, ")");
458 void print_operation (FILE *out
, struct operation
*op
, int identsize
, int options
)
460 int nosemicolon
= FALSE
;
462 if (op
->type
== OP_ASM
) {
463 print_asm (out
, op
, identsize
, options
);
467 if (op
->type
== OP_INSTRUCTION
) {
468 if (op
->info
.iop
.loc
->insn
->flags
& (INSN_JUMP
))
470 } else if (op
->type
== OP_NOP
|| op
->type
== OP_START
||
471 op
->type
== OP_END
|| op
->type
== OP_PHI
) {
475 ident_line (out
, identsize
);
476 if (op
->type
== OP_INSTRUCTION
) {
477 switch (op
->info
.iop
.insn
) {
478 case I_ADD
: print_binaryop (out
, op
, "+", options
); break;
479 case I_ADDU
: print_binaryop (out
, op
, "+", options
); break;
480 case I_SUB
: print_binaryop (out
, op
, "-", options
); break;
481 case I_SUBU
: print_binaryop (out
, op
, "-", options
); break;
482 case I_XOR
: print_binaryop (out
, op
, "^", options
); break;
483 case I_AND
: print_binaryop (out
, op
, "&", options
); break;
484 case I_OR
: print_binaryop (out
, op
, "|", options
); break;
485 case I_SRAV
: print_binaryop (out
, op
, ">>", options
); break;
486 case I_SRLV
: print_binaryop (out
, op
, ">>", options
); break;
487 case I_SLLV
: print_binaryop (out
, op
, "<<", options
); break;
488 case I_INS
: print_ins (out
, op
, options
); break;
489 case I_EXT
: print_ext (out
, op
, options
); break;
490 case I_MIN
: print_complexop (out
, op
, "MIN", options
); break;
491 case I_MAX
: print_complexop (out
, op
, "MAX", options
); break;
492 case I_BITREV
: print_complexop (out
, op
, "BITREV", options
); break;
493 case I_CLZ
: print_complexop (out
, op
, "CLZ", options
); break;
494 case I_CLO
: print_complexop (out
, op
, "CLO", options
); break;
495 case I_NOR
: print_nor (out
, op
, options
); break;
496 case I_MOVN
: print_movnz (out
, op
, TRUE
, options
); break;
497 case I_MOVZ
: print_movnz (out
, op
, FALSE
, options
); break;
498 case I_SLT
: print_slt (out
, op
, FALSE
, options
); break;
499 case I_SLTU
: print_slt (out
, op
, TRUE
, options
); break;
500 case I_LW
: print_load (out
, op
, 2, FALSE
, options
); break;
501 case I_LB
: print_load (out
, op
, 0, FALSE
, options
); break;
502 case I_LBU
: print_load (out
, op
, 0, TRUE
, options
); break;
503 case I_LH
: print_load (out
, op
, 1, FALSE
, options
); break;
504 case I_LHU
: print_load (out
, op
, 1, TRUE
, options
); break;
505 case I_LL
: print_complexop (out
, op
, "LL", options
); break;
506 case I_LWL
: print_complexop (out
, op
, "LWL", options
); break;
507 case I_LWR
: print_complexop (out
, op
, "LWR", options
); break;
508 case I_SW
: print_store (out
, op
, 2, FALSE
, options
); break;
509 case I_SH
: print_store (out
, op
, 1, FALSE
, options
); break;
510 case I_SB
: print_store (out
, op
, 0, FALSE
, options
); break;
511 case I_SC
: print_complexop (out
, op
, "SC", options
); break;
512 case I_SWL
: print_complexop (out
, op
, "SWL", options
); break;
513 case I_SWR
: print_complexop (out
, op
, "SWR", options
); break;
514 case I_SEB
: print_signextend (out
, op
, TRUE
, options
); break;
515 case I_SEH
: print_signextend (out
, op
, TRUE
, options
); break;
517 if (op
->info
.iop
.loc
->insn
->flags
& INSN_BRANCH
) {
518 print_condition (out
, op
, options
);
523 } else if (op
->type
== OP_MOVE
) {
525 print_value (out
, list_headvalue (op
->results
));
526 fprintf (out
, " = ");
528 print_value (out
, list_headvalue (op
->operands
));
529 } else if (op
->type
== OP_CALL
) {
530 print_call (out
, op
, options
);
533 if (!(options
& OPTS_DEFERRED
)) {
534 if (nosemicolon
) fprintf (out
, "\n");
535 else fprintf (out
, ";\n");