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

Subversion Repositories or1k

[/] [or1k/] [tags/] [stable_0_2_0_rc2/] [or1ksim/] [cuc/] [cuc.c] - Blame information for rev 1003

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 879 markom
/* cuc.c -- OpenRISC Custom Unit Compiler
2
 *    Copyright (C) 2002 Marko Mlinar, markom@opencores.org
3
 *
4
 *    This file is part of OpenRISC 1000 Architectural Simulator.
5
 *
6
 *    This program is free software; you can redistribute it and/or modify
7
 *    it under the terms of the GNU General Public License as published by
8
 *    the Free Software Foundation; either version 2 of the License, or
9
 *    (at your option) any later version.
10
 *
11
 *    This program is distributed in the hope that it will be useful,
12
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
13
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
 *    GNU General Public License for more details.
15
 *
16
 *    You should have received a copy of the GNU General Public License
17
 *    along with this program; if not, write to the Free Software
18
 *    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
19
 
20
/* Main file, including code optimization and command prompt */
21
 
22
#include <stdio.h>
23
#include <stdlib.h>
24
#include <stdarg.h>
25
#include <assert.h>
26 915 markom
#include <ctype.h>
27 879 markom
#include "sim-config.h"
28
#include "cuc.h"
29
#include "insn.h"
30
#include "profiler.h"
31 883 markom
#include "opcode/or32.h"
32 897 markom
#include "parse.h"
33 879 markom
 
34
FILE *flog;
35 883 markom
int cuc_debug = 0;
36 879 markom
 
37
/* Last used registers by software convention */
38 939 markom
/* Note that r11 is caller saved register, and we can destroy it.
39
   Due to CUC architecture we must always return something, even garbage (so that
40
   caller knows, we are finished, when we send acknowledge).
41
   In case r11 was not used (trivial register assignment) we will remove it later,
42
   but if we assigned a value to it, it must not be removed, so caller_saved[11] = 0 */
43
const int caller_saved[MAX_REGS] = {
44 879 markom
  0, 0, 0, 1, 1, 1, 1, 1,
45 939 markom
  1, 1, 0, 0, 0, 1, 0, 1,
46 879 markom
  0, 1, 0, 1, 0, 1, 0, 1,
47
  0, 1, 0, 1, 0, 1, 0, 1,
48
  1, 1};
49
 
50 933 markom
/* returns log2(x) */
51
int log2 (unsigned long x)
52
{
53
  int c = 0;
54
  assert (x >= 0);
55
  if (!x) return 0; /* not by the book, but practical */
56
  while (x != 1) x >>= 1, c++;
57
  return c;
58
}
59
 
60 931 markom
/* Does all known instruction optimizations */
61
void cuc_optimize (cuc_func *func)
62
{
63
  int modified = 0;
64 936 markom
  int first = 1;
65 931 markom
  log ("Optimizing.\n");
66
  do {
67
    modified = 0;
68 941 markom
    clean_deps (func);
69
    if (cuc_debug >= 6) print_cuc_bb (func, "AFTER_CLEAN_DEPS");
70 931 markom
    if (optimize_cmovs (func)) {
71
      if (cuc_debug >= 6) print_cuc_bb (func, "AFTER_OPT_CMOVS");
72
      modified = 1;
73
    }
74 934 markom
    if (cuc_debug) cuc_check (func);
75 931 markom
    if (optimize_tree (func)) {
76
      if (cuc_debug >= 6) print_cuc_bb (func, "AFTER_OPT_TREE1");
77
      modified = 1;
78
    }
79
    if (remove_nops (func)) {
80
      if (cuc_debug >= 6) print_cuc_bb (func, "NO_NOPS");
81
      modified = 1;
82
    }
83 934 markom
    if (cuc_debug) cuc_check (func);
84 931 markom
    if (remove_dead (func)) {
85
      if (cuc_debug >= 5) print_cuc_bb (func, "AFTER_DEAD");
86
      modified = 1;
87
    }
88 934 markom
    if (cuc_debug) cuc_check (func);
89 931 markom
    if (cse (func)) {
90
      log ("Common subexpression elimination.\n");
91
      if (cuc_debug >= 3) print_cuc_bb (func, "AFTER_CSE");
92
      modified = 1;
93
    }
94 936 markom
    if (first) {
95
      insert_conditional_facts (func);
96
      if (cuc_debug >= 3) print_cuc_bb (func, "AFTER_COND_FACT");
97
      if (cuc_debug) cuc_check (func);
98
      first = 0;
99
    }
100 931 markom
    if (optimize_bb (func)) {
101
      if (cuc_debug >= 5) print_cuc_bb (func, "AFTER_OPT_BB");
102
      modified = 1;
103
    }
104 934 markom
    if (cuc_debug) cuc_check (func);
105 931 markom
    if (remove_nops (func)) {
106
      if (cuc_debug >= 6) print_cuc_bb (func, "NO_NOPS");
107
      modified = 1;
108
    }
109
    if (remove_dead_bb (func)) {
110
      if (cuc_debug >= 5) print_cuc_bb (func, "AFTER_DEAD_BB");
111
      modified = 1;
112
    }
113
    if (remove_trivial_regs (func)) {
114
      if (cuc_debug >= 2) print_cuc_bb (func, "AFTER_TRIVIAL");
115
      modified = 1;
116
    }
117
    if (remove_nops (func)) {
118
      if (cuc_debug >= 6) print_cuc_bb (func, "NO_NOPS");
119
      modified = 1;
120
    }
121 941 markom
    add_memory_dep (func, func->memory_order);
122
    if (cuc_debug >= 7) print_cuc_bb (func, "AFTER_MEMORY_DEP");
123
    add_data_dep (func);
124
    if (cuc_debug >= 8) print_cuc_bb (func, "AFTER_DATA_DEP");
125 953 markom
    if (schedule_memory (func, func->memory_order)) {
126
      if (cuc_debug >= 7) print_cuc_bb (func, "AFTER_SCHEDULE_MEM");
127
      modified = 1;
128
    }
129 931 markom
  } while (modified);
130 953 markom
  set_io (func);
131 937 markom
#if 0
132 936 markom
  detect_max_values (func);
133
  if (cuc_debug >= 5) print_cuc_bb (func, "AFTER_MAX_VALUES");
134 937 markom
#endif
135 931 markom
}
136
 
