URL
https://opencores.org/ocsvn/or1k/or1k/trunk
Subversion Repositories or1k
Compare Revisions
- This comparison shows the changes necessary to convert path
/
- from Rev 924 to Rev 925
- ↔ Reverse comparison
Rev 924 → Rev 925
/trunk/or1ksim/virtex.tim
0,0 → 1,41
# |
# very draft timing table for FPGA Virtex, sg -5 |
# size is in gates, delay in ns |
# |
# instruction_name size_normal size_immediate delay_normal delay_immediate |
# |
|
add 30. 15. 8. 4. |
sub 30. 15. 8. 4. |
and 5. 1. 1. 0.5 |
or 5. 1. 1. 0.5 |
xor 10. 2. 1. 0.5 |
mul 700. 200. 12. 5. |
srl 100. 1. 24. 12. |
sll 100. 1. 24. 12. |
sra 100. 1. 24. 12. |
|
lb 50. 50. 5. 5. |
lh 50. 50. 5. 5. |
lw 50. 50. 5. 5. |
sb 50. 50. 5. 5. |
sh 50. 50. 5. 5. |
sw 50. 50. 5. 5. |
|
sfeq 20. 10. 5. 2. |
sfne 20. 10. 5. 2. |
sfle 30. 10. 8. 4. |
sflt 30. 10. 8. 4. |
sfgt 30. 10. 8. 4. |
sfge 30. 10. 8. 4. |
sfor 1. 0.5 1. 0.5 |
bf 50. 50. 1. 1. |
|
lrbb 60. 60. 1. 1. |
cmov 15. 15. 5. 2. |
reg 60. 60. 1. 1. |
|
call 100. 100. 3. 3. |
nop 0. 0. 0. 0. |
|
|
/trunk/or1ksim/cuc/cuc.h
73,9 → 73,11
|
#define BB_INLOOP 0x01 /* This block is inside a loop */ |
#define BB_OPTIONAL 0x02 |
#define BB_END 0x04 /* Last block in a function */ |
#define BB_END 0x04 /* Whether this block is last */ |
#define BB_DEAD 0x08 /* This block is unaccessible -> to be removed */ |
|
#define BBID_END MAX_BB /* End pointer */ |
|
/* Various macros to minimize code size */ |
#define REF(bb,i) (((bb) * MAX_INSNS) + (i)) |
#define REF_BB(r) ((r) / MAX_INSNS) |
215,6 → 217,9
/* Prints out instructions */ |
void print_insns (cuc_insn *insn, int size, int verbose); |
|
/* prints out bb string */ |
void print_bb_num (int num); |
|
/* Print out basic blocks */ |
void print_cuc_bb (cuc_func *func, char *s); |
|
/trunk/or1ksim/cuc/bb.c
27,6 → 27,14
#include "insn.h" |
#include "support/profile.h" |
|
/* prints out bb string */ |
void print_bb_num (int num) |
{ |
if (num < 0) printf ("*"); |
else if (num == BBID_END) printf ("END"); |
else printf ("%2x", num); |
} |
|
/* Print out basic blocks */ |
void print_cuc_bb (cuc_func *f, char *s) |
{ |
36,14 → 44,11
if (f->bb[i].insn) printf ("\n---- BB%-2x * %x ---- ", i, f->bb[i].cnt); |
else printf ("BB%-2x: %4x-%-4x", i, f->bb[i].first, f->bb[i].last); |
printf (" type %02x tmp %i ", f->bb[i].type, f->bb[i].tmp); |
if (f->bb[i].next[0] >= 0) printf ("next %2x ", f->bb[i].next[0]); |
else printf ("next * "); |
if (f->bb[i].next[1] >= 0) printf ("%2x ", f->bb[i].next[1]); |
else printf ("* "); |
if (f->bb[i].prev[0] >= 0) printf ("prev %2x ", f->bb[i].prev[0]); |
else printf ("prev * "); |
if (f->bb[i].prev[1] >= 0) printf ("%2x\n", f->bb[i].prev[1]); |
else printf ("*\n"); |
printf ("next "); print_bb_num (f->bb[i].next[0]); |
printf (" "); print_bb_num (f->bb[i].next[1]); |
printf (" prev "); print_bb_num (f->bb[i].prev[0]); |
printf (" "); print_bb_num (f->bb[i].prev[1]); |
printf ("\n"); |
|
if (f->bb[i].insn) print_insns (f->bb[i].insn, f->bb[i].ninsn, 0); |
} |
228,6 → 233,7
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; |
301,6 → 307,12
} |
} |
} |
/* 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; |
} |
if (cuc_debug >= 3) print_cuc_bb (f, "AFTER_PREV"); |
} |
|
435,24 → 447,38
#if 1 |
/* LRBB at start of succ BB is not valid, it should be set when */ |
if (insn[n1].index == II_LRBB) { |
assert (0); /* not tested yet */ |
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; |
if (f->bb[pred].next[0] != succ) { |
unsigned long t; /* negate conditional -- exchange */ |
assert (f->bb[pred].next[1] == succ); |
t = insn[i].op[1]; |
insn[i].op[1] = insn[i].op[2]; |
insn[i].op[2] = t; |
t = insn[i].opt[1]; |
insn[i].opt[1] = insn[i].opt[2]; |
insn[i].opt[2] = t; |
if (type == 1) { |
/* We have two possibilities, how this could have happened: |
1. we just moved second predecessor of succ to pred, |
pred now having two predecessors => everything is ok |
2. we just moved second predecessor of succ to pred, |
now, having just one predecessor => LRBB is not needed anymore */ |
if (f->bb[pred].prev[1] < 0) { /* handle second option */ |
change_insn_type (&insn[n1], II_ADD); |
insn[n1].op[1] = 1; insn[n1].opt[1] = OPT_CONST; |
insn[n1].op[2] = 0; insn[n1].opt[2] = OPT_CONST; |
insn[n1].opt[3] = OPT_NONE; |
} |
} else { |
assert (0); /* not tested yet */ |
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; |
if (f->bb[pred].next[0] != succ) { |
unsigned long t; /* negate conditional -- exchange */ |
assert (f->bb[pred].next[1] == succ); |
t = insn[i].op[1]; |
insn[i].op[1] = insn[i].op[2]; |
insn[i].op[2] = t; |
t = insn[i].opt[1]; |
insn[i].opt[1] = insn[i].opt[2]; |
insn[i].opt[2] = t; |
} |
} |
} |
} |
} |
#endif |
|
496,9 → 522,15
} |
|
if (cuc_debug) cuc_check (f); |
f->bb[pred].type |= f->bb[succ].type; |
if (f->bb[succ].type & BB_END) { |
f->bb[pred].type |= BB_END; |
if (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); |
assert (f->bb[pred].next[0] >= 0 && f->bb[pred].next[0] != BBID_END); |
switch (type) { |
case 0: |
if (f->bb[pred].next[0] == succ) f->bb[pred].next[0] = f->bb[succ].next[0]; |
519,9 → 551,10
f->bb[succ].type = BB_DEAD; |
//printf (" %x %x %x %x %x\n", f->bb[pred].next[0], f->bb[pred].next[1], f->bb[succ].next[0], f->bb[succ].next[1], insn[ninsn - 1].type); |
/* 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 */ |
if (f->bb[pred].next[1] < 0 && insn[ninsn - 1].type & IT_BRANCH) { |
assert (f->bb[pred].next[0] != pred); /* end BB, loop should not be possible */ |
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; |
569,7 → 602,7
for (j = 0; j < f->bb[i].ninsn; j++) |
if (f->bb[i].insn[j].index == II_LRBB) { |
cuc_insn *t; |
cucdebug (4, "-lrbb %i.%i\n", i, j); |
cucdebug (4, "-lrbb %x.%x\n", i, j); |
|
/* Change to add LRBB, 0, 0 */ |
change_insn_type (&f->bb[i].insn[j], II_ADD); |
580,12 → 613,12
f->bb[i].insn[j].opt[3] = OPT_NONE; |
|
/* If the predecessor still has a conditional jump instruction, we must be careful. |
This could only have occured when we found out that next[0] == next[1] and have |
joined them. Now we will link lrbb and correct the situation */ |
If next[0] == next[1] join them. Now we will link lrbb and correct the situation */ |
if (t->type & IT_BRANCH) { /* We must set a reference to branch result */ |
f->bb[i].insn[j].opt[1] = t->opt[1]; |
f->bb[i].insn[j].op[1] = t->op[1]; |
change_insn_type (t, II_NOP); |
/* sometimes branch is not needed anymore */ |
if (f->bb[f->bb[i].prev[0]].next[1] < 0) change_insn_type (t, II_NOP); |
} |
} |
} |
607,10 → 640,28
/* Type 1 joining |
1. link between pred & succ |
2. no other pred's successors |
3. no other succ's predecessors */ |
3. no other succ's predecessors, except if pred has max one */ |
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 */ |
&& f->bb[f->bb[i].prev[0]].next[0] >= 0 && f->bb[f->bb[i].prev[0]].next[1] < 0) { /* one successor */ |
/* one successor and max sum of 3 predecessors */ |
if (f->bb[f->bb[i].prev[0]].next[0] >= 0 && f->bb[f->bb[i].prev[0]].next[1] < 0 |
&& (f->bb[f->bb[i].prev[0]].prev[1] < 0 || f->bb[i].prev[1] < 0)) { |
/* First we will move all predecessors from succ to pred, and then we will do |
real type 1 joining */ |
if (f->bb[i].prev[1] >= 0) { |
/* joining is surely not worth another extra memory access */ |
if (f->bb[f->bb[i].prev[0]].nmemory) continue; |
if (f->bb[f->bb[i].prev[0]].prev[0] >= 0) { |
assert (f->bb[f->bb[i].prev[0]].prev[1] < 0); |
f->bb[f->bb[i].prev[0]].prev[1] = f->bb[i].prev[1]; |
} else f->bb[f->bb[i].prev[0]].prev[0] = f->bb[i].prev[1]; |
if (f->bb[f->bb[i].prev[1]].next[0] == i) |
f->bb[f->bb[i].prev[1]].next[0] = f->bb[i].prev[0]; |
else if (f->bb[f->bb[i].prev[1]].next[1] == i) |
f->bb[f->bb[i].prev[1]].next[1] = f->bb[i].prev[0]; |
else assert (0); |
f->bb[i].prev[1] = -1; |
} |
assert (f->bb[i].prev[0] >= 0 && f->bb[i].prev[1] < 0); /* one predecessor */ |
join_bb (f, f->bb[i].prev[0], i, 1); |
goto remove_lrbb; |
} |
663,18 → 714,23
|
/* repair references */ |
for (i = 0; i < f->num_bb; i++) if (!(f->bb[i].type & BB_DEAD)) { |
printf ("%x %x %x %x %x\n", i, f->bb[i].prev[0], f->bb[i].prev[1], f->bb[i].next[0], f->bb[i].next[1]); |
fflush (stdout); |
if (f->bb[i].prev[0] >= 0) assert ((f->bb[i].prev[0] = reloc[f->bb[i].prev[0]]) >= 0); |
if (f->bb[i].prev[1] >= 0) assert ((f->bb[i].prev[1] = reloc[f->bb[i].prev[1]]) >= 0); |
if (f->bb[i].next[0] >= 0) assert ((f->bb[i].next[0] = reloc[f->bb[i].next[0]]) >= 0); |
if (f->bb[i].next[1] >= 0) assert ((f->bb[i].next[1] = reloc[f->bb[i].next[1]]) >= 0); |
if (f->bb[i].next[0] >= 0 && f->bb[i].next[0] != BBID_END) |
assert ((f->bb[i].next[0] = reloc[f->bb[i].next[0]]) >= 0); |
if (f->bb[i].next[1] >= 0 && f->bb[i].next[1] != BBID_END) |
assert ((f->bb[i].next[1] = reloc[f->bb[i].next[1]]) >= 0); |
if (f->bb[i].prev[0] == f->bb[i].prev[1]) f->bb[i].prev[1] = -1; |
if (f->bb[i].next[0] == f->bb[i].next[1]) f->bb[i].next[1] = -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_BB && (signed)f->bb[i].insn[j].op[k] >= 0) |
assert ((f->bb[i].insn[j].op[k] = reloc[f->bb[i].insn[j].op[k]]) >= 0); |
else if (f->bb[i].insn[j].opt[k] & OPT_REF) { |
if (f->bb[i].insn[j].opt[k] & OPT_BB && (signed)f->bb[i].insn[j].op[k] >= 0) { |
if (f->bb[i].insn[j].op[k] != BBID_END) |
assert ((f->bb[i].insn[j].op[k] = reloc[f->bb[i].insn[j].op[k]]) >= 0); |
} else if (f->bb[i].insn[j].opt[k] & OPT_REF) { |
int t = f->bb[i].insn[j].op[k]; |
assert (reloc[REF_BB(t)] >= 0); |
f->bb[i].insn[j].op[k] = REF (reloc[REF_BB(t)], REF_I (t)); |
704,8 → 760,10
} |
} |
|
if (f->bb[cur].next[0] >= 0) reg_dep_rec (f, f->bb[cur].next[0]); |
if (f->bb[cur].next[1] >= 0) reg_dep_rec (f, f->bb[cur].next[1]); |
if (f->bb[cur].next[0] >= 0 && f->bb[cur].next[0] != BBID_END) |
reg_dep_rec (f, f->bb[cur].next[0]); |
if (f->bb[cur].next[1] >= 0 && f->bb[cur].next[1] != BBID_END) |
reg_dep_rec (f, f->bb[cur].next[1]); |
} |
|
/* Detect register dependencies */ |
911,12 → 969,12
i = f->bb[b1].next[0]; |
f->bb[n + j].prev[0] = j == 1 ? b : b1 - 1; |
f->bb[n + j].prev[1] = -1; |
if (i >= 0) { |
if (i >= 0 && i != BBID_END) { |
if (f->bb[i].prev[0] == b) f->bb[i].prev[0] = b1; |
if (f->bb[i].prev[1] == b) f->bb[i].prev[1] = b1; |
} |
i = f->bb[b1].next[1]; |
if (i >= 0) { |
if (i >= 0 && i != BBID_END) { |
if (f->bb[i].prev[0] == b) f->bb[i].prev[0] = b1; |
if (f->bb[i].prev[1] == b) f->bb[i].prev[1] = b1; |
} |
1153,7 → 1211,7
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] = ob->next[0] == b ? ob->next[1] : ob->next[0]; |
n->bb[b1].next[0] = -1; |
n->bb[b1].next[1] = -1; |
|
prevb = b1 - 1; |
1164,10 → 1222,11
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, "unroll1"); |
/* repair BB after loop, to point back to latest artificial BB */ |
b1 = n->bb[prevart_b].next[0]; |
if (b1 >= 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; |
else assert (0); |
1295,7 → 1354,7
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] = ob->next[0] == b ? ob->next[1] : ob->next[0]; |
n->bb[b1].next[0] = -1; |
n->bb[b1].next[1] = -1; |
|
prevb = b1 - 1; |
1305,11 → 1364,12
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) { |
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; |
else assert (0); |
/trunk/or1ksim/cuc/insn.c
100,7 → 100,7
case OPT_JUMP: printf ("J%x ", insn[i].op[j]); break; |
case OPT_REGISTER: printf ("r%i, ", insn[i].op[j]); break; |
case OPT_REF: printf ("[%x.%x], ", REF_BB(insn[i].op[j]), REF_I(insn[i].op[j])); break; |
case OPT_BB: printf ("BB%x, ", insn[i].op[j]); break; |
case OPT_BB: printf ("BB "); print_bb_num (insn[i].op[j]); printf (", "); break; |
case OPT_LRBB: printf ("LRBB, "); break; |
default: |
fprintf (stderr, "Invalid operand type %s(%x.%x) = %x\n", |
/trunk/or1ksim/cuc/verilog.c
155,7 → 155,7
} |
} else if (ii->index == II_LRBB) { |
GEN (" if (rst) t%x_%x <= #Tp 1'b0;\n", b, i); |
assert (f->bb[b].prev[0] >= 0); |
assert (f->bb[b].prev[0] >= 0 && f->bb[b].prev[0] != BBID_END); |
GEN (" else if (bb_start[%i]) t%x_%x <= #Tp bb_stb[%i];\n", b, b, i, f->bb[b].prev[0]); |
} else if (ii->index == II_REG) { |
GEN (" if (rst) t%x_%x <= #Tp 32'h0;\n", b, i); |
458,8 → 458,8
print_deps (fo, f, end_bb_no, end_bb->mdep, 0); |
} |
|
/* Is there a loop right at end? */ |
if (end_bb->next[0] >= 0) { |
/* 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); |
473,17 → 473,18
GEN ("wire [%2i:0] bb_start = {\n", f->num_bb - 1); |
for (b = f->num_bb - 1; b >= 0; b--) { |
GEN (" /* bb_start[%2i] */ ", b); |
if (f->bb[b].prev[0] < 0) GEN ("start_i"); |
else { |
cuc_bb *prev = &f->bb[f->bb[b].prev[0]]; |
for (i = 0; i < 2; i++) if (f->bb[b].prev[i] >= 0) { |
cuc_bb *prev = &f->bb[f->bb[b].prev[i]]; |
int t; |
if (i) GEN ("\n || "); |
if (prev->mdep) { |
print_deps (fo, f, f->bb[b].prev[0], prev->mdep, 0); |
print_deps (fo, f, f->bb[b].prev[i], prev->mdep, 0); |
GEN (" && "); |
} |
GEN ("bb_stb[%i]", f->bb[b].prev[0]); |
if (prev->next[0] >= 0 && prev->next[1] >= 0) { |
int bi = REF (f->bb[b].prev[0], branch_index (&f->bb[f->bb[b].prev[0]])); |
GEN ("bb_stb[%i]", f->bb[b].prev[i]); |
if (prev->next[0] >= 0 && prev->next[0] != BBID_END |
&& prev->next[1] >= 0 && prev->next[1] != BBID_END) { |
int bi = REF (f->bb[b].prev[i], branch_index (&f->bb[f->bb[b].prev[i]])); |
int ci; |
assert (bi >= 0); |
ci = f->INSN(bi).op[1]; |
497,23 → 498,8
GEN ("%s%i", t ? "" : "!", ci); |
} |
} |
if (f->bb[b].prev[1] >= 0) { |
prev = &f->bb[f->bb[b].prev[1]]; |
GEN ("\n || "); |
if (prev->mdep) { |
print_deps (fo, f, f->bb[b].prev[1], prev->mdep, 0); |
GEN (" && "); |
} |
GEN ("bb_stb[%i]", f->bb[b].prev[1]); |
if (prev->next[0] >= 0 && prev->next[1] >= 0) { |
int bidx = branch_index (&f->bb[f->bb[b].prev[1]]); |
assert (bidx >= 0); |
GEN (" && "); |
t = prev->next[0] == b; |
GEN ("%st%x_%x", t ? "" : "!", f->bb[b].prev[1], bidx); |
} |
} |
} |
} else break; |
if (!i) GEN ("start_i"); |
if (b == 0) GEN ("};\n"); |
else GEN (",\n"); |
} |