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

Subversion Repositories or1k

Compare Revisions

  • This comparison shows the changes necessary to convert path
    /
    from Rev 904 to Rev 905
    Reverse comparison

Rev 904 → Rev 905

/trunk/or1ksim/cuc/cuc.h
199,6 → 199,9
/* Loads from file into global array insn */
int cuc_load (char *in_fn);
 
/* Negates conditional instruction */
void negate_conditional (cuc_insn *ii);
 
/* Scans sequence of BBs and set bb[].cnt */
void generate_bb_seq (cuc_func *f, char *mp_filename, char *bb_filename);
 
/trunk/or1ksim/cuc/load.c
80,6 → 80,20
insn[j] = t;
}
 
/* Negates conditional instruction */
void negate_conditional (cuc_insn *ii)
{
assert (ii->type & IT_COND);
if (ii->index == II_SFEQ) change_insn_type (ii, II_SFNE);
else if (ii->index == II_SFNE) change_insn_type (ii, II_SFEQ);
else if (ii->index == II_SFLT) change_insn_type (ii, II_SFGE);
else if (ii->index == II_SFGT) change_insn_type (ii, II_SFLE);
else if (ii->index == II_SFLE) change_insn_type (ii, II_SFGT);
else if (ii->index == II_SFGE) change_insn_type (ii, II_SFLT);
else assert (0);
}
 
/* Remove delay slots */
void remove_dslots ()
{
269,7 → 283,7
insn[d].type = 0;
insn[d].op[0] = -1; insn[d].opt[0] = OPT_REGISTER | OPT_DEST;
insn[d].op[1] = insn[d].op[2]; insn[d].opt[1] = insn[d].opt[2];
insn[d].op[2] = 0x20000000; insn[d].opt[2] = OPT_CONST;
insn[d].op[2] = 0x80000000; insn[d].opt[2] = OPT_CONST;
insn[d].opt[3] = OPT_NONE;
 
insn[--d] = insn[i];
277,7 → 291,7
insn[d].type = 0;
insn[d].op[0] = -1; insn[d].opt[0] = OPT_REGISTER | OPT_DEST;
insn[d].op[1] = insn[d].op[1]; insn[d].opt[1] = insn[d].opt[1];
insn[d].op[2] = 0x20000000; insn[d].opt[2] = OPT_CONST;
insn[d].op[2] = 0x80000000; insn[d].opt[2] = OPT_CONST;
insn[d].opt[3] = OPT_NONE;
 
reloc[i] = d;
343,16 → 357,6
insn[i].type |= IT_BRANCH | IT_VOLATILE;
} else {
i--;
if (f) {
//printf ("%s\n", cuc_insn_name (&insn[i]));
if (insn[i].index == II_SFEQ) change_insn_type (&insn[i], II_SFNE);
else if (insn[i].index == II_SFNE) change_insn_type (&insn[i], II_SFEQ);
else if (insn[i].index == II_SFLT) change_insn_type (&insn[i], II_SFGE);
else if (insn[i].index == II_SFGT) change_insn_type (&insn[i], II_SFLE);
else if (insn[i].index == II_SFLE) change_insn_type (&insn[i], II_SFGT);
else if (insn[i].index == II_SFGE) change_insn_type (&insn[i], II_SFLT);
else assert (0);
}
/* repair params */
insn[i].op[2] = insn[i].op[1]; insn[i].opt[2] = insn[i].opt[1] & ~OPT_DEST;
insn[i].op[1] = insn[i].op[0]; insn[i].opt[1] = insn[i].opt[0] & ~OPT_DEST;
359,6 → 363,7
insn[i].op[0] = FLAG_REG; insn[i].opt[0] = OPT_DEST | OPT_REGISTER;
insn[i].opt[3] = OPT_NONE;
insn[i].type |= IT_COND;
if (f) negate_conditional (&insn[i]);
i++;
change_insn_type (&insn[i], II_BF);
insn[i].op[0] = i + insn[i].op[0]; insn[i].opt[0] = OPT_JUMP;
/trunk/or1ksim/cuc/bb.c
295,6 → 295,29
if (cuc_debug >= 3) print_cuc_bb (f, "AFTER_PREV");
}
 
/* We do a quick check if there are some anomalies with references */
void cuc_check (cuc_func *f)
{
int i, j, k;
for (i = 0; i < f->num_bb; i++) {
if (!f->bb[i].insn && f->bb[i].ninsn) {
printf ("Anomaly detected at BB%x (insn NULL)\n", i);
print_cuc_bb (f, "ANOMALY");
exit (1);
}
for (j = 0; j < f->bb[i].ninsn; j++)
for (k = 0; k < MAX_OPERANDS; k++)
if (f->bb[i].insn[j].opt[k] & OPT_REF) {
int t = f->bb[i].insn[j].op[k];
if (REF_BB(t) >= f->num_bb || REF_I (t) >= f->bb[REF_BB(t)].ninsn) {
printf ("Anomaly detected at %x.%x[%i]\n", i, j, k);
print_cuc_bb (f, "ANOMALY");
exit (1);
}
}
}
}
 