137
/* Pre/unrolls basic block and optimizes it */
138 879 markom
cuc_timings *preunroll_bb (char *bb_filename, cuc_func *f, cuc_timings *timings, int b, int i, int j)
139
{
140
  cuc_func *func;
141 883 markom
  cucdebug (2, "BB%i unroll %i times preroll %i times\n", b, j, i);
142 879 markom
  func = preunroll_loop (f, b, i, j, bb_filename);
143 883 markom
  if (cuc_debug >= 2) print_cuc_bb (func, "AFTER_PREUNROLL");
144 931 markom
  cuc_optimize (func);
145 879 markom
 
146 883 markom
  cucdebug (2, "new_time = %i, old_time = %i, size = %f\n",
147 879 markom
           timings->new_time, func->orig_time, timings->size);
148
  log ("new time = %icyc, old_time = %icyc, size = %.0f gates\n",
149
         timings->new_time, func->orig_time, timings->size);
150
  //output_verilog (func, argv[1]);
151
  free_func (func);
152
  timings->b = b;
153
  timings->unroll = j;
154
  timings->preroll = i;
155 883 markom
  timings->nshared = 0;
156 879 markom
  return timings;
157
}
158
 
159 931 markom
/* Simple comparison function */
160 879 markom
int tim_comp (cuc_timings *a, cuc_timings *b)
161
{
162
  if (a->new_time < b->new_time) return -1;
163
  else if (a->new_time > b->new_time) return 1;
164
  else return 0;
165
}
166
 
167 931 markom
/* Analyses function; done when cuc command is entered in (sim) prompt */
168 879 markom
cuc_func *analyse_function (char *module_name, long orig_time,
169 897 markom
                unsigned long start_addr, unsigned long end_addr,
170
                int memory_order)
