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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [or1ksim/] [cuc/] [cuc.c] - Diff between revs 19 and 224

Go to most recent revision | Only display areas with differences | Details | Blame | View Log

Rev 19 Rev 224
/* cuc.c -- OpenRISC Custom Unit Compiler
/* cuc.c -- OpenRISC Custom Unit Compiler
 
 
   Copyright (C) 2002 Marko Mlinar, markom@opencores.org
   Copyright (C) 2002 Marko Mlinar, markom@opencores.org
   Copyright (C) 2008 Embecosm Limited
   Copyright (C) 2008 Embecosm Limited
 
 
   Contributor Jeremy Bennett <jeremy.bennett@embecosm.com>
   Contributor Jeremy Bennett <jeremy.bennett@embecosm.com>
 
 
   This file is part of OpenRISC 1000 Architectural Simulator.
   This file is part of OpenRISC 1000 Architectural Simulator.
 
 
   This program is free software; you can redistribute it and/or modify it
   This program is free software; you can redistribute it and/or modify it
   under the terms of the GNU General Public License as published by the Free
   under the terms of the GNU General Public License as published by the Free
   Software Foundation; either version 3 of the License, or (at your option)
   Software Foundation; either version 3 of the License, or (at your option)
   any later version.
   any later version.
 
 
   This program is distributed in the hope that it will be useful, but WITHOUT
   This program is distributed in the hope that it will be useful, but WITHOUT
   ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
   FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
   more details.
   more details.
 
 
   You should have received a copy of the GNU General Public License along
   You should have received a copy of the GNU General Public License along
   with this program.  If not, see <http://www.gnu.org/licenses/>. */
   with this program.  If not, see <http://www.gnu.org/licenses/>. */
 
 
/* This program is commented throughout in a fashion suitable for processing
/* This program is commented throughout in a fashion suitable for processing
   with Doxygen. */
   with Doxygen. */
 
 
/* Main file, including code optimization and command prompt */
/* Main file, including code optimization and command prompt */
 
 
 
 
/* Autoconf and/or portability configuration */
/* Autoconf and/or portability configuration */
#include "config.h"
#include "config.h"
#include "port.h"
#include "port.h"
 
 
/* System includes */
/* System includes */
#include <stdlib.h>
#include <stdlib.h>
#include <unistd.h>
#include <unistd.h>
#include <assert.h>
#include <assert.h>
 
 
/* Package includes */
/* Package includes */
#include "cuc.h"
#include "cuc.h"
#include "sim-config.h"
#include "sim-config.h"
#include "profiler.h"
#include "profiler.h"
#include "insn.h"
#include "insn.h"
#include "opcode/or32.h"
#include "opcode/or32.h"
#include "parse.h"
#include "parse.h"
#include "verilog.h"
#include "verilog.h"
#include "debug.h"
#include "debug.h"
 
 
FILE *flog;
FILE *flog;
int cuc_debug = 0;
int cuc_debug = 0;
 
 
/* Last used registers by software convention */
/* Last used registers by software convention */
/* Note that r11 is caller saved register, and we can destroy it.
/* Note that r11 is caller saved register, and we can destroy it.
   Due to CUC architecture we must always return something, even garbage (so that
   Due to CUC architecture we must always return something, even garbage (so that
   caller knows, we are finished, when we send acknowledge).
   caller knows, we are finished, when we send acknowledge).
   In case r11 was not used (trivial register assignment) we will remove it later,
   In case r11 was not used (trivial register assignment) we will remove it later,
   but if we assigned a value to it, it must not be removed, so caller_saved[11] = 0 */
   but if we assigned a value to it, it must not be removed, so caller_saved[11] = 0 */