/* Build basic blocks */
void build_bb (cuc_func *f)
{
342,19 → 365,7
if (f->bb[i].insn[j].type & IT_MEMORY) f->bb[i].nmemory++;
}
}
 
/* We do a quick check if there are some anomalies */
for (i = 0; i < f->num_bb; i++)
for (j = 0; j < f->bb[i].ninsn; j++)
for (k = 0; k < MAX_OPERANDS; k++)
if (f->bb[i].insn[j].opt[k] & OPT_REF) {
int t = f->bb[i].insn[j].op[k];
if (REF_I (t) >= f->bb[REF_BB(t)].ninsn) {
printf ("Anomaly detected at %x.%x[%i]\n", i, j, k);
print_cuc_bb (f, "ANOMALY");
exit (1);
}
}
cuc_check (f);
}
 
/* type == 0; keep predecessor condition
362,46 → 373,63
* type == 2; join loop unrolled blocks */
static void join_bb (cuc_func *f, int pred, int succ, int type)
{
int i, j, k, add, ninsn, add_cond = 0;
int i, j, k, n1, n2, ninsn, add_cond = 0;
unsigned long cond_op, cond_opt;
cuc_insn *insn;
 
if (cuc_debug) cuc_check (f);
cucdebug (3, "%x <= %x+%x (%i)\n", pred, pred, succ, type);
cucdebug (3, "%x %x\n", f->bb[pred].ninsn, f->bb[succ].ninsn);
if (cuc_debug >= 3) fflush (stdout);
 
add = f->bb[pred].ninsn;
if (f->bb[pred].ninsn <= 0
|| !(f->bb[pred].insn[f->bb[pred].ninsn - 1].type & IT_BRANCH)) type = 1;
n1 = f->bb[pred].ninsn;
n2 = f->bb[succ].ninsn;
if (n1 <= 0
|| !(f->bb[pred].insn[n1 - 1].type & IT_BRANCH)) type = 1;
if (type == 0 && f->bb[succ].prev[0] == f->bb[succ].next[0]) add_cond = 1;
if (type == 2) add_cond = 1;
 
assert (f->bb[pred].next[0] == f->bb[succ].next[0] || type != 2); /* not supported */
ninsn = f->bb[pred].ninsn + f->bb[succ].ninsn + (type == 0 ? 1 : type == 1 ? 0 : 2)
+ (add_cond ? MAX_REGS : 0);
ninsn = n1 + n2 + (type == 1 ? 0 : 1) + (add_cond ? MAX_REGS : 0);
 
insn = (cuc_insn *) malloc (ninsn * sizeof (cuc_insn));
for (i = 0; i < add; i++) insn[i] = f->bb[pred].insn[i];
/* when type == 0, we copy the last (jump) instruction to the end */
for (i = 0; i < n1; i++) insn[i] = f->bb[pred].insn[i];
/* when type == 0, we move the last (jump) instruction to the end */
if (type == 0 || type == 2) {
insn[ninsn - 1] = insn[add - 1];
cond_op = insn[add - 1].op[1];
cond_opt = insn[add - 1].opt[1];
change_insn_type (&insn[add - 1], II_NOP);
/* Move first branch instruction to the end */
assert (insn[n1 - 1].type & IT_BRANCH);
insn[ninsn - 1] = insn[n1 - 1];
cond_op = insn[n1 - 1].op[1];
cond_opt = insn[n1 - 1].opt[1];
/* Remove old branch */
change_insn_type (&insn[n1 - 1], II_NOP);
}
/* Copy second block */
for (i = 0; i < f->bb[succ].ninsn; i++) insn[i + f->bb[pred].ninsn] = f->bb[succ].insn[i];
for (i = 0; i < n2; i++) insn[i + n1] = f->bb[succ].insn[i];
 
 
/* and when type == 2, we may need to add sfor instruction, to quit when either is true */
if (type == 2) {
assert (0);
/* Move second branch instruction to the end */
if (insn[n1 + n2 - 1].type & IT_BRANCH) {
insn[ninsn - 1] = insn[n1 + n2 - 1];
 
/* Use conditional from cmov FLAG_REG, c_p, c_s, c_p */
insn[ninsn - 1].op[1] = REF (pred, n1 + n2 + FLAG_REG); insn[ninsn - 1].opt[1] = OPT_REF;
 
/* Remove old one */
change_insn_type (&insn[n1 + n2 - 1], II_NOP);
} else change_insn_type (&insn[ninsn - 1], II_NOP); /* do not use branch slot */
}
 
#if 1
/* LRBB at start of succ BB is not valid, it should be set when */
if (insn[add].index == II_LRBB) {
if (insn[n1].index == II_LRBB) {
assert (0); /* not tested yet */
change_insn_type (&insn[add], II_NOP);
for (i = add; i < ninsn; i++)
if (insn[i].index == II_CMOV && insn[i].op[3] == REF (succ, add)) {
change_insn_type (&insn[n1], II_NOP);
for (i = n1; i < ninsn; i++)
if (insn[i].index == II_CMOV && insn[i].op[3] == REF (pred, n1)) {
assert (insn[i].opt[3] == OPT_REF);
insn[i].op[3] = cond_op;
insn[i].opt[3] = cond_opt;
417,6 → 445,7
}
}
}
#endif
for (i = 0; i < ninsn; i++) reloc[i] = -1;
 
426,9 → 455,9
recalc_last_used_reg (f, succ);
 
/* r0 -- add nop for it */
change_insn_type (&insn[add + f->bb[succ].ninsn], II_NOP);
change_insn_type (&insn[n1 + n2], II_NOP);
for (i = 1; i < MAX_REGS; i++) {
cuc_insn *ii = &insn[add + f->bb[succ].ninsn + i];
cuc_insn *ii = &insn[n1 + n2 + i];
int a = f->bb[pred].last_used_reg[i];
int b = f->bb[succ].last_used_reg[i];
 
440,7 → 469,8
ii->op[0] = i; ii->opt[0] = OPT_REGISTER | OPT_DEST;
ii->op[1] = b; ii->opt[1] = OPT_REF;
ii->op[2] = 0; ii->opt[2] = OPT_CONST;
ii->op[3] = OPT_NONE;
ii->opt[3] = OPT_NONE;
if (i == FLAG_REG) ii->type |= IT_COND;
} else if (b >= 0) {
change_insn_type (ii, II_CMOV);
ii->type = 0;
449,12 → 479,14
ii->op[1] = a; ii->opt[1] = OPT_REF;
ii->op[2] = b; ii->opt[2] = OPT_REF;
ii->op[3] = cond_op; ii->opt[3] = cond_opt;
reloc[REF_I(a)] = REF (pred, add + f->bb[succ].ninsn + i);
reloc[REF_I(a)] = REF (pred, n1 + n2 + i);
if (i == FLAG_REG) ii->type |= IT_COND;
}
sprintf (ii->disasm, "cmov (join BB)");
}
}
if (cuc_debug) cuc_check (f);
f->bb[pred].type |= f->bb[succ].type;
i = 0;
assert (f->bb[pred].next[0] >= 0);
468,13 → 500,22
f->bb[pred].next[0] = f->bb[succ].next[0];
f->bb[pred].next[1] = f->bb[succ].next[1];
break;
case 2:
f->bb[pred].next[0] = f->bb[succ].next[0];
f->bb[pred].next[1] = f->bb[succ].next[1];
break;
}
if (f->bb[pred].next[0] == f->bb[pred].next[1]) f->bb[pred].next[1] = -1;
f->bb[succ].type = BB_DEAD;
/* remove branch instruction, if there is only one successor */
if (f->bb[pred].next[1] < 0 && insn[ninsn - 1].type & IT_BRANCH
&& f->bb[pred].next[0] != pred) /* not when end BB, loop */
change_insn_type (&insn[ninsn - 1], II_NOP);
 
