From 0f38ba9847be88c8845527f6b69706ec882a27ce Mon Sep 17 00:00:00 2001 From: Humberto Date: Thu, 14 May 2009 19:38:52 -0300 Subject: [PATCH] Melhorado o structures --- constants.c | 38 +++++++++++-- dataflow.c | 31 +++++------ main.c | 39 +++++++------- outcode.c | 17 +++--- outgraph.c | 69 +++++------------------- output.c | 172 +++++++++++++++++++++++++++++++---------------------------- output.h | 16 +++--- structures.c | 17 +++--- 8 files changed, 201 insertions(+), 198 deletions(-) diff --git a/constants.c b/constants.c index de35b6a..f7961f9 100644 --- a/constants.c +++ b/constants.c @@ -107,7 +107,7 @@ void propagate_constants (struct subroutine *sub) if (op->type == OP_MOVE) { val = list_headvalue (op->operands); temp.value = get_constant_value (val); - op->status |= OP_STAT_CONSTANT; + op->status |= OP_STAT_CONSTANT; } else if (op->type == OP_INSTRUCTION) { uint32 val1, val2; switch (op->info.iop.insn) { @@ -115,14 +115,14 @@ void propagate_constants (struct subroutine *sub) case I_ADDU: val1 = get_constant_value (list_headvalue (op->operands)); val2 = get_constant_value (list_tailvalue (op->operands)); + op->status |= OP_STAT_CONSTANT; temp.value = val1 + val2; - op->status |= OP_STAT_CONSTANT; break; case I_OR: val1 = get_constant_value (list_headvalue (op->operands)); val2 = get_constant_value (list_tailvalue (op->operands)); + op->status |= OP_STAT_CONSTANT; temp.value = val1 | val2; - op->status |= OP_STAT_CONSTANT; break; default: temp.status = VAR_STAT_NOTCONSTANT; @@ -138,8 +138,7 @@ void propagate_constants (struct subroutine *sub) useel = list_head (var->uses); while (useel) { struct operation *use = element_getvalue (useel); - if (use->type == OP_INSTRUCTION || use->type == OP_MOVE || - use->type == OP_PHI) { + if (use->type == OP_INSTRUCTION || use->type == OP_MOVE || use->type == OP_PHI) { varel = list_head (use->results); while (varel) { val = element_getvalue (varel); @@ -161,6 +160,35 @@ void propagate_constants (struct subroutine *sub) } list_free (worklist); + + + varel = list_head (sub->ssavars); + while (varel) { + struct ssavar *var = element_getvalue (varel); + struct operation *op = var->def; + element useel; + + if (CONST_TYPE (var->status) == VAR_STAT_CONSTANT) { + op->status |= OP_STAT_DEFERRED; + useel = list_head (var->uses); + while (useel) { + struct operation *use = element_getvalue (useel); + if (use->type == OP_PHI) { + struct value *val = list_headvalue (use->results); + if (val->type != VAL_SSAVAR) break; + if (CONST_TYPE (val->val.variable->status) != VAR_STAT_CONSTANT) + break; + } else if (use->type == OP_ASM) break; + useel = element_next (useel); + } + if (useel) { + op->status &= ~OP_STAT_DEFERRED; + } + } + + varel = element_next (varel); + } + } diff --git a/dataflow.c b/dataflow.c index 92cd923..6d5f40a 100644 --- a/dataflow.c +++ b/dataflow.c @@ -54,32 +54,33 @@ void extract_variables (struct subroutine *sub) varel = list_head (sub->ssavars); while (varel) { struct ssavar *var = element_getvalue (varel); + struct operation *op = var->def; + if (var->type == SSAVAR_UNK) { if (IS_BIT_SET (regmask_localvars, var->name.val.intval)) { - if (var->def->type == OP_START) { + if (op->type == OP_START) { mark_ssavar (var, SSAVAR_ARGUMENT, var->name.val.intval); - } else if (var->def->type == OP_CALL && var->name.val.intval != REGISTER_GPR_V0 && + } else if (op->type == OP_CALL && var->name.val.intval != REGISTER_GPR_V0 && var->name.val.intval != REGISTER_GPR_V1) { mark_ssavar (var, SSAVAR_INVALID, 0); } else { - int istemp = FALSE; - if (list_size (var->uses) <= 1 && - !(var->status & VAR_STAT_PHIARG)) { - istemp = FALSE; - } + if (op->type == OP_MOVE || op->type == OP_INSTRUCTION) { + if (!(var->status & (VAR_STAT_PHIARG | VAR_STAT_ASMARG))) { + if (list_size (var->uses) <= 1) + op->status |= OP_STAT_DEFERRED; + } - if (var->def->type == OP_MOVE || var->def->type == OP_INSTRUCTION) { - if (var->def->type == OP_INSTRUCTION) { - if (var->def->info.iop.loc->insn->flags & (INSN_LOAD | INSN_STORE | INSN_BRANCH)) - istemp = FALSE; + if (op->type == OP_INSTRUCTION) { + if (op->info.iop.loc->insn->flags & (INSN_LOAD | INSN_STORE)) + op->status &= ~OP_STAT_DEFERRED; + else if ((op->info.iop.loc->insn->flags & (INSN_BRANCH)) && + !op->info.iop.loc->branchalways) + op->status &= ~OP_STAT_DEFERRED; } - } else { - istemp = FALSE; } - if (istemp) { - var->def->status |= OP_STAT_DEFERRED; + if (op->status & OP_STAT_DEFERRED) { var->type = SSAVAR_TEMP; var->info = 0; } else { diff --git a/main.c b/main.c index 87a39bd..f843e73 100644 --- a/main.c +++ b/main.c @@ -12,6 +12,10 @@ #include "hash.h" #include "utils.h" + +int g_verbosity; +int g_printoptions; + static void print_help (char *prgname) { @@ -26,7 +30,6 @@ void print_help (char *prgname) " -x print the reverse dominator\n" " -f print the frontier\n" " -z print the reverse frontier\n" - " -p print phi functions\n" " -q print code into nodes\n" " -s print structures\n" " -e print edge types\n" @@ -43,16 +46,17 @@ int main (int argc, char **argv) char *prxfilename = NULL; char *nidsfilename = NULL; - int i, j, verbosity = 0; + int i, j; int printgraph = FALSE; int printcode = FALSE; int printinfo = FALSE; - int graphoptions = 0; struct nidstable *nids = NULL; struct prx *p = NULL; struct code *c; + g_verbosity = 0; + for (i = 1; i < argc; i++) { if (strcmp ("--help", argv[i]) == 0) { print_help (argv[0]); @@ -61,20 +65,19 @@ int main (int argc, char **argv) char *s = argv[i]; for (j = 0; s[j]; j++) { switch (s[j]) { - case 'v': verbosity++; break; + case 'v': g_verbosity++; break; case 'g': printgraph = TRUE; break; case 'c': printcode = TRUE; break; case 'i': printinfo = TRUE; break; - case 't': graphoptions |= OUT_PRINT_DFS; break; - case 'r': graphoptions |= OUT_PRINT_RDFS; break; - case 'd': graphoptions |= OUT_PRINT_DOMINATOR; break; - case 'x': graphoptions |= OUT_PRINT_RDOMINATOR; break; - case 'f': graphoptions |= OUT_PRINT_FRONTIER; break; - case 'z': graphoptions |= OUT_PRINT_RFRONTIER; break; - case 'p': graphoptions |= OUT_PRINT_PHIS; break; - case 'q': graphoptions |= OUT_PRINT_CODE; break; - case 's': graphoptions |= OUT_PRINT_STRUCTURES; break; - case 'e': graphoptions |= OUT_PRINT_EDGE_TYPES; break; + case 't': g_printoptions |= OUT_PRINT_DFS; break; + case 'r': g_printoptions |= OUT_PRINT_RDFS; break; + case 'd': g_printoptions |= OUT_PRINT_DOMINATOR; break; + case 'x': g_printoptions |= OUT_PRINT_RDOMINATOR; break; + case 'f': g_printoptions |= OUT_PRINT_FRONTIER; break; + case 'z': g_printoptions |= OUT_PRINT_RFRONTIER; break; + case 'q': g_printoptions |= OUT_PRINT_CODE; break; + case 's': g_printoptions |= OUT_PRINT_STRUCTURES; break; + case 'e': g_printoptions |= OUT_PRINT_EDGE_TYPES; break; case 'n': if (i == (argc - 1)) fatal (__FILE__ ": missing nids file"); @@ -103,11 +106,11 @@ int main (int argc, char **argv) if (nids) prx_resolve_nids (p, nids); - if (verbosity > 2 && nids && printinfo) + if (g_verbosity > 2 && nids && printinfo) nids_print (nids); - if (verbosity > 0 && printinfo) - prx_print (p, (verbosity > 1)); + if (g_verbosity > 0 && printinfo) + prx_print (p, (g_verbosity > 1)); c = code_analyse (p); if (!c) @@ -115,7 +118,7 @@ int main (int argc, char **argv) if (printgraph) - print_graph (c, prxfilename, graphoptions); + print_graph (c, prxfilename); if (printcode) print_code (c, prxfilename); diff --git a/outcode.c b/outcode.c index 0be36e5..0e727da 100644 --- a/outcode.c +++ b/outcode.c @@ -38,15 +38,18 @@ void print_block_recursive (FILE *out, struct basicblock *block) int revcond = block->status & BLOCK_STAT_REVCOND; int first = TRUE, isloop = FALSE; - fprintf (out, "block%d:\n", block->node.dfsnum); - if (block->type == BLOCK_SIMPLE){ - struct location *loc; - loc = block->info.simple.begin; - while (1) { - fprintf (out, " %s\n", allegrex_disassemble (loc->opc, loc->address, TRUE)); - if (loc++ == block->info.simple.end) break; + if (g_verbosity > 1) { + fprintf (out, "block%d:\n", block->node.dfsnum); + if (block->type == BLOCK_SIMPLE){ + struct location *loc; + loc = block->info.simple.begin; + while (1) { + fprintf (out, " %s\n", allegrex_disassemble (loc->opc, loc->address, TRUE)); + if (loc++ == block->info.simple.end) break; + } } } + if (block->status & BLOCK_STAT_ISSWITCHTARGET) { ref = list_head (block->inrefs); while (ref) { diff --git a/outgraph.c b/outgraph.c index e523a7f..86c6450 100644 --- a/outgraph.c +++ b/outgraph.c @@ -48,48 +48,6 @@ void print_block_code (FILE *out, struct basicblock *block) } static -void print_block_phis (FILE *out, struct basicblock *block) -{ - element opsel, argel; - opsel = list_head (block->operations); - while (opsel) { - struct operation *op = element_getvalue (opsel); - int count1 = 0, count2 = 0; - - if (op->type != OP_START && op->type != OP_END) { - argel = list_head (op->results); - while (argel) { - struct value *val = element_getvalue (argel); - if (val->type != VAL_CONSTANT) { - if (count1++ == 0) fprintf (out, "<"); - print_value (out, val, 0); - fprintf (out, " "); - } - argel = element_next (argel); - } - if (count1 > 0) fprintf (out, "> = "); - - if (op->type == OP_PHI) { - fprintf (out, "PHI"); - } - argel = list_head (op->operands); - while (argel) { - struct value *val = element_getvalue (argel); - if (val->type != VAL_CONSTANT) { - if (count2++ == 0) fprintf (out, "<"); - print_value (out, val, 0); - fprintf (out, " "); - } - argel = element_next (argel); - } - if (count2 > 0) fprintf (out, ">"); - if (count1 || count2) fprintf (out, "\\l"); - } - opsel = element_next (opsel); - } -} - -static void print_dominator (FILE *out, struct basicblock *block, int reverse, const char *color) { struct basicblock *dominator; @@ -127,7 +85,7 @@ void print_frontier (FILE *out, struct basicblock *block, list frontier, const c } static -void print_subroutine_graph (FILE *out, struct code *c, struct subroutine *sub, int options) +void print_subroutine_graph (FILE *out, struct code *c, struct subroutine *sub) { struct basicblock *block; element el, ref; @@ -144,13 +102,13 @@ void print_subroutine_graph (FILE *out, struct code *c, struct subroutine *sub, fprintf (out, " %3d ", block->node.dfsnum); fprintf (out, "[label=\""); - if (options & OUT_PRINT_STRUCTURES) + if (g_printoptions & OUT_PRINT_STRUCTURES) print_structures (out, block); - if (options & OUT_PRINT_DFS) + if (g_printoptions & OUT_PRINT_DFS) fprintf (out, "(%d) ", block->node.dfsnum); - if (options & OUT_PRINT_RDFS) + if (g_printoptions & OUT_PRINT_RDFS) fprintf (out, "(%d) ", block->revnode.dfsnum); switch (block->type) { @@ -163,25 +121,22 @@ void print_subroutine_graph (FILE *out, struct code *c, struct subroutine *sub, if (block->status & BLOCK_STAT_HASLABEL) fprintf (out, "(*)"); fprintf (out, "\\l"); - if (options & OUT_PRINT_PHIS) - print_block_phis (out, block); - - if (options & OUT_PRINT_CODE) + if (g_printoptions & OUT_PRINT_CODE) print_block_code (out, block); fprintf (out, "\"];\n"); - if (options & OUT_PRINT_DOMINATOR) + if (g_printoptions & OUT_PRINT_DOMINATOR) print_dominator (out, block, FALSE, "green"); - if (options & OUT_PRINT_RDOMINATOR) + if (g_printoptions & OUT_PRINT_RDOMINATOR) print_dominator (out, block, TRUE, "yellow"); - if (options & OUT_PRINT_FRONTIER) + if (g_printoptions & OUT_PRINT_FRONTIER) print_frontier (out, block, block->node.frontier, "orange"); - if (options & OUT_PRINT_RFRONTIER) + if (g_printoptions & OUT_PRINT_RFRONTIER) print_frontier (out, block, block->revnode.frontier, "blue"); @@ -201,7 +156,7 @@ void print_subroutine_graph (FILE *out, struct code *c, struct subroutine *sub, } else if (block->node.dfsnum >= refblock->node.dfsnum) { fprintf (out, "[color=red]"); } - if (options & OUT_PRINT_EDGE_TYPES) { + if (g_printoptions & OUT_PRINT_EDGE_TYPES) { fprintf (out, "[label=\""); switch (edge->type) { case EDGE_UNKNOWN: fprintf (out, "UNK"); break; @@ -226,7 +181,7 @@ void print_subroutine_graph (FILE *out, struct code *c, struct subroutine *sub, } -int print_graph (struct code *c, char *prxname, int options) +int print_graph (struct code *c, char *prxname) { char buffer[128]; char basename[32]; @@ -252,7 +207,7 @@ int print_graph (struct code *c, char *prxname, int options) xerror (__FILE__ ": can't open file for writing `%s'", buffer); ret = 0; } else { - print_subroutine_graph (fp, c, sub, options); + print_subroutine_graph (fp, c, sub); fclose (fp); } } else { diff --git a/output.c b/output.c index 7c85fbe..448151f 100644 --- a/output.c +++ b/output.c @@ -123,7 +123,7 @@ void print_value (FILE *out, struct value *val, int options) case VAL_SSAVAR: var = val->val.variable; if (CONST_TYPE (var->status) != VAR_STAT_NOTCONSTANT && - !(options & OPTS_DONTPRINTCONSTANTS)) { + !(options & OPTS_RESULT)) { struct prx *file; file = var->def->block->sub->code->file; if (var->def->status & OP_STAT_HASRELOC) { @@ -223,8 +223,8 @@ void print_asm (FILE *out, struct operation *op, int identsize, int options) static void print_binaryop (FILE *out, struct operation *op, const char *opsymbol, int options) { - if (!(options & OPTS_DEFERRED)) { - print_value (out, list_headvalue (op->results), OPTS_DONTPRINTCONSTANTS); + if (!(options & OPTS_NORESULT)) { + print_value (out, list_headvalue (op->results), OPTS_RESULT); fprintf (out, " = "); } print_value (out, list_headvalue (op->operands), 0); @@ -237,8 +237,8 @@ void print_complexop (FILE *out, struct operation *op, const char *opsymbol, int { element el; - if (list_size (op->results) != 0 && !(options & OPTS_DEFERRED)) { - print_value (out, list_headvalue (op->results), OPTS_DONTPRINTCONSTANTS); + if (list_size (op->results) != 0 && !(options & OPTS_NORESULT)) { + print_value (out, list_headvalue (op->results), OPTS_RESULT); fprintf (out, " = "); } @@ -263,10 +263,10 @@ void print_call (FILE *out, struct operation *op, int options) { element el; - if (list_size (op->info.callop.retvalues) != 0 && !(options & OPTS_DEFERRED)) { + if (list_size (op->info.callop.retvalues) != 0 && !(options & OPTS_NORESULT)) { el = list_head (op->info.callop.retvalues); while (el) { - print_value (out, element_getvalue (el), OPTS_DONTPRINTCONSTANTS); + print_value (out, element_getvalue (el), OPTS_RESULT); fprintf (out, " "); el = element_next (el); } @@ -328,8 +328,8 @@ void print_ext (FILE *out, struct operation *op, int options) val3 = element_getvalue (el); mask = 0xFFFFFFFF >> (32 - val3->val.intval); - if (!(options & OPTS_DEFERRED)) { - print_value (out, list_headvalue (op->results), OPTS_DONTPRINTCONSTANTS); + if (!(options & OPTS_NORESULT)) { + print_value (out, list_headvalue (op->results), OPTS_RESULT); fprintf (out, " = "); } @@ -353,8 +353,8 @@ void print_ins (FILE *out, struct operation *op, int options) val4 = element_getvalue (el); mask = 0xFFFFFFFF >> (32 - val4->val.intval); - if (!(options & OPTS_DEFERRED)) { - print_value (out, list_headvalue (op->results), OPTS_DONTPRINTCONSTANTS); + if (!(options & OPTS_NORESULT)) { + print_value (out, list_headvalue (op->results), OPTS_RESULT); fprintf (out, " = "); } @@ -379,8 +379,8 @@ void print_nor (FILE *out, struct operation *op, int options) if (val1->val.intval == 0) val1 = val2; } - if (!(options & OPTS_DEFERRED)) { - print_value (out, list_headvalue (op->results), OPTS_DONTPRINTCONSTANTS); + if (!(options & OPTS_NORESULT)) { + print_value (out, list_headvalue (op->results), OPTS_RESULT); fprintf (out, " = "); } @@ -409,8 +409,8 @@ void print_movnz (FILE *out, struct operation *op, int ismovn, int options) val3 = element_getvalue (el); result = list_headvalue (op->results); - if (!(options & OPTS_DEFERRED)) { - print_value (out, result, OPTS_DONTPRINTCONSTANTS); + if (!(options & OPTS_NORESULT)) { + print_value (out, result, OPTS_RESULT); fprintf (out, " = "); } @@ -437,8 +437,8 @@ void print_slt (FILE *out, struct operation *op, int isunsigned, int options) val2 = element_getvalue (el); result = list_headvalue (op->results); - if (!(options & OPTS_DEFERRED)) { - print_value (out, result, OPTS_DONTPRINTCONSTANTS); + if (!(options & OPTS_NORESULT)) { + print_value (out, result, OPTS_RESULT); fprintf (out, " = "); } @@ -453,8 +453,8 @@ void print_slt (FILE *out, struct operation *op, int isunsigned, int options) static void print_signextend (FILE *out, struct operation *op, int isbyte, int options) { - if (!(options & OPTS_DEFERRED)) { - print_value (out, list_headvalue (op->results), OPTS_DONTPRINTCONSTANTS); + if (!(options & OPTS_NORESULT)) { + print_value (out, list_headvalue (op->results), OPTS_RESULT); fprintf (out, " = "); } @@ -503,8 +503,8 @@ void print_memory_address (FILE *out, struct operation *op, int size, int isunsi static void print_load (FILE *out, struct operation *op, int size, int isunsigned, int options) { - if (!(options & OPTS_DEFERRED)) { - print_value (out, list_headvalue (op->results), OPTS_DONTPRINTCONSTANTS); + if (!(options & OPTS_NORESULT)) { + print_value (out, list_headvalue (op->results), OPTS_RESULT); fprintf (out, " = "); } print_memory_address (out, op, size, isunsigned, options); @@ -573,75 +573,83 @@ void print_operation (FILE *out, struct operation *op, int identsize, int option if (op->info.iop.loc->insn->flags & (INSN_JUMP)) return; if (loc->branchalways) return; - } else if (op->type == OP_NOP || op->type == OP_START/* || - op->type == OP_PHI*/) { + } else if (op->type == OP_NOP || op->type == OP_START || op->type == OP_PHI) { return; } ident_line (out, identsize); - if (op->type == OP_INSTRUCTION) { - switch (op->info.iop.insn) { - case I_ADD: print_binaryop (out, op, "+", options); break; - case I_ADDU: print_binaryop (out, op, "+", options); break; - case I_SUB: print_binaryop (out, op, "-", options); break; - case I_SUBU: print_binaryop (out, op, "-", options); break; - case I_XOR: print_binaryop (out, op, "^", options); break; - case I_AND: print_binaryop (out, op, "&", options); break; - case I_OR: print_binaryop (out, op, "|", options); break; - case I_SRAV: print_binaryop (out, op, ">>", options); break; - case I_SRLV: print_binaryop (out, op, ">>", options); break; - case I_SLLV: print_binaryop (out, op, "<<", options); break; - case I_INS: print_ins (out, op, options); break; - case I_EXT: print_ext (out, op, options); break; - case I_MIN: print_complexop (out, op, "MIN", options); break; - case I_MAX: print_complexop (out, op, "MAX", options); break; - case I_BITREV: print_complexop (out, op, "BITREV", options); break; - case I_CLZ: print_complexop (out, op, "CLZ", options); break; - case I_CLO: print_complexop (out, op, "CLO", options); break; - case I_NOR: print_nor (out, op, options); break; - case I_MOVN: print_movnz (out, op, TRUE, options); break; - case I_MOVZ: print_movnz (out, op, FALSE, options); break; - case I_SLT: print_slt (out, op, FALSE, options); break; - case I_SLTU: print_slt (out, op, TRUE, options); break; - case I_LW: print_load (out, op, 2, FALSE, options); break; - case I_LB: print_load (out, op, 0, FALSE, options); break; - case I_LBU: print_load (out, op, 0, TRUE, options); break; - case I_LH: print_load (out, op, 1, FALSE, options); break; - case I_LHU: print_load (out, op, 1, TRUE, options); break; - case I_LL: print_complexop (out, op, "LL", options); break; - case I_LWL: print_complexop (out, op, "LWL", options); break; - case I_LWR: print_complexop (out, op, "LWR", options); break; - case I_SW: print_store (out, op, 2, FALSE, options); break; - case I_SH: print_store (out, op, 1, FALSE, options); break; - case I_SB: print_store (out, op, 0, FALSE, options); break; - case I_SC: print_complexop (out, op, "SC", options); break; - case I_SWL: print_complexop (out, op, "SWL", options); break; - case I_SWR: print_complexop (out, op, "SWR", options); break; - case I_SEB: print_signextend (out, op, TRUE, options); break; - case I_SEH: print_signextend (out, op, TRUE, options); break; - default: - if (loc->insn->flags & INSN_BRANCH) { - print_condition (out, op, options); - nosemicolon = TRUE; - }; - break; - } - } else if (op->type == OP_MOVE) { - if (!options) { - print_value (out, list_headvalue (op->results), OPTS_DONTPRINTCONSTANTS); + + if ((op->status & (OP_STAT_CONSTANT | OP_STAT_DEFERRED)) == OP_STAT_CONSTANT) { + struct value *val = list_headvalue (op->results); + if (!(options & OPTS_NORESULT)) { + print_value (out, val, OPTS_RESULT); fprintf (out, " = "); } - print_value (out, list_headvalue (op->operands), 0); - } else if (op->type == OP_CALL) { - print_call (out, op, options); - } else if (op->type == OP_END) { - print_return (out, op, options); - } else if (op->type == OP_PHI) { - print_complexop (out, op, "PHI", options); + print_value (out, val, 0); + } else { + if (op->type == OP_INSTRUCTION) { + switch (op->info.iop.insn) { + case I_ADD: print_binaryop (out, op, "+", options); break; + case I_ADDU: print_binaryop (out, op, "+", options); break; + case I_SUB: print_binaryop (out, op, "-", options); break; + case I_SUBU: print_binaryop (out, op, "-", options); break; + case I_XOR: print_binaryop (out, op, "^", options); break; + case I_AND: print_binaryop (out, op, "&", options); break; + case I_OR: print_binaryop (out, op, "|", options); break; + case I_SRAV: print_binaryop (out, op, ">>", options); break; + case I_SRLV: print_binaryop (out, op, ">>", options); break; + case I_SLLV: print_binaryop (out, op, "<<", options); break; + case I_INS: print_ins (out, op, options); break; + case I_EXT: print_ext (out, op, options); break; + case I_MIN: print_complexop (out, op, "MIN", options); break; + case I_MAX: print_complexop (out, op, "MAX", options); break; + case I_BITREV: print_complexop (out, op, "BITREV", options); break; + case I_CLZ: print_complexop (out, op, "CLZ", options); break; + case I_CLO: print_complexop (out, op, "CLO", options); break; + case I_NOR: print_nor (out, op, options); break; + case I_MOVN: print_movnz (out, op, TRUE, options); break; + case I_MOVZ: print_movnz (out, op, FALSE, options); break; + case I_SLT: print_slt (out, op, FALSE, options); break; + case I_SLTU: print_slt (out, op, TRUE, options); break; + case I_LW: print_load (out, op, 2, FALSE, options); break; + case I_LB: print_load (out, op, 0, FALSE, options); break; + case I_LBU: print_load (out, op, 0, TRUE, options); break; + case I_LH: print_load (out, op, 1, FALSE, options); break; + case I_LHU: print_load (out, op, 1, TRUE, options); break; + case I_LL: print_complexop (out, op, "LL", options); break; + case I_LWL: print_complexop (out, op, "LWL", options); break; + case I_LWR: print_complexop (out, op, "LWR", options); break; + case I_SW: print_store (out, op, 2, FALSE, options); break; + case I_SH: print_store (out, op, 1, FALSE, options); break; + case I_SB: print_store (out, op, 0, FALSE, options); break; + case I_SC: print_complexop (out, op, "SC", options); break; + case I_SWL: print_complexop (out, op, "SWL", options); break; + case I_SWR: print_complexop (out, op, "SWR", options); break; + case I_SEB: print_signextend (out, op, TRUE, options); break; + case I_SEH: print_signextend (out, op, TRUE, options); break; + default: + if (loc->insn->flags & INSN_BRANCH) { + print_condition (out, op, options); + nosemicolon = TRUE; + }; + break; + } + } else if (op->type == OP_MOVE) { + if (!(options & OPTS_NORESULT)) { + print_value (out, list_headvalue (op->results), OPTS_RESULT); + fprintf (out, " = "); + } + print_value (out, list_headvalue (op->operands), 0); + } else if (op->type == OP_CALL) { + print_call (out, op, options); + } else if (op->type == OP_END) { + print_return (out, op, options); + /*} else if (op->type == OP_PHI) { + print_complexop (out, op, "PHI", options);*/ + } } - - if (!(options & OPTS_DEFERRED)) { + if (!(options & OPTS_NORESULT)) { if (nosemicolon) fprintf (out, "\n"); else fprintf (out, ";\n"); } diff --git a/output.h b/output.h index aa7acbd..967b9d5 100644 --- a/output.h +++ b/output.h @@ -14,14 +14,16 @@ #define OUT_PRINT_RDOMINATOR 8 #define OUT_PRINT_FRONTIER 16 #define OUT_PRINT_RFRONTIER 32 -#define OUT_PRINT_PHIS 64 -#define OUT_PRINT_CODE 128 -#define OUT_PRINT_STRUCTURES 256 -#define OUT_PRINT_EDGE_TYPES 512 +#define OUT_PRINT_CODE 64 +#define OUT_PRINT_STRUCTURES 128 +#define OUT_PRINT_EDGE_TYPES 256 -#define OPTS_DEFERRED 1 +#define OPTS_NORESULT 1 #define OPTS_REVERSECOND 2 -#define OPTS_DONTPRINTCONSTANTS 4 +#define OPTS_RESULT 4 + +extern int g_verbosity; +extern int g_printoptions; void ident_line (FILE *out, int size); @@ -32,6 +34,6 @@ void print_subroutine_name (FILE *out, struct subroutine *sub); void print_subroutine_declaration (FILE *out, struct subroutine *sub); int print_code (struct code *c, char *filename); -int print_graph (struct code *c, char *prxname, int options); +int print_graph (struct code *c, char *prxname); #endif /* __OUTPUT_H */ diff --git a/structures.c b/structures.c index cd88d56..6d7d98d 100644 --- a/structures.c +++ b/structures.c @@ -161,13 +161,16 @@ void extract_returns (struct subroutine *sub) } static -int struct_isancestor (struct ctrlstruct *ancestor, struct ctrlstruct *st) +int check_nestedifs (struct basicblock *ifb, struct basicblock *end) { - while (st) { - if (st == ancestor) return TRUE; - st = st->parent; - } - return FALSE; + struct ctrlstruct *st = ifb->st; + struct ctrlstruct *ancestor = end->st; + + if (st == end->st) return TRUE; + if (st->type != CONTROL_IF) return FALSE; + if (st->end != end) return FALSE; + + return TRUE; } static @@ -241,7 +244,7 @@ void structure_search (struct basicblock *block, struct ctrlstruct *parentst, in nst->info.ifctrl.endfollow = TRUE; end->mark1 = TRUE; } else { - if (!struct_isancestor (end->st, block->st)) { + if (!check_nestedifs (block, end)) { nst->hasendgoto = TRUE; end->status |= BLOCK_STAT_HASLABEL; } -- 2.11.4.GIT