171 879 markom
{
172
  cuc_timings timings;
173
  cuc_func *func = (cuc_func *) malloc (sizeof (cuc_func));
174
  cuc_func *saved;
175
  int b, i, j;
176
  char tmp1[256];
177
  char tmp2[256];
178
 
179
  func->orig_time = orig_time;
180
  func->start_addr = start_addr;
181
  func->end_addr = end_addr;
182 897 markom
  func->memory_order = memory_order;
183 906 markom
  func->nfdeps = 0;
184
  func->fdeps = NULL;
185 879 markom
 
186
  sprintf (tmp1, "%s.bin", module_name);
187 883 markom
  cucdebug (2, "Loading %s.bin\n", module_name);
188 897 markom
  if (cuc_load (tmp1)) {
189
    free (func);
190
    return NULL;
191
  }
192 879 markom
 
193
  log ("Detecting basic blocks\n");
194
  detect_bb (func);
195 883 markom
  if (cuc_debug >= 2) print_cuc_insns ("WITH_BB_LIMITS", 0);
196 879 markom
 
197
  //sprintf (tmp1, "%s.bin.mp", module_name);
198
  sprintf (tmp2, "%s.bin.bb", module_name);
199
  generate_bb_seq (func, config.sim.mprof_fn, tmp2);
200 897 markom
  log ("Assuming %i clk cycle load (%i cyc burst)\n", runtime.cuc.mdelay[0], runtime.cuc.mdelay[2]);
201
  log ("Assuming %i clk cycle store (%i cyc burst)\n", runtime.cuc.mdelay[1], runtime.cuc.mdelay[3]);
202 879 markom
 
203
  build_bb (func);
204 883 markom
  if (cuc_debug >= 5) print_cuc_bb (func, "AFTER_BUILD_BB");
205 879 markom
  reg_dep (func);
206
 
207
  log ("Detecting dependencies\n");
208 883 markom
  if (cuc_debug >= 2) print_cuc_bb (func, "AFTER_REG_DEP");
209 931 markom
  cuc_optimize (func);
210 879 markom
 
211 897 markom
#if 0
212 883 markom
  csm (func);
213 897 markom
#endif
214 879 markom
  assert (saved = dup_func (func));
215 883 markom
 
216
  timings.preroll = timings.unroll = 1;
217
  timings.nshared = 0;
218 931 markom
 
219 883 markom
  add_latches (func);
220
  if (cuc_debug >= 1) print_cuc_bb (func, "AFTER_LATCHES");
221
  analyse_timings (func, &timings);
222 879 markom
 
223
  free_func (func);
224 883 markom
  log ("Base option: pre%i,un%i,sha%i: %icyc %.1f\n",
225
        timings.preroll, timings.unroll, timings.nshared, timings.new_time, timings.size);
226
  saved->timings = timings;
227 879 markom
 
228
#if 1
229
  /* detect and unroll simple loops */
230
  for (b = 0; b < saved->num_bb; b++) {
231
    cuc_timings t[MAX_UNROLL * MAX_PREROLL];
232
    cuc_timings *ut;
233
    cuc_timings *cut = &t[0];
234
    int nt = 1;
235
    double csize;
236 897 markom
    saved->bb[b].selected_tim = -1;
237 879 markom
 
238
    /* Is it a loop? */
239
    if (saved->bb[b].next[0] != b && saved->bb[b].next[1] != b) continue;
240
    t[0] = timings;
241
    t[0].b = b;
242
    t[0].preroll = 1;
243
    t[0].unroll = 1;
244 883 markom
    t[0].nshared = 0;
245 879 markom
 
246
    sprintf (tmp1, "%s.bin.bb", module_name);
247
    i = 1;
248
    do {
249
      cuc_timings *pt;
250
      cuc_timings *cpt = cut;
251
      j = 1;
252
 
253
      do {
254
        pt = cpt;
255
        cpt = preunroll_bb (tmp1, saved, &t[nt++], b, ++j, i);
256 915 markom
      } while (j <= MAX_PREROLL && pt->new_time > cpt->new_time);
257 879 markom
      i++;
258
      ut = cut;
259
      cut = preunroll_bb (tmp1, saved, &t[nt++], b, 1, i);
260 915 markom
    } while (i <= MAX_UNROLL && ut->new_time > cut->new_time);
261 879 markom
 
262
    /* Sort the timings */
263 883 markom
#if 0
264
    if (cuc_debug >= 3)
265 997 markom
    for (i = 0; i < nt; i++) PRINTF ("%i:%i,%i: %icyc\n",
266 879 markom
                    t[i].b, t[i].preroll, t[i].unroll, t[i].new_time);
267 883 markom
#endif
268 879 markom
 
269
    qsort (t, nt, sizeof (cuc_timings), (int (*)(const void *, const void *))tim_comp);
270
 
271
    /* Delete timings, that have worst time and bigger size than other */
272
    j = 1;
273
    csize = t[0].size;
274
    for (i = 1; i < nt; i++)
275
      if (t[i].size < csize) t[j++] = t[i];
276
    nt = j;
277 883 markom
 
278
    cucdebug (1, "Available options\n");
279
    for (i = 0; i < nt; i++) cucdebug (1, "%i:%i,%i: %icyc %.1f\n",
280
        t[i].b, t[i].preroll, t[i].unroll, t[i].new_time, t[i].size);
281
    /* Add results from CSM */
282
    j = nt;
283
    for (i = 0; i < saved->bb[b].ntim; i++) {
284
      int i1;
285
      for (i1 = 0; i1 < nt; i1++) {
286
        t[j] = t[i1];
287
        t[j].size += saved->bb[b].tim[i].size - timings.size;
288
        t[j].new_time += saved->bb[b].tim[i].new_time - timings.new_time;
289
        t[j].nshared = saved->bb[b].tim[i].nshared;
290
        t[j].shared = saved->bb[b].tim[i].shared;
291
        if (++j >= MAX_UNROLL * MAX_PREROLL) goto full;
292
      }
293
    }
294
 
295
full:
296
    nt = j;
297 879 markom
 
298 883 markom
    cucdebug (1, "Available options:\n");
299
    for (i = 0; i < nt; i++) cucdebug (1, "%i:%i,%i: %icyc %.1f\n",
300
        t[i].b, t[i].preroll, t[i].unroll, t[i].new_time, t[i].size);
301 879 markom
 
302 883 markom
    /* Sort again with new timings added */
303
    qsort (t, nt, sizeof (cuc_timings), (int (*)(const void *, const void *))tim_comp);
304
 
305
    /* Delete timings, that have worst time and bigger size than other */
306
    j = 1;
307
    csize = t[0].size;
308
    for (i = 1; i < nt; i++)
309
      if (t[i].size < csize) t[j++] = t[i];
310
    nt = j;
311
 
312
    cucdebug (1, "Available options:\n");
313
    for (i = 0; i < nt; i++) cucdebug (1, "%i:%i,%i: %icyc %.1f\n",
314
                               t[i].b, t[i].preroll, t[i].unroll, t[i].new_time, t[i].size);
315
 
316
    if (saved->bb[b].ntim) free (saved->bb[b].tim);
317 879 markom
    saved->bb[b].ntim = nt;
318
    assert (saved->bb[b].tim = (cuc_timings *) malloc (sizeof (cuc_timings) * nt));
319
 
320
    /* Copy options in reverse order -- smallest first */
321
    for (i = 0; i < nt; i++) saved->bb[b].tim[i] = t[nt - 1 - i];
322 883 markom
 
323
    log ("Available options:\n");
324
    for (i = 0; i < saved->bb[b].ntim; i++) {
325
      log ("%i:pre%i,un%i,sha%i: %icyc %.1f\n",
326
        saved->bb[b].tim[i].b, saved->bb[b].tim[i].preroll, saved->bb[b].tim[i].unroll,
327
        saved->bb[b].tim[i].nshared, saved->bb[b].tim[i].new_time, saved->bb[b].tim[i].size);
328
    }
329 879 markom
  }
330
#endif
331
  return saved;
332
}
333
 