/* Set max count */
if (f->bb[pred].cnt < f->bb[succ].cnt) f->bb[pred].cnt = f->bb[succ].cnt;
f->bb[pred].ninsn = ninsn;
f->bb[succ].ninsn = 0;
free (f->bb[pred].insn); f->bb[pred].insn = NULL;
free (f->bb[succ].insn); f->bb[succ].insn = NULL;
f->bb[pred].insn = insn;
488,22 → 529,12
/* Check if we are referencing successor BB -> relocate to second part of
the new block */
if (REF_BB (f->bb[i].insn[j].op[k]) == succ) {
if (type == 0 && f->bb[i].insn[j].op[j] == REF (succ, ninsn - 1))
f->bb[i].insn[j].op[j] = REF (pred, f->bb[pred].ninsn);
else {
int t = f->bb[i].insn[j].op[k];
int ndest = REF (pred, REF_I (t) + add);
int t = f->bb[i].insn[j].op[k];
int ndest = REF (pred, REF_I (t) + n1);
//printf ("%x: %x %x\n", REF(i, j), t, ndest);
 
/* We've found a reference to succ. block, being removed, relocate */
if (add_cond && i != succ && !(i == pred && j >= ninsn - MAX_REGS)) {
//printf ("%x!\n", t);
//printf ("%x!\n", f->INSN(ndest).op[0]);
/* interblock dependency should have physical register attached */
assert (f->INSN(ndest).opt[0] == OPT_DEST | OPT_REGISTER);
assert (f->INSN(ndest).op[0] >= 0);
f->bb[i].insn[j].op[k] = REF (pred, add + f->bb[succ].ninsn + f->INSN(ndest).op[0]);
} else f->bb[i].insn[j].op[k] = ndest;
}
/* We've found a reference to succ. block, being removed, relocate */
f->bb[i].insn[j].op[k] = ndest;
} else if (REF_BB(f->bb[i].insn[j].op[k]) == pred) {
if (i != pred && reloc[REF_I(f->bb[i].insn[j].op[k])] >= 0) {
f->bb[i].insn[j].op[k] = reloc[REF_I(f->bb[i].insn[j].op[k])];
512,6 → 543,7
}
}
if (cuc_debug) cuc_check (f);
if (cuc_debug >= 3) print_cuc_bb (f, "join");
}
 
