URL
https://opencores.org/ocsvn/or1k/or1k/trunk
Subversion Repositories or1k
Compare Revisions
- This comparison shows the changes necessary to convert path
/
- from Rev 1060 to Rev 1061
- ↔ Reverse comparison
Rev 1060 → Rev 1061
/trunk/or1ksim/cpu/common/parse.c
632,8 → 632,10
if (str_tbl) { |
i = 0; |
while(syms--) { |
if (sym_tbl[i].st_name) |
if (sym_tbl[i].st_name && sym_tbl[i].st_info && ELF_SHORT_H(sym_tbl[i].st_shndx) < 0x8000) { |
add_label(ELF_LONG_H(sym_tbl[i].st_value), &str_tbl[ELF_LONG_H(sym_tbl[i].st_name)]); |
debug (8, "%08x(%s): %x %x %x\n", ELF_LONG_H(sym_tbl[i].st_value), &str_tbl[ELF_LONG_H(sym_tbl[i].st_name)], sym_tbl[i].st_info, sym_tbl[i].st_other, ELF_SHORT_H(sym_tbl[i].st_shndx)); |
} |
i++; |
} |
} |
/trunk/or1ksim/cuc/cuc.h
73,7 → 73,6
|
#define BB_INLOOP 0x01 /* This block is inside a loop */ |
#define BB_OPTIONAL 0x02 |
#define BB_END 0x04 /* Whether this block is last */ |
#define BB_DEAD 0x08 /* This block is unaccessible -> to be removed */ |
|
#define BBID_START MAX_BB /* Start BB pointer */ |
/trunk/or1ksim/cuc/load.c
234,7 → 234,7
d = num_insn + num_bra; |
assert (d < MAX_INSNS); |
|
/* Split memory commands */ |
/* Add nop before branch */ |
for (i = num_insn - 1; i >= 0; i--) if (insn[i].type & IT_BRANCH) { |
insn[--d] = insn[i]; |
insn[--d] = insn[i]; |
273,8 → 273,8
insn[d + 1].op[0] = insn[i].op[2]; insn[d + 1].opt[0] = insn[d + 1].opt[2]; |
insn[d + 1].opt[2] = OPT_NONE; |
insn[d + 1].type &= ~IT_BBSTART; |
insn[d].op[2] = insn[d].op[0]; insn[d].opt[2] = insn[d].opt[0]; |
insn[d].op[0] = -1; insn[d].opt[0] = OPT_REGISTER | OPT_DEST; /* add rd, ra, rb */ |
insn[d].op[2] = insn[i].op[0]; insn[d].opt[2] = insn[i].opt[0]; |
insn[d].opt[3] = OPT_NONE; |
insn[d].type &= IT_INDELAY | IT_BBSTART; |
insn[d].type |= IT_MEMADD; |
/trunk/or1ksim/cuc/bb.c
234,7 → 234,6
f->bb[i].next[1] = i + 1; |
if (++f->bb[i + 1].tmp > 2) eb++; |
} else if (f->bb[i].last == num_insn - 1) { /* Last instruction doesn't have to do anything */ |
f->bb[i].type |= BB_END; |
} else { |
f->bb[i].next[0] = i + 1; |
if (++f->bb[i + 1].tmp > 2) eb++; |
254,7 → 253,6
while (j-- > 2) { |
f->bb[--end_bb].first = f->bb[i].first; |
f->bb[end_bb].last = -1; |
f->bb[end_bb].type &= ~BB_END; |
f->bb[end_bb].next[0] = -1; |
f->bb[end_bb].next[1] = -1; |
f->bb[end_bb].tmp = 0; |
332,14 → 330,12
} |
/* Add START marker */ |
assert (f->bb[0].prev[0] < 0); |
f->bb[0].prev[0]= BBID_START; |
f->bb[0].prev[0] = BBID_START; |
|
/* Add END marker */ |
for (i = 0; i < f->num_bb; i++) |
if (f->bb[i].type & BB_END) { |
assert (f->bb[i].next[0] < 0); |
f->bb[i].next[0] = BBID_END; |
} |
assert (f->bb[f->num_bb - 1].next[0] < 0); |
assert (f->bb[f->num_bb - 1].next[1] < 0); |
f->bb[f->num_bb - 1].next[0] = BBID_END; |
if (cuc_debug >= 3) print_cuc_bb (f, "AFTER_PREV"); |
} |
|
360,7 → 356,7
goto err; |
} |
} |
for (k = 0; k < MAX_OPERANDS; k++) |
for (k = 0; k < MAX_OPERANDS; k++) { |
if (ii->opt[k] & OPT_REF) { |
int t = ii->op[k]; |
if (REF_BB(t) >= f->num_bb || REF_I (t) >= f->bb[REF_BB(t)].ninsn |
368,6 → 364,11
(f->INSN(t).type & IT_COND) != (ii->type & IT_COND) && k < 3 |
|| !(f->INSN(t).type & IT_COND) && k == 3)) goto err; |
} |
if (k && ii->opt[k] & OPT_DEST) { |
cucdebug (1, "Destination only allowed for op0!\n"); |
goto err; |
} |
} |
} |
} |
return; |
608,26 → 609,20
} |
|
if (cuc_debug) cuc_check (f); |
if (f->bb[succ].type & BB_END) { |
f->bb[pred].type |= BB_END; |
if (ninsn > 0 && insn[ninsn - 1].type & IT_BRANCH && insn[ninsn - 1].op[0] == succ) { |
assert (insn[ninsn - 1].opt[0] & OPT_BB); |
insn[ninsn - 1].op[0] = BBID_END; |
} |
} |
i = 0; |
assert (f->bb[pred].next[0] >= 0 && f->bb[pred].next[0] != BBID_END); |
switch (type) { |
case 0: |
assert (f->bb[pred].next[0] >= 0); |
if (f->bb[pred].next[0] == succ) f->bb[pred].next[0] = f->bb[succ].next[0]; |
if (f->bb[pred].next[1] == succ) f->bb[pred].next[1] = f->bb[succ].next[0]; |
assert (f->bb[succ].next[1] < 0); |
break; |
case 1: |
assert (f->bb[pred].next[0] >= 0 && f->bb[pred].next[0] != BBID_END); |
f->bb[pred].next[0] = f->bb[succ].next[0]; |
f->bb[pred].next[1] = f->bb[succ].next[1]; |
break; |
case 2: |
assert (f->bb[pred].next[0] >= 0 && f->bb[pred].next[0] != BBID_END); |
f->bb[pred].next[0] = f->bb[succ].next[0]; |
f->bb[pred].next[1] = f->bb[succ].next[1]; |
break; |
635,6 → 630,8
if (f->bb[pred].next[0] < 0) f->bb[pred].next[0] = f->bb[pred].next[1]; |
if (f->bb[pred].next[0] == f->bb[pred].next[1]) f->bb[pred].next[1] = -1; |
|
if (type == 0) assert (f->bb[succ].next[1] < 0); |
|
/* We just did something stupid -- we joined two predecessors into one; |
succ may need the information from which block we came. We will repair |
this by converting LRBB to CMOV */ |
1073,7 → 1070,7
if (f->bb[b].insn[i].type & IT_UNUSED) change_insn_type (&f->bb[b].insn[i], II_NOP); |
|
/* SSAs with final register value are marked as outputs */ |
assert (f->bb[f->num_bb - 1].type & BB_END); |
assert (f->bb[f->num_bb - 1].next[0] == BBID_END); |
for (i = 0; i < MAX_REGS; i++) if (!caller_saved[i]) { |
int t = f->bb[f->num_bb - 1].last_used_reg[i]; |
/* Mark them volatile, so optimizer does not remove them */ |
1288,9 → 1285,9
} |
} |
|
/* Unroll loop b unroll times and return new function. Original |
function is unmodified. */ |
static cuc_func *unroll_loop (cuc_func *f, int b, int unroll) |
/* Preroll if type == 1 or unroll if type == 0 loop in BB b `ntimes' times and return |
new function. Original function is unmodified. */ |
static cuc_func *roll_loop (cuc_func *f, int b, int ntimes, int type) |
{ |
int b1, t, i, j, prevb, prevart_b; |
cuc_func *n = dup_func (f); |
1297,22 → 1294,32
cuc_bb *ob = &f->bb[b]; |
cuc_insn *ii; |
|
assert (unroll > 1); |
//PRINTF ("unroll BB%i x %i (num_bb %i)\n", b, unroll, n->num_bb); |
unroll--; |
assert (n->num_bb + unroll * 2 < MAX_BB); |
assert (ntimes > 1); |
cucdebug (3, "roll type = %i, BB%i x %i (num_bb %i)\n", type, b, ntimes, n->num_bb); |
ntimes--; |
assert (n->num_bb + ntimes * 2 < MAX_BB); |
|
prevb = b; |
prevart_b = b; |
|
/* point to first artificial block */ |
if (n->bb[b].next[0] != b) { |
n->bb[b].next[0] = n->num_bb + 1; |
} else if (n->bb[b].next[1] != b) { |
n->bb[b].next[1] = n->num_bb + 1; |
} |
|
/* Duplicate the BB */ |
for (t = 0; t < unroll; t++) { |
for (t = 0; t < ntimes; t++) { |
cuc_bb *pb = &n->bb[prevart_b]; |
/* Add new block and set links */ |
b1 = n->num_bb++; |
cpy_bb (&n->bb[b1], ob); |
/* Only one should be in loop, so we remove any INLOOP flags from duplicates */ |
n->bb[b1].type &= ~(BB_END | BB_INLOOP); |
n->bb[b1].type &= ~BB_INLOOP; |
print_cuc_bb (n, "prerollA"); |
|
printf ("prevb %i b1 %i prevart %i\n", prevb, b1, prevart_b); |
/* Set predecessor's successor */ |
if (n->bb[prevb].next[0] == b) { |
n->bb[prevb].next[0] = b1; |
1384,22 → 1391,21
ii->type = IT_COND; |
|
/* Only one should be in loop, so we remove any INLOOP flags from duplicates */ |
n->bb[b1].type &= ~(BB_END | BB_INLOOP); |
n->bb[b1].type &= ~BB_INLOOP; |
n->bb[b1].prev[0] = prevart_b; |
n->bb[b1].prev[1] = b1 - 1; |
n->bb[b1].next[0] = -1; |
n->bb[b1].next[1] = -1; |
|
|
prevb = b1 - 1; |
prevart_b = b1; |
print_cuc_bb (n, "prerollB"); |
} |
if (ob->type & BB_END) { |
n->bb[prevart_b].type |= BB_END; |
n->bb[b].type &= ~BB_END; |
} |
|
print_cuc_bb (n, "preroll0"); |
n->bb[prevart_b].next[0] = ob->next[0] == b ? ob->next[1] : ob->next[0]; |
|
n->bb[prevart_b].next[0] = ob->next[0] == b ? ob->next[1] : ob->next[0]; |
//print_cuc_bb (n, "unroll1"); |
print_cuc_bb (n, "preroll1"); |
/* repair BB after loop, to point back to latest artificial BB */ |
b1 = n->bb[prevart_b].next[0]; |
if (b1 >= 0 && b1 != BBID_END) { |
1408,166 → 1414,35
else assert (0); |
} |
|
/* Relink back to start of the loop */ |
/* Set predecessor's successor */ |
if (n->bb[prevb].next[0] == b) n->bb[prevb].next[0] = b; |
else if (n->bb[prevb].next[1] == b) n->bb[prevb].next[1] = b; |
else assert (0); |
|
/* Set predecessor */ |
if (n->bb[b].prev[0] == b) n->bb[b].prev[0] = prevb; |
else if (n->bb[b].prev[1] == b) n->bb[b].prev[1] = prevb; |
else assert (0); |
|
//print_cuc_bb (n, "unroll2"); |
|
/* Relocate backward references to current instance and forward references |
to previous one */ |
relocate_bb (&n->bb[b], b, b, prevb); |
|
/* Relocate all other blocks to point to latest prevart_b */ |
for (i = 0; i < f->num_bb; i++) |
if (i != b) relocate_bb (&n->bb[i], b, prevart_b, prevart_b); |
|
return n; |
} |
|
/* Preroll loop b preroll times and return new function. Original |
function is unmodified. */ |
static cuc_func *preroll_loop (cuc_func *f, int b, int preroll) |
{ |
int b1, t, i, j, prevb, prevart_b; |
cuc_func *n = dup_func (f); |
cuc_bb *ob = &f->bb[b]; |
cuc_insn *ii; |
|
assert (preroll > 1); |
//PRINTF ("preroll BB%i x %i (num_bb %i)\n", b, preroll, n->num_bb); |
preroll--; |
assert (n->num_bb + preroll * 2 < MAX_BB); |
|
prevb = b; |
prevart_b = b; |
/* Duplicate the BB */ |
for (t = 0; t < preroll; t++) { |
cuc_bb *pb = &n->bb[prevart_b]; |
/* Add new block and set links */ |
b1 = n->num_bb++; |
cpy_bb (&n->bb[b1], ob); |
/* Only one should be in loop, so we remove any INLOOP flags from duplicates */ |
n->bb[b1].type &= ~(BB_END | BB_INLOOP); |
if (type) { |
/* Relink to itself */ |
/* Set predecessor's successor */ |
if (n->bb[prevb].next[0] == b) n->bb[prevb].next[0] = prevb; |
else if (n->bb[prevb].next[1] == b) n->bb[prevb].next[1] = prevb; |
else assert (0); |
n->bb[prevb].prev[1] = prevb; |
|
/* Set predecessor */ |
if (n->bb[b].prev[0] == b) { |
n->bb[b].prev[0] = n->bb[b].prev[1]; |
n->bb[b].prev[1] = -1; |
} else if (n->bb[b].prev[1] == b) n->bb[b].prev[1] = -1; |
else assert (0); |
} else { |
/* Relink back to start of the loop */ |
/* Set predecessor's successor */ |
if (n->bb[prevb].next[0] == b) { |
n->bb[prevb].next[0] = b1; |
if (pb->next[0] < 0) pb->next[0] = b1 + 1; |
else pb->next[1] = b1 + 1; |
n->bb[b1].next[1] = b1 + 1; |
} else if (n->bb[prevb].next[1] == b) { |
if (pb->next[0] < 0) pb->next[0] = b1 + 1; |
else pb->next[1] = b1 + 1; |
n->bb[b1].next[0] = b1 + 1; |
n->bb[prevb].next[1] = b1; |
} else assert (0); |
if (n->bb[prevb].next[0] == b) n->bb[prevb].next[0] = b; |
else if (n->bb[prevb].next[1] == b) n->bb[prevb].next[1] = b; |
else assert (0); |
|
/* Set predecessor */ |
n->bb[b1].prev[0] = prevb; |
n->bb[b1].prev[1] = -1; |
|
/* Relocate backward references to current instance and forward references |
to previous one */ |
relocate_bb (&n->bb[b1], b, b1, prevb); |
|
/* add artificial block, just to join accesses */ |
b1 = n->num_bb++; |
cpy_bb (&n->bb[b1], ob); |
n->bb[b1].cnt = 0; |
|
for (i = 0; i < ob->ninsn - 1; i++) { |
ii = &n->bb[b1].insn[i]; |
if (ob->insn[i].opt[0] & OPT_DEST) { |
change_insn_type (ii, II_CMOV); |
ii->op[0] = -1; ii->opt[0] = OPT_REGISTER | OPT_DEST; |
ii->op[1] = REF (prevart_b, i); ii->opt[1] = OPT_REF; |
ii->op[2] = REF (b1 - 1, i); ii->opt[2] = OPT_REF; |
|
/* Take left one, if we should have finished the first iteration*/ |
if (pb->insn[pb->ninsn - 1].type & IT_BRANCH) { |
ii->op[3] = pb->insn[pb->ninsn - 1].op[1]; ii->opt[3] = pb->insn[pb->ninsn - 1].opt[1]; |
} else { |
assert (pb->insn[pb->ninsn - 1].type & IT_COND); |
ii->op[3] = REF (prevart_b, pb->ninsn - 1); ii->opt[3] = OPT_REF; |
} |
ii->dep = NULL; |
ii->type = ob->insn[i].type & IT_COND; |
} else { |
change_insn_type (ii, II_NOP); |
} |
} |
|
/* Add conditional or instruction at the end, prioritizing flags */ |
ii = &n->bb[b1].insn[ob->ninsn - 1]; |
change_insn_type (ii, II_CMOV); |
ii->op[0] = FLAG_REG; ii->opt[0] = OPT_REGISTER | OPT_DEST; |
if (pb->insn[pb->ninsn - 1].type & IT_BRANCH) { |
ii->op[1] = pb->insn[pb->ninsn - 1].op[1]; |
ii->opt[1] = pb->insn[pb->ninsn - 1].opt[1]; |
} else { |
ii->op[1] = REF (prevart_b, pb->ninsn - 1); |
ii->opt[1] = OPT_REF; |
} |
if (n->bb[b1 - 1].insn[pb->ninsn - 1].type & IT_BRANCH) { |
ii->op[2] = n->bb[b1 - 1].insn[pb->ninsn - 1].op[1]; |
ii->opt[2] = n->bb[b1 - 1].insn[pb->ninsn - 1].opt[1]; |
} else { |
ii->op[2] = REF (b1 - 1, pb->ninsn - 1); |
ii->opt[2] = OPT_REF; |
} |
/* {z = x || y;} is same as {z = x ? x : y;} */ |
ii->op[3] = ii->op[1]; ii->opt[3] = ii->opt[1]; |
ii->type = IT_COND; |
|
/* Only one should be in loop, so we remove any INLOOP flags from duplicates */ |
n->bb[b1].type &= ~(BB_END | BB_INLOOP); |
n->bb[b1].prev[0] = prevart_b; |
n->bb[b1].prev[1] = b1 - 1; |
n->bb[b1].next[0] = -1; |
n->bb[b1].next[1] = -1; |
|
prevb = b1 - 1; |
prevart_b = b1; |
} |
if (ob->type & BB_END) { |
n->bb[prevart_b].type |= BB_END; |
n->bb[b].type &= ~BB_END; |
} |
n->bb[prevart_b].next[0] = ob->next[0] == b ? ob->next[1] : ob->next[0]; |
|
//print_cuc_bb (n, "preroll1"); |
/* repair BB after loop, to point back to latest artificial BB */ |
b1 = n->bb[prevart_b].next[0]; |
if (b1 >= 0 && b1 != BBID_END) { |
if (n->bb[b1].prev[0] == b) n->bb[b1].prev[0] = prevart_b; |
else if (n->bb[b1].prev[1] == b) n->bb[b1].prev[1] = prevart_b; |
if (n->bb[b].prev[0] == b) n->bb[b].prev[0] = prevb; |
else if (n->bb[b].prev[1] == b) n->bb[b].prev[1] = prevb; |
else assert (0); |
} |
|
/* Relink to itself */ |
/* Set predecessor's successor */ |
if (n->bb[prevb].next[0] == b) n->bb[prevb].next[0] = prevb; |
else if (n->bb[prevb].next[1] == b) n->bb[prevb].next[1] = prevb; |
else assert (0); |
n->bb[prevb].prev[1] = prevb; |
print_cuc_bb (n, "preroll2"); |
|
if (n->bb[b].prev[0] == b) { |
n->bb[b].prev[0] = n->bb[b].prev[1]; |
n->bb[b].prev[1] = -1; |
} else if (n->bb[b].prev[1] == b) { |
n->bb[b].prev[1] = -1; |
} |
|
//print_cuc_bb (n, "preroll2"); |
|
/* Relocate backward references to current instance and forward references |
to previous one */ |
relocate_bb (&n->bb[b], b, b, prevb); |
1589,16 → 1464,16
int *bb_reloc; |
|
if (preroll > 1) { |
t = preroll_loop (f, b, preroll); |
t = roll_loop (f, b, preroll, 1); |
b1 = t->num_bb - 2; |
if (unroll > 1) { |
//print_cuc_bb (t, "preunroll1"); |
n = unroll_loop (t, b1, unroll); |
n = roll_loop (t, b1, unroll, 0); |
free_func (t); |
} else n = t; |
} else { |
b1 = b; |
if (unroll > 1) n = unroll_loop (f, b1, unroll); |
if (unroll > 1) n = roll_loop (f, b1, unroll, 0); |
else return dup_func (f); |
} |
|
/trunk/or1ksim/cuc/verilog.c
212,8 → 212,6
int ci = 0, co = 0; |
int nloads = 0, nstores = 0, ncalls = 0; |
char tmp[256]; |
cuc_bb *end_bb = NULL; |
int end_bb_no = -1; |
sprintf (tmp, "%s.v", filename); |
|
log ("Generating verilog file \"%s\"\n", tmp); |
223,10 → 221,6
exit (1); |
} |
|
for (b = 0; b < f->num_bb; b++) |
if (f->bb[b].type & BB_END) end_bb = &f->bb[end_bb_no = b]; |
assert (end_bb && end_bb->type & BB_END); |
|
/* output header */ |
GEN ("/* %s -- generated by OpenRISC Custom Unit Compiler\n", tmp); |
GEN (" (C) 2002 OpenCores http://www.opencores.org/\n"); |
448,19 → 442,23
ncalls - 1, ncalls); |
|
GEN ("\n/* last dependency */\n"); |
GEN ("wire end_o = bb_stb[%i]", end_bb_no); |
if (end_bb->mdep) { |
GEN (" && "); |
print_deps (fo, f, end_bb_no, end_bb->mdep, 0); |
GEN ("wire end_o = "); |
for (b = 0; b < f->num_bb; b++) { |
for (i = 0; i < 2; i++) if (f->bb[b].next[i] == BBID_END) { |
GEN ("bb_stb[%i]", b); |
if (f->bb[b].mdep) { |
GEN (" && "); |
print_deps (fo, f, b, f->bb[b].mdep, 0); |
} |
/* Is branch to BBID_END conditional? */ |
if (f->bb[b].next[1 - i] >= 0) { |
int bidx = branch_index (&f->bb[b]); |
char t[30]; |
print_op_v (f, t, REF (b, bidx), 1); |
GEN (" && %s%s", i ? "" : "!", t); |
} |
} |
} |
|
/* Is there a loop right at the end? */ |
if (end_bb->next[0] != BBID_END || end_bb->next[1] != BBID_END && end_bb->next[1] >= 0) { |
int bidx = branch_index (end_bb); |
char t[30]; |
print_op_v (f, t, REF (end_bb_no, bidx), 1); |
GEN (" && !%s", t); |
} |
GEN (";\n"); |
GEN ("wire busy_o = |bb_stb;\n"); |
|
706,7 → 704,7
int ncallees[MAX_FUNCS]; |
int nl[MAX_FUNCS], ns[MAX_FUNCS]; |
int maxncallees = 0; |
sprintf (tmp, "%s.v", filename); |
sprintf (tmp, "%s_top.v", filename); |
|
for (i = 0, nrf = 0; i < nfuncs; i++) { |
nl[i] = ns[i] = 0; |
/trunk/or1ksim/cuc/cuc.c
32,7 → 32,7
#include "parse.h" |
|
FILE *flog; |
int cuc_debug = 0; |
int cuc_debug = 9; |
|
/* Last used registers by software convention */ |
/* Note that r11 is caller saved register, and we can destroy it. |
586,7 → 586,6
|
prof_set (1, 0); |
assert (prof_acquire (config.sim.prof_fn) == 0); |
cuc_debug = 0; |
|
if (config.cuc.calling_convention) |
PRINTF ("Assuming OpenRISC standard calling convention.\n"); |
/trunk/or1ksim/toplevel.c
60,7 → 60,7
#include "atahost.h" |
|
/* CVS revision number. */ |
const char rcsrev[] = "$Revision: 1.95 $"; |
const char rcsrev[] = "$Revision: 1.96 $"; |
|
/* History of execution */ |
int histexec[HISTEXEC_LEN]; |
454,6 → 454,7
#ifdef HAVE_LIBREADLINE |
/* Must disable readline in new mode. It isn't compatible |
with non blocking environments */ |
wait_input: |
if(!config.debug.gdb_enabled) |
linestr = readline("(sim) "); |
else |
461,13 → 462,16
#else |
if(!config.debug.gdb_enabled) |
PRINTF ("(sim) "); |
wait_input: |
linestr = fgets(b2, sizeof b2, stdin); |
#endif |
} else |
strcpy(linestr = b2, "run -1 hush"); |
|
if (!linestr) |
break; |
if (!linestr) { |
usleep (1000); |
goto wait_input; |
} |
linestr = stripwhite (linestr); |
|
#ifdef HAVE_LIBREADLINE |