URL
https://opencores.org/ocsvn/or1k_old/or1k_old/trunk
Subversion Repositories or1k_old
Compare Revisions
- This comparison shows the changes necessary to convert path
/
- from Rev 901 to Rev 902
- ↔ Reverse comparison
Rev 901 → Rev 902
/trunk/or1ksim/cuc/bb.c
375,7 → 375,7
|| !(f->bb[pred].insn[f->bb[pred].ninsn - 1].type & IT_BRANCH)) type = 1; |
if (type == 0 && f->bb[succ].prev[0] == f->bb[succ].next[0]) add_cond = 1; |
|
ninsn = f->bb[pred].ninsn + f->bb[succ].ninsn + (type == 0 || type == 2 ? 1 : 0) |
ninsn = f->bb[pred].ninsn + f->bb[succ].ninsn + (type == 0 ? 1 : type == 1 ? 0 : 2) |
+ (add_cond ? MAX_REGS : 0); |
|
insn = (cuc_insn *) malloc (ninsn * sizeof (cuc_insn)); |
386,14 → 386,37
cond_op = insn[add - 1].op[1]; |
cond_opt = insn[add - 1].opt[1]; |
change_insn_type (&insn[add - 1], II_NOP); |
/* and when type == 2, we must add sfor instruction, to quit when either is true */ |
if (type == 2) { |
/* TODO */ |
assert (0); |
} |
} |
/* Copy second block */ |
for (i = 0; i < f->bb[succ].ninsn; i++) insn[i + f->bb[pred].ninsn] = 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); |
} |
|
/* LRBB at start of succ BB is not valid, it should be set when */ |
if (insn[add].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)) { |
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; |
} |
} |
} |
|
for (i = 0; i < ninsn; i++) reloc[i] = -1; |
|
/trunk/or1ksim/cuc/insn.c
252,6 → 252,103
return 0; |
} |
|
/* First primary input */ |
static unsigned long tmp_op, tmp_opt; |
|
/* Recursive function that searches for primary inputs; |
returns 0 if cmov can be replaced by add */ |
static int cmov_needed (cuc_func *f, int ref) |
{ |
cuc_insn *ii = &f->INSN(ref); |
int j; |
|
//printf (" %x", ref); |
/* mark visited, if already marked, we have a loop, ignore */ |
if (ii->tmp) return 0; |
ii->tmp = 1; |
|
/* handle normal movs separately */ |
if ((ii->index == II_ADD || !(ii->type & IT_VOLATILE)) |
&& ii->opt[2] == OPT_CONST && ii->op[2] == 0) { |
if (ii->opt[1] == OPT_REF) { |
if (cmov_needed (f, ii->op[1])) { |
ii->tmp = 0; |
return 1; |
} |
} else { |
if (tmp_opt == OPT_NONE) { |
tmp_op = ii->op[1]; |
tmp_opt = ii->opt[1]; |
} else if (tmp_opt != ii->opt[1] || tmp_op != ii->op[1]) { |
ii->tmp = 0; |
return 1; |
} |
} |
ii->tmp = 0; |
return 0; |
} |
|
/* Is this instruction CMOV? no => add to primary inputs */ |
if (ii->index != II_CMOV || ii->type & IT_VOLATILE) |
if (tmp_opt == OPT_NONE) { |
tmp_op = ref; |
tmp_opt = OPT_REF; |
ii->tmp = 0; |
return 0; |
} else if (tmp_opt != OPT_REF || tmp_op != ref) { |
ii->tmp = 0; |
return 1; |
} |
|
for (j = 1; j < 3; j++) { |
//printf ("(%x:%i)", ref, j); |
if (ii->opt[j] == OPT_REF) { |
if (cmov_needed (f, ii->op[j])) { |
ii->tmp = 0; |
return 1; |
} |
} else { |
if (tmp_opt == OPT_NONE) { |
tmp_op = ii->op[j]; |
tmp_opt = ii->opt[j]; |
} else if (tmp_opt != ii->opt[j] || tmp_op != ii->op[j]) { |
ii->tmp = 0; |
return 1; |
} |
} |
} |
|
ii->tmp = 0; |
return 0; |
} |
|
/* Search and optimize complex cmov assignments */ |
void optimize_cmovs (cuc_func *f) |
{ |
int b, i, j; |
|
/* Mark all instructions unvisited */ |
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 (b = 0; b < f->num_bb; b++) if (!(f->bb[b].type & BB_DEAD)) { |
for (i = 0; i < f->bb[b].ninsn; i++) { |
cuc_insn *ii = &f->bb[b].insn[i]; |
if (ii->index == II_CMOV && !(ii->type & IT_VOLATILE)) { |
tmp_opt = OPT_NONE; |
printf ("\n"); |
if (!cmov_needed (f, REF(b, i))) { |
assert (tmp_opt != OPT_NONE); |
change_insn_type (ii, II_ADD); |
ii->op[1] = tmp_op; ii->opt[1] = tmp_opt; |
ii->op[2] = 0; ii->opt[2] = OPT_CONST; |
ii->opt[3] = OPT_NONE; |
} |
} |
} |
} |
} |
|
/* Optimizes dataflow tree */ |
void optimize_tree (cuc_func *f) |
{ |
480,6 → 577,7
f->lur[i] = -1; |
f->used_regs[i] = 0; |
} |
if (cuc_debug > 5) print_cuc_bb (f, "SET_IO"); |
for (b = 0; b < f->num_bb; b++) { |
for (i = 0; i < f->bb[b].ninsn; i++) |
for (j = 0; j < MAX_OPERANDS; j++) |
/trunk/or1ksim/cuc/verilog.c
161,8 → 161,8
int end_bb_no = -1; |
sprintf (tmp, "%s.v", filename); |
|
log ("Generating verilog file \"%s\"\n", filename); |
printf ("Generating verilog file \"%s\"\n", filename); |
log ("Generating verilog file \"%s\"\n", tmp); |
printf ("Generating verilog file \"%s\"\n", tmp); |
if ((fo = fopen (tmp, "wt+")) == NULL) { |
fprintf (stderr, "Cannot open '%s'\n", tmp); |
exit (1); |
173,7 → 173,11
assert (end_bb && end_bb->type & BB_END); |
|
/* output header */ |
fprintf (fo, "/* %s -- generated by OpenRISC Custom Unit Compiler (c) OpenCores */\n", tmp); |
fprintf (fo, "/* %s -- generated by OpenRISC Custom Unit Compiler\n", tmp); |
fprintf (fo, " (C) 2002 OpenCores.\n"); |
fprintf (fo, " function \"%s\"\n", filename); |
fprintf (fo, " at %08x - %08x\n", f->start_addr, f->end_addr); |
fprintf (fo, " num BBs %i */\n\n", f->num_bb); |
fprintf (fo, "module %s (clk, rst,\n", filename); |
fprintf (fo, " lwb_adr_o, lwb_dat_i, lwb_cycstb_o,\n"); |
fprintf (fo, " lwb_sel_o, lwb_linbrst_o, lwb_ack_i,\n"); |
418,7 → 422,8
fprintf (fo, "reg [%2i:0] bb_start_r;\n\n", f->num_bb - 1); |
fprintf (fo, "always @(posedge rst or posedge clk)\n"); |
fprintf (fo, "begin\n"); |
fprintf (fo, " if (rst || end_o) bb_start_r <= #1 %i'b0;\n", f->num_bb); |
fprintf (fo, " if (rst) bb_start_r <= #1 %i'b0;\n", f->num_bb); |
fprintf (fo, " else if (end_o) bb_start_r <= #1 %i'b0;\n", f->num_bb); |
fprintf (fo, " else bb_start_r <= #1 bb_start;\n"); |
fprintf (fo, "end\n"); |
|
477,7 → 482,7
fprintf (fo, ") begin\n"); |
while (dep) { |
assert (f->INSN(dep->ref).type & IT_MEMORY); |
fprintf (fo, " %c_end[%i] <= #1 1'b0;\n", |
fprintf (fo, " %c_stb[%i] <= #1 1'b0;\n", |
II_IS_LOAD (f->INSN(dep->ref).index) ? 'l' : 's', find_ls_index (f, dep->ref)); |
dep = dep->next; |
} |
485,9 → 490,9
fprintf (fo, " lwb_cycstb_o <= #1 1'b1;\n"); |
fprintf (fo, " lwb_sel_o[3:0] <= #1 4'b"); |
switch (f->mtype[i] & MT_WIDTH) { |
case 1: fprintf (fo, "0001 << (%s & 32h'3);\n", |
case 1: fprintf (fo, "0001 << (%s & 32'h3);\n", |
print_op_v (f, t, f->msched[i], 1)); break; |
case 2: fprintf (fo, "0011 << ((%s & 32h'1) << 1);\n", |
case 2: fprintf (fo, "0011 << ((%s & 32'h1) << 1);\n", |
print_op_v (f, t, f->msched[i], 1)); break; |
case 4: fprintf (fo, "1111;\n"); break; |
default: assert (0); |
532,7 → 537,7
fprintf (fo, ") begin\n"); |
while (dep) { |
assert (f->INSN(dep->ref).type & IT_MEMORY); |
fprintf (fo, " %c_end[%i] <= #1 1'b0;\n", |
fprintf (fo, " %c_stb[%i] <= #1 1'b0;\n", |
II_IS_LOAD (f->INSN(dep->ref).index) ? 'l' : 's', find_ls_index (f, dep->ref)); |
dep = dep->next; |
} |
540,9 → 545,9
fprintf (fo, " swb_cycstb_o <= #1 1'b1;\n"); |
fprintf (fo, " swb_sel_o[3:0] <= #1 4'b"); |
switch (f->mtype[i] & MT_WIDTH) { |
case 1: fprintf (fo, "0001 << (%s & 32h'3);\n", |
case 1: fprintf (fo, "0001 << (%s & 32'h3);\n", |
print_op_v (f, t, f->msched[i], 1)); break; |
case 2: fprintf (fo, "0011 << ((%s & 32h'1) << 1);\n", |
case 2: fprintf (fo, "0011 << ((%s & 32'h1) << 1);\n", |
print_op_v (f, t, f->msched[i], 1)); break; |
case 4: fprintf (fo, "1111;\n"); break; |
default: assert (0); |
567,10 → 572,10
fprintf (fo, "\n/* Basic blocks state machine */\n"); |
fprintf (fo, "always @(posedge clk or posedge rst)\n"); |
fprintf (fo, "begin\n"); |
fprintf (fo, " if (rst || end_o) begin\n"); |
fprintf (fo, " bb_stb <= #1 %i'h%x;\n", f->num_bb, 0); |
fprintf (fo, " if (rst) bb_stb <= #1 %i'h%x;\n", f->num_bb, 0); |
fprintf (fo, " else if (end_o) bb_stb <= #1 %i'h%x;\n", f->num_bb, 0); |
for (i = 0; i < f->num_bb; i++) { |
fprintf (fo, " end else if (bb_start[%i]) begin\n", i); |
fprintf (fo, " else if (bb_start[%i]) begin\n", i); |
fprintf (fo, " bb_stb <= #1 %i'h%x;\n", f->num_bb, 1 << i); |
} |
fprintf (fo, " end else if (end_o) begin\n"); |
/trunk/or1ksim/cuc/cuc.c
49,10 → 49,12
if (cuc_debug >= 2) print_cuc_bb (func, "AFTER_PREUNROLL"); |
|
log ("Optimizing.\n"); |
optimize_cmovs (func); |
if (cuc_debug >= 6) print_cuc_bb (func, "AFTER_OPT_CMOVS"); |
optimize_tree (func); |
if (cuc_debug >= 6) //print_cuc_bb (func, "AFTER_OPT_TREE1"); |
if (cuc_debug >= 6) print_cuc_bb (func, "AFTER_OPT_TREE1"); |
remove_nops (func); |
if (cuc_debug >= 6) //print_cuc_bb (func, "NO_NOPS"); |
if (cuc_debug >= 6) print_cuc_bb (func, "NO_NOPS"); |
remove_dead (func); |
if (cuc_debug >= 5) print_cuc_bb (func, "AFTER_DEAD1"); |
optimize_bb (func); |
138,6 → 140,8
|
log ("Detecting dependencies\n"); |
if (cuc_debug >= 2) print_cuc_bb (func, "AFTER_REG_DEP"); |
optimize_cmovs (func); |
if (cuc_debug >= 6) print_cuc_bb (func, "AFTER_OPT_CMOVS"); |
optimize_tree (func); |
log ("Optimizing.\n"); |
if (cuc_debug >= 2) print_cuc_bb (func, "AFTER_OPT_TREE1"); |
358,7 → 362,7
log ("Generating function %s.\n", name); |
printf ("Generating function %s.\n", name); |
|
print_cuc_bb (f, "BEFORE_GENERATE"); |
if (cuc_debug >= 2) print_cuc_bb (f, "BEFORE_GENERATE"); |
add_latches (f); |
set_io (f); |
if (cuc_debug >= 1) print_cuc_bb (f, "AFTER_LATCHES"); |
365,7 → 369,7
|
format_func_options (tmp, rf); |
if (strlen (tmp)) printf ("Applying options: %s\n", tmp); |
else printf ("Basic options.\n"); |
else printf ("Using basic options.\n"); |
|
/* Generate function as specified by options */ |
for (b = 0; b < f->num_bb; b++) { |
626,6 → 630,8
} |
if (any) printf ("--------------------------------------------------------\n"); |
else printf ("Sorry. No available options.\n"); |
} else if (strcmp (tmp1, "") == 0) { |
/* Ignore empty string */ |
} else { |
/* help command */ |
if (strcmp (tmp1, "h") != 0 && strcmp (tmp1, "help") != 0) |
/trunk/or1ksim/cuc/insn.h
97,6 → 97,9
/* Find known instruction and attach them to insn */ |
void change_insn_type (cuc_insn *i, int index); |
|
/* Search and otimize complex cmov assignments */ |
void optimize_cmovs (cuc_func *f); |
|
/* Returns instruction name */ |
const char *cuc_insn_name (cuc_insn *ii); |
|