581,10 → 613,20
for (i = 0; i < f->num_bb; i++) if (!(f->bb[i].type & BB_DEAD))
if (f->bb[i].prev[0] >= 0 && f->bb[i].prev[1] < 0) { /* one predecessor */
int p = f->bb[i].prev[0];
if (f->bb[p].next[0] == i && f->bb[p].next[1] == f->bb[p].next[1]) {
join_bb (f, f->bb[i].prev[0], i, 2);
#if 0 /* not yet supported */
if (f->bb[p].next[0] == i
&& (f->bb[i].next[1] == f->bb[p].next[1]
|| f->bb[i].next[1] == f->bb[p].next[0])) {
join_bb (f, p, i, 2);
goto remove_lrbb;
}
#endif
if (f->bb[p].next[1] == i
&& (f->bb[i].next[0] == f->bb[p].next[1]
|| f->bb[i].next[0] == f->bb[p].next[0])) {
join_bb (f, p, i, 2);
goto remove_lrbb;
}
}
#endif
}
/trunk/or1ksim/cuc/insn.c
50,8 → 50,8
{"sfne", 1, "assign \1 = \2 != \3;"},
{"sfle", 0, "assign \1 = \2 <= \3;"},
{"sflt", 0, "assign \1 = \2 < \3;"},
{"sfge", 0, "assign \1 = \2 >= \3;"},
{"sfgt", 0, "assign \1 = \2 > \3;"},
{"sfge", 0, "assign \1 = \2 >= \3;"},
{"sfor", 1, "assign \1 = \2 || \3;"},
{"bf", 0, ""},
 
248,6 → 248,16
ii->opt[3] = OPT_NONE;
return 1;
}
if (ii->opt[3] & OPT_CONST) {
change_insn_type (ii, II_ADD);
if (ii->op[3]) {
ii->op[2] = 0; ii->opt[2] = OPT_CONST;
} else {
ii->op[1] = 0; ii->opt[1] = OPT_CONST;
}
ii->opt[3] = OPT_NONE;
return 1;
}
}
return 0;
}
/trunk/or1ksim/cuc/cuc.c
472,7 → 472,7
 
prof_set (1, 0);
assert (prof_acquire (config.sim.prof_fn) == 0);
//cuc_debug = 9;
cuc_debug = 9;
if (config.cuc.calling_convention)
printf ("Assuming OpenRISC standard calling convention.\n");
533,7 → 533,8
ntime += nt * func[i]->num_runs;
size += s;
} else ntime += prof_func[i].cum_cycles;
printf ("%8.1f |%8.1f | %-8s|\n", 1.f * prof_func[i].cum_cycles / func[i]->timings.new_time, f, format_func_options (tmp, func[i]));
printf ("%8.1f |%8.1f | %-8s|\n", 1.f * prof_func[i].cum_cycles
/ func[i]->timings.new_time, f, format_func_options (tmp, func[i]));
} else {
printf (" N/A | N/A | |\n");
ntime += prof_func[i].cum_cycles;
543,7 → 544,8
for (i = 0; i < prof_nfuncs; i++)
prof_func[i].cum_cycles = -prof_func[i].cum_cycles;
printf ("-----------------------------------------------------------------------------\n");
printf ("Total %i cycles (was %i), total added gates = %i. Speed factor %.1f\n", ntime, prof_cycles, size, 1. * prof_cycles / ntime);
printf ("Total %i cycles (was %i), total added gates = %i. Speed factor %.1f\n",
ntime, prof_cycles, size, 1. * prof_cycles / ntime);
} else if (strncmp (tmp1, "d", 1) == 0 || strncmp (tmp1, "debug", 5) == 0) {
/* debug command */
sscanf (tmp1, "%*s %i", &cuc_debug);

powered by: WebSVN 2.1.0

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