From 8b298301cd4887cb9a2a2dfac1df3dd129353d7f Mon Sep 17 00:00:00 2001 From: Humberto Date: Thu, 7 May 2009 04:25:37 -0300 Subject: [PATCH] Ficando cada vez melhor --- code.h | 11 +++++++---- constants.c | 3 ++- dataflow.c | 60 +++++++++++++++++++++++++++++++++--------------------------- operations.c | 14 ++++++++++++++ output.c | 7 ++++++- 5 files changed, 62 insertions(+), 33 deletions(-) diff --git a/code.h b/code.h index 1ad5b7c..4afb5b9 100644 --- a/code.h +++ b/code.h @@ -73,6 +73,7 @@ extern const uint32 regmask_call_gen[NUM_REGMASK]; extern const uint32 regmask_call_kill[NUM_REGMASK]; extern const uint32 regmask_subend_gen[NUM_REGMASK]; +extern const uint32 regmask_localvars[NUM_REGMASK]; /* Possible reachable status */ @@ -348,16 +349,14 @@ void extract_subroutines (struct code *c); void extract_cfg (struct subroutine *sub); void cfg_traverse (struct subroutine *sub, int reverse); - int dom_isancestor (struct basicblocknode *ancestor, struct basicblocknode *node); struct basicblocknode *dom_common (struct basicblocknode *n1, struct basicblocknode *n2); -void reset_marks (struct subroutine *sub); -void extract_structures (struct subroutine *sub); struct operation *operation_alloc (struct basicblock *block); struct value *value_append (struct subroutine *sub, list l, enum valuetype type, uint32 value); void extract_operations (struct subroutine *sub); +void merge_block_operations (struct subroutine *sub); void fixup_call_arguments (struct subroutine *sub); void remove_call_arguments (struct subroutine *sub); @@ -367,9 +366,13 @@ void live_registers_imports (struct code *c); void build_ssa (struct subroutine *sub); void unbuild_ssa (struct subroutine *sub); +void abi_check (struct subroutine *sub); + void propagate_constants (struct subroutine *sub); void extract_variables (struct subroutine *sub); -void abi_check (struct subroutine *sub); + +void reset_marks (struct subroutine *sub); +void extract_structures (struct subroutine *sub); #endif /* __CODE_H */ diff --git a/constants.c b/constants.c index d85912c..4c74551 100644 --- a/constants.c +++ b/constants.c @@ -53,7 +53,8 @@ void propagate_constants (struct subroutine *sub) var->type = VARIABLE_CONSTANTUNK; if (var->def->type == OP_ASM || var->def->type == OP_CALL || - var->def->type == OP_START) + var->def->type == OP_START || + !(IS_BIT_SET (regmask_localvars, var->name.val.intval))) var->type = VARIABLE_UNK; else list_inserttail (worklist, var); diff --git a/dataflow.c b/dataflow.c index 3ea7517..135d532 100644 --- a/dataflow.c +++ b/dataflow.c @@ -2,6 +2,8 @@ #include "code.h" #include "utils.h" +const uint32 regmask_localvars[NUM_REGMASK] = { 0x43FFFFFE, 0x00000000 }; + static void mark_variable (struct variable *var, enum variabletype type, int num) { @@ -50,40 +52,44 @@ void extract_variables (struct subroutine *sub) while (varel) { struct variable *var = element_getvalue (varel); if (var->type == VARIABLE_UNK) { - if (var->def->type == OP_START) { - mark_variable (var, VARIABLE_ARGUMENT, var->name.val.intval); - } else if (var->def->type == OP_CALL && var->name.val.intval != 2 && - var->name.val.intval != 3) { - var->type = VARIABLE_INVALID; - } else { - int istemp = FALSE; + if (IS_BIT_SET (regmask_localvars, var->name.val.intval)) { + if (var->def->type == OP_START) { + mark_variable (var, VARIABLE_ARGUMENT, var->name.val.intval); + } else if (var->def->type == OP_CALL && var->name.val.intval != REGISTER_GPR_V0 && + var->name.val.intval != REGISTER_GPR_V1) { + var->type = VARIABLE_INVALID; + } else { + int istemp = FALSE; - if (list_size (var->uses) <= 1) { - struct operation *op = list_headvalue (var->uses); - if (op) { - if (op->type != OP_PHI) + if (list_size (var->uses) <= 1) { + struct operation *op = list_headvalue (var->uses); + if (op) { + if (op->type != OP_PHI) + istemp = TRUE; + } else { istemp = TRUE; - } else { - istemp = TRUE; + } } - } - 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 (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; + } + } else { + istemp = FALSE; } - } else { - istemp = FALSE; - } - if (istemp) { - var->def->deferred = TRUE; - var->type = VARIABLE_TEMP; - var->info = 0; - } else { - mark_variable (var, VARIABLE_LOCAL, ++count); + if (istemp) { + var->def->deferred = TRUE; + var->type = VARIABLE_TEMP; + var->info = 0; + } else { + mark_variable (var, VARIABLE_LOCAL, ++count); + } } + } else { + var->type = VARIABLE_ARGUMENT; } } varel = element_next (varel); diff --git a/operations.c b/operations.c index 7a00d81..a164a75 100644 --- a/operations.c +++ b/operations.c @@ -497,6 +497,20 @@ void extract_operations (struct subroutine *sub) } } + +void merge_block_operations (struct subroutine *sub) +{ + element el, ref; + el = list_head (sub->blocks); + + while (el) { + struct basicblock *block = element_getvalue (el); + el = element_next (el); + } + +} + + void fixup_call_arguments (struct subroutine *sub) { struct operation *op; diff --git a/output.c b/output.c index 3c4c204..6dd2b4f 100644 --- a/output.c +++ b/output.c @@ -53,7 +53,12 @@ void print_value (FILE *out, struct value *val) case VAL_VARIABLE: switch (val->val.variable->type) { case VARIABLE_ARGUMENT: - fprintf (out, "arg%d", val->val.variable->name.val.intval); + if (val->val.variable->name.val.intval >= REGISTER_GPR_A0 && + val->val.variable->name.val.intval <= REGISTER_GPR_T3) { + fprintf (out, "arg%d", val->val.variable->name.val.intval - REGISTER_GPR_A0 + 1); + } else { + print_value (out, &val->val.variable->name); + } break; case VARIABLE_LOCAL: fprintf (out, "local%d", val->val.variable->info); -- 2.11.4.GIT