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); |