334 897 markom
/* Utility option formatting functions */
335
static const char *option_char = "?abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
336
 
337
/*static */char *gen_option (char *s, int bb_no, int f_opt)
338 883 markom
{
339 897 markom
  if (bb_no >= 0) sprintf (s, "%i", bb_no);
340
  assert (f_opt <= strlen (option_char));
341
  sprintf (s, "%s%c", s, option_char[f_opt]);
342
  return s;
343
}
344
 
345
/*static */void print_option (int bb_no, int f_opt)
346
{
347
  char tmp1[10];
348
  char tmp2[10];
349
  sprintf (tmp2, "%s", gen_option (tmp1, bb_no, f_opt));
350 997 markom
  PRINTF ("%3s", tmp2);
351 897 markom
}
352
 
353
static char *format_func_options (char *s, cuc_func *f)
354
{
355
  int b, first = 1;
356
  *s = '\0';
357
  for (b = 0; b < f->num_bb; b++)
358
    if (f->bb[b].selected_tim >= 0) {
359
      char tmp[10];
360
      sprintf (s, "%s%s%s", s, first ? "" : ",", gen_option (tmp, b, f->bb[b].selected_tim));
361
      first = 0;
362
    }
363
  return s;
364
}
365
 
366
static void options_cmd (int func_no, cuc_func *f)
367
{
368 883 markom
  int b, i;
369 903 markom
  char tmp[30];
370 897 markom
  char *name = prof_func[func_no].name;
371 997 markom
  PRINTF ("-----------------------------------------------------------------------------\n");
372
  PRINTF ("|%-28s|pre/unrolled|shared|  time  |  gates |old_time|\n",
373 904 markom
            strstrip (tmp, name, 28));
374 997 markom
  PRINTF ("|                    BASE    |%4i / %4i | %4i |%8i|%8.f|%8i|\n", 1, 1, 0,
375 903 markom
          f->timings.new_time, f->timings.size, f->orig_time);
376 883 markom
  for (b = 0; b < f->num_bb; b++) {
377
    /* Print out results */
378 897 markom
    for (i = 1; i < f->bb[b].ntim; i++) { /* First one is base option */
379
      int time = f->bb[b].tim[i].new_time - f->timings.new_time;
380
      double size = f->bb[b].tim[i].size - f->timings.size;
381 997 markom
      PRINTF ("|                   ");
382 897 markom
      print_option (b, i);
383 997 markom
      PRINTF ("      |%4i / %4i | %4i |%+8i|%+8.f|        |\n",
384 897 markom
        f->bb[b].tim[i].preroll, f->bb[b].tim[i].unroll, f->bb[b].tim[i].nshared,
385
        time, size);
386 883 markom
    }
387
  }
388
}
389
 
390 897 markom
/* Generates a function, based on specified parameters */
391 915 markom
cuc_func *generate_function (cuc_func *rf, char *name, char *cut_filename)
392 897 markom
{
393
  int b, i, j;
394
  char tmp[256];
395
  cuc_timings tt;
396
  cuc_func *f;
397
  assert (f = dup_func (rf));
398
 
399 915 markom
  if (cuc_debug >= 2) print_cuc_bb (f, "BEFORE_GENERATE");
400 897 markom
  log ("Generating function %s.\n", name);
401 997 markom
  PRINTF ("Generating function %s.\n", name);
402 897 markom
 
403
  format_func_options (tmp, rf);
404 997 markom
  if (strlen (tmp)) PRINTF ("Applying options: %s\n", tmp);
405
  else PRINTF ("Using basic options.\n");
406 897 markom
 
407
  /* Generate function as specified by options */
408
  for (b = 0; b < f->num_bb; b++) {
409
    cuc_timings *st;
410
    if (rf->bb[b].selected_tim < 0) continue;
411
    st = &rf->bb[b].tim[rf->bb[b].selected_tim];
412
    sprintf (tmp, "%s.bin.bb", name);
413
    preunroll_bb (&tmp[0], f, &tt, b, st->preroll, st->unroll);
414
    if (cuc_debug >= 1) print_cuc_bb (f, "AFTER_PREUNROLL");
415
  }
416
  for (b = 0; b < f->num_bb; b++) {
417
    cuc_timings *st;
418
    if (rf->bb[b].selected_tim < 0) continue;
419
    st = &rf->bb[b].tim[rf->bb[b].selected_tim];
420
    if (!st->nshared) continue;
421
    assert (0);
422
    //csm_gen (f, rf, st->nshared, st->shared);
423
  }
424 915 markom
  add_latches (f);
425
  if (cuc_debug >= 1) print_cuc_bb (f, "AFTER_LATCHES");
426 897 markom
  analyse_timings (f, &tt);
427 915 markom
 
428
  sprintf (tmp, "%s%s", cut_filename, name);
429 941 markom
  output_verilog (f, tmp, name);
430 897 markom
  return f;
431
}
432
 