const int caller_saved[MAX_REGS] = {
const int caller_saved[MAX_REGS] = {
  0, 0, 0, 1, 1, 1, 1, 1,
  0, 0, 0, 1, 1, 1, 1, 1,
  1, 1, 0, 0, 0, 1, 0, 1,
  1, 1, 0, 0, 0, 1, 0, 1,
  0, 1, 0, 1, 0, 1, 0, 1,
  0, 1, 0, 1, 0, 1, 0, 1,
  0, 1, 0, 1, 0, 1, 0, 1,
  0, 1, 0, 1, 0, 1, 0, 1,
  1, 1
  1, 1
};
};
 
 
/* Does all known instruction optimizations */
/* Does all known instruction optimizations */
void
void
cuc_optimize (cuc_func * func)
cuc_optimize (cuc_func * func)
{
{
  int modified = 0;
  int modified = 0;
  int first = 1;
  int first = 1;
  log ("Optimizing.\n");
  log ("Optimizing.\n");
  do
  do
    {
    {
      modified = 0;
      modified = 0;
      clean_deps (func);
      clean_deps (func);
      if (cuc_debug >= 6)
      if (cuc_debug >= 6)
        print_cuc_bb (func, "AFTER_CLEAN_DEPS");
        print_cuc_bb (func, "AFTER_CLEAN_DEPS");
      if (optimize_cmovs (func))
      if (optimize_cmovs (func))
        {
        {
          if (cuc_debug >= 6)
          if (cuc_debug >= 6)
            print_cuc_bb (func, "AFTER_OPT_CMOVS");
            print_cuc_bb (func, "AFTER_OPT_CMOVS");
          modified = 1;
          modified = 1;
        }
        }
      if (cuc_debug)
      if (cuc_debug)
        cuc_check (func);
        cuc_check (func);
      if (optimize_tree (func))
      if (optimize_tree (func))
        {
        {
          if (cuc_debug >= 6)
          if (cuc_debug >= 6)
            print_cuc_bb (func, "AFTER_OPT_TREE1");
            print_cuc_bb (func, "AFTER_OPT_TREE1");
          modified = 1;
          modified = 1;
        }
        }
      if (remove_nops (func))
      if (remove_nops (func))
        {
        {
          if (cuc_debug >= 6)
          if (cuc_debug >= 6)
            print_cuc_bb (func, "NO_NOPS");
            print_cuc_bb (func, "NO_NOPS");
          modified = 1;
          modified = 1;
        }
        }
      if (cuc_debug)
      if (cuc_debug)
        cuc_check (func);
        cuc_check (func);
      if (remove_dead (func))
      if (remove_dead (func))
        {
        {
          if (cuc_debug >= 5)
          if (cuc_debug >= 5)
            print_cuc_bb (func, "AFTER_DEAD");
            print_cuc_bb (func, "AFTER_DEAD");
          modified = 1;
          modified = 1;
        }
        }
      if (cuc_debug)
      if (cuc_debug)
        cuc_check (func);
        cuc_check (func);
      if (cse (func))
      if (cse (func))
        {
        {
          log ("Common subexpression elimination.\n");
          log ("Common subexpression elimination.\n");
          if (cuc_debug >= 3)
          if (cuc_debug >= 3)
            print_cuc_bb (func, "AFTER_CSE");
            print_cuc_bb (func, "AFTER_CSE");
          modified = 1;
          modified = 1;
        }
        }
      if (first)
      if (first)
        {
        {
          insert_conditional_facts (func);
          insert_conditional_facts (func);
          if (cuc_debug >= 3)
          if (cuc_debug >= 3)
            print_cuc_bb (func, "AFTER_COND_FACT");
            print_cuc_bb (func, "AFTER_COND_FACT");
          if (cuc_debug)
          if (cuc_debug)
            cuc_check (func);
            cuc_check (func);
          first = 0;
          first = 0;
        }
        }
      if (optimize_bb (func))
      if (optimize_bb (func))
        {
        {
          if (cuc_debug >= 5)
          if (cuc_debug >= 5)
            print_cuc_bb (func, "AFTER_OPT_BB");
            print_cuc_bb (func, "AFTER_OPT_BB");
          modified = 1;
          modified = 1;
        }
        }
      if (cuc_debug)
      if (cuc_debug)
        cuc_check (func);
        cuc_check (func);
      if (remove_nops (func))
      if (remove_nops (func))
        {
        {
          if (cuc_debug >= 6)
          if (cuc_debug >= 6)
            print_cuc_bb (func, "NO_NOPS");
            print_cuc_bb (func, "NO_NOPS");
          modified = 1;
          modified = 1;
        }
        }
      if (remove_dead_bb (func))
      if (remove_dead_bb (func))
        {
        {
          if (cuc_debug >= 5)
          if (cuc_debug >= 5)
            print_cuc_bb (func, "AFTER_DEAD_BB");
            print_cuc_bb (func, "AFTER_DEAD_BB");
          modified = 1;
          modified = 1;
        }
        }
      if (remove_trivial_regs (func))
      if (remove_trivial_regs (func))
        {
        {
          if (cuc_debug >= 2)
          if (cuc_debug >= 2)
            print_cuc_bb (func, "AFTER_TRIVIAL");
            print_cuc_bb (func, "AFTER_TRIVIAL");
          modified = 1;
          modified = 1;
        }
        }
      if (remove_nops (func))
      if (remove_nops (func))
        {
        {
          if (cuc_debug >= 6)
          if (cuc_debug >= 6)
            print_cuc_bb (func, "NO_NOPS");
            print_cuc_bb (func, "NO_NOPS");
          modified = 1;
          modified = 1;
        }
        }
      add_memory_dep (func, func->memory_order);
      add_memory_dep (func, func->memory_order);
      if (cuc_debug >= 7)
      if (cuc_debug >= 7)
        print_cuc_bb (func, "AFTER_MEMORY_DEP");
        print_cuc_bb (func, "AFTER_MEMORY_DEP");
      add_data_dep (func);
      add_data_dep (func);
      if (cuc_debug >= 8)
      if (cuc_debug >= 8)
        print_cuc_bb (func, "AFTER_DATA_DEP");
        print_cuc_bb (func, "AFTER_DATA_DEP");
      if (schedule_memory (func, func->memory_order))
      if (schedule_memory (func, func->memory_order))
        {
        {
          if (cuc_debug >= 7)
          if (cuc_debug >= 7)
            print_cuc_bb (func, "AFTER_SCHEDULE_MEM");
            print_cuc_bb (func, "AFTER_SCHEDULE_MEM");
          modified = 1;
          modified = 1;
        }
        }
    }
    }
  while (modified);
  while (modified);
  set_io (func);
  set_io (func);
#if 0
#if 0
  detect_max_values (func);
  detect_max_values (func);
  if (cuc_debug >= 5)
  if (cuc_debug >= 5)
    print_cuc_bb (func, "AFTER_MAX_VALUES");
    print_cuc_bb (func, "AFTER_MAX_VALUES");
#endif
#endif
}
}
 
 
/* Pre/unrolls basic block and optimizes it */
/* Pre/unrolls basic block and optimizes it */
cuc_timings *
cuc_timings *
preunroll_bb (char *bb_filename, cuc_func * f, cuc_timings * timings, int b,
preunroll_bb (char *bb_filename, cuc_func * f, cuc_timings * timings, int b,
              int i, int j)
              int i, int j)
{
{
  cuc_func *func;
  cuc_func *func;
  cucdebug (2, "BB%i unroll %i times preroll %i times\n", b, j, i);
  cucdebug (2, "BB%i unroll %i times preroll %i times\n", b, j, i);
  log ("BB%i unroll %i times preroll %i times\n", b, j, i);
  log ("BB%i unroll %i times preroll %i times\n", b, j, i);
  func = preunroll_loop (f, b, i, j, bb_filename);
  func = preunroll_loop (f, b, i, j, bb_filename);
  if (cuc_debug >= 2)
  if (cuc_debug >= 2)
    print_cuc_bb (func, "AFTER_PREUNROLL");
    print_cuc_bb (func, "AFTER_PREUNROLL");
  cuc_optimize (func);
  cuc_optimize (func);
  analyse_timings (func, timings);
  analyse_timings (func, timings);
 
 
  cucdebug (2, "new_time = %i, old_time = %i, size = %f\n",
  cucdebug (2, "new_time = %i, old_time = %i, size = %f\n",
            timings->new_time, func->orig_time, timings->size);
            timings->new_time, func->orig_time, timings->size);
  log ("new time = %icyc, old_time = %icyc, size = %.0f gates\n",
  log ("new time = %icyc, old_time = %icyc, size = %.0f gates\n",
       timings->new_time, func->orig_time, timings->size);
       timings->new_time, func->orig_time, timings->size);
  //output_verilog (func, argv[1]);
  //output_verilog (func, argv[1]);
  free_func (func);
  free_func (func);
  timings->b = b;
  timings->b = b;
  timings->unroll = j;
  timings->unroll = j;
  timings->preroll = i;
  timings->preroll = i;
  timings->nshared = 0;
  timings->nshared = 0;
  return timings;
  return timings;
}
}
 
 
 
 
/* Simple comparison function */
/* Simple comparison function */
int
int
tim_comp (cuc_timings * a, cuc_timings * b)
tim_comp (cuc_timings * a, cuc_timings * b)
{
{
  if (a->new_time < b->new_time)
  if (a->new_time < b->new_time)
    return -1;
    return -1;
  else if (a->new_time > b->new_time)
  else if (a->new_time > b->new_time)
    return 1;
    return 1;
  else
  else
    return 0;
    return 0;
}
}
 
 
/* Analyses function; done when cuc command is entered in (sim) prompt */
/* Analyses function; done when cuc command is entered in (sim) prompt */
cuc_func *
cuc_func *
analyse_function (char *module_name, long orig_time,
analyse_function (char *module_name, long orig_time,
                  unsigned long start_addr, unsigned long end_addr,
                  unsigned long start_addr, unsigned long end_addr,
                  int memory_order, int num_runs)
                  int memory_order, int num_runs)
{
{
  cuc_timings timings;
  cuc_timings timings;
  cuc_func *func = (cuc_func *) malloc (sizeof (cuc_func));
  cuc_func *func = (cuc_func *) malloc (sizeof (cuc_func));
  cuc_func *saved;
  cuc_func *saved;
  int b, i, j;
  int b, i, j;
  char tmp1[256];
  char tmp1[256];
  char tmp2[256];
  char tmp2[256];
 
 
  func->orig_time = orig_time;
  func->orig_time = orig_time;
  func->start_addr = start_addr;
  func->start_addr = start_addr;
  func->end_addr = end_addr;
  func->end_addr = end_addr;
  func->memory_order = memory_order;
  func->memory_order = memory_order;
  func->nfdeps = 0;
  func->nfdeps = 0;
  func->fdeps = NULL;
  func->fdeps = NULL;
  func->num_runs = num_runs;
  func->num_runs = num_runs;
 
 
  sprintf (tmp1, "%s.bin", module_name);
  sprintf (tmp1, "%s.bin", module_name);
  cucdebug (2, "Loading %s.bin\n", module_name);
  cucdebug (2, "Loading %s.bin\n", module_name);
  if (cuc_load (tmp1))
  if (cuc_load (tmp1))
    {
    {
      free (func);
      free (func);
      return NULL;
      return NULL;
    }
    }
 
 
  log ("Detecting basic blocks\n");
  log ("Detecting basic blocks\n");
  detect_bb (func);
  detect_bb (func);
  if (cuc_debug >= 2)
  if (cuc_debug >= 2)
    print_cuc_insns ("WITH_BB_LIMITS", 0);
    print_cuc_insns ("WITH_BB_LIMITS", 0);
 
 
  //sprintf (tmp1, "%s.bin.mp", module_name);
  //sprintf (tmp1, "%s.bin.mp", module_name);
  sprintf (tmp2, "%s.bin.bb", module_name);
  sprintf (tmp2, "%s.bin.bb", module_name);
  generate_bb_seq (func, config.sim.mprof_fn, tmp2);
  generate_bb_seq (func, config.sim.mprof_fn, tmp2);
  log ("Assuming %i clk cycle load (%i cyc burst)\n", runtime.cuc.mdelay[0],
  log ("Assuming %i clk cycle load (%i cyc burst)\n", runtime.cuc.mdelay[0],
       runtime.cuc.mdelay[2]);
       runtime.cuc.mdelay[2]);
  log ("Assuming %i clk cycle store (%i cyc burst)\n", runtime.cuc.mdelay[1],
  log ("Assuming %i clk cycle store (%i cyc burst)\n", runtime.cuc.mdelay[1],
       runtime.cuc.mdelay[3]);
       runtime.cuc.mdelay[3]);
 
 
  build_bb (func);
  build_bb (func);
  if (cuc_debug >= 5)
  if (cuc_debug >= 5)
    print_cuc_bb (func, "AFTER_BUILD_BB");
    print_cuc_bb (func, "AFTER_BUILD_BB");
  reg_dep (func);
  reg_dep (func);
 
 
  log ("Detecting dependencies\n");
  log ("Detecting dependencies\n");
  if (cuc_debug >= 2)
  if (cuc_debug >= 2)
    print_cuc_bb (func, "AFTER_REG_DEP");
    print_cuc_bb (func, "AFTER_REG_DEP");
  cuc_optimize (func);
  cuc_optimize (func);
 
 
#if 0
#if 0
  csm (func);
  csm (func);
#endif
#endif
  assert (saved = dup_func (func));
  assert (saved = dup_func (func));
 
 
  timings.preroll = timings.unroll = 1;
  timings.preroll = timings.unroll = 1;
  timings.nshared = 0;
  timings.nshared = 0;
 
 
  add_latches (func);
  add_latches (func);
  if (cuc_debug >= 1)
  if (cuc_debug >= 1)
    print_cuc_bb (func, "AFTER_LATCHES");
    print_cuc_bb (func, "AFTER_LATCHES");
  analyse_timings (func, &timings);
  analyse_timings (func, &timings);
 
 
  free_func (func);
  free_func (func);
  log ("Base option: pre%i,un%i,sha%i: %icyc %.1f\n",
  log ("Base option: pre%i,un%i,sha%i: %icyc %.1f\n",
       timings.preroll, timings.unroll, timings.nshared, timings.new_time,
       timings.preroll, timings.unroll, timings.nshared, timings.new_time,
       timings.size);
       timings.size);
  saved->timings = timings;
  saved->timings = timings;
 
 
#if 1
#if 1
  /* detect and unroll simple loops */
  /* detect and unroll simple loops */
  for (b = 0; b < saved->num_bb; b++)
  for (b = 0; b < saved->num_bb; b++)
    {
    {
      cuc_timings t[MAX_UNROLL * MAX_PREROLL];
      cuc_timings t[MAX_UNROLL * MAX_PREROLL];
      cuc_timings *ut;
      cuc_timings *ut;
      cuc_timings *cut = &t[0];
      cuc_timings *cut = &t[0];
      int nt = 1;
      int nt = 1;
      double csize;
      double csize;
      saved->bb[b].selected_tim = -1;
      saved->bb[b].selected_tim = -1;
 
 
      /* Is it a loop? */
      /* Is it a loop? */
      if (saved->bb[b].next[0] != b && saved->bb[b].next[1] != b)
      if (saved->bb[b].next[0] != b && saved->bb[b].next[1] != b)
        continue;
        continue;
      log ("Found loop at BB%x.  Trying to unroll.\n", b);
      log ("Found loop at BB%x.  Trying to unroll.\n", b);
      t[0] = timings;
      t[0] = timings;
      t[0].b = b;
      t[0].b = b;
      t[0].preroll = 1;
      t[0].preroll = 1;
      t[0].unroll = 1;
      t[0].unroll = 1;
      t[0].nshared = 0;
      t[0].nshared = 0;
 
 
      sprintf (tmp1, "%s.bin.bb", module_name);
      sprintf (tmp1, "%s.bin.bb", module_name);
      i = 1;
      i = 1;
      do
      do
        {
        {
          cuc_timings *pt;
          cuc_timings *pt;
          cuc_timings *cpt = cut;
          cuc_timings *cpt = cut;
          j = 1;
          j = 1;
 
 
          do
          do
            {
            {
              pt = cpt;
              pt = cpt;
              cpt = preunroll_bb (tmp1, saved, &t[nt++], b, ++j, i);
              cpt = preunroll_bb (tmp1, saved, &t[nt++], b, ++j, i);
            }
            }
          while (j <= MAX_PREROLL && pt->new_time > cpt->new_time);
          while (j <= MAX_PREROLL && pt->new_time > cpt->new_time);
          i++;
          i++;
          ut = cut;
          ut = cut;
          cut = preunroll_bb (tmp1, saved, &t[nt++], b, 1, i);
          cut = preunroll_bb (tmp1, saved, &t[nt++], b, 1, i);
        }
        }
      while (i <= MAX_UNROLL && ut->new_time > cut->new_time);
      while (i <= MAX_UNROLL && ut->new_time > cut->new_time);
 
 
      /* Sort the timings */
      /* Sort the timings */
#if 0
#if 0
      if (cuc_debug >= 3)
      if (cuc_debug >= 3)
        for (i = 0; i < nt; i++)
        for (i = 0; i < nt; i++)
          PRINTF ("%i:%i,%i: %icyc\n",
          PRINTF ("%i:%i,%i: %icyc\n",
                  t[i].b, t[i].preroll, t[i].unroll, t[i].new_time);
                  t[i].b, t[i].preroll, t[i].unroll, t[i].new_time);
#endif
#endif
 
 
#if HAVE___COMPAR_FN_T
#if HAVE___COMPAR_FN_T
      qsort (t, nt, sizeof (cuc_timings),
      qsort (t, nt, sizeof (cuc_timings),
             (__compar_fn_t) tim_comp);
             (__compar_fn_t) tim_comp);
#else
#else
      qsort (t, nt, sizeof (cuc_timings),
      qsort (t, nt, sizeof (cuc_timings),
             (int (*) (const void *, const void *)) tim_comp);
             (int (*) (const void *, const void *)) tim_comp);
#endif
#endif
 
 
      /* Delete timings, that have worst time and bigger size than other */
      /* Delete timings, that have worst time and bigger size than other */
      j = 1;
      j = 1;
      csize = t[0].size;
      csize = t[0].size;
      for (i = 1; i < nt; i++)
      for (i = 1; i < nt; i++)
        if (t[i].size < csize)
        if (t[i].size < csize)
          t[j++] = t[i];
          t[j++] = t[i];
      nt = j;
      nt = j;
 
 
      cucdebug (1, "Available options\n");
      cucdebug (1, "Available options\n");
      for (i = 0; i < nt; i++)
      for (i = 0; i < nt; i++)
        cucdebug (1, "%i:%i,%i: %icyc %.1f\n",
        cucdebug (1, "%i:%i,%i: %icyc %.1f\n",
                  t[i].b, t[i].preroll, t[i].unroll, t[i].new_time,
                  t[i].b, t[i].preroll, t[i].unroll, t[i].new_time,
                  t[i].size);
                  t[i].size);
      /* Add results from CSM */
      /* Add results from CSM */
      j = nt;
      j = nt;
      for (i = 0; i < saved->bb[b].ntim; i++)
      for (i = 0; i < saved->bb[b].ntim; i++)
        {
        {
          int i1;
          int i1;
          for (i1 = 0; i1 < nt; i1++)
          for (i1 = 0; i1 < nt; i1++)
            {
            {
              t[j] = t[i1];
              t[j] = t[i1];
              t[j].size += saved->bb[b].tim[i].size - timings.size;
              t[j].size += saved->bb[b].tim[i].size - timings.size;
              t[j].new_time +=
              t[j].new_time +=
                saved->bb[b].tim[i].new_time - timings.new_time;
                saved->bb[b].tim[i].new_time - timings.new_time;
              t[j].nshared = saved->bb[b].tim[i].nshared;
              t[j].nshared = saved->bb[b].tim[i].nshared;
              t[j].shared = saved->bb[b].tim[i].shared;
              t[j].shared = saved->bb[b].tim[i].shared;
              if (++j >= MAX_UNROLL * MAX_PREROLL)
              if (++j >= MAX_UNROLL * MAX_PREROLL)
                goto full;
                goto full;
            }
            }
        }
        }
 
 
    full:
    full:
      nt = j;
      nt = j;
 
 
      cucdebug (1, "Available options:\n");
      cucdebug (1, "Available options:\n");
      for (i = 0; i < nt; i++)
      for (i = 0; i < nt; i++)
        cucdebug (1, "%i:%i,%i: %icyc %.1f\n",
        cucdebug (1, "%i:%i,%i: %icyc %.1f\n",
                  t[i].b, t[i].preroll, t[i].unroll, t[i].new_time,
                  t[i].b, t[i].preroll, t[i].unroll, t[i].new_time,
                  t[i].size);
                  t[i].size);
 
 
      /* Sort again with new timings added */
      /* Sort again with new timings added */
#if HAVE___COMPAR_FN_T
#if HAVE___COMPAR_FN_T
      qsort (t, nt, sizeof (cuc_timings),
      qsort (t, nt, sizeof (cuc_timings),
             (__compar_fn_t) tim_comp);
             (__compar_fn_t) tim_comp);
#else
#else
      qsort (t, nt, sizeof (cuc_timings),
      qsort (t, nt, sizeof (cuc_timings),
             (int (*)(const void *, const void *)) tim_comp);
             (int (*)(const void *, const void *)) tim_comp);
#endif
#endif
 
 
      /* Delete timings, that have worst time and bigger size than other */
      /* Delete timings, that have worst time and bigger size than other */
      j = 1;
      j = 1;
      csize = t[0].size;
      csize = t[0].size;
      for (i = 1; i < nt; i++)
      for (i = 1; i < nt; i++)
        if (t[i].size < csize)
        if (t[i].size < csize)
          t[j++] = t[i];
          t[j++] = t[i];
      nt = j;
      nt = j;
 
 
      cucdebug (1, "Available options:\n");
      cucdebug (1, "Available options:\n");
      for (i = 0; i < nt; i++)
      for (i = 0; i < nt; i++)
        cucdebug (1, "%i:%i,%i: %icyc %.1f\n",
        cucdebug (1, "%i:%i,%i: %icyc %.1f\n",
                  t[i].b, t[i].preroll, t[i].unroll, t[i].new_time,
                  t[i].b, t[i].preroll, t[i].unroll, t[i].new_time,
                  t[i].size);
                  t[i].size);
 
 
      if (saved->bb[b].ntim)
      if (saved->bb[b].ntim)
        free (saved->bb[b].tim);
        free (saved->bb[b].tim);
      saved->bb[b].ntim = nt;
      saved->bb[b].ntim = nt;
      assert (saved->bb[b].tim =
      assert (saved->bb[b].tim =
              (cuc_timings *) malloc (sizeof (cuc_timings) * nt));
              (cuc_timings *) malloc (sizeof (cuc_timings) * nt));
 
 
      /* Copy options in reverse order -- smallest first */
      /* Copy options in reverse order -- smallest first */
      for (i = 0; i < nt; i++)
      for (i = 0; i < nt; i++)
        saved->bb[b].tim[i] = t[nt - 1 - i];
        saved->bb[b].tim[i] = t[nt - 1 - i];
 
 
      log ("Available options:\n");
      log ("Available options:\n");
      for (i = 0; i < saved->bb[b].ntim; i++)
      for (i = 0; i < saved->bb[b].ntim; i++)
        {
        {
          log ("%i:pre%i,un%i,sha%i: %icyc %.1f\n",
          log ("%i:pre%i,un%i,sha%i: %icyc %.1f\n",
               saved->bb[b].tim[i].b, saved->bb[b].tim[i].preroll,
               saved->bb[b].tim[i].b, saved->bb[b].tim[i].preroll,
               saved->bb[b].tim[i].unroll, saved->bb[b].tim[i].nshared,
               saved->bb[b].tim[i].unroll, saved->bb[b].tim[i].nshared,
               saved->bb[b].tim[i].new_time, saved->bb[b].tim[i].size);
               saved->bb[b].tim[i].new_time, saved->bb[b].tim[i].size);
        }
        }
    }
    }
#endif
#endif
  return saved;
  return saved;
}
}
 
 
/* Utility option formatting functions */
/* Utility option formatting functions */
static const char *option_char =
static const char *option_char =
  "?abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
  "?abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
 
 
