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 fprintf (out
, "arg%d", val
->val
.variable
->name
.val
.intval
);
59 fprintf (out
, "local%d", val
->val
.variable
->info
);
61 case VARIABLE_CONSTANT
:
62 fprintf (out
, "0x%08X", val
->val
.variable
->info
);
65 if (val
->val
.variable
->def
->type
!= OP_MOVE
)
67 print_operation (out
, val
->val
.variable
->def
, 0, TRUE
);
68 if (val
->val
.variable
->def
->type
!= OP_MOVE
)
72 print_value (out
, &val
->val
.variable
->name
);
73 fprintf (out
, "/* Invalid block %d %d */",
74 val
->val
.variable
->def
->block
->node
.dfsnum
,
75 val
->val
.variable
->def
->type
);
80 if (val
->val
.intval
== REGISTER_HI
) fprintf (out
, "hi");
81 else if (val
->val
.intval
== REGISTER_LO
) fprintf (out
, "lo");
82 else fprintf (out
, "%s", gpr_names
[val
->val
.intval
]);
90 void print_asm_reglist (FILE *out
, list regs
, int identsize
, int options
)
95 ident_line (out
, identsize
);
98 el
= list_head (regs
);
100 struct value
*val
= element_getvalue (el
);
101 if (el
!= list_head (regs
))
103 fprintf (out
, "\"=r\"(");
104 print_value (out
, val
);
106 el
= element_next (el
);
111 void print_asm (FILE *out
, struct operation
*op
, int identsize
, int options
)
113 struct location
*loc
;
115 ident_line (out
, identsize
);
116 fprintf (out
, "__asm__ (");
117 for (loc
= op
->info
.asmop
.begin
; ; loc
++) {
118 if (loc
!= op
->info
.asmop
.begin
) {
120 ident_line (out
, identsize
);
123 fprintf (out
, "\"%s\"", allegrex_disassemble (loc
->opc
, loc
->address
, FALSE
));
124 if (loc
== op
->info
.asmop
.end
) break;
126 if (list_size (op
->results
) != 0 || list_size (op
->operands
) != 0) {
127 print_asm_reglist (out
, op
->results
, identsize
, options
);
128 if (list_size (op
->operands
) != 0) {
129 print_asm_reglist (out
, op
->operands
, identsize
, options
);
133 fprintf (out
, ");\n");
137 void print_binaryop (FILE *out
, struct operation
*op
, const char *opsymbol
, int options
)
139 if (!(options
& OPTS_DEFERRED
)) {
140 print_value (out
, list_headvalue (op
->results
));
141 fprintf (out
, " = ");
143 print_value (out
, list_headvalue (op
->operands
));
144 fprintf (out
, " %s ", opsymbol
);
145 print_value (out
, list_tailvalue (op
->operands
));
148 void print_complexop (FILE *out
, struct operation
*op
, const char *opsymbol
, int options
)
152 if (list_size (op
->results
) != 0 && !(options
& OPTS_DEFERRED
)) {
153 print_value (out
, list_headvalue (op
->results
));
154 fprintf (out
, " = ");
157 fprintf (out
, "%s (", opsymbol
);
158 el
= list_head (op
->operands
);
161 val
= element_getvalue (el
);
162 if (val
->type
== VAL_VARIABLE
) {
163 if (val
->val
.variable
->type
== VARIABLE_INVALID
) break;
165 if (el
!= list_head (op
->operands
))
167 print_value (out
, val
);
168 el
= element_next (el
);
173 void print_call (FILE *out
, struct operation
*op
, int options
)
177 if (list_size (op
->info
.callop
.retvalues
) != 0 && !(options
& OPTS_DEFERRED
)) {
178 el
= list_head (op
->info
.callop
.retvalues
);
180 print_value (out
, list_tailvalue (op
->results
));
182 el
= element_next (el
);
187 if (op
->block
->info
.call
.calltarget
) {
188 print_subroutine_name (out
, op
->block
->info
.call
.calltarget
);
190 fprintf (out
, "CALL");
195 el
= list_head (op
->info
.callop
.arguments
);
198 val
= element_getvalue (el
);
199 if (val
->type
== VAL_VARIABLE
) {
200 if (val
->val
.variable
->type
== VARIABLE_INVALID
) break;
202 if (el
!= list_head (op
->info
.callop
.arguments
))
204 print_value (out
, val
);
205 el
= element_next (el
);
211 void print_ext (FILE *out
, struct operation
*op
, int options
)
213 struct value
*val1
, *val2
, *val3
;
217 el
= list_head (op
->operands
);
218 val1
= element_getvalue (el
); el
= element_next (el
);
219 val2
= element_getvalue (el
); el
= element_next (el
);
220 val3
= element_getvalue (el
);
222 mask
= 0xFFFFFFFF >> (32 - val3
->val
.intval
);
223 if (!(options
& OPTS_DEFERRED
)) {
224 print_value (out
, list_headvalue (op
->results
));
225 fprintf (out
, " = ");
229 print_value (out
, val1
);
230 fprintf (out
, " >> %d)", val2
->val
.intval
);
231 fprintf (out
, " & 0x%08X", mask
);
235 void print_ins (FILE *out
, struct operation
*op
, int options
)
237 struct value
*val1
, *val2
, *val3
, *val4
;
241 el
= list_head (op
->operands
);
242 val1
= element_getvalue (el
); el
= element_next (el
);
243 val2
= element_getvalue (el
); el
= element_next (el
);
244 val3
= element_getvalue (el
); el
= element_next (el
);
245 val4
= element_getvalue (el
);
247 mask
= 0xFFFFFFFF >> (32 - val4
->val
.intval
);
248 if (!(options
& OPTS_DEFERRED
)) {
249 print_value (out
, list_headvalue (op
->results
));
250 fprintf (out
, " = ");
254 print_value (out
, val2
);
255 fprintf (out
, " & 0x%08X) | (", ~(mask
<< val3
->val
.intval
));
256 print_value (out
, val1
);
257 fprintf (out
, " & 0x%08X)", mask
);
261 void print_nor (FILE *out
, struct operation
*op
, int options
)
263 struct value
*val1
, *val2
;
266 val1
= list_headvalue (op
->operands
);
267 val2
= list_tailvalue (op
->operands
);
269 if (val1
->val
.intval
== 0 || val2
->val
.intval
== 0) {
271 if (val1
->val
.intval
== 0) val1
= val2
;
274 if (!(options
& OPTS_DEFERRED
)) {
275 print_value (out
, list_headvalue (op
->results
));
276 fprintf (out
, " = ");
281 print_value (out
, val1
);
282 fprintf (out
, " | ");
283 print_value (out
, val2
);
287 print_value (out
, val1
);
292 void print_movnz (FILE *out
, struct operation
*op
, int ismovn
, int options
)
294 struct value
*val1
, *val2
, *val3
;
295 struct value
*result
;
298 el
= list_head (op
->operands
);
299 val1
= element_getvalue (el
); el
= element_next (el
);
300 val2
= element_getvalue (el
); el
= element_next (el
);
301 val3
= element_getvalue (el
);
302 result
= list_headvalue (op
->results
);
304 if (!(options
& OPTS_DEFERRED
)) {
305 print_value (out
, result
);
306 fprintf (out
, " = ");
313 print_value (out
, val2
);
314 fprintf (out
, ") ? ");
315 print_value (out
, val1
);
316 fprintf (out
, " : ");
317 print_value (out
, val3
);
321 void print_slt (FILE *out
, struct operation
*op
, int isunsigned
, int options
)
323 struct value
*val1
, *val2
;
324 struct value
*result
;
327 el
= list_head (op
->operands
);
328 val1
= element_getvalue (el
); el
= element_next (el
);
329 val2
= element_getvalue (el
);
330 result
= list_headvalue (op
->results
);
332 if (!(options
& OPTS_DEFERRED
)) {
333 print_value (out
, result
);
334 fprintf (out
, " = ");
339 print_value (out
, val1
);
340 fprintf (out
, " < ");
341 print_value (out
, val2
);
346 void print_signextend (FILE *out
, struct operation
*op
, int isbyte
, int options
)
348 if (!(options
& OPTS_DEFERRED
)) {
349 print_value (out
, list_headvalue (op
->results
));
350 fprintf (out
, " = ");
354 fprintf (out
, "(char) ");
356 fprintf (out
, "(short) ");
358 print_value (out
, list_headvalue (op
->operands
));
362 void print_memory_address (FILE *out
, struct operation
*op
, int size
, int isunsigned
, int options
)
369 if (isunsigned
) type
= "unsigned char *";
370 else type
= "char *";
371 } else if (size
== 1) {
372 if (isunsigned
) type
= "unsigned short *";
373 else type
= "short *";
374 } else if (size
== 2) {
378 val
= list_headvalue (op
->operands
);
379 if (val
->type
== VAL_VARIABLE
) {
380 if (val
->val
.variable
->type
== VARIABLE_CONSTANT
) {
381 address
= val
->val
.variable
->type
;
382 val
= list_tailvalue (op
->operands
);
383 address
+= val
->val
.intval
;
384 fprintf (out
, "*((%s) 0x%08X)", type
, address
);
389 fprintf (out
, "((%s) ", type
);
390 print_value (out
, val
);
391 val
= list_tailvalue (op
->operands
);
392 fprintf (out
, ")[%d]", val
->val
.intval
>> size
);
396 void print_load (FILE *out
, struct operation
*op
, int size
, int isunsigned
, int options
)
398 if (!(options
& OPTS_DEFERRED
)) {
399 print_value (out
, list_headvalue (op
->results
));
400 fprintf (out
, " = ");
402 print_memory_address (out
, op
, size
, isunsigned
, options
);
406 void print_store (FILE *out
, struct operation
*op
, int size
, int isunsigned
, int options
)
408 struct value
*val
= element_getvalue (element_next (list_head (op
->operands
)));
409 print_memory_address (out
, op
, size
, isunsigned
, options
);
410 fprintf (out
, " = ");
411 print_value (out
, val
);
415 void print_condition (FILE *out
, struct operation
*op
, int options
)
417 fprintf (out
, "if (");
418 if (options
& OPTS_REVERSECOND
) fprintf (out
, "!(");
419 print_value (out
, list_headvalue (op
->operands
));
420 switch (op
->info
.iop
.insn
) {
422 fprintf (out
, " != ");
425 fprintf (out
, " == ");
429 fprintf (out
, " >= 0");
432 fprintf (out
, " > 0");
435 fprintf (out
, " <= 0");
439 fprintf (out
, " < 0");
444 if (list_size (op
->operands
) == 2)
445 print_value (out
, list_tailvalue (op
->operands
));
447 if (options
& OPTS_REVERSECOND
) fprintf (out
, ")");
453 void print_operation (FILE *out
, struct operation
*op
, int identsize
, int options
)
455 int nosemicolon
= FALSE
;
457 if (op
->type
== OP_ASM
) {
458 print_asm (out
, op
, identsize
, options
);
462 if (op
->type
== OP_INSTRUCTION
) {
463 if (op
->info
.iop
.loc
->insn
->flags
& (INSN_JUMP
))
465 } else if (op
->type
== OP_NOP
|| op
->type
== OP_START
||
466 op
->type
== OP_END
|| op
->type
== OP_PHI
) {
470 ident_line (out
, identsize
);
471 if (op
->type
== OP_INSTRUCTION
) {
472 switch (op
->info
.iop
.insn
) {
473 case I_ADD
: print_binaryop (out
, op
, "+", options
); break;
474 case I_ADDU
: print_binaryop (out
, op
, "+", options
); break;
475 case I_SUB
: print_binaryop (out
, op
, "-", options
); break;
476 case I_SUBU
: print_binaryop (out
, op
, "-", options
); break;
477 case I_XOR
: print_binaryop (out
, op
, "^", options
); break;
478 case I_AND
: print_binaryop (out
, op
, "&", options
); break;
479 case I_OR
: print_binaryop (out
, op
, "|", options
); break;
480 case I_SRAV
: print_binaryop (out
, op
, ">>", options
); break;
481 case I_SRLV
: print_binaryop (out
, op
, ">>", options
); break;
482 case I_SLLV
: print_binaryop (out
, op
, "<<", options
); break;
483 case I_INS
: print_ins (out
, op
, options
); break;
484 case I_EXT
: print_ext (out
, op
, options
); break;
485 case I_MIN
: print_complexop (out
, op
, "MIN", options
); break;
486 case I_MAX
: print_complexop (out
, op
, "MAX", options
); break;
487 case I_BITREV
: print_complexop (out
, op
, "BITREV", options
); break;
488 case I_CLZ
: print_complexop (out
, op
, "CLZ", options
); break;
489 case I_CLO
: print_complexop (out
, op
, "CLO", options
); break;
490 case I_NOR
: print_nor (out
, op
, options
); break;
491 case I_MOVN
: print_movnz (out
, op
, TRUE
, options
); break;
492 case I_MOVZ
: print_movnz (out
, op
, FALSE
, options
); break;
493 case I_SLT
: print_slt (out
, op
, FALSE
, options
); break;
494 case I_SLTU
: print_slt (out
, op
, TRUE
, options
); break;
495 case I_LW
: print_load (out
, op
, 2, FALSE
, options
); break;
496 case I_LB
: print_load (out
, op
, 0, FALSE
, options
); break;
497 case I_LBU
: print_load (out
, op
, 0, TRUE
, options
); break;
498 case I_LH
: print_load (out
, op
, 1, FALSE
, options
); break;
499 case I_LHU
: print_load (out
, op
, 1, TRUE
, options
); break;
500 case I_LL
: print_complexop (out
, op
, "LL", options
); break;
501 case I_LWL
: print_complexop (out
, op
, "LWL", options
); break;
502 case I_LWR
: print_complexop (out
, op
, "LWR", options
); break;
503 case I_SW
: print_store (out
, op
, 2, FALSE
, options
); break;
504 case I_SH
: print_store (out
, op
, 1, FALSE
, options
); break;
505 case I_SB
: print_store (out
, op
, 0, FALSE
, options
); break;
506 case I_SC
: print_complexop (out
, op
, "SC", options
); break;
507 case I_SWL
: print_complexop (out
, op
, "SWL", options
); break;
508 case I_SWR
: print_complexop (out
, op
, "SWR", options
); break;
509 case I_SEB
: print_signextend (out
, op
, TRUE
, options
); break;
510 case I_SEH
: print_signextend (out
, op
, TRUE
, options
); break;
512 if (op
->info
.iop
.loc
->insn
->flags
& INSN_BRANCH
) {
513 print_condition (out
, op
, options
);
518 } else if (op
->type
== OP_MOVE
) {
520 print_value (out
, list_headvalue (op
->results
));
521 fprintf (out
, " = ");
523 print_value (out
, list_headvalue (op
->operands
));
524 } else if (op
->type
== OP_CALL
) {
525 print_call (out
, op
, options
);
528 if (!(options
& OPTS_DEFERRED
)) {
529 if (nosemicolon
) fprintf (out
, "\n");
530 else fprintf (out
, ";\n");