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

Subversion Repositories or1k

[/] [or1k/] [trunk/] [or1ksim/] [cuc/] [cuc.c] - Blame information for rev 941

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

powered by: WebSVN 2.1.0

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