/*static */ char *
/*static */ char *
gen_option (char *s, int bb_no, int f_opt)
gen_option (char *s, int bb_no, int f_opt)
{
{
  if (bb_no >= 0)
  if (bb_no >= 0)
    sprintf (s, "%i", bb_no);
    sprintf (s, "%i", bb_no);
  assert (f_opt <= strlen (option_char));
  assert (f_opt <= strlen (option_char));
  sprintf (s, "%s%c", s, option_char[f_opt]);
  sprintf (s, "%s%c", s, option_char[f_opt]);
  return s;
  return s;
}
}
 
 
/*static */ void
/*static */ void
print_option (int bb_no, int f_opt)
print_option (int bb_no, int f_opt)
{
{
  char tmp1[10];
  char tmp1[10];
  char tmp2[10];
  char tmp2[10];
  sprintf (tmp2, "%s", gen_option (tmp1, bb_no, f_opt));
  sprintf (tmp2, "%s", gen_option (tmp1, bb_no, f_opt));
  PRINTF ("%3s", tmp2);
  PRINTF ("%3s", tmp2);
}
}
 
 
static char *
static char *
format_func_options (char *s, cuc_func * f)
format_func_options (char *s, cuc_func * f)
{
{
  int b, first = 1;
  int b, first = 1;
  *s = '\0';
  *s = '\0';
  for (b = 0; b < f->num_bb; b++)
  for (b = 0; b < f->num_bb; b++)
    if (f->bb[b].selected_tim >= 0)
    if (f->bb[b].selected_tim >= 0)
      {
      {
        char tmp[10];
        char tmp[10];
        sprintf (s, "%s%s%s", s, first ? "" : ",",
        sprintf (s, "%s%s%s", s, first ? "" : ",",
                 gen_option (tmp, b, f->bb[b].selected_tim));
                 gen_option (tmp, b, f->bb[b].selected_tim));
        first = 0;
        first = 0;
      }
      }
  return s;
  return s;
}
}
 
 
static void
static void
options_cmd (int func_no, cuc_func * f)
options_cmd (int func_no, cuc_func * f)
{
{
  int b, i;
  int b, i;
  char tmp[30];
  char tmp[30];
  char *name = prof_func[func_no].name;
  char *name = prof_func[func_no].name;
  PRINTF
  PRINTF
    ("-----------------------------------------------------------------------------\n");
    ("-----------------------------------------------------------------------------\n");
  PRINTF ("|%-28s|pre/unrolled|shared|  time  |  gates |old_time|\n",
  PRINTF ("|%-28s|pre/unrolled|shared|  time  |  gates |old_time|\n",
          strstrip (tmp, name, 28));
          strstrip (tmp, name, 28));
  PRINTF ("|                    BASE    |%4i / %4i | %4i |%8i|%8.f|%8i|\n", 1,
  PRINTF ("|                    BASE    |%4i / %4i | %4i |%8i|%8.f|%8i|\n", 1,
          1, 0, f->timings.new_time, f->timings.size, f->orig_time);
          1, 0, f->timings.new_time, f->timings.size, f->orig_time);
  for (b = 0; b < f->num_bb; b++)
  for (b = 0; b < f->num_bb; b++)
    {
    {
      /* Print out results */
      /* Print out results */
      for (i = 1; i < f->bb[b].ntim; i++)
      for (i = 1; i < f->bb[b].ntim; i++)
        {                       /* First one is base option */
        {                       /* First one is base option */
          int time = f->bb[b].tim[i].new_time - f->timings.new_time;
          int time = f->bb[b].tim[i].new_time - f->timings.new_time;
          double size = f->bb[b].tim[i].size - f->timings.size;
          double size = f->bb[b].tim[i].size - f->timings.size;
          PRINTF ("|                   ");
          PRINTF ("|                   ");
          print_option (b, i);
          print_option (b, i);
          PRINTF ("      |%4i / %4i | %4i |%+8i|%+8.f|        |\n",
          PRINTF ("      |%4i / %4i | %4i |%+8i|%+8.f|        |\n",
                  f->bb[b].tim[i].preroll, f->bb[b].tim[i].unroll,
                  f->bb[b].tim[i].preroll, f->bb[b].tim[i].unroll,
                  f->bb[b].tim[i].nshared, time, size);
                  f->bb[b].tim[i].nshared, time, size);
        }
        }
    }
    }
}
}
 
 
/* Generates a function, based on specified parameters */
/* Generates a function, based on specified parameters */
cuc_func *
cuc_func *
generate_function (cuc_func * rf, char *name, char *cut_filename)
generate_function (cuc_func * rf, char *name, char *cut_filename)
{
{
  int b;
  int b;
  char tmp[256];
  char tmp[256];
  cuc_timings tt;
  cuc_timings tt;
  cuc_func *f;
  cuc_func *f;
  assert (f = dup_func (rf));
  assert (f = dup_func (rf));
 
 
  if (cuc_debug >= 2)
  if (cuc_debug >= 2)
    print_cuc_bb (f, "BEFORE_GENERATE");
    print_cuc_bb (f, "BEFORE_GENERATE");
  log ("Generating function %s.\n", name);
  log ("Generating function %s.\n", name);
  PRINTF ("Generating function %s.\n", name);
  PRINTF ("Generating function %s.\n", name);
 
 
  format_func_options (tmp, rf);
  format_func_options (tmp, rf);
  if (strlen (tmp))
  if (strlen (tmp))
    PRINTF ("Applying options: %s\n", tmp);
    PRINTF ("Applying options: %s\n", tmp);
  else
  else
    PRINTF ("Using basic options.\n");
    PRINTF ("Using basic options.\n");
 
 
  /* Generate function as specified by options */
  /* Generate function as specified by options */
  for (b = 0; b < f->num_bb; b++)
  for (b = 0; b < f->num_bb; b++)
    {
    {
      cuc_timings *st;
      cuc_timings *st;
      if (rf->bb[b].selected_tim < 0)
      if (rf->bb[b].selected_tim < 0)
        continue;
        continue;
      st = &rf->bb[b].tim[rf->bb[b].selected_tim];
      st = &rf->bb[b].tim[rf->bb[b].selected_tim];
      sprintf (tmp, "%s.bin.bb", name);
      sprintf (tmp, "%s.bin.bb", name);
      preunroll_bb (&tmp[0], f, &tt, b, st->preroll, st->unroll);
      preunroll_bb (&tmp[0], f, &tt, b, st->preroll, st->unroll);
      if (cuc_debug >= 1)
      if (cuc_debug >= 1)
        print_cuc_bb (f, "AFTER_PREUNROLL");
        print_cuc_bb (f, "AFTER_PREUNROLL");
    }
    }
  for (b = 0; b < f->num_bb; b++)
  for (b = 0; b < f->num_bb; b++)
    {
    {
      cuc_timings *st;
      cuc_timings *st;
      if (rf->bb[b].selected_tim < 0)
      if (rf->bb[b].selected_tim < 0)
        continue;
        continue;
      st = &rf->bb[b].tim[rf->bb[b].selected_tim];
      st = &rf->bb[b].tim[rf->bb[b].selected_tim];
      if (!st->nshared)
      if (!st->nshared)
        continue;
        continue;
      assert (0);
      assert (0);
      //csm_gen (f, rf, st->nshared, st->shared);
      //csm_gen (f, rf, st->nshared, st->shared);
    }
    }
  add_latches (f);
  add_latches (f);
  if (cuc_debug >= 1)
  if (cuc_debug >= 1)
    print_cuc_bb (f, "AFTER_LATCHES");
    print_cuc_bb (f, "AFTER_LATCHES");
  analyse_timings (f, &tt);
  analyse_timings (f, &tt);
 
 
  sprintf (tmp, "%s%s", cut_filename, name);
  sprintf (tmp, "%s%s", cut_filename, name);
  output_verilog (f, tmp, name);
  output_verilog (f, tmp, name);
  return f;
  return f;
}
}
 
 
/* Calculates required time, based on selected options */
/* Calculates required time, based on selected options */
int
int
calc_cycles (cuc_func * f)
calc_cycles (cuc_func * f)
{
{
  int b, ntime = f->timings.new_time;
  int b, ntime = f->timings.new_time;
  for (b = 0; b < f->num_bb; b++)
  for (b = 0; b < f->num_bb; b++)
    if (f->bb[b].selected_tim >= 0)
    if (f->bb[b].selected_tim >= 0)
      {
      {
        assert (f->bb[b].selected_tim < f->bb[b].ntim);
        assert (f->bb[b].selected_tim < f->bb[b].ntim);
        ntime +=
        ntime +=
          f->bb[b].tim[f->bb[b].selected_tim].new_time - f->timings.new_time;
          f->bb[b].tim[f->bb[b].selected_tim].new_time - f->timings.new_time;
      }
      }
  return ntime;
  return ntime;
}
}
 
 
/* Calculates required size, based on selected options */
/* Calculates required size, based on selected options */
double
double
calc_size (cuc_func * f)
calc_size (cuc_func * f)
{
{
  int b;
  int b;
  double size = f->timings.size;
  double size = f->timings.size;
  for (b = 0; b < f->num_bb; b++)
  for (b = 0; b < f->num_bb; b++)
    if (f->bb[b].selected_tim >= 0)
    if (f->bb[b].selected_tim >= 0)
      {
      {
        assert (f->bb[b].selected_tim < f->bb[b].ntim);
        assert (f->bb[b].selected_tim < f->bb[b].ntim);
        size += f->bb[b].tim[f->bb[b].selected_tim].size - f->timings.size;
        size += f->bb[b].tim[f->bb[b].selected_tim].size - f->timings.size;
      }
      }
  return size;
  return size;
}
}
 
 
/* Dumps specified function to file (hex) */
/* Dumps specified function to file (hex) */
unsigned long
unsigned long
extract_function (char *out_fn, unsigned long start_addr)
extract_function (char *out_fn, unsigned long start_addr)
{
{
  FILE *fo;
  FILE *fo;
  unsigned long a = start_addr;
  unsigned long a = start_addr;
  int x = 0;
  int x = 0;
  assert (fo = fopen (out_fn, "wt+"));
  assert (fo = fopen (out_fn, "wt+"));
 
 
  do
  do
    {
    {
      unsigned long d = eval_direct32 (a, 0, 0);
      unsigned long d = eval_direct32 (a, 0, 0);
      int index = insn_decode (d);
      int index = insn_decode (d);
      assert (index >= 0);
      assert (index >= 0);
      if (x)
      if (x)
        x++;
        x++;
      if (strcmp (insn_name (index), "l.jr") == 0)
      if (strcmp (insn_name (index), "l.jr") == 0)
        x = 1;
        x = 1;
      a += 4;
      a += 4;
      fprintf (fo, "%08lx\n", d);
      fprintf (fo, "%08lx\n", d);
    }
    }
  while (x < 2);
  while (x < 2);
 
 
  fclose (fo);
  fclose (fo);
  return a - 4;
  return a - 4;
}
}
 
 
static cuc_func *func[MAX_FUNCS];
static cuc_func *func[MAX_FUNCS];
static int func_v[MAX_FUNCS];
static int func_v[MAX_FUNCS];
 
 
/* Detects function dependencies and removes  */
/* Detects function dependencies and removes  */
static void
static void
set_func_deps ()
set_func_deps ()
{
{
  int f, b, i, j;
  int f, b, i, j;
restart:
restart:
  for (f = 0; f < prof_nfuncs - 1; f++)
  for (f = 0; f < prof_nfuncs - 1; f++)
    if (func[f])
    if (func[f])
      {
      {
        int fused[MAX_FUNCS] = { 0 };
        int fused[MAX_FUNCS] = { 0 };
        int c = 0;
        int c = 0;
        for (b = 0; b < func[f]->num_bb; b++)
        for (b = 0; b < func[f]->num_bb; b++)
          for (i = 0; i < func[f]->bb[b].ninsn; i++)
          for (i = 0; i < func[f]->bb[b].ninsn; i++)
            {
            {
              cuc_insn *ii = &func[f]->bb[b].insn[i];
              cuc_insn *ii = &func[f]->bb[b].insn[i];
              if (ii->index == II_CALL)
              if (ii->index == II_CALL)
                {
                {
                  assert (ii->opt[0] == OPT_CONST);
                  assert (ii->opt[0] == OPT_CONST);
                  for (j = 0; j < prof_nfuncs - 1; j++)
                  for (j = 0; j < prof_nfuncs - 1; j++)
                    if (func[j] && func[j]->start_addr == ii->op[0])
                    if (func[j] && func[j]->start_addr == ii->op[0])
                      break;
                      break;
                  if (j >= prof_nfuncs - 1)
                  if (j >= prof_nfuncs - 1)
                    {
                    {
                      log ("%s is calling unknown function, address %08lx\n",
                      log ("%s is calling unknown function, address %08lx\n",
                           prof_func[f].name, ii->op[0]);
                           prof_func[f].name, ii->op[0]);
                      debug (1,
                      debug (1,
                             "%s is calling unknown function, address %08lx\n",
                             "%s is calling unknown function, address %08lx\n",
                             prof_func[f].name, ii->op[0]);
                             prof_func[f].name, ii->op[0]);
                      free_func (func[f]);
                      free_func (func[f]);
                      func[f] = NULL;
                      func[f] = NULL;
                      goto restart;
                      goto restart;
                    }
                    }
                  else if (f == j)
                  else if (f == j)
                    {
                    {
                      log ("%s is recursive, ignoring\n", prof_func[f].name);
                      log ("%s is recursive, ignoring\n", prof_func[f].name);
                      debug (1, "%s is recursive, ignoring\n",
                      debug (1, "%s is recursive, ignoring\n",
                             prof_func[f].name);
                             prof_func[f].name);
                      free_func (func[f]);
                      free_func (func[f]);
                      func[f] = NULL;
                      func[f] = NULL;
                      goto restart;
                      goto restart;
                    }
                    }
                  else
                  else
                    fused[j]++;
                    fused[j]++;
                }
                }
            }
            }
        for (i = 0; i < MAX_FUNCS; i++)
        for (i = 0; i < MAX_FUNCS; i++)
          if (fused[i])
          if (fused[i])
            c++;
            c++;
        if (func[f]->nfdeps)
        if (func[f]->nfdeps)
          free (func[f]->fdeps);
          free (func[f]->fdeps);
        func[f]->nfdeps = c;
        func[f]->nfdeps = c;
        func[f]->fdeps = (cuc_func **) malloc (sizeof (cuc_func *) * c);
        func[f]->fdeps = (cuc_func **) malloc (sizeof (cuc_func *) * c);
        for (i = 0, j = 0; i < MAX_FUNCS; i++)
        for (i = 0, j = 0; i < MAX_FUNCS; i++)
          if (fused[i])
          if (fused[i])
            func[f]->fdeps[j++] = func[i];
            func[f]->fdeps[j++] = func[i];
      }
      }
 
 
  /* Detect loops */
  /* Detect loops */
  {
  {
    int change;
    int change;
    for (f = 0; f < MAX_FUNCS; f++)
    for (f = 0; f < MAX_FUNCS; f++)
      if (func[f])
      if (func[f])
        func[f]->tmp = 0;
        func[f]->tmp = 0;
    do
    do
      {
      {
        change = 0;
        change = 0;
        for (f = 0; f < MAX_FUNCS; f++)
        for (f = 0; f < MAX_FUNCS; f++)
          if (func[f] && !func[f]->tmp)
          if (func[f] && !func[f]->tmp)
            {
            {
              int o = 1;
              int o = 1;
              for (i = 0; i < func[f]->nfdeps; i++)
              for (i = 0; i < func[f]->nfdeps; i++)
                if (!func[f]->fdeps[i]->tmp)
                if (!func[f]->fdeps[i]->tmp)
                  {
                  {
                    o = 0;
                    o = 0;
                    break;
                    break;
                  }
                  }
              if (o)
              if (o)
                {
                {
                  func[f]->tmp = 1;
                  func[f]->tmp = 1;
                  change = 1;
                  change = 1;
                }
                }
            }
            }
      }
      }
    while (change);
    while (change);
 
 
    change = 0;
    change = 0;
    for (f = 0; f < MAX_FUNCS; f++)
    for (f = 0; f < MAX_FUNCS; f++)
      if (func[f] && !func[f]->tmp)
      if (func[f] && !func[f]->tmp)
        {
        {
          free_func (func[f]);
          free_func (func[f]);
          func[f] = NULL;
          func[f] = NULL;
          change = 1;
          change = 1;
        }
        }
    if (change)
    if (change)
      goto restart;
      goto restart;
  }
  }
}
}
 
 
void
void
main_cuc (char *filename)
main_cuc (char *filename)
{
{
  int i, j;
  int i, j;
  char tmp1[256];
  char tmp1[256];
  char filename_cut[256];
  char filename_cut[256];
#if 0                           /* Select prefix, based on binary program name */
#if 0                           /* Select prefix, based on binary program name */
  for (i = 0; i < sizeof (filename_cut); i++)
  for (i = 0; i < sizeof (filename_cut); i++)
    {
    {
      if (isalpha (filename[i]))
      if (isalpha (filename[i]))
        filename_cut[i] = filename[i];
        filename_cut[i] = filename[i];
      else
      else
        {
        {
          filename_cut[i] = '\0';
          filename_cut[i] = '\0';
          break;
          break;
        }
        }
    }
    }
#else
#else
  strcpy (filename_cut, "cu");
  strcpy (filename_cut, "cu");
#endif
#endif
 
 
  PRINTF ("Entering OpenRISC Custom Unit Compiler command prompt\n");
  PRINTF ("Entering OpenRISC Custom Unit Compiler command prompt\n");
  PRINTF ("Using profile file \"%s\" and memory profile file \"%s\".\n",
  PRINTF ("Using profile file \"%s\" and memory profile file \"%s\".\n",
          config.sim.prof_fn, config.sim.mprof_fn);
          config.sim.prof_fn, config.sim.mprof_fn);
  sprintf (tmp1, "%s.log", filename_cut);
  sprintf (tmp1, "%s.log", filename_cut);
  PRINTF ("Analyzing. (log file \"%s\").\n", tmp1);
  PRINTF ("Analyzing. (log file \"%s\").\n", tmp1);
  assert (flog = fopen (tmp1, "wt+"));
  assert (flog = fopen (tmp1, "wt+"));
 
 
  /* Loads in the specified timings table */
  /* Loads in the specified timings table */
  PRINTF ("Using timings from \"%s\" at %s\n", config.cuc.timings_fn,
  PRINTF ("Using timings from \"%s\" at %s\n", config.cuc.timings_fn,
          generate_time_pretty (tmp1, config.sim.clkcycle_ps));
          generate_time_pretty (tmp1, config.sim.clkcycle_ps));
  load_timing_table (config.cuc.timings_fn);
  load_timing_table (config.cuc.timings_fn);
  runtime.cuc.cycle_duration = 1000. * config.sim.clkcycle_ps;
  runtime.cuc.cycle_duration = 1000. * config.sim.clkcycle_ps;
  PRINTF ("Multicycle logic %s, bursts %s, %s memory order.\n",
  PRINTF ("Multicycle logic %s, bursts %s, %s memory order.\n",
          config.cuc.no_multicycle ? "OFF" : "ON",
          config.cuc.no_multicycle ? "OFF" : "ON",
          config.cuc.enable_bursts ? "ON" : "OFF",
          config.cuc.enable_bursts ? "ON" : "OFF",
          config.cuc.memory_order ==
          config.cuc.memory_order ==
          MO_NONE ? "no" : config.cuc.memory_order ==
          MO_NONE ? "no" : config.cuc.memory_order ==
          MO_WEAK ? "weak" : config.cuc.memory_order ==
          MO_WEAK ? "weak" : config.cuc.memory_order ==
          MO_STRONG ? "strong" : "exact");
          MO_STRONG ? "strong" : "exact");
 
 
  prof_set (1, 0);
  prof_set (1, 0);
  assert (prof_acquire (config.sim.prof_fn) == 0);
  assert (prof_acquire (config.sim.prof_fn) == 0);
 
 
  if (config.cuc.calling_convention)
  if (config.cuc.calling_convention)
    PRINTF ("Assuming OpenRISC standard calling convention.\n");
    PRINTF ("Assuming OpenRISC standard calling convention.\n");
 
 
  /* Try all functions except "total" */
  /* Try all functions except "total" */
  for (i = 0; i < prof_nfuncs - 1; i++)
  for (i = 0; i < prof_nfuncs - 1; i++)
    {
    {
      long orig_time;
      long orig_time;
      unsigned long start_addr, end_addr;
      unsigned long start_addr, end_addr;
      orig_time = prof_func[i].cum_cycles;
      orig_time = prof_func[i].cum_cycles;
      start_addr = prof_func[i].addr;
      start_addr = prof_func[i].addr;
 
 
      /* Extract the function from the binary */
      /* Extract the function from the binary */
      sprintf (tmp1, "%s.bin", prof_func[i].name);
      sprintf (tmp1, "%s.bin", prof_func[i].name);
      end_addr = extract_function (tmp1, start_addr);
      end_addr = extract_function (tmp1, start_addr);
 
 
      log ("Testing function %s (%08lx - %08lx)\n", prof_func[i].name,
      log ("Testing function %s (%08lx - %08lx)\n", prof_func[i].name,
           start_addr, end_addr);
           start_addr, end_addr);
      PRINTF ("Testing function %s (%08lx - %08lx)\n", prof_func[i].name,
      PRINTF ("Testing function %s (%08lx - %08lx)\n", prof_func[i].name,
              start_addr, end_addr);
              start_addr, end_addr);
      func[i] =
      func[i] =
        analyse_function (prof_func[i].name, orig_time, start_addr, end_addr,
        analyse_function (prof_func[i].name, orig_time, start_addr, end_addr,
                          config.cuc.memory_order, prof_func[i].calls);
                          config.cuc.memory_order, prof_func[i].calls);
      func_v[i] = 0;
      func_v[i] = 0;
    }
    }
  set_func_deps ();
  set_func_deps ();
 
 
  while (1)
  while (1)
    {
    {
      char *s;
      char *s;
    wait_command:
    wait_command:
      PRINTF ("(cuc) ");
      PRINTF ("(cuc) ");
      fflush (stdout);
      fflush (stdout);
    wait_command_empty:
    wait_command_empty:
      s = fgets (tmp1, sizeof tmp1, stdin);
      s = fgets (tmp1, sizeof tmp1, stdin);
      usleep (100);
      usleep (100);
      if (!s)
      if (!s)
        goto wait_command_empty;
        goto wait_command_empty;
      for (s = tmp1; *s != '\0' && *s != '\n' && *s != '\r'; s++);
      for (s = tmp1; *s != '\0' && *s != '\n' && *s != '\r'; s++);
      *s = '\0';
      *s = '\0';
 
 
      /* quit command */
      /* quit command */
      if (strcmp (tmp1, "q") == 0 || strcmp (tmp1, "quit") == 0)
      if (strcmp (tmp1, "q") == 0 || strcmp (tmp1, "quit") == 0)
        {
        {
          /* Delete temporary files */
          /* Delete temporary files */
          for (i = 0; i < prof_nfuncs - 1; i++)
          for (i = 0; i < prof_nfuncs - 1; i++)
            {
            {
              sprintf (tmp1, "%s.bin", prof_func[i].name);
              sprintf (tmp1, "%s.bin", prof_func[i].name);
              log ("Deleting temporary file %s %s\n", tmp1,
              log ("Deleting temporary file %s %s\n", tmp1,
                   remove (tmp1) ? "FAILED" : "OK");
                   remove (tmp1) ? "FAILED" : "OK");
              sprintf (tmp1, "%s.bin.bb", prof_func[i].name);
              sprintf (tmp1, "%s.bin.bb", prof_func[i].name);
              log ("Deleting temporary file %s %s\n", tmp1,
              log ("Deleting temporary file %s %s\n", tmp1,
                   remove (tmp1) ? "FAILED" : "OK");
                   remove (tmp1) ? "FAILED" : "OK");
            }
            }
          break;
          break;
 
 
          /* profile command */
          /* profile command */
        }
        }
      else if (strcmp (tmp1, "p") == 0 || strcmp (tmp1, "profile") == 0)
      else if (strcmp (tmp1, "p") == 0 || strcmp (tmp1, "profile") == 0)
        {
        {
          int ntime = 0;
          int ntime = 0;
          int size = 0;
          int size = 0;
          PRINTF
          PRINTF
            ("-----------------------------------------------------------------------------\n");
            ("-----------------------------------------------------------------------------\n");
          PRINTF
          PRINTF
            ("|function name       |calls|avg cycles  |old%%| max. f.  | impr. f.| options |\n");
            ("|function name       |calls|avg cycles  |old%%| max. f.  | impr. f.| options |\n");
          PRINTF
          PRINTF
            ("|--------------------+-----+------------+----+----------|---------+---------|\n");
            ("|--------------------+-----+------------+----+----------|---------+---------|\n");
          for (j = 0; j < prof_nfuncs; j++)
          for (j = 0; j < prof_nfuncs; j++)
            {
            {
              int bestcyc = 0, besti = 0;
              int bestcyc = 0, besti = 0;
              char tmp[100];
              char tmp[100];
              for (i = 0; i < prof_nfuncs; i++)
              for (i = 0; i < prof_nfuncs; i++)
                if (prof_func[i].cum_cycles > bestcyc)
                if (prof_func[i].cum_cycles > bestcyc)
                  {
                  {
                    bestcyc = prof_func[i].cum_cycles;
                    bestcyc = prof_func[i].cum_cycles;
                    besti = i;
                    besti = i;
                  }
                  }
              i = besti;
              i = besti;
              PRINTF ("|%-20s|%5li|%12.1f|%3.0f%%| ",
              PRINTF ("|%-20s|%5li|%12.1f|%3.0f%%| ",
                      strstrip (tmp, prof_func[i].name, 20),
                      strstrip (tmp, prof_func[i].name, 20),
                      prof_func[i].calls,
                      prof_func[i].calls,
                      ((double) prof_func[i].cum_cycles / prof_func[i].calls),
                      ((double) prof_func[i].cum_cycles / prof_func[i].calls),
                      (100. * prof_func[i].cum_cycles / prof_cycles));
                      (100. * prof_func[i].cum_cycles / prof_cycles));
              if (func[i])
              if (func[i])
                {
                {
                  double f = 1.0;
                  double f = 1.0;
                  if (func_v[i])
                  if (func_v[i])
                    {
                    {
                      int nt = calc_cycles (func[i]);
                      int nt = calc_cycles (func[i]);
                      int s = calc_size (func[i]);
                      int s = calc_size (func[i]);
                      f = 1. * func[i]->orig_time / nt;
                      f = 1. * func[i]->orig_time / nt;
                      ntime += nt;
                      ntime += nt;
                      size += s;
                      size += s;
                    }
                    }
                  else
                  else
                    ntime += prof_func[i].cum_cycles;
                    ntime += prof_func[i].cum_cycles;
                  PRINTF ("%8.1f |%8.1f | %-8s|\n",
                  PRINTF ("%8.1f |%8.1f | %-8s|\n",
                          1.f * prof_func[i].cum_cycles /
                          1.f * prof_func[i].cum_cycles /
                          func[i]->timings.new_time, f,
                          func[i]->timings.new_time, f,
                          format_func_options (tmp, func[i]));
                          format_func_options (tmp, func[i]));
                }
                }
              else
              else
                {
                {
                  PRINTF ("     N/A |     N/A |     N/A |\n");
                  PRINTF ("     N/A |     N/A |     N/A |\n");
                  ntime += prof_func[i].cum_cycles;
                  ntime += prof_func[i].cum_cycles;
                }
                }
              prof_func[i].cum_cycles = -prof_func[i].cum_cycles;
              prof_func[i].cum_cycles = -prof_func[i].cum_cycles;
            }
            }
          for (i = 0; i < prof_nfuncs; i++)
          for (i = 0; i < prof_nfuncs; i++)
            prof_func[i].cum_cycles = -prof_func[i].cum_cycles;
            prof_func[i].cum_cycles = -prof_func[i].cum_cycles;
          PRINTF
          PRINTF
            ("-----------------------------------------------------------------------------\n");
            ("-----------------------------------------------------------------------------\n");
          PRINTF
          PRINTF
            ("Total %i cycles (was %i), total added gates = %i. Speed factor %.1f\n",
            ("Total %i cycles (was %i), total added gates = %i. Speed factor %.1f\n",
             ntime, prof_cycles, size, 1. * prof_cycles / ntime);
             ntime, prof_cycles, size, 1. * prof_cycles / ntime);
 
 
          /* debug command */
          /* debug command */
        }
        }
      else if (strncmp (tmp1, "d", 1) == 0 || strncmp (tmp1, "debug", 5) == 0)
      else if (strncmp (tmp1, "d", 1) == 0 || strncmp (tmp1, "debug", 5) == 0)
        {
        {
          sscanf (tmp1, "%*s %i", &cuc_debug);
          sscanf (tmp1, "%*s %i", &cuc_debug);
          if (cuc_debug < 0)
          if (cuc_debug < 0)
            cuc_debug = 0;
            cuc_debug = 0;
          if (cuc_debug > 9)
          if (cuc_debug > 9)
            cuc_debug = 9;
            cuc_debug = 9;
 
 
          /* generate command */
          /* generate command */
        }
        }
      else if (strcmp (tmp1, "g") == 0 || strcmp (tmp1, "generate") == 0)
      else if (strcmp (tmp1, "g") == 0 || strcmp (tmp1, "generate") == 0)
        {
        {
          /* check for function dependencies */
          /* check for function dependencies */
          for (i = 0; i < prof_nfuncs; i++)
          for (i = 0; i < prof_nfuncs; i++)
            if (func[i])
            if (func[i])
              func[i]->tmp = func_v[i];
              func[i]->tmp = func_v[i];
          for (i = 0; i < prof_nfuncs; i++)
          for (i = 0; i < prof_nfuncs; i++)
            if (func[i])
            if (func[i])
              for (j = 0; j < func[i]->nfdeps; j++)
              for (j = 0; j < func[i]->nfdeps; j++)
                if (!func[i]->fdeps[j] || !func[i]->fdeps[j]->tmp)
                if (!func[i]->fdeps[j] || !func[i]->fdeps[j]->tmp)
                  {
                  {
                    PRINTF
                    PRINTF
                      ("Function %s must be selected for translation (required by %s)\n",
                      ("Function %s must be selected for translation (required by %s)\n",
                       prof_func[j].name, prof_func[i].name);
                       prof_func[j].name, prof_func[i].name);
                    goto wait_command;
                    goto wait_command;
                  }
                  }
          for (i = 0; i < prof_nfuncs; i++)
          for (i = 0; i < prof_nfuncs; i++)
            if (func[i] && func_v[i])
            if (func[i] && func_v[i])
              generate_function (func[i], prof_func[i].name, filename_cut);
              generate_function (func[i], prof_func[i].name, filename_cut);
          generate_main (prof_nfuncs, func, filename_cut);
          generate_main (prof_nfuncs, func, filename_cut);
 
 
          /* list command */
          /* list command */
        }
        }
      else if (strcmp (tmp1, "l") == 0 || strcmp (tmp1, "list") == 0)
      else if (strcmp (tmp1, "l") == 0 || strcmp (tmp1, "list") == 0)
        {
        {
          /* check for function dependencies */
          /* check for function dependencies */
          for (i = 0; i < prof_nfuncs; i++)
          for (i = 0; i < prof_nfuncs; i++)
            if (func_v[i])
            if (func_v[i])
              {
              {
                PRINTF ("%s\n", prof_func[i].name);
                PRINTF ("%s\n", prof_func[i].name);
              }
              }
 
 
          /* selectall command */
          /* selectall command */
        }
        }
      else if (strcmp (tmp1, "sa") == 0 || strcmp (tmp1, "selectall") == 0)
      else if (strcmp (tmp1, "sa") == 0 || strcmp (tmp1, "selectall") == 0)
        {
        {
          int f;
          int f;
          for (f = 0; f < prof_nfuncs; f++)
          for (f = 0; f < prof_nfuncs; f++)
            if (func[f])
            if (func[f])
              {
              {
                func_v[f] = 1;
                func_v[f] = 1;
                PRINTF ("Function %s selected for translation.\n",
                PRINTF ("Function %s selected for translation.\n",
                        prof_func[f].name);
                        prof_func[f].name);
              }
              }
 
 
          /* select command */
          /* select command */
        }
        }
      else if (strncmp (tmp1, "s", 1) == 0
      else if (strncmp (tmp1, "s", 1) == 0
               || strncmp (tmp1, "select", 6) == 0)
               || strncmp (tmp1, "select", 6) == 0)
        {
        {
          char tmp[50], ch;
          char tmp[50], ch;
          int p, o, b, f;
          int p, o, b, f;
          p = sscanf (tmp1, "%*s %s %i%c", tmp, &b, &ch);
          p = sscanf (tmp1, "%*s %s %i%c", tmp, &b, &ch);
          if (p < 1)
          if (p < 1)
            PRINTF ("Invalid parameters.\n");
            PRINTF ("Invalid parameters.\n");
          else
          else
            {
            {
              /* Check if we have valid option */
              /* Check if we have valid option */
              for (f = 0; f < prof_nfuncs; f++)
              for (f = 0; f < prof_nfuncs; f++)
                if (strcmp (prof_func[f].name, tmp) == 0 && func[f])
                if (strcmp (prof_func[f].name, tmp) == 0 && func[f])
                  break;
                  break;
              if (f < prof_nfuncs)
              if (f < prof_nfuncs)
                {
                {
                  if (p == 1)
                  if (p == 1)
                    {
                    {
                      if (func[f])
                      if (func[f])
                        {
                        {
                          func_v[f] = 1;
                          func_v[f] = 1;
                          PRINTF ("Function %s selected for translation.\n",
                          PRINTF ("Function %s selected for translation.\n",
                                  prof_func[f].name);
                                  prof_func[f].name);
                        }
                        }
                      else
                      else
                        PRINTF ("Function %s not suitable for translation.\n",
                        PRINTF ("Function %s not suitable for translation.\n",
                                prof_func[f].name);
                                prof_func[f].name);
                    }
                    }
                  else
                  else
                    {
                    {
                      if (!func_v[f])
                      if (!func_v[f])
                        PRINTF
                        PRINTF
                          ("Function %s not yet selected for translation.\n",
                          ("Function %s not yet selected for translation.\n",
                           prof_func[f].name);
                           prof_func[f].name);
                      if (p < 3)
                      if (p < 3)
                        goto invalid_option;
                        goto invalid_option;
                      for (o = 0;
                      for (o = 0;
                           option_char[o] != '\0' && option_char[o] != ch;
                           option_char[o] != '\0' && option_char[o] != ch;
                           o++);
                           o++);
                      if (!option_char[o])
                      if (!option_char[o])
                        goto invalid_option;
                        goto invalid_option;
                      if (b < 0 || b >= func[f]->num_bb)
                      if (b < 0 || b >= func[f]->num_bb)
                        goto invalid_option;
                        goto invalid_option;
                      if (o < 0 || o >= func[f]->bb[b].ntim)
                      if (o < 0 || o >= func[f]->bb[b].ntim)
                        goto invalid_option;
                        goto invalid_option;
 
 
                      /* select an option */
                      /* select an option */
                      func[f]->bb[b].selected_tim = o;
                      func[f]->bb[b].selected_tim = o;
                      if (func[f]->bb[b].tim[o].nshared)
                      if (func[f]->bb[b].tim[o].nshared)
                        {
                        {
                          PRINTF ("Option has shared instructions: ");
                          PRINTF ("Option has shared instructions: ");
                          print_shared (func[f], func[f]->bb[b].tim[o].shared,
                          print_shared (func[f], func[f]->bb[b].tim[o].shared,
                                        func[f]->bb[b].tim[o].nshared);
                                        func[f]->bb[b].tim[o].nshared);
                          PRINTF ("\n");
                          PRINTF ("\n");
                        }
                        }
                      goto wait_command;
                      goto wait_command;
                    invalid_option:
                    invalid_option:
                      PRINTF ("Invalid option.\n");
                      PRINTF ("Invalid option.\n");
                    }
                    }
                }
                }
              else
              else
                PRINTF ("Invalid function.\n");
                PRINTF ("Invalid function.\n");
            }
            }
 
 
          /* unselect command */
          /* unselect command */
        }
        }
      else if (strncmp (tmp1, "u", 1) == 0
      else if (strncmp (tmp1, "u", 1) == 0
               || strncmp (tmp1, "unselect", 8) == 0)
               || strncmp (tmp1, "unselect", 8) == 0)
        {
        {
          char tmp[50], ch;
          char tmp[50], ch;
          int p, o, b, f;
          int p, o, b, f;
          p = sscanf (tmp1, "%*s %s %i%c", tmp, &b, &ch);
          p = sscanf (tmp1, "%*s %s %i%c", tmp, &b, &ch);
          if (p < 1)
          if (p < 1)
            PRINTF ("Invalid parameters.\n");
            PRINTF ("Invalid parameters.\n");
          else
          else
            {
            {
              /* Check if we have valid option */
              /* Check if we have valid option */
              for (f = 0; f < prof_nfuncs; f++)
              for (f = 0; f < prof_nfuncs; f++)
                if (strcmp (prof_func[f].name, tmp) == 0 && func[f])
                if (strcmp (prof_func[f].name, tmp) == 0 && func[f])
                  break;
                  break;
              if (f < prof_nfuncs)
              if (f < prof_nfuncs)
                {
                {
                  if (p == 1)
                  if (p == 1)
                    {
                    {
                      if (func[f])
                      if (func[f])
                        {
                        {
                          func_v[f] = 0;
                          func_v[f] = 0;
                          PRINTF ("Function %s unselected for translation.\n",
                          PRINTF ("Function %s unselected for translation.\n",
                                  prof_func[f].name);
                                  prof_func[f].name);
                        }
                        }
                      else
                      else
                        PRINTF ("Function %s not suitable for translation.\n",
                        PRINTF ("Function %s not suitable for translation.\n",
                                prof_func[f].name);
                                prof_func[f].name);
                    }
                    }
                  else
                  else
                    {
                    {
                      if (p < 3)
                      if (p < 3)
                        goto invalid_option;
                        goto invalid_option;
                      for (o = 0;
                      for (o = 0;
                           option_char[o] != '\0' && option_char[o] != ch;
                           option_char[o] != '\0' && option_char[o] != ch;
                           o++);
                           o++);
                      if (!option_char[o])
                      if (!option_char[o])
                        goto invalid_option;
                        goto invalid_option;
                      if (b < 0 || b >= func[f]->num_bb)
                      if (b < 0 || b >= func[f]->num_bb)
                        goto invalid_option;
                        goto invalid_option;
                      if (o < 0 || o >= func[f]->bb[b].ntim)
                      if (o < 0 || o >= func[f]->bb[b].ntim)
                        goto invalid_option;
                        goto invalid_option;
 
 
                      /* select an option */
                      /* select an option */
                      func[f]->bb[b].selected_tim = -1;
                      func[f]->bb[b].selected_tim = -1;
                    }
                    }
                }
                }
              else
              else
                PRINTF ("Invalid function.\n");
                PRINTF ("Invalid function.\n");
            }
            }
 
 
          /* options command */
          /* options command */
        }
        }
      else if (strcmp (tmp1, "o") == 0 || strcmp (tmp1, "options") == 0)
      else if (strcmp (tmp1, "o") == 0 || strcmp (tmp1, "options") == 0)
        {
        {
          int any = 0;
          int any = 0;
          PRINTF ("Available options:\n");
          PRINTF ("Available options:\n");
          for (i = 0; i < prof_nfuncs; i++)
          for (i = 0; i < prof_nfuncs; i++)
            if (func[i])
            if (func[i])
              {
              {
                options_cmd (i, func[i]);
                options_cmd (i, func[i]);
                any = 1;
                any = 1;
              }
              }
          if (any)
          if (any)
            PRINTF
            PRINTF
              ("-----------------------------------------------------------------------------\n");
              ("-----------------------------------------------------------------------------\n");
          else
          else
            PRINTF ("Sorry. No available options.\n");
            PRINTF ("Sorry. No available options.\n");
 
 
          /* Ignore empty string */
          /* Ignore empty string */
        }
        }
      else if (strcmp (tmp1, "") == 0)
      else if (strcmp (tmp1, "") == 0)
        {
        {
 
 
          /* help command */
          /* help command */
        }
        }
      else
      else
        {
        {
          if (strcmp (tmp1, "h") != 0 && strcmp (tmp1, "help") != 0)
          if (strcmp (tmp1, "h") != 0 && strcmp (tmp1, "help") != 0)
            PRINTF ("Unknown command.\n");
            PRINTF ("Unknown command.\n");
          PRINTF ("OpenRISC Custom Unit Compiler command prompt\n");
          PRINTF ("OpenRISC Custom Unit Compiler command prompt\n");
          PRINTF ("Available commands:\n");
          PRINTF ("Available commands:\n");
          PRINTF ("  h | help                   displays this help\n");
          PRINTF ("  h | help                   displays this help\n");
          PRINTF ("  q | quit                   returns to or1ksim prompt\n");
          PRINTF ("  q | quit                   returns to or1ksim prompt\n");
          PRINTF
          PRINTF
            ("  p | profile                displays function profiling\n");
            ("  p | profile                displays function profiling\n");
          PRINTF ("  d | debug #                sets debug level (0-9)\n");
          PRINTF ("  d | debug #                sets debug level (0-9)\n");
          PRINTF
          PRINTF
            ("  o | options                displays available options\n");
            ("  o | options                displays available options\n");
          PRINTF
          PRINTF
            ("  s | select func [option]   selects an option/function\n");
            ("  s | select func [option]   selects an option/function\n");
          PRINTF
          PRINTF
            ("  u | unselect func [option] unselects an option/function\n");
            ("  u | unselect func [option] unselects an option/function\n");
          PRINTF ("  g | generate               generates verilog file\n");
          PRINTF ("  g | generate               generates verilog file\n");
          PRINTF
          PRINTF
            ("  l | list                   displays selected functions\n");
            ("  l | list                   displays selected functions\n");
        }
        }
    }
    }
 
 
  /* Dispose memory */
  /* Dispose memory */
  for (i = 0; i < prof_nfuncs - 1; i++)
  for (i = 0; i < prof_nfuncs - 1; i++)
    if (func[i])
    if (func[i])
      free_func (func[i]);
      free_func (func[i]);
 
 
  fclose (flog);
  fclose (flog);
}
}
 
 
/*----------------------------------------------------[ CUC Configuration ]---*/
/*----------------------------------------------------[ CUC Configuration ]---*/
 
 
/*---------------------------------------------------------------------------*/
/*---------------------------------------------------------------------------*/
/*!Set the memory order
/*!Set the memory order
 
 
   Value must be one of none, weak, strong or exact. Invalid values are
   Value must be one of none, weak, strong or exact. Invalid values are
   ignored with a warning.
   ignored with a warning.
 
 
   @param[in] val  The value to use
   @param[in] val  The value to use
   @param[in] dat  The config data structure (not used here)                 */
   @param[in] dat  The config data structure (not used here)                 */
