* sim-base.h (sim_cpu_base): New members name, options.
authorDoug Evans <dje@google.com>
Fri, 27 Feb 1998 18:39:22 +0000 (18:39 +0000)
committerDoug Evans <dje@google.com>
Fri, 27 Feb 1998 18:39:22 +0000 (18:39 +0000)
(sim_cpu_lookup): Add prototype.
* sim-module.c (sim_pre_argv_init): Provide default names for cpus.
* sim-options.h (DECLARE_OPTION_HANDLER): New argument `cpu'.
(sim_add_option_table): Update prototype.
* sim-options.c (sim_add_option_table): New argument `cpu'.
(standard_option_handler,standard_install): Update.
(sim_parse_args): Handle cpu specific options.
(print_help): New static function.
(sim_print_help): Call it.  Print cpu specific options.
(find_match): New static function.
(sim_args_command): Call it.  Handle cpu specific options.
* sim-utils.c (sim_cpu_lookup): New function.
* sim-memopt.c (memory_option_handler): Update.
(sim_memopt_install): Update.
* sim-model.c (model_option_handler): Update.
(model_install): Update.
* sim-profile.c (profile_option_handler): Update.
(profile_install): Update.
* sim-trace.c (trace_option_handler): Update.
(trace_install): Update.
* sim-watch.c (watchpoint_option_handler): Update.
(sim_watchpoint_install): Update.
* cgen-scache.c (scache_option_handler): Update.
(scache_install): Update.

sim/common/ChangeLog
sim/common/sim-base.h
sim/common/sim-memopt.c
sim/common/sim-module.c
sim/common/sim-options.c
sim/common/sim-profile.c
sim/common/sim-utils.c

index e63c873..d345e3f 100644 (file)
@@ -1,3 +1,31 @@
+Fri Feb 27 18:26:16 1998  Doug Evans  <devans@canuck.cygnus.com>
+
+       * sim-base.h (sim_cpu_base): New members name, options.
+       (sim_cpu_lookup): Add prototype.
+       * sim-module.c (sim_pre_argv_init): Provide default names for cpus.
+       * sim-options.h (DECLARE_OPTION_HANDLER): New argument `cpu'.
+       (sim_add_option_table): Update prototype.
+       * sim-options.c (sim_add_option_table): New argument `cpu'.
+       (standard_option_handler,standard_install): Update.
+       (sim_parse_args): Handle cpu specific options.
+       (print_help): New static function.
+       (sim_print_help): Call it.  Print cpu specific options.
+       (find_match): New static function.
+       (sim_args_command): Call it.  Handle cpu specific options.
+       * sim-utils.c (sim_cpu_lookup): New function.
+       * sim-memopt.c (memory_option_handler): Update.
+       (sim_memopt_install): Update.
+       * sim-model.c (model_option_handler): Update.
+       (model_install): Update.
+       * sim-profile.c (profile_option_handler): Update.
+       (profile_install): Update.
+       * sim-trace.c (trace_option_handler): Update.
+       (trace_install): Update.
+       * sim-watch.c (watchpoint_option_handler): Update.
+       (sim_watchpoint_install): Update.
+       * cgen-scache.c (scache_option_handler): Update.
+       (scache_install): Update.
+
 Wed Feb 25 11:00:26 1998  Doug Evans  <devans@canuck.cygnus.com>
 
        * Make-common.in (check): Run `make check' in testsuite dir.
index 231b26e..5b2f48d 100644 (file)
@@ -28,9 +28,12 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 
      #include "sim-basics.h"
      typedef address_word sim_cia;
+     /-* If `sim_cia' is not an integral value (e.g. a struct), define
+         CIA_ADDR to return the integral value.  *-/
+     /-* #define CIA_ADDR(cia) (...) *-/
      #include "sim-base.h"
    