433
/* Calculates required time, based on selected options */
434
int calc_cycles (cuc_func *f)
435
{
436
  int b, i, ntime = f->timings.new_time;
437
  for (b = 0; b < f->num_bb; b++)
438
    if (f->bb[b].selected_tim >= 0) {
439
      assert (f->bb[b].selected_tim < f->bb[b].ntim);
440
      ntime += f->bb[b].tim[f->bb[b].selected_tim].new_time - f->timings.new_time;
441
    }
442
  return ntime;
443
}
444
 
445
/* Calculates required size, based on selected options */
446
double calc_size (cuc_func *f)
447
{
448
  int b, i;
449
  double size = f->timings.size;
450
  for (b = 0; b < f->num_bb; b++)
451
    if (f->bb[b].selected_tim >= 0) {
452
      assert (f->bb[b].selected_tim < f->bb[b].ntim);
453
      size += f->bb[b].tim[f->bb[b].selected_tim].size - f->timings.size;
454
    }
455
  return size;
456
}
457
 
458 879 markom
/* Dumps specified function to file (hex) */
459
unsigned long extract_function (char *out_fn, unsigned long start_addr)
460
{
461
  FILE *fo;
462
  unsigned long a = start_addr;
463
  int x = 0;
464
  assert (fo = fopen (out_fn, "wt+"));
465
 
466
  do {
467
    unsigned long d = evalsim_mem32 (a);
468
    int index = insn_decode (d);
469
    assert (index >= 0);
470
    if (x) x++;
471
    if (strcmp (insn_name (index), "l.jr") == 0) x = 1;
472
    a += 4;
473
    fprintf (fo, "%08x\n", d);
474
  } while (x < 2);
475
 
476
  fclose (fo);
477
  return a - 4;
478
}
479
 
480
static cuc_func *func[MAX_FUNCS];
481 897 markom
static int func_v[MAX_FUNCS];
482 879 markom
 
483 906 markom
/* Detects function dependencies and removes  */
484
static void set_func_deps ()
485
{
486
  int f, b, i, j;
487
restart:
488
  for (f = 0; f < prof_nfuncs - 1; f++) if (func[f]) {
489
    int fused[MAX_FUNCS] = {0};
490
    int c;
491
    for (b = 0; b < func[f]->num_bb; b++)
492
      for (i = 0; i < func[f]->bb[b].ninsn; i++) {
493
        cuc_insn *ii = &func[f]->bb[b].insn[i];
494
        if (ii->index == II_CALL) {
495
          assert (ii->opt[0] == OPT_CONST);
496
          for (j = 0; j < prof_nfuncs - 1; j++)
497
            if (func[j] && func[j]->start_addr == ii->op[0]) break;
498
          if (j >= prof_nfuncs - 1) {
499
            log ("%s is calling unknown function, address %08x\n",
500
                            prof_func[f].name, ii->op[0]);
501
            debug (1, "%s is calling unknown function, address %08x\n",
502
                            prof_func[f].name, ii->op[0]);
503
            free_func (func[f]);
504
            func[f] = NULL;
505
            goto restart;
506
          } else if (f == j) {
507
            log ("%s is recursive, ignoring\n", prof_func[f].name);
508
            debug (1, "%s is recursive, ignoring\n", prof_func[f].name);
509
            free_func (func[f]);
510
            func[f] = NULL;
511
            goto restart;
512
          } else fused[j]++;
513
        }
514
      }
515
    for (i = 0; i < MAX_FUNCS; i++) if (fused[i]) c++;
516
    if (func[f]->nfdeps) free (func[f]->fdeps);
517
    func[f]->nfdeps = c;
518
    func[f]->fdeps = (cuc_func **) malloc (sizeof (cuc_func *) * c);
519
    for (i = 0, j = 0; i < MAX_FUNCS; i++)
520
      if (fused[i]) func[f]->fdeps[j++] = func[i];
521
  }
522
 
523
  /* Detect loops */
524
  {
525
    int change;
526
    for (f = 0; f < MAX_FUNCS; f++) if (func[f]) func[f]->tmp = 0;
527
    do {
528
      change = 0;
529
      for (f = 0; f < MAX_FUNCS; f++) if (func[f] && !func[f]->tmp) {
530
        int o = 1;
531
        for (i = 0; i < func[f]->nfdeps; i++)
532
          if (!func[f]->fdeps[i]->tmp) {o = 0; break;}
533
        if (o) {
534
          func[f]->tmp = 1;
535
          change = 1;
536
        }
537
      }
538
    } while (change);
539
 
540
    change = 0;
541
    for (f = 0; f < MAX_FUNCS; f++) if (func[f] && !func[f]->tmp) {
542
      free_func (func[f]);
543
      func[f] = NULL;
544
      change = 1;
545
    }
546
    if (change) goto restart;
547
  }
548
}
549
 