/*---------------------------------------------------------------------------*/
/*---------------------------------------------------------------------------*/
static void
static void
cuc_memory_order (union param_val val, void *dat)
cuc_memory_order (union param_val val, void *dat)
{
{
  if (strcasecmp (val.str_val, "none") == 0)
  if (strcasecmp (val.str_val, "none") == 0)
    {
    {
      config.cuc.memory_order = MO_NONE;
      config.cuc.memory_order = MO_NONE;
    }
    }
  else if (strcasecmp (val.str_val, "weak") == 0)
  else if (strcasecmp (val.str_val, "weak") == 0)
    {
    {
      config.cuc.memory_order = MO_WEAK;
      config.cuc.memory_order = MO_WEAK;
    }
    }
  else if (strcasecmp (val.str_val, "strong") == 0)
  else if (strcasecmp (val.str_val, "strong") == 0)
    {
    {
      config.cuc.memory_order = MO_STRONG;
      config.cuc.memory_order = MO_STRONG;
    }
    }
  else if (strcasecmp (val.str_val, "exact") == 0)
  else if (strcasecmp (val.str_val, "exact") == 0)
    {
    {
      config.cuc.memory_order = MO_EXACT;
      config.cuc.memory_order = MO_EXACT;
    }
    }
  else
  else
    {
    {
      fprintf (stderr, "Warning: CUC memory order invalid. Ignored");
      fprintf (stderr, "Warning: CUC memory order invalid. Ignored");
    }
    }
}                               /* cuc_memory_order() */
}                               /* cuc_memory_order() */
 
 
 
 
static void
static void
cuc_calling_conv (union param_val val, void *dat)
cuc_calling_conv (union param_val val, void *dat)
{
{
  config.cuc.calling_convention = val.int_val;
  config.cuc.calling_convention = val.int_val;
}
}
 
 
static void
static void
cuc_enable_bursts (union param_val val, void *dat)
cuc_enable_bursts (union param_val val, void *dat)
{
{
  config.cuc.enable_bursts = val.int_val;
  config.cuc.enable_bursts = val.int_val;
}
}
 
 
static void
static void
cuc_no_multicycle (union param_val val, void *dat)
cuc_no_multicycle (union param_val val, void *dat)
{
{
  config.cuc.no_multicycle = val.int_val;
  config.cuc.no_multicycle = val.int_val;
}
}
 
 
 
 
/*---------------------------------------------------------------------------*/
/*---------------------------------------------------------------------------*/
/*!Set the timings file
/*!Set the timings file
 
 
   Free any existing string.
   Free any existing string.
 
 
   @param[in] val  The value to use
   @param[in] val  The value to use
   @param[in] dat  The config data structure (not used here)                 */
   @param[in] dat  The config data structure (not used here)                 */