-   finally, two data types ``struct _sim_cpu' and ``struct sim_state'
+   finally, two data types `struct _sim_cpu' and `struct sim_state'
    are defined:
 
      struct _sim_cpu {
@@ -147,13 +150,6 @@ typedef struct {
   MODULE_SUSPEND_LIST *suspend_list;
 #define STATE_SUSPEND_LIST(sd) ((sd)->base.suspend_list)
 
-#ifdef SIM_HAVE_MODEL
-  /* ??? This might be more appropriate in sim_cpu.  */
-  /* Machine tables for this cpu.  See sim-model.h.  */
-  const MODEL *model;
-#define STATE_MODEL(sd) ((sd)->base.model)
-#endif
-
   /* Supported options.  */
   struct option_list *options;
 #define STATE_OPTIONS(sd) ((sd)->base.options)
@@ -195,13 +191,11 @@ typedef struct {
   SIM_ADDR start_addr;
 #define STATE_START_ADDR(sd) ((sd)->base.start_addr)
 
-#if WITH_SCACHE
   /* Size of the simulator's cache, if any.
      This is not the target's cache.  It is the cache the simulator uses
      to process instructions.  */
   unsigned int scache_size;
 #define STATE_SCACHE_SIZE(sd) ((sd)->base.scache_size)
-#endif
 
   /* FIXME: Move to top level sim_state struct (as some struct)?  */
 #ifdef SIM_HAVE_FLATMEM
@@ -254,6 +248,14 @@ typedef struct {
   SIM_DESC state;
 #define CPU_STATE(cpu) ((cpu)->base.state)
 
+  /* The name of the cpu.  */
+  const char *name;
+#define CPU_NAME(cpu) ((cpu)->base.name)
+
+  /* Options specific to this cpu.  */
+  struct option_list *options;
+#define CPU_OPTIONS(cpu) ((cpu)->base.options)
+
   /* Processor specific core data */
   sim_cpu_core core;
 #define CPU_CORE(cpu) (& (cpu)->base.core)
@@ -286,6 +288,15 @@ typedef struct {
   PROFILE_DATA profile_data;
 #define CPU_PROFILE_DATA(cpu) (& (cpu)->base.profile_data)
 
+#ifdef SIM_HAVE_MODEL
+  /* Machine tables for this cpu.  See sim-model.h.  */
+  const MACH *mach;
+#define CPU_MACH(cpu) ((cpu)->base.mach)
+  /* The selected model.  */
+  const MODEL *model;
+#define CPU_MODEL(cpu) ((cpu)->base.model)
+#endif
+
 } sim_cpu_base;
 
 
@@ -293,5 +304,8 @@ typedef struct {
 SIM_DESC sim_state_alloc PARAMS ((SIM_OPEN_KIND kind, host_callback *callback));
 void sim_state_free PARAMS ((SIM_DESC));
 
+/* Return a pointer to the cpu data for CPU_NAME, or NULL if not found.  */
+sim_cpu *sim_cpu_lookup (SIM_DESC sd, const char *cpu_name);
+
 
 #endif /* SIM_BASE_H */
index 82578c0..b21ea19 100644 (file)
@@ -180,11 +180,8 @@ parse_addr (char *chp,
 
 
 static SIM_RC
-memory_option_handler (sd, opt, arg, is_command)
-     SIM_DESC sd;
-     int opt;
-     char *arg;
-     int is_command;
+memory_option_handler (SIM_DESC sd, sim_cpu *cpu, int opt,
+                      char *arg, int is_command)
 {
   switch (opt)
     {
@@ -252,14 +249,15 @@ memory_option_handler (sd, opt, arg, is_command)
        chp = parse_size (chp + 1, &nr_bytes, &modulo);
        /* try to attach/insert the main record */
        entry = do_memopt_add (sd, level, space, addr, nr_bytes, modulo,
-                              &STATE_MEMOPT (sd), zalloc (nr_bytes));
+                              &STATE_MEMOPT (sd),
+                              zalloc (modulo ? modulo : nr_bytes));
        /* now attach all the aliases */
        while (*chp == ',')
          {
            int a_level = level;
            int a_space = space;
            address_word a_addr = addr;
-           chp = parse_addr (chp, &a_level, &a_space, &a_addr);
+           chp = parse_addr (chp + 1, &a_level, &a_space, &a_addr);
            do_memopt_add (sd, a_level, a_space, a_addr, nr_bytes, modulo,
                           &entry->alias, entry->buffer);
          }
@@ -320,8 +318,7 @@ memory_option_handler (sd, opt, arg, is_command)
              sim_io_printf (sd, " alias ");
            if (entry->space != 0)
              sim_io_printf (sd, "0x%lx:", (long) entry->space);
-           sim_io_printf (sd, "0x%08lx",
-                          (long) entry->addr);
+           sim_io_printf (sd, "0x%08lx", (long) entry->addr);
            if (entry->level != 0)
              sim_io_printf (sd, "@0x%lx", (long) entry->level);
            sim_io_printf (sd, ",0x%lx",
@@ -334,7 +331,7 @@ memory_option_handler (sd, opt, arg, is_command)
              {
                if (alias->space != 0)
                  sim_io_printf (sd, "0x%lx:", (long) alias->space);
-               sim_io_printf (sd, ",0x%08lx", alias->addr);
+               sim_io_printf (sd, ",0x%08lx", (long) alias->addr);
                if (alias->level != 0)
                  sim_io_printf (sd, "@0x%lx", (long) alias->level);
              }
@@ -366,7 +363,7 @@ SIM_RC
 sim_memopt_install (SIM_DESC sd)
 {
   SIM_ASSERT (STATE_MAGIC (sd) == SIM_MAGIC_NUMBER);
-  sim_add_option_table (sd, memory_options);
+  sim_add_option_table (sd, NULL, memory_options);
   sim_module_add_uninstall_fn (sd, sim_memory_uninstall);
   sim_module_add_init_fn (sd, sim_memory_init);
   return SIM_RC_OK;
index 323d3e4..c4dcd30 100644 (file)
@@ -74,6 +74,17 @@ sim_pre_argv_init (SIM_DESC sd, const char *myname)
   while (STATE_MY_NAME (sd) > myname && STATE_MY_NAME (sd)[-1] != '/')
     --STATE_MY_NAME (sd);
 
+  /* Set the cpu names to default values.  */
+  {
+    int i;
+    for (i = 0; i < MAX_NR_PROCESSORS; ++i)
+      {
+       const char *name;
+       asprintf (&name, "cpu%d", i);
+       CPU_NAME (STATE_CPU (sd, i)) = name;
+      }
+  }
+
   /* Install all configured in modules.  */
   if (sim_module_install (sd) != SIM_RC_OK)
     return SIM_RC_FAIL;
index 9f86d7e..ca38af5 100644 (file)
@@ -42,9 +42,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
    This is intended to be called by modules in their `install' handler.  */
 
 SIM_RC
-sim_add_option_table (sd, table)
-     SIM_DESC sd;
-     const OPTION *table;
+sim_add_option_table (SIM_DESC sd, sim_cpu *cpu, const OPTION *table)
 {
   struct option_list *ol = ((struct option_list *)
                            xmalloc (sizeof (struct option_list)));
@@ -52,9 +50,19 @@ sim_add_option_table (sd, table)
   /* Note: The list is constructed in the reverse order we're called so
      later calls will override earlier ones (in case that ever happens).
      This is the intended behaviour.  */
-  ol->next = STATE_OPTIONS (sd);
-  ol->options = table;
-  STATE_OPTIONS (sd) = ol;
+
+  if (cpu)
+    {
+      ol->next = CPU_OPTIONS (cpu);
+      ol->options = table;
+      CPU_OPTIONS (cpu) = ol;
+    }
+  else
+    {
+      ol->next = STATE_OPTIONS (sd);
+      ol->options = table;
+      STATE_OPTIONS (sd) = ol;
+    }
 
   return SIM_RC_OK;
 }
@@ -178,11 +186,8 @@ static const OPTION standard_options[] =
 };
 
 static SIM_RC
-standard_option_handler (sd, opt, arg, is_command)
-     SIM_DESC sd;
-     int opt;
-     char *arg;
-     int is_command;
+standard_option_handler (SIM_DESC sd, sim_cpu *cpu, int opt,
+                        char *arg, int is_command)
 {
   int i,n;
 
@@ -375,7 +380,7 @@ standard_option_handler (sd, opt, arg, is_command)
        const char **lp;
        if (list == NULL)
          abort ();
-       sim_io_printf (sd, "Valid architectures:");
+       sim_io_printf (sd, "Possible architectures:");
        for (lp = list; *lp != NULL; lp++)
          sim_io_printf (sd, " %s", *lp);
        sim_io_printf (sd, "\n");
@@ -406,7 +411,7 @@ SIM_RC
 standard_install (SIM_DESC sd)
 {
   SIM_ASSERT (STATE_MAGIC (sd) == SIM_MAGIC_NUMBER);
-  if (sim_add_option_table (sd, standard_options) != SIM_RC_OK)
+  if (sim_add_option_table (sd, NULL, standard_options) != SIM_RC_OK)
     return SIM_RC_FAIL;
   return SIM_RC_OK;
 }
@@ -453,7 +458,7 @@ sim_parse_args (sd, argv)
      SIM_DESC sd;
      char **argv;
 {
-  int i, argc, num_opts;
+  int c, i, argc, num_opts;
   char *p, *short_options;
   /* The `val' option struct entry is dynamically assigned for options that
      only come in the long form.  ORIG_VAL is used to get the original value
@@ -463,6 +468,7 @@ sim_parse_args (sd, argv)
   const struct option_list *ol;
   const OPTION *opt;
   OPTION_HANDLER **handlers;
+  sim_cpu **opt_cpu;
 
   /* Count the number of arguments.  */
   for (argc = 0; argv[argc] != NULL; ++argc)
@@ -473,22 +479,30 @@ sim_parse_args (sd, argv)
   for (ol = STATE_OPTIONS (sd); ol != NULL; ol = ol->next)
     for (opt = ol->options; OPTION_VALID_P (opt); ++opt)
       ++num_opts;
+  for (i = 0; i < MAX_NR_PROCESSORS; ++i)
+    for (ol = CPU_OPTIONS (STATE_CPU (sd, i)); ol != NULL; ol = ol->next)
+      for (opt = ol->options; OPTION_VALID_P (opt); ++opt)
+       ++num_opts;
 
   /* Initialize duplicate argument checker.  */
   (void) dup_arg_p (NULL);
 
   /* Build the option table for getopt.  */
+
   long_options = NZALLOC (struct option, num_opts + 1);
   lp = long_options;
   short_options = NZALLOC (char, num_opts * 3 + 1);
   p = short_options;
   handlers = NZALLOC (OPTION_HANDLER *, OPTION_START + num_opts);
   orig_val = NZALLOC (int, OPTION_START + num_opts);
+  opt_cpu = NZALLOC (sim_cpu *, OPTION_START + num_opts);
+
   /* Set '+' as first char so argument permutation isn't done.  This
      is done to stop getopt_long returning options that appear after
      the target program.  Such options should be passed unchanged into
      the program image. */
   *p++ = '+';
+
   for (i = OPTION_START, ol = STATE_OPTIONS (sd); ol != NULL; ol = ol->next)
     for (opt = ol->options; OPTION_VALID_P (opt); ++opt)
       {
@@ -514,14 +528,51 @@ sim_parse_args (sd, argv)
            lp->val = i++;
            handlers[lp->val] = opt->handler;
            orig_val[lp->val] = opt->opt.val;
+           opt_cpu[lp->val] = NULL;
            ++lp;
          }
       }
+
+  for (c = 0; c < MAX_NR_PROCESSORS; ++c)
+    {
+      sim_cpu *cpu = STATE_CPU (sd, c);
+      for (ol = CPU_OPTIONS (cpu); ol != NULL; ol = ol->next)
+       for (opt = ol->options; OPTION_VALID_P (opt); ++opt)
+         {
+#if 0 /* Each option is prepended with --<cpuname>- so this greatly cuts down
+        on the need for dup_arg_p checking.  Maybe in the future it'll be
+        needed so this is just commented out, and not deleted.  */
+           if (dup_arg_p (opt->opt.name))
+             continue;
+#endif
+           /* Don't allow short versions of cpu specific options for now.  */
+           if (opt->shortopt != 0)
+             {
+               sim_io_eprintf (sd, "internal error, short cpu specific option");
+               return SIM_RC_FAIL;
+             }
+           if (opt->opt.name != NULL)
+             {
+               *lp = opt->opt;
+               /* Prepend --<cpuname>- to the option.  */
+               asprintf (&lp->name, "%s-%s", CPU_NAME (cpu), lp->name);
+               /* Dynamically assign `val' numbers for long options. */
+               lp->val = i++;
+               handlers[lp->val] = opt->handler;
+               orig_val[lp->val] = opt->opt.val;
+               opt_cpu[lp->val] = cpu;
+               ++lp;
+             }
+         }
+    }
+           
+  /* Terminate the short and long option lists.  */
   *p = 0;
   lp->name = NULL;
 
   /* Ensure getopt is initialized.  */
   optind = 0;
+
   while (1)
     {
       int longind, optc;
@@ -536,36 +587,21 @@ sim_parse_args (sd, argv)
       if (optc == '?')
        return SIM_RC_FAIL;
 
-      if ((*handlers[optc]) (sd, orig_val[optc], optarg, 0/*!is_command*/) == SIM_RC_FAIL)
+      if ((*handlers[optc]) (sd, opt_cpu[optc], orig_val[optc], optarg, 0/*!is_command*/) == SIM_RC_FAIL)
        return SIM_RC_FAIL;
     }
 
   return SIM_RC_OK;
 }
 
-/* Print help messages for the options.  */
+/* Utility of sim_print_help to print a list of option tables.  */
 
-void
-sim_print_help (sd, is_command)
-     SIM_DESC sd;
-     int is_command;
+static void
+print_help (SIM_DESC sd, sim_cpu *cpu, const struct option_list *ol, int is_command)
 {
-  const struct option_list *ol;
   const OPTION *opt;
 
-  if (STATE_OPEN_KIND (sd) == SIM_OPEN_STANDALONE)
-    sim_io_printf (sd, "Usage: %s [options] program [program args]\n",
-                  STATE_MY_NAME (sd));
-
-  /* Initialize duplicate argument checker.  */
-  (void) dup_arg_p (NULL);
-
-  if (STATE_OPEN_KIND (sd) == SIM_OPEN_STANDALONE)
-    sim_io_printf (sd, "Options:\n");
-  else
-    sim_io_printf (sd, "Commands:\n");
-
-  for (ol = STATE_OPTIONS (sd); ol != NULL; ol = ol->next)
+  for ( ; ol != NULL; ol = ol->next)
     for (opt = ol->options; OPTION_VALID_P (opt); ++opt)
       {
        const int indent = 30;
@@ -621,15 +657,18 @@ sim_print_help (sd, is_command)
        do
          {
            const char *name;
+           const char *cpu_prefix = cpu ? CPU_NAME (cpu) : NULL;
            if (o->doc_name != NULL)
              name = o->doc_name;
            else
              name = o->opt.name;
            if (name != NULL)
              {
-               sim_io_printf (sd, "%s%s%s",
+               sim_io_printf (sd, "%s%s%s%s%s",
                               comma ? ", " : "",
                               is_command ? "" : "--",
+                              cpu ? cpu_prefix : "",
+                              cpu ? "-" : "",
                               name);
                len += ((comma ? 2 : 0)
                        + (is_command ? 0 : 2)
@@ -679,8 +718,45 @@ sim_print_help (sd, is_command)
          sim_io_printf (sd, "%s\n", chp);
        }
       }
+}
+
+/* Print help messages for the options.  */
+
+void
+sim_print_help (sd, is_command)
+     SIM_DESC sd;
+     int is_command;
+{
+  if (STATE_OPEN_KIND (sd) == SIM_OPEN_STANDALONE)
+    sim_io_printf (sd, "Usage: %s [options] program [program args]\n",
+                  STATE_MY_NAME (sd));
+
+  /* Initialize duplicate argument checker.  */
+  (void) dup_arg_p (NULL);
+
+  if (STATE_OPEN_KIND (sd) == SIM_OPEN_STANDALONE)
+    sim_io_printf (sd, "Options:\n");
+  else
+    sim_io_printf (sd, "Commands:\n");
 
+  print_help (sd, NULL, STATE_OPTIONS (sd), is_command);
   sim_io_printf (sd, "\n");
+
+  /* Print cpu-specific options.  */
+  {
+    int i;
+
+    for (i = 0; i < MAX_NR_PROCESSORS; ++i)
+      {
+       sim_cpu *cpu = STATE_CPU (sd, i);
+       if (CPU_OPTIONS (cpu) == NULL)
+         continue;
+       sim_io_printf (sd, "CPU %s specific options:\n", CPU_NAME (cpu));
+       print_help (sd, cpu, CPU_OPTIONS (cpu), is_command);
+       sim_io_printf (sd, "\n");
+      }
+  }
+
   sim_io_printf (sd, "Note: Depending on the simulator configuration some %ss\n",
                 STATE_OPEN_KIND (sd) == SIM_OPEN_STANDALONE ? "option" : "command");
   sim_io_printf (sd, "      may not be applicable\n");
@@ -693,13 +769,69 @@ sim_print_help (sd, is_command)
     }
 }
 
+/* Utility of sim_args_command to find the closest match for a command.
+   Commands that have "-" in them can be specified as separate words.
+   e.g. sim memory-region 0x800000,0x4000
+   or   sim memory region 0x800000,0x4000
+   If CPU is non-null, use its option table list, otherwise use the main one.
+   *PARGI is where to start looking in ARGV.  It is updated to point past
+   the found option.  */
 
+static const OPTION *
+find_match (SIM_DESC sd, sim_cpu *cpu, char *argv[], int *pargi)
+{
+  const struct option_list *ol;
+  const OPTION *opt;
+  /* most recent option match */
+  const OPTION *matching_opt = NULL;
+  int matching_argi = -1;
+
+  if (cpu)
+    ol = CPU_OPTIONS (cpu);
+  else
+    ol = STATE_OPTIONS (sd);
+
+  /* Skip passed elements specified by *PARGI.  */
+  argv += *pargi;
+
+  for ( ; ol != NULL; ol = ol->next)
+    for (opt = ol->options; OPTION_VALID_P (opt); ++opt)
+      {
+       int argi = 0;
+       const char *name = opt->opt.name;
+       if (name == NULL)
+         continue;
+       while (strncmp (name, argv [argi], strlen (argv [argi])) == 0)
+         {
+           name = &name [strlen (argv[argi])];
+           if (name [0] == '-')
+             {
+               /* leading match ...<a-b-c>-d-e-f - continue search */
+               name ++; /* skip `-' */
+               argi ++;
+               continue;
+             }
+           else if (name [0] == '\0')
+             {
+               /* exact match ...<a-b-c-d-e-f> - better than before? */
+               if (argi > matching_argi)
+                 {
+                   matching_argi = argi;
+                   matching_opt = opt;
+                 }
+               break;
+             }
+           else
+             break;
+         }
+      }
 
+  *pargi = matching_argi;
+  return matching_opt;
+}
 
 SIM_RC
-sim_args_command (sd, cmd)
-     SIM_DESC sd;
-     char *cmd;
+sim_args_command (SIM_DESC sd, char *cmd)
 {
   /* something to do? */
   if (cmd == NULL)
@@ -715,52 +847,54 @@ sim_args_command (sd, cmd)
     }
   else
     {
-      /* user specified <opt> form? */
-      const struct option_list *ol;
-      const OPTION *opt;
       char **argv = buildargv (cmd);
-      /* most recent option match */
       const OPTION *matching_opt = NULL;
-      int matching_argi = -1;
-      if (argv [0] != NULL)
-       for (ol = STATE_OPTIONS (sd); ol != NULL; ol = ol->next)
-         for (opt = ol->options; OPTION_VALID_P (opt); ++opt)
-           {
-             int argi = 0;
-             const char *name = opt->opt.name;
-             if (name == NULL)
-               continue;
-             while (strncmp (name, argv [argi], strlen (argv [argi])) == 0)
-               {
-                 name = &name [strlen (argv[argi])];
-                 if (name [0] == '-')
-                   {
-                     /* leading match ...<a-b-c>-d-e-f - continue search */
-                     name ++; /* skip `-' */
-                     argi ++;
-                     continue;
-                   }
-                 else if (name [0] == '\0')
-                   {
-                     /* exact match ...<a-b-c-d-e-f> - better than before? */
-                     if (argi > matching_argi)
-                       {
-                         matching_argi = argi;
-                         matching_opt = opt;
-                       }
-                     break;
-                   }
-                 else
-                   break;
-               }
-           }
+      int matching_argi;
+      sim_cpu *cpu;
+      int argi = 0;
+
+      if (argv [0] == NULL)
+       return;
+
+      /* First check for a cpu selector.  */
+      {
+       char *cpu_name = xstrdup (argv[0]);
+       char *hyphen = strchr (cpu_name, '-');
+       if (hyphen)
+         *hyphen = 0;
+       cpu = sim_cpu_lookup (sd, cpu_name);
+       if (cpu)
+         {
+           /* If <cpuname>-<command>, point argv[0] at <command>.  */
+           if (hyphen)
+             {
+               matching_argi = 0;
+               argv[0] += hyphen - cpu_name + 1;
+             }
+           else
+             matching_argi = 1;
+           matching_opt = find_match (sd, cpu, argv, &matching_argi);
+           /* If hyphen found restore argv[0].  */
+           if (hyphen)
+             argv[0] -= hyphen - cpu_name + 1;
+         }
+       free (cpu_name);
+      }
+
+      /* If that failed, try the main table.  */
+      if (matching_opt == NULL)
+       {
+         matching_argi = 0;
+         matching_opt = find_match (sd, NULL, argv, &matching_argi);
+       }
+
       if (matching_opt != NULL)
        {
          switch (matching_opt->opt.has_arg)
            {
            case no_argument:
              if (argv [matching_argi + 1] == NULL)
-               matching_opt->handler (sd, matching_opt->opt.val,
+               matching_opt->handler (sd, cpu, matching_opt->opt.val,
                                       NULL, 1/*is_command*/);
              else
                sim_io_eprintf (sd, "Command `%s' takes no arguments\n",
@@ -768,10 +902,10 @@ sim_args_command (sd, cmd)
              break;
            case optional_argument:
              if (argv [matching_argi + 1] == NULL)
-               matching_opt->handler (sd, matching_opt->opt.val,
+               matching_opt->handler (sd, cpu, matching_opt->opt.val,
                                       NULL, 1/*is_command*/);
              else if (argv [matching_argi + 2] == NULL)
-               matching_opt->handler (sd, matching_opt->opt.val,
+               matching_opt->handler (sd, cpu, matching_opt->opt.val,
                                       argv [matching_argi + 1], 1/*is_command*/);
              else
                sim_io_eprintf (sd, "Command `%s' requires no more than one argument\n",
@@ -782,14 +916,17 @@ sim_args_command (sd, cmd)
                sim_io_eprintf (sd, "Command `%s' requires an argument\n",
                                matching_opt->opt.name);
              else if (argv [matching_argi + 2] == NULL)
-               matching_opt->handler (sd, matching_opt->opt.val,
+               matching_opt->handler (sd, cpu, matching_opt->opt.val,
                                       argv [matching_argi + 1], 1/*is_command*/);
              else
                sim_io_eprintf (sd, "Command `%s' requires only one argument\n",
                                matching_opt->opt.name);
            }
+         freeargv (argv);
          return SIM_RC_OK;
        }
+
+      freeargv (argv);
     }
       
   /* didn't find anything that remotly matched */
index f9807da..796b945 100644 (file)
@@ -103,6 +103,7 @@ static const OPTION profile_options[] = {
 
 static SIM_RC
 profile_option_handler (SIM_DESC sd,
+                       sim_cpu *cpu,
                        int opt,
                        char *arg,
                        int is_command)
@@ -938,7 +939,7 @@ profile_install (SIM_DESC sd)
   int i;
 
   SIM_ASSERT (STATE_MAGIC (sd) == SIM_MAGIC_NUMBER);
-  sim_add_option_table (sd, profile_options);
+  sim_add_option_table (sd, NULL, profile_options);
   for (i = 0; i < MAX_NR_PROCESSORS; ++i)
     memset (CPU_PROFILE_DATA (STATE_CPU (sd, i)), 0,
            sizeof (* CPU_PROFILE_DATA (STATE_CPU (sd, i))));
index aee2ed9..8327c5e 100644 (file)
@@ -1,5 +1,5 @@
 /* Miscellaneous simulator utilities.
-   Copyright (C) 1997 Free Software Foundation, Inc.
+   Copyright (C) 1997, 1998 Free Software Foundation, Inc.
    Contributed by Cygnus Support.
 
 This file is part of GDB, the GNU debugger.
@@ -76,7 +76,6 @@ SIM_DESC
 sim_state_alloc (SIM_OPEN_KIND kind,
                 host_callback *callback)
 {
-  int cpu_nr;
   SIM_DESC sd = ZALLOC (struct sim_state);
 
   STATE_MAGIC (sd) = SIM_MAGIC_NUMBER;
@@ -84,15 +83,19 @@ sim_state_alloc (SIM_OPEN_KIND kind,
   STATE_OPEN_KIND (sd) = kind;
 
 #if 0
-  /* Initialize the back link from the cpu struct to the state struct.  */
-  /* ??? I can envision a design where the state struct contains an array
-     of pointers to cpu structs, rather than an array of structs themselves.
-     Implementing this is trickier as one may not know what to allocate until
-     one has parsed the args.  Parsing the args twice wouldn't be unreasonable,
-     IMHO.  If the state struct ever does contain an array of pointers then we
-     can't do this here.  */
-  for (cpu_nr = 0; cpu_nr < MAX_NR_PROCESSORS; cpu_nr++)
-    CPU_STATE (STATE_CPU (sd, cpu_nr)) = sd;
+  {
+    int cpu_nr;
+
+    /* Initialize the back link from the cpu struct to the state struct.  */
+    /* ??? I can envision a design where the state struct contains an array
+       of pointers to cpu structs, rather than an array of structs themselves.
+       Implementing this is trickier as one may not know what to allocate until
+       one has parsed the args.  Parsing the args twice wouldn't be unreasonable,
+       IMHO.  If the state struct ever does contain an array of pointers then we
+       can't do this here.  */
+    for (cpu_nr = 0; cpu_nr < MAX_NR_PROCESSORS; cpu_nr++)
+      CPU_STATE (STATE_CPU (sd, cpu_nr)) = sd;
+  }
 #endif
 
 #ifdef SIM_STATE_INIT
@@ -116,6 +119,19 @@ sim_state_free (SIM_DESC sd)
   zfree (sd);
 }
 
+/* Return a pointer to the cpu data for CPU_NAME, or NULL if not found.  */
+
+sim_cpu *
+sim_cpu_lookup (SIM_DESC sd, const char *cpu_name)
+{
+  int i;
+
+  for (i = 0; i < MAX_NR_PROCESSORS; ++i)
+    if (strcmp (cpu_name, CPU_NAME (STATE_CPU (sd, i))) == 0)
+      return STATE_CPU (sd, i);
+  return NULL;
+}
+
 /* Turn VALUE into a string with commas.  */
 
 char *