OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [branches/] [stable_0_2_x/] [or1ksim/] [cuc/] [insn.c] - Diff between revs 930 and 931

Go to most recent revision | Show entire file | Details | Blame | View Log

Rev 930 Rev 931
Line 168... Line 168...
/* returns nonzero, if instruction was simplified */
/* returns nonzero, if instruction was simplified */
int apply_edge_condition (cuc_insn *ii)
int apply_edge_condition (cuc_insn *ii)
{
{
  unsigned int c = ii->op[2];
  unsigned int c = ii->op[2];
 
 
  if (ii->index == II_AND) {
  switch (ii->index) {
 
  case II_AND:
    if (ii->opt[2] & OPT_CONST && c == 0) {
    if (ii->opt[2] & OPT_CONST && c == 0) {
      change_insn_type (ii, II_ADD);
      change_insn_type (ii, II_ADD);
      ii->op[1] = 0; ii->opt[1] = OPT_CONST;
      ii->op[1] = 0; ii->opt[1] = OPT_CONST;
      ii->op[2] = 0; ii->opt[2] = OPT_CONST;
      ii->op[2] = 0; ii->opt[2] = OPT_CONST;
      return 1;
      return 1;
    }
    } else break;
  } else if (ii->index == II_OR) {
  case II_OR:
    if (ii->opt[2] & OPT_CONST && c == 0xffffffff) {
    if (ii->opt[2] & OPT_CONST && c == 0xffffffff) {
      change_insn_type (ii, II_ADD);
      change_insn_type (ii, II_ADD);
      ii->op[1] = c; ii->opt[1] = OPT_CONST;
      ii->op[1] = c; ii->opt[1] = OPT_CONST;
      ii->op[2] = 0; ii->opt[2] = OPT_CONST;
      ii->op[2] = 0; ii->opt[2] = OPT_CONST;
      return 1;
      return 1;
    }
    } else break;
  } else if (ii->index == II_SUB) {
  case II_SUB:
    if (ii->opt[1] == ii->opt[2] && ii->op[1] == ii->op[2]) {
    if (ii->opt[1] == ii->opt[2] && ii->op[1] == ii->op[2]) {
      change_insn_type (ii, II_ADD);
      change_insn_type (ii, II_ADD);
      ii->op[1] = 0; ii->opt[1] = OPT_CONST;
      ii->op[1] = 0; ii->opt[1] = OPT_CONST;
      ii->op[2] = 0; ii->opt[2] = OPT_CONST;
      ii->op[2] = 0; ii->opt[2] = OPT_CONST;
      return 1;
      return 1;
    }
    } else break;
  } else if (ii->index == II_MUL) {
  case II_MUL:
    if (ii->opt[2] & OPT_CONST && c == 0) {
    if (ii->opt[2] & OPT_CONST && c == 0) {
      change_insn_type (ii, II_ADD);
      change_insn_type (ii, II_ADD);
      ii->op[1] = 0; ii->opt[1] = OPT_CONST;
      ii->op[1] = 0; ii->opt[1] = OPT_CONST;
      ii->op[2] = 0; ii->opt[2] = OPT_CONST;
      ii->op[2] = 0; ii->opt[2] = OPT_CONST;
      return 1;
      return 1;
Line 207... Line 208...
    if (ii->opt[2] & OPT_CONST && c == 0xffffffff) {
    if (ii->opt[2] & OPT_CONST && c == 0xffffffff) {
      change_insn_type (ii, II_SUB);
      change_insn_type (ii, II_SUB);
      ii->op[2] = ii->op[1]; ii->opt[2] = ii->opt[1];
      ii->op[2] = ii->op[1]; ii->opt[2] = ii->opt[1];
      ii->op[1] = 0; ii->opt[1] = OPT_CONST;
      ii->op[1] = 0; ii->opt[1] = OPT_CONST;
      return 1;
      return 1;
    }
    } else break;
  } else if (ii->index == II_SRL) {
  case II_SRL:
    if (ii->opt[2] & OPT_CONST && c == 0) {
    if (ii->opt[2] & OPT_CONST && c == 0) {
      change_insn_type (ii, II_ADD);
      change_insn_type (ii, II_ADD);
      ii->op[1] = c; ii->opt[1] = OPT_CONST;
      ii->op[1] = c; ii->opt[1] = OPT_CONST;
      ii->op[2] = 0; ii->opt[2] = OPT_CONST;
      ii->op[2] = 0; ii->opt[2] = OPT_CONST;
      return 1;
      return 1;
    } else if (ii->opt[2] & OPT_CONST && c >= 32) {
    } else if (ii->opt[2] & OPT_CONST && c >= 32) {
      change_insn_type (ii, II_ADD);
      change_insn_type (ii, II_ADD);
      ii->op[1] = 0; ii->opt[1] = OPT_CONST;
      ii->op[1] = 0; ii->opt[1] = OPT_CONST;
      ii->op[2] = 0; ii->opt[2] = OPT_CONST;
      ii->op[2] = 0; ii->opt[2] = OPT_CONST;
      return 1;
      return 1;
    }
    } else break;
  } else if (ii->index == II_SLL) {
  case II_SLL:
    if (ii->opt[2] & OPT_CONST && c == 0) {
    if (ii->opt[2] & OPT_CONST && c == 0) {
      change_insn_type (ii, II_ADD);
      change_insn_type (ii, II_ADD);
      ii->op[1] = c; ii->opt[1] = OPT_CONST;
      ii->op[1] = c; ii->opt[1] = OPT_CONST;
      ii->op[2] = 0; ii->opt[2] = OPT_CONST;
      ii->op[2] = 0; ii->opt[2] = OPT_CONST;
      return 1;
      return 1;
    } else if (ii->opt[2] & OPT_CONST && c >= 32) {
    } else if (ii->opt[2] & OPT_CONST && c >= 32) {
      change_insn_type (ii, II_ADD);
      change_insn_type (ii, II_ADD);
      ii->op[1] = 0; ii->opt[1] = OPT_CONST;
      ii->op[1] = 0; ii->opt[1] = OPT_CONST;
      ii->op[2] = 0; ii->opt[2] = OPT_CONST;
      ii->op[2] = 0; ii->opt[2] = OPT_CONST;
      return 1;
      return 1;
    }
    } else break;
  } else if (ii->index == II_SRA) {
  case II_SRA:
    if (ii->opt[2] & OPT_CONST && c == 0) {
    if (ii->opt[2] & OPT_CONST && c == 0) {
      change_insn_type (ii, II_ADD);
      change_insn_type (ii, II_ADD);
      ii->op[1] = c; ii->opt[1] = OPT_CONST;
      ii->op[1] = c; ii->opt[1] = OPT_CONST;
      ii->op[2] = 0; ii->opt[2] = OPT_CONST;
      ii->op[2] = 0; ii->opt[2] = OPT_CONST;
      return 1;
      return 1;
    }
    } else break;
  } else if (ii->index == II_CMOV) {
  case II_SFEQ:
 
    if (ii->opt[1] & OPT_CONST && ii->opt[2] & OPT_CONST) {
 
      change_insn_type (ii, II_ADD);
 
      ii->op[1] = ii->op[1] == ii->op[2]; ii->opt[1] = OPT_CONST;
 
      ii->op[2] = 0; ii->opt[2] = OPT_CONST;
 
      return 1;
 
    } else break;
 
  case II_SFNE:
 
    if (ii->opt[1] & OPT_CONST && ii->opt[2] & OPT_CONST) {
 
      change_insn_type (ii, II_ADD);
 
      ii->op[1] = ii->op[1] != ii->op[2]; ii->opt[1] = OPT_CONST;
 
      ii->op[2] = 0; ii->opt[2] = OPT_CONST;
 
      return 1;
 
    } else break;
 
  case II_SFLE:
 
    if (ii->opt[1] & OPT_CONST && ii->opt[2] & OPT_CONST) {
 
      change_insn_type (ii, II_ADD);
 
      ii->op[1] = ii->op[1] <= ii->op[2]; ii->opt[1] = OPT_CONST;
 
      ii->op[2] = 0; ii->opt[2] = OPT_CONST;
 
      return 1;
 
    } else break;
 
  case II_SFLT:
 
    if (ii->opt[1] & OPT_CONST && ii->opt[2] & OPT_CONST) {
 
      change_insn_type (ii, II_ADD);
 
      ii->op[1] = ii->op[1] < ii->op[2]; ii->opt[1] = OPT_CONST;
 
      ii->op[2] = 0; ii->opt[2] = OPT_CONST;
 
      return 1;
 
    } else break;
 
  case II_SFGE:
 
    if (ii->opt[1] & OPT_CONST && ii->opt[2] & OPT_CONST) {
 
      change_insn_type (ii, II_ADD);
 
      ii->op[1] = ii->op[1] >= ii->op[2]; ii->opt[1] = OPT_CONST;
 
      ii->op[2] = 0; ii->opt[2] = OPT_CONST;
 
      return 1;
 
    } else break;
 
  case II_SFGT:
 
    if (ii->opt[1] & OPT_CONST && ii->opt[2] & OPT_CONST) {
 
      change_insn_type (ii, II_ADD);
 
      ii->op[1] = ii->op[1] > ii->op[2]; ii->opt[1] = OPT_CONST;
 
      ii->op[2] = 0; ii->opt[2] = OPT_CONST;
 
      return 1;
 
    } else break;
 
  case II_CMOV:
    if (ii->opt[1] == ii->opt[2] && ii->op[1] == ii->op[2]) {
    if (ii->opt[1] == ii->opt[2] && ii->op[1] == ii->op[2]) {
      change_insn_type (ii, II_ADD);
      change_insn_type (ii, II_ADD);
      ii->op[2] = 0; ii->opt[2] = OPT_CONST;
      ii->op[2] = 0; ii->opt[2] = OPT_CONST;
      ii->opt[3] = OPT_NONE;
      ii->opt[3] = OPT_NONE;
      return 1;
      return 1;
Line 279... Line 322...
          ii->op[1] = 0; ii->opt[1] = OPT_CONST;
          ii->op[1] = 0; ii->opt[1] = OPT_CONST;
          ii->op[2] = 0; ii->opt[2] = OPT_CONST;
          ii->op[2] = 0; ii->opt[2] = OPT_CONST;
          ii->opt[3] = OPT_NONE;
          ii->opt[3] = OPT_NONE;
          return 1;
          return 1;
        }
        }
        if (ii->op[1] == ii->opt[3] && ii->opt[1] == ii->opt[3]) {
      }
 
      if (ii->op[1] == ii->op[3] && ii->opt[1] == ii->opt[3]) {
          ii->op[1] = 1; ii->opt[1] = OPT_CONST;
          ii->op[1] = 1; ii->opt[1] = OPT_CONST;
          return 1;
          return 1;
        }
        }
        if (ii->op[2] == ii->opt[3] && ii->opt[2] == ii->opt[3]) {
      if (ii->op[2] == ii->op[3] && ii->opt[2] == ii->opt[3]) {
          ii->op[2] = 0; ii->opt[2] = OPT_CONST;
          ii->op[2] = 0; ii->opt[2] = OPT_CONST;
          return 1;
          return 1;
        }
        }
      }
      }
    }
    break;
  }
  }
  return 0;
  return 0;
}
}
 
 
/* First primary input */
/* First primary input */
Line 367... Line 411...
  ii->tmp = 0;
  ii->tmp = 0;
  return 0;
  return 0;
}
}
 
 
/* Search and optimize complex cmov assignments */
/* Search and optimize complex cmov assignments */
void optimize_cmovs (cuc_func *f)
int optimize_cmovs (cuc_func *f)
{
{
 
  int modified = 0;
  int b, i, j;
  int b, i, j;
 
 
  /* Mark all instructions unvisited */
  /* Mark all instructions unvisited */
  for (b = 0; b < f->num_bb; b++) if (!(f->bb[b].type & BB_DEAD))
  for (b = 0; b < f->num_bb; b++) if (!(f->bb[b].type & BB_DEAD))
    for (i = 0; i < f->bb[b].ninsn; i++) f->bb[b].insn[i].tmp = 0;
    for (i = 0; i < f->bb[b].ninsn; i++) f->bb[b].insn[i].tmp = 0;
Line 387... Line 432...
          assert (tmp_opt != OPT_NONE);
          assert (tmp_opt != OPT_NONE);
          change_insn_type (ii, II_ADD);
          change_insn_type (ii, II_ADD);
          ii->op[1] = tmp_op; ii->opt[1] = tmp_opt;
          ii->op[1] = tmp_op; ii->opt[1] = tmp_opt;
          ii->op[2] = 0; ii->opt[2] = OPT_CONST;
          ii->op[2] = 0; ii->opt[2] = OPT_CONST;
          ii->opt[3] = OPT_NONE;
          ii->opt[3] = OPT_NONE;
 
          modified = 1;
        }
        }
      }
      }
    }
    }
  }
  }
 
  return modified;
}
}
 
 
/* returns number of instructions, using instruction ref */
/* returns number of instructions, using instruction ref */
static int insn_uses (cuc_func *f, int ref)
static int insn_uses (cuc_func *f, int ref)
{
{
Line 463... Line 510...
 
 
  if (ii->opt[3] == OPT_REF) {
  if (ii->opt[3] == OPT_REF) {
    cuc_insn *prev = &f->INSN(ii->op[3]);
    cuc_insn *prev = &f->INSN(ii->op[3]);
    assert (prev->type & IT_COND);
    assert (prev->type & IT_COND);
    if (prev->index == II_CMOV) {
    if (prev->index == II_CMOV) {
 
      /* negated conditional:
 
           cmov x, 0, 1, y
 
           cmov z, a, b, x
 
         is replaced by
 
           cmov z, b, a, y */
 
      if (prev->opt[1] & OPT_CONST && prev->opt[2] & OPT_CONST
 
       && !prev->op[1] && prev->op[2]) {
 
        unsigned long t;
 
        t = ii->op[1]; ii->op[1] = ii->op[2]; ii->op[2] = t;
 
        t = ii->opt[1]; ii->opt[1] = ii->opt[2]; ii->opt[2] = t;
 
        ii->op[3] = prev->op[3]; ii->opt[3] = prev->opt[3];
 
      }
    } else if (prev->index == II_ADD) {
    } else if (prev->index == II_ADD) {
 
      /*   add x, y, 0
 
           cmov z, a, b, x
 
        is replaced by
 
           cmov z, a, b, y */
      if (prev->opt[2] & OPT_CONST && prev->op[2] == 0) {
      if (prev->opt[2] & OPT_CONST && prev->op[2] == 0) {
        ii->op[3] = prev->op[1]; ii->opt[3] = prev->opt[1];
        ii->op[3] = prev->op[1]; ii->opt[3] = prev->opt[1];
        return 1;
        return 1;
      }
      }
    }
    }
  }
  }
  return 0;
  return 0;
}
}
 
 
/* Optimizes dataflow tree */
/* Optimizes dataflow tree */
void optimize_tree (cuc_func *f)
int optimize_tree (cuc_func *f)
{
{
  int b, i, j;
  int b, i, j;
  int modified;
  int modified;
 
  int gmodified = 0;
 
 
  do {
  do {
    modified = 0;
    modified = 0;
    if (cuc_debug) cuc_check (f);
    if (cuc_debug) cuc_check (f);
    for (b = 0; b < f->num_bb; b++) if (!(f->bb[b].type & BB_DEAD)) {
    for (b = 0; b < f->num_bb; b++) if (!(f->bb[b].type & BB_DEAD)) {
Line 519... Line 583...
          if (ii->opt[j] & OPT_REF) {
          if (ii->opt[j] & OPT_REF) {
            cuc_insn *t = &f->INSN(ii->op[j]);
            cuc_insn *t = &f->INSN(ii->op[j]);
            if (f->INSN(ii->op[j]).index == II_ADD
            if (f->INSN(ii->op[j]).index == II_ADD
             && f->INSN(ii->op[j]).opt[2] & OPT_CONST
             && f->INSN(ii->op[j]).opt[2] & OPT_CONST
             && f->INSN(ii->op[j]).op[2] == 0
             && f->INSN(ii->op[j]).op[2] == 0
             && !(ii->type & IT_MEMORY && t->type & IT_MEMADD)
             && !(ii->type & IT_MEMORY && t->type & IT_MEMADD)) {
             && !(ii->type & IT_BRANCH) && !(t->type & IT_COND)) {
 
            /* do not promote through add-mem, and branches */
            /* do not promote through add-mem, and branches */
              modified = 1; cucdebug (2, "%8x:promote%i %8x %8x\n", REF (b, i), j, ii->op[j], t->op[1]);
              modified = 1; cucdebug (2, "%8x:promote%i %8x %8x\n", REF (b, i), j, ii->op[j], t->op[1]);
              ii->op[j] = t->op[1]; ii->opt[j] = t->opt[1];
              ii->op[j] = t->op[1]; ii->opt[j] = t->opt[1];
            }
            }
          }
          }
Line 626... Line 689...
            }
            }
          }
          }
        }
        }
      }
      }
    }
    }
 
    if (modified) gmodified = 1;
  } while (modified);
  } while (modified);
 
  return gmodified;
}
}
 
 
/* Remove nop instructions */
/* Remove nop instructions */
void remove_nops (cuc_func *f)
int remove_nops (cuc_func *f)
{
{
  int b;
  int b;
 
  int modified = 0;
  for (b = 0; b < f->num_bb; b++) {
  for (b = 0; b < f->num_bb; b++) {
    int c, d = 0, i, j;
    int c, d = 0, i, j;
    cuc_insn *insn = f->bb[b].insn;
    cuc_insn *insn = f->bb[b].insn;
    for (i = 0; i < f->bb[b].ninsn; i++)
    for (i = 0; i < f->bb[b].ninsn; i++)
      if (insn[i].index != II_NOP) {
      if (insn[i].index != II_NOP) {
        reloc [i] = d;
        reloc [i] = d;
        insn[d++] = insn[i];
        insn[d++] = insn[i];
      } else {
      } else {
        reloc[i] = d; /* For jumps only */
        reloc[i] = d; /* For jumps only */
      }
      }
 
    if (f->bb[b].ninsn != d) modified = 1;
    f->bb[b].ninsn = d;
    f->bb[b].ninsn = d;
 
 
    /* Relocate references from all basic blocks */
    /* Relocate references from all basic blocks */
    for (c = 0; c < f->num_bb; c++)
    for (c = 0; c < f->num_bb; c++)
      for (i = 0; i < f->bb[c].ninsn; i++) {
      for (i = 0; i < f->bb[c].ninsn; i++) {
Line 660... Line 727...
          if (REF_BB(d->ref) == b) d->ref = REF (b, reloc[REF_I (d->ref)]);
          if (REF_BB(d->ref) == b) d->ref = REF (b, reloc[REF_I (d->ref)]);
          d = d->next;
          d = d->next;
        }
        }
      }
      }
  }
  }
 
  return modified;
}
}
 
 
/* Remove unused assignments */
/* Remove unused assignments */
void remove_dead (cuc_func *f)
int remove_dead (cuc_func *f)
{
{
  int b, i, j;
  int b, i, j;
  for (b = 0; b < f->num_bb; b++)
  for (b = 0; b < f->num_bb; b++)
    for (i = 0; i < f->bb[b].ninsn; i++)
    for (i = 0; i < f->bb[b].ninsn; i++)
      if (!(f->bb[b].insn[i].type & (IT_VOLATILE | IT_OUTPUT)))
      if (!(f->bb[b].insn[i].type & (IT_VOLATILE | IT_OUTPUT)))
Line 685... Line 753...
    for (i = 0; i < f->bb[b].ninsn; i++)
    for (i = 0; i < f->bb[b].ninsn; i++)
      if (f->bb[b].insn[i].type & IT_UNUSED) {
      if (f->bb[b].insn[i].type & IT_UNUSED) {
        change_insn_type (&f->bb[b].insn[i], II_NOP);
        change_insn_type (&f->bb[b].insn[i], II_NOP);
      }
      }
 
 
  remove_nops (f);
  return remove_nops (f);
}
}
 
 
/* Removes trivial register assignments */
/* Removes trivial register assignments */
void remove_trivial_regs (cuc_func *f)
int remove_trivial_regs (cuc_func *f)
{
{
  int b, i;
  int b, i;
  for (i = 0; i < MAX_REGS; i++) f->saved_regs[i] = call_saved[i];
  for (i = 0; i < MAX_REGS; i++) f->saved_regs[i] = call_saved[i];
 
 
  for (b = 0; b < f->num_bb; b++) {
  for (b = 0; b < f->num_bb; b++) {
Line 711... Line 779...
  if (cuc_debug >= 2) {
  if (cuc_debug >= 2) {
    printf ("saved regs ");
    printf ("saved regs ");
    for (i = 0; i < MAX_REGS; i++) printf ("%i:%i ", i, f->saved_regs[i]);
    for (i = 0; i < MAX_REGS; i++) printf ("%i:%i ", i, f->saved_regs[i]);
    printf ("\n");
    printf ("\n");
  }
  }
  remove_nops (f);
  return remove_nops (f);
}
}
 
 
/* Determine inputs and outputs */
/* Determine inputs and outputs */
void set_io (cuc_func *f)
void set_io (cuc_func *f)
{
{
Line 830... Line 898...
          }
          }
        }
        }
}
}
 
 
/* CSE -- common subexpression elimination */
/* CSE -- common subexpression elimination */
void cse (cuc_func *f)
int cse (cuc_func *f)
{
{
 
  int modified = 0;
  int b, i, j, b1, i1, b2, i2, j2;
  int b, i, j, b1, i1, b2, i2, j2;
  for (b1 = 0; b1 < f->num_bb; b1++)
  for (b1 = 0; b1 < f->num_bb; b1++)
    for (i1 = 0; i1 < f->bb[b1].ninsn; i1++) if (f->bb[b1].insn[i1].index != II_NOP
    for (i1 = 0; i1 < f->bb[b1].ninsn; i1++) if (f->bb[b1].insn[i1].index != II_NOP
       && f->bb[b1].insn[i1].index != II_LRBB && !(f->bb[b1].insn[i1].type & IT_MEMORY)
       && f->bb[b1].insn[i1].index != II_LRBB && !(f->bb[b1].insn[i1].type & IT_MEMORY)
       && !(f->bb[b1].insn[i1].type & IT_MEMADD))
       && !(f->bb[b1].insn[i1].type & IT_MEMADD))
Line 867... Line 936...
 
 
            if (ok) {
            if (ok) {
              /* remove duplicated instruction and relink the references */
              /* remove duplicated instruction and relink the references */
              cucdebug (3, "%x - %x are same\n", REF(b1, i1), REF(b2, i2));
              cucdebug (3, "%x - %x are same\n", REF(b1, i1), REF(b2, i2));
              change_insn_type (ii2, II_NOP);
              change_insn_type (ii2, II_NOP);
 
              modified = 1;
              for (b = 0; b < f->num_bb; b++)
              for (b = 0; b < f->num_bb; b++)
                for (i = 0; i < f->bb[b].ninsn; i++)
                for (i = 0; i < f->bb[b].ninsn; i++)
                  for (j = 0; j < MAX_OPERANDS; j++)
                  for (j = 0; j < MAX_OPERANDS; j++)
                    if (f->bb[b].insn[i].opt[j] & OPT_REF
                    if (f->bb[b].insn[i].opt[j] & OPT_REF
                     && f->bb[b].insn[i].op[j] == REF (b2, i2))
                     && f->bb[b].insn[i].op[j] == REF (b2, i2))
                      f->bb[b].insn[i].op[j] = REF (b1, i1);
                      f->bb[b].insn[i].op[j] = REF (b1, i1);
            }
            }
          }
          }
 
  return modified;
}
}
 
 
static int count_cmovs (cuc_insn *ii, int match)
static int count_cmovs (cuc_insn *ii, int match)
{
{
  int c = 0, j;
  int c = 0, j;

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.