/*---------------------------------------------------------------------------*/
/*---------------------------------------------------------------------------*/
static void
static void
cuc_timings_fn (union param_val val, void *dat)
cuc_timings_fn (union param_val val, void *dat)
{
{
  if (NULL != config.cuc.timings_fn)
  if (NULL != config.cuc.timings_fn)
    {
    {
      free (config.cuc.timings_fn);
      free (config.cuc.timings_fn);
    }
    }
 
 
  config.cuc.timings_fn = strdup (val.str_val);
  config.cuc.timings_fn = strdup (val.str_val);
 
 
}                               /* cuc_timings_fn() */
}                               /* cuc_timings_fn() */
 
 
 
 
void
void
reg_cuc_sec ()
reg_cuc_sec ()
{
{
  struct config_section *sec = reg_config_sec ("cuc", NULL, NULL);
  struct config_section *sec = reg_config_sec ("cuc", NULL, NULL);
 
 
  reg_config_param (sec, "memory_order", paramt_word, cuc_memory_order);
  reg_config_param (sec, "memory_order",       PARAMT_WORD, cuc_memory_order);
  reg_config_param (sec, "calling_convention", paramt_int, cuc_calling_conv);
  reg_config_param (sec, "calling_convention", PARAMT_INT, cuc_calling_conv);
  reg_config_param (sec, "enable_bursts", paramt_int, cuc_enable_bursts);
  reg_config_param (sec, "enable_bursts",      PARAMT_INT, cuc_enable_bursts);
  reg_config_param (sec, "no_multicycle", paramt_int, cuc_no_multicycle);
  reg_config_param (sec, "no_multicycle",      PARAMT_INT, cuc_no_multicycle);
  reg_config_param (sec, "timings_file", paramt_str, cuc_timings_fn);
  reg_config_param (sec, "timings_file",       PARAMT_STR, cuc_timings_fn);
  reg_config_param (sec, "timings_fn", paramt_str, cuc_timings_fn);
  reg_config_param (sec, "timings_fn",         PARAMT_STR, cuc_timings_fn);
}
}
 
 

powered by: WebSVN 2.1.0

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