550 879 markom
void main_cuc (char *filename)
551
{
552 883 markom
  int i, j;
553 879 markom
  char tmp1[256];
554 915 markom
  char filename_cut[256];
555 940 markom
  for (i = 0; i < sizeof (filename_cut); i++) {
556 915 markom
    if (isalpha(filename[i])) filename_cut[i] = filename[i];
557
    else {
558
      filename_cut[i] = '\0';
559
      break;
560
    }
561
  }
562 879 markom
 
563 997 markom
  PRINTF ("Entering OpenRISC Custom Unit Compiler command prompt\n");
564
  PRINTF ("Using profile file \"%s\" and memory profile file \"%s\".\n", config.sim.prof_fn, config.sim.mprof_fn);
565 915 markom
  sprintf (tmp1, "%s.log", filename_cut);
566 997 markom
  PRINTF ("Analyzing. (log file \"%s\").\n", tmp1);
567 879 markom
  assert (flog = fopen (tmp1, "wt+"));
568
 
569
  /* Loads in the specified timings table */
570 997 markom
  PRINTF ("Using timings from \"%s\" at %s\n",config.cuc.timings_fn,
571 897 markom
                 generate_time_pretty (tmp1, config.sim.clkcycle_ps));
572
  load_timing_table (config.cuc.timings_fn);
573
  runtime.cuc.cycle_duration = 1000. * config.sim.clkcycle_ps;
574 997 markom
  PRINTF ("Multicycle logic %s, bursts %s, %s memory order.\n",
575 897 markom
    config.cuc.no_multicycle ? "OFF" : "ON", config.cuc.enable_bursts ? "ON" : "OFF",
576
    config.cuc.memory_order == MO_NONE ? "no" : config.cuc.memory_order == MO_WEAK ? "weak" :
577
    config.cuc.memory_order == MO_STRONG ? "strong" : "exact");
578 879 markom
 
579
  prof_set (1, 0);
580
  assert (prof_acquire (config.sim.prof_fn) == 0);
581 973 markom
  cuc_debug = 0;
582 897 markom
 
583
  if (config.cuc.calling_convention)
584 997 markom
    PRINTF ("Assuming OpenRISC standard calling convention.\n");
585 879 markom
 
586
  /* Try all functions except "total" */
587
  for (i = 0; i < prof_nfuncs - 1; i++) {
588
    long orig_time;
589
    unsigned long start_addr, end_addr;
590
    orig_time = prof_func[i].cum_cycles;
591
    start_addr = prof_func[i].addr;
592
 
593
    /* Extract the function from the binary */
594
    sprintf (tmp1, "%s.bin", prof_func[i].name);
595
    end_addr = extract_function (tmp1, start_addr);
596
 
597
    log ("Testing function %s (%08x - %08x)\n", prof_func[i].name, start_addr, end_addr);
598 997 markom
    PRINTF ("Testing function %s (%08x - %08x)\n", prof_func[i].name, start_addr, end_addr);
599 897 markom
    func[i] = analyse_function (prof_func[i].name, orig_time, start_addr,
600
                   end_addr, config.cuc.memory_order);
601
    func_v[i] = 0;
602 879 markom
  }
603 906 markom
  set_func_deps ();
604
 
605 883 markom
  while (1) {
606
    char *s;
607 906 markom
wait_command:
608 997 markom
    PRINTF ("(cuc) ");
609 883 markom
    fflush (stdout);
610
    fgets(tmp1, sizeof tmp1, stdin);
611
    for (s = tmp1; *s != '\0' && *s != '\n' && *s != '\r'; s++);
612
    *s = '\0';
613
 
614 906 markom
      /* quit command */
615 883 markom
    if (strcmp (tmp1, "q") == 0 || strcmp (tmp1, "quit") == 0) {
616 1003 markom
      /* Delete temporary files */
617
      for (i = 0; i < prof_nfuncs - 1; i++) {
618
        sprintf (tmp1, "%s.bin", prof_func[i].name);
619
        log ("Deleting temporary file %s %s\n", tmp1, remove (tmp1) ? "OK" : "FAILED");
620
        sprintf (tmp1, "%s.bin.bb", prof_func[i].name);
621
        log ("Deleting temporary file %s %s\n", tmp1, remove (tmp1) ? "OK" : "FAILED");
622
      }
623 883 markom
      break;
624 1003 markom
 
625 906 markom
      /* profile command */
626 883 markom
    } else if (strcmp (tmp1, "p") == 0 || strcmp (tmp1, "profile") == 0) {
627 897 markom
      int ntime = 0;
628
      int size = 0;
629 997 markom
      PRINTF ("-----------------------------------------------------------------------------\n");
630
      PRINTF ("|function name       |calls|avg cycles  |old%| max. f.  | impr. f.| options |\n");
631
      PRINTF ("|--------------------+-----+------------+----+----------|---------+---------|\n");
632 883 markom
      for (j = 0; j < prof_nfuncs; j++) {
633
        int bestcyc = 0, besti = 0;
634 897 markom
        char tmp[100];
635 883 markom
        for (i = 0; i < prof_nfuncs; i++)
636
          if (prof_func[i].cum_cycles > bestcyc) {
637
            bestcyc = prof_func[i].cum_cycles;
638
            besti = i;
639
          }
640
        i = besti;
641 997 markom
        PRINTF ("|%-20s|%5i|%12.1f|%3.0f%%| ",
642 897 markom
                strstrip (tmp, prof_func[i].name, 20),  prof_func[i].calls,
643 883 markom
                ((double)prof_func[i].cum_cycles / prof_func[i].calls),
644
                (100. * prof_func[i].cum_cycles / prof_cycles));
645
        if (func[i]) {
646 897 markom
          double f = 1.0;
647
          if (func_v[i]) {
648
            int nt = calc_cycles (func[i]);
649
            int s = calc_size (func[i]);
650 996 markom
            f = 1. * func[i]->orig_time / nt;
651 897 markom
            ntime += nt * func[i]->num_runs;
652
            size += s;
653
          } else ntime += prof_func[i].cum_cycles;
654 997 markom
          PRINTF ("%8.1f |%8.1f | %-8s|\n", 1.f * prof_func[i].cum_cycles
655 905 markom
                          / func[i]->timings.new_time, f, format_func_options (tmp, func[i]));
656 897 markom
        } else {
657 997 markom
          PRINTF ("     N/A |     N/A |     N/A |\n");
658 897 markom
          ntime += prof_func[i].cum_cycles;
659
        }
660
        prof_func[i].cum_cycles = -prof_func[i].cum_cycles;
661 883 markom
      }
662 897 markom
      for (i = 0; i < prof_nfuncs; i++)
663
        prof_func[i].cum_cycles = -prof_func[i].cum_cycles;
664 997 markom
      PRINTF ("-----------------------------------------------------------------------------\n");
665
      PRINTF ("Total %i cycles (was %i), total added gates = %i. Speed factor %.1f\n",
666 905 markom
                      ntime, prof_cycles, size, 1. * prof_cycles / ntime);
667 906 markom
 
668
      /* debug command */
669 883 markom
    } else if (strncmp (tmp1, "d", 1) == 0 || strncmp (tmp1, "debug", 5) == 0) {
670
      sscanf (tmp1, "%*s %i", &cuc_debug);
671
      if (cuc_debug < 0) cuc_debug = 0;
672
      if (cuc_debug > 9) cuc_debug = 9;
673 906 markom
 
674
      /* generate command */
675 883 markom
    } else if (strcmp (tmp1, "g") == 0 || strcmp (tmp1, "generate") == 0) {
676 906 markom
      /* check for function dependencies */
677 897 markom
      for (i = 0; i < prof_nfuncs; i++)
678 906 markom
        if (func[i]) func[i]->tmp = func_v[i];
679 915 markom
      for (i = 0; i < prof_nfuncs; i++) if (func[i])
680 906 markom
        for (j = 0; j < func[i]->nfdeps; j++)
681
          if (!func[i]->fdeps[j] || !func[i]->fdeps[j]->tmp) {
682 997 markom
            PRINTF ("Function %s must be selected for translation (required by %s)\n",
683 906 markom
                    prof_func[j].name, prof_func[i].name);
684
            goto wait_command;
685
          }
686
      for (i = 0; i < prof_nfuncs; i++)
687 915 markom
        if (func[i] && func_v[i]) generate_function (func[i], prof_func[i].name, filename_cut);
688
      generate_main (prof_nfuncs, func, filename_cut);
689
 
690 918 markom
      /* selectall command */
691
    } else if (strcmp (tmp1, "sa") == 0 || strcmp (tmp1, "selectall") == 0) {
692
      char tmp[50], ch;
693
      int p, o, b, f;
694
      for (f = 0; f < prof_nfuncs; f++) if (func[f]) {
695
        func_v[f] = 1;
696 997 markom
        PRINTF ("Function %s selected for translation.\n", prof_func[f].name);
697 918 markom
      }
698
 
699 906 markom
      /* select command */
700 897 markom
    } else if (strncmp (tmp1, "s", 1) == 0 || strncmp (tmp1, "select", 6) == 0) {
701
      char tmp[50], ch;
702
      int p, o, b, f;
703
      p = sscanf (tmp1, "%*s %s %i%c", tmp, &b, &ch);
704 997 markom
      if (p < 1) PRINTF ("Invalid parameters.\n");
705 897 markom
      else {
706
        /* Check if we have valid option */
707
        for (f = 0; f < prof_nfuncs; f++)
708
          if (strcmp (prof_func[f].name, tmp) == 0 && func[f]) break;
709
        if (f < prof_nfuncs) {
710
          if (p == 1) {
711
            if (func[f]) {
712
              func_v[f] = 1;
713 997 markom
              PRINTF ("Function %s selected for translation.\n", prof_func[f].name);
714
            } else PRINTF ("Function %s not suitable for translation.\n", prof_func[f].name);
715 897 markom
          } else {
716
            if (!func_v[f])
717 997 markom
              PRINTF ("Function %s not yet selected for translation.\n", prof_func[f].name);
718 897 markom
            if (p < 3) goto invalid_option;
719
            for (o = 0; option_char[o] != '\0' && option_char[o] != ch; o++);
720
            if (!option_char[o]) goto invalid_option;
721
            if (b < 0 || b >= func[f]->num_bb) goto invalid_option;
722
            if (o < 0 || o >= func[f]->bb[b].ntim) goto invalid_option;
723
 
724
            /* select an option */
725
            func[f]->bb[b].selected_tim = o;
726
            if (func[f]->bb[b].tim[o].nshared) {
727 997 markom
              PRINTF ("Option has shared instructions: ");
728 897 markom
              print_shared (func[f], func[f]->bb[b].tim[o].shared, func[f]->bb[b].tim[o].nshared);
729 997 markom
              PRINTF ("\n");
730 897 markom
            }
731 906 markom
            goto wait_command;
732 897 markom
invalid_option:
733 997 markom
            PRINTF ("Invalid option.\n");
734 897 markom
          }
735 997 markom
        } else PRINTF ("Invalid function.\n");
736 897 markom
      }
737 906 markom
 
738
      /* unselect command */
739 897 markom
    } else if (strncmp (tmp1, "u", 1) == 0 || strncmp (tmp1, "unselect", 8) == 0) {
740
      char tmp[50], ch;
741
      int p, o, b, f;
742
      p = sscanf (tmp1, "%*s %s %i%c", tmp, &b, &ch);
743 997 markom
      if (p < 1) PRINTF ("Invalid parameters.\n");
744 897 markom
      else {
745
        /* Check if we have valid option */
746
        for (f = 0; f < prof_nfuncs; f++)
747
          if (strcmp (prof_func[f].name, tmp) == 0 && func[f]) break;
748
        if (f < prof_nfuncs) {
749
          if (p == 1) {
750
            if (func[f]) {
751
              func_v[f] = 0;
752 997 markom
              PRINTF ("Function %s unselected for translation.\n", prof_func[f].name);
753
            } else PRINTF ("Function %s not suitable for translation.\n", prof_func[f].name);
754 897 markom
          } else {
755
            if (p < 3) goto invalid_option;
756
            for (o = 0; option_char[o] != '\0' && option_char[o] != ch; o++);
757
            if (!option_char[o]) goto invalid_option;
758
            if (b < 0 || b >= func[f]->num_bb) goto invalid_option;
759
            if (o < 0 || o >= func[f]->bb[b].ntim) goto invalid_option;
760
 
761
            /* select an option */
762
            func[f]->bb[b].selected_tim = -1;
763
          }
764 997 markom
        } else PRINTF ("Invalid function.\n");
765 897 markom
      }
766 906 markom
 
767
      /* options command */
768 883 markom
    } else if (strcmp (tmp1, "o") == 0 || strcmp (tmp1, "options") == 0) {
769 897 markom
      int any = 0;
770 997 markom
      PRINTF ("Available options:\n");
771 883 markom
      for (i = 0; i < prof_nfuncs; i++)
772 897 markom
        if (func[i]) {
773
          options_cmd (i, func[i]);
774
          any = 1;
775
        }
776 997 markom
      if (any) PRINTF ("-----------------------------------------------------------------------------\n");
777
      else PRINTF ("Sorry. No available options.\n");
778 906 markom
 
779
      /* Ignore empty string */
780 902 markom
    } else if (strcmp (tmp1, "") == 0) {
781 906 markom
 
782
      /* help command */
783 883 markom
    } else {
784
      if (strcmp (tmp1, "h") != 0 && strcmp (tmp1, "help") != 0)
785 997 markom
        PRINTF ("Unknown command.\n");
786
      PRINTF ("OpenRISC Custom Unit Compiler command prompt\n");
787
      PRINTF ("Available commands:\n");
788
      PRINTF ("  h | help                   displays this help\n");
789
      PRINTF ("  q | quit                   returns to or1ksim prompt\n");
790
      PRINTF ("  p | profile                displays function profiling\n");
791
      PRINTF ("  d | debug #                sets debug level (0-9)\n");
792
      PRINTF ("  o | options                displays available options\n");
793
      PRINTF ("  s | select func [option]   selects an option/function\n");
794
      PRINTF ("  u | unselect func [option] unselects an option/function\n");
795
      PRINTF ("  g | generate               generates verilog file\n");
796 883 markom
    }
797
  }
798
 
799 879 markom
  /* Dispose memory */
800
  for (i = 0; i < prof_nfuncs -1; i++)
801
    if (func[i]) free_func (func[i]);
802
 
803
  fclose (flog);
804
}
805
 

powered by: WebSVN 2.1.0

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