Ejemplo n.º 1
0
void analyse_statements(Stmts *statements, sym_table *table, char *scope_id) {
    while (statements != NULL) {
        Stmt *statement = statements->first;

        StmtKind kind = statement->kind;
        SInfo *info = &(statement->info);
        int line_no = statement->lineno;

        // Switch on kind of statement and print appropriately
        switch (kind) {
            case STMT_ASSIGN:
                analyse_assign(&info->assign, table, scope_id, line_no);
                break;

            case STMT_COND:
                analyse_if(&info->cond, table, scope_id, line_no);
                break;

            case STMT_READ:
                analyse_read(info->read, table, scope_id, line_no);
                break;

            case STMT_WHILE:
                analyse_while(&info->loop, table, scope_id, line_no);
                break;

            case STMT_WRITE:
                analyse_write(info->write, table, scope_id, line_no);
                break;

            case STMT_FUNC:
                analyse_function(info->func, table, scope_id, line_no);
                break;
        }
        statements = statements->rest;
    }
}
Ejemplo n.º 2
0
void
main_cuc (char *filename)
{
  int i, j;
  char tmp1[256];
  char filename_cut[256];
#if 0				/* Select prefix, based on binary program name */
  for (i = 0; i < sizeof (filename_cut); i++)
    {
      if (isalpha (filename[i]))
	filename_cut[i] = filename[i];
      else
	{
	  filename_cut[i] = '\0';
	  break;
	}
    }
#else
  strcpy (filename_cut, "cu");
#endif

  PRINTF ("Entering OpenRISC Custom Unit Compiler command prompt\n");
  PRINTF ("Using profile file \"%s\" and memory profile file \"%s\".\n",
	  config.sim.prof_fn, config.sim.mprof_fn);
  sprintf (tmp1, "%s.log", filename_cut);
  PRINTF ("Analyzing. (log file \"%s\").\n", tmp1);
  assert (flog = fopen (tmp1, "wt+"));

  /* Loads in the specified timings table */
  PRINTF ("Using timings from \"%s\" at %s\n", config.cuc.timings_fn,
	  generate_time_pretty (tmp1, config.sim.clkcycle_ps));
  load_timing_table (config.cuc.timings_fn);
  runtime.cuc.cycle_duration = 1000. * config.sim.clkcycle_ps;
  PRINTF ("Multicycle logic %s, bursts %s, %s memory order.\n",
	  config.cuc.no_multicycle ? "OFF" : "ON",
	  config.cuc.enable_bursts ? "ON" : "OFF",
	  config.cuc.memory_order ==
	  MO_NONE ? "no" : config.cuc.memory_order ==
	  MO_WEAK ? "weak" : config.cuc.memory_order ==
	  MO_STRONG ? "strong" : "exact");

  prof_set (1, 0);
  assert (prof_acquire (config.sim.prof_fn) == 0);

  if (config.cuc.calling_convention)
    PRINTF ("Assuming OpenRISC standard calling convention.\n");

  /* Try all functions except "total" */
  for (i = 0; i < prof_nfuncs - 1; i++)
    {
      long orig_time;
      unsigned long start_addr, end_addr;
      orig_time = prof_func[i].cum_cycles;
      start_addr = prof_func[i].addr;

      /* Extract the function from the binary */
      sprintf (tmp1, "%s.bin", prof_func[i].name);
      end_addr = extract_function (tmp1, start_addr);

      log ("Testing function %s (%08lx - %08lx)\n", prof_func[i].name,
	   start_addr, end_addr);
      PRINTF ("Testing function %s (%08lx - %08lx)\n", prof_func[i].name,
	      start_addr, end_addr);
      func[i] =
	analyse_function (prof_func[i].name, orig_time, start_addr, end_addr,
			  config.cuc.memory_order, prof_func[i].calls);
      func_v[i] = 0;
    }
  set_func_deps ();

  while (1)
    {
      char *s;
    wait_command:
      PRINTF ("(cuc) ");
      fflush (stdout);
    wait_command_empty:
      s = fgets (tmp1, sizeof tmp1, stdin);
      usleep (100);
      if (!s)
	goto wait_command_empty;
      for (s = tmp1; *s != '\0' && *s != '\n' && *s != '\r'; s++);
      *s = '\0';

      /* quit command */
      if (strcmp (tmp1, "q") == 0 || strcmp (tmp1, "quit") == 0)
	{
	  /* Delete temporary files */
	  for (i = 0; i < prof_nfuncs - 1; i++)
	    {
	      sprintf (tmp1, "%s.bin", prof_func[i].name);
	      log ("Deleting temporary file %s %s\n", tmp1,
		   remove (tmp1) ? "FAILED" : "OK");
	      sprintf (tmp1, "%s.bin.bb", prof_func[i].name);
	      log ("Deleting temporary file %s %s\n", tmp1,
		   remove (tmp1) ? "FAILED" : "OK");
	    }
	  break;

	  /* profile command */
	}
      else if (strcmp (tmp1, "p") == 0 || strcmp (tmp1, "profile") == 0)
	{
	  int ntime = 0;
	  int size = 0;
	  PRINTF
	    ("-----------------------------------------------------------------------------\n");
	  PRINTF
	    ("|function name       |calls|avg cycles  |old%%| max. f.  | impr. f.| options |\n");
	  PRINTF
	    ("|--------------------+-----+------------+----+----------|---------+---------|\n");
	  for (j = 0; j < prof_nfuncs; j++)
	    {
	      int bestcyc = 0, besti = 0;
	      char tmp[100];
	      for (i = 0; i < prof_nfuncs; i++)
		if (prof_func[i].cum_cycles > bestcyc)
		  {
		    bestcyc = prof_func[i].cum_cycles;
		    besti = i;
		  }
	      i = besti;
	      PRINTF ("|%-20s|%5li|%12.1f|%3.0f%%| ",
		      strstrip (tmp, prof_func[i].name, 20),
		      prof_func[i].calls,
		      ((double) prof_func[i].cum_cycles / prof_func[i].calls),
		      (100. * prof_func[i].cum_cycles / prof_cycles));
	      if (func[i])
		{
		  double f = 1.0;
		  if (func_v[i])
		    {
		      int nt = calc_cycles (func[i]);
		      int s = calc_size (func[i]);
		      f = 1. * func[i]->orig_time / nt;
		      ntime += nt;
		      size += s;
		    }
		  else
		    ntime += prof_func[i].cum_cycles;
		  PRINTF ("%8.1f |%8.1f | %-8s|\n",
			  1.f * prof_func[i].cum_cycles /
			  func[i]->timings.new_time, f,
			  format_func_options (tmp, func[i]));
		}
	      else
		{
		  PRINTF ("     N/A |     N/A |     N/A |\n");
		  ntime += prof_func[i].cum_cycles;
		}
	      prof_func[i].cum_cycles = -prof_func[i].cum_cycles;
	    }
	  for (i = 0; i < prof_nfuncs; i++)
	    prof_func[i].cum_cycles = -prof_func[i].cum_cycles;
	  PRINTF
	    ("-----------------------------------------------------------------------------\n");
	  PRINTF
	    ("Total %i cycles (was %i), total added gates = %i. Speed factor %.1f\n",
	     ntime, prof_cycles, size, 1. * prof_cycles / ntime);

	  /* debug command */
	}
      else if (strncmp (tmp1, "d", 1) == 0 || strncmp (tmp1, "debug", 5) == 0)
	{
	  sscanf (tmp1, "%*s %i", &cuc_debug);
	  if (cuc_debug < 0)
	    cuc_debug = 0;
	  if (cuc_debug > 9)
	    cuc_debug = 9;

	  /* generate command */
	}
      else if (strcmp (tmp1, "g") == 0 || strcmp (tmp1, "generate") == 0)
	{
	  /* check for function dependencies */
	  for (i = 0; i < prof_nfuncs; i++)
	    if (func[i])
	      func[i]->tmp = func_v[i];
	  for (i = 0; i < prof_nfuncs; i++)
	    if (func[i])
	      for (j = 0; j < func[i]->nfdeps; j++)
		if (!func[i]->fdeps[j] || !func[i]->fdeps[j]->tmp)
		  {
		    PRINTF
		      ("Function %s must be selected for translation (required by %s)\n",
		       prof_func[j].name, prof_func[i].name);
		    goto wait_command;
		  }
	  for (i = 0; i < prof_nfuncs; i++)
	    if (func[i] && func_v[i])
	      generate_function (func[i], prof_func[i].name, filename_cut);
	  generate_main (prof_nfuncs, func, filename_cut);

	  /* list command */
	}
      else if (strcmp (tmp1, "l") == 0 || strcmp (tmp1, "list") == 0)
	{
	  /* check for function dependencies */
	  for (i = 0; i < prof_nfuncs; i++)
	    if (func_v[i])
	      {
		PRINTF ("%s\n", prof_func[i].name);
	      }

	  /* selectall command */
	}
      else if (strcmp (tmp1, "sa") == 0 || strcmp (tmp1, "selectall") == 0)
	{
	  int f;
	  for (f = 0; f < prof_nfuncs; f++)
	    if (func[f])
	      {
		func_v[f] = 1;
		PRINTF ("Function %s selected for translation.\n",
			prof_func[f].name);
	      }

	  /* select command */
	}
      else if (strncmp (tmp1, "s", 1) == 0
	       || strncmp (tmp1, "select", 6) == 0)
	{
	  char tmp[50], ch;
	  int p, o, b, f;
	  p = sscanf (tmp1, "%*s %s %i%c", tmp, &b, &ch);
	  if (p < 1)
	    PRINTF ("Invalid parameters.\n");
	  else
	    {
	      /* Check if we have valid option */
	      for (f = 0; f < prof_nfuncs; f++)
		if (strcmp (prof_func[f].name, tmp) == 0 && func[f])
		  break;
	      if (f < prof_nfuncs)
		{
		  if (p == 1)
		    {
		      if (func[f])
			{
			  func_v[f] = 1;
			  PRINTF ("Function %s selected for translation.\n",
				  prof_func[f].name);
			}
		      else
			PRINTF ("Function %s not suitable for translation.\n",
				prof_func[f].name);
		    }
		  else
		    {
		      if (!func_v[f])
			PRINTF
			  ("Function %s not yet selected for translation.\n",
			   prof_func[f].name);
		      if (p < 3)
			goto invalid_option;
		      for (o = 0;
			   option_char[o] != '\0' && option_char[o] != ch;
			   o++);
		      if (!option_char[o])
			goto invalid_option;
		      if (b < 0 || b >= func[f]->num_bb)
			goto invalid_option;
		      if (o < 0 || o >= func[f]->bb[b].ntim)
			goto invalid_option;

		      /* select an option */
		      func[f]->bb[b].selected_tim = o;
		      if (func[f]->bb[b].tim[o].nshared)
			{
			  PRINTF ("Option has shared instructions: ");
			  print_shared (func[f], func[f]->bb[b].tim[o].shared,
					func[f]->bb[b].tim[o].nshared);
			  PRINTF ("\n");
			}
		      goto wait_command;
		    invalid_option:
		      PRINTF ("Invalid option.\n");
		    }
		}
	      else
		PRINTF ("Invalid function.\n");
	    }

	  /* unselect command */
	}
      else if (strncmp (tmp1, "u", 1) == 0
	       || strncmp (tmp1, "unselect", 8) == 0)
	{
	  char tmp[50], ch;
	  int p, o, b, f;
	  p = sscanf (tmp1, "%*s %s %i%c", tmp, &b, &ch);
	  if (p < 1)
	    PRINTF ("Invalid parameters.\n");
	  else
	    {
	      /* Check if we have valid option */
	      for (f = 0; f < prof_nfuncs; f++)
		if (strcmp (prof_func[f].name, tmp) == 0 && func[f])
		  break;
	      if (f < prof_nfuncs)
		{
		  if (p == 1)
		    {
		      if (func[f])
			{
			  func_v[f] = 0;
			  PRINTF ("Function %s unselected for translation.\n",
				  prof_func[f].name);
			}
		      else
			PRINTF ("Function %s not suitable for translation.\n",
				prof_func[f].name);
		    }
		  else
		    {
		      if (p < 3)
			goto invalid_option;
		      for (o = 0;
			   option_char[o] != '\0' && option_char[o] != ch;
			   o++);
		      if (!option_char[o])
			goto invalid_option;
		      if (b < 0 || b >= func[f]->num_bb)
			goto invalid_option;
		      if (o < 0 || o >= func[f]->bb[b].ntim)
			goto invalid_option;

		      /* select an option */
		      func[f]->bb[b].selected_tim = -1;
		    }
		}
	      else
		PRINTF ("Invalid function.\n");
	    }

	  /* options command */
	}
      else if (strcmp (tmp1, "o") == 0 || strcmp (tmp1, "options") == 0)
	{
	  int any = 0;
	  PRINTF ("Available options:\n");
	  for (i = 0; i < prof_nfuncs; i++)
	    if (func[i])
	      {
		options_cmd (i, func[i]);
		any = 1;
	      }
	  if (any)
	    PRINTF
	      ("-----------------------------------------------------------------------------\n");
	  else
	    PRINTF ("Sorry. No available options.\n");

	  /* Ignore empty string */
	}
      else if (strcmp (tmp1, "") == 0)
	{

	  /* help command */
	}
      else
	{
	  if (strcmp (tmp1, "h") != 0 && strcmp (tmp1, "help") != 0)
	    PRINTF ("Unknown command.\n");
	  PRINTF ("OpenRISC Custom Unit Compiler command prompt\n");
	  PRINTF ("Available commands:\n");
	  PRINTF ("  h | help                   displays this help\n");
	  PRINTF ("  q | quit                   returns to or1ksim prompt\n");
	  PRINTF
	    ("  p | profile                displays function profiling\n");
	  PRINTF ("  d | debug #                sets debug level (0-9)\n");
	  PRINTF
	    ("  o | options                displays available options\n");
	  PRINTF
	    ("  s | select func [option]   selects an option/function\n");
	  PRINTF
	    ("  u | unselect func [option] unselects an option/function\n");
	  PRINTF ("  g | generate               generates verilog file\n");
	  PRINTF
	    ("  l | list                   displays selected functions\n");
	}
    }

  /* Dispose memory */
  for (i = 0; i < prof_nfuncs - 1; i++)
    if (func[i])
      free_func (func[i]);

  fclose (flog);
}