Fix TCL error in gdb.python/py-format-string.exp.
[deliverable/binutils-gdb.git] / sim / ppc / psim.c
index c2d3a6067b462df96e272ec6d9d880cd66cbb5f6..3e322e3820f83830d5076cf46fe7e69ee48804b8 100644 (file)
@@ -1,10 +1,10 @@
 /*  This file is part of the program psim.
 
 /*  This file is part of the program psim.
 
-    Copyright (C) 1994-1996, Andrew Cagney <cagney@highland.com.au>
+    Copyright 1994, 1995, 1996, 1997, 2003 Andrew Cagney
 
     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
 
     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 Software Foundation; either version 2 of the License, or
+    the Free Software Foundation; either version 3 of the License, or
     (at your option) any later version.
 
     This program is distributed in the hope that it will be useful,
     (at your option) any later version.
 
     This program is distributed in the hope that it will be useful,
@@ -13,8 +13,7 @@
     GNU General Public License for more details.
  
     You should have received a copy of the GNU General Public License
     GNU General Public License for more details.
  
     You should have received a copy of the GNU General Public License
-    along with this program; if not, write to the Free Software
-    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+    along with this program; if not, see <http://www.gnu.org/licenses/>.
  
     */
 
  
     */
 
@@ -28,6 +27,8 @@
 
 #include "tree.h"
 
 
 #include "tree.h"
 
+#include <signal.h>
+
 #include <stdio.h>
 #include <ctype.h>
 
 #include <stdio.h>
 #include <ctype.h>
 
@@ -47,7 +48,8 @@
 
 
 #include "bfd.h"
 
 
 #include "bfd.h"
-
+#include "libiberty.h"
+#include "gdb/signals.h"
 
 /* system structure, actual size of processor array determined at
    runtime */
 
 /* system structure, actual size of processor array determined at
    runtime */
@@ -116,7 +118,7 @@ find_arg(char *err_msg,
 
 INLINE_PSIM\
 (void)
 
 INLINE_PSIM\
 (void)
-psim_usage(int verbose)
+psim_usage (int verbose, int help, SIM_OPEN_KIND kind)
 {
   printf_filtered("Usage:\n");
   printf_filtered("\n");
 {
   printf_filtered("Usage:\n");
   printf_filtered("\n");
@@ -147,8 +149,16 @@ psim_usage(int verbose)
   printf_filtered("The following are valid <psim-option>s:\n");
   printf_filtered("\n");
 
   printf_filtered("The following are valid <psim-option>s:\n");
   printf_filtered("\n");
 
-  printf_filtered("\t-i              Print instruction counting statistics\n");
-  if (verbose) { printf_filtered("\n"); }
+  printf_filtered("\t-c <count>      Limit the simulation to <count> iterations\n");
+  if (verbose) { 
+  printf_filtered("\n");
+  }
+
+  printf_filtered("\t-i or -i2       Print instruction counting statistics\n");
+  if (verbose) { 
+  printf_filtered("\t                Specify -i2 for a more detailed display\n");
+  printf_filtered("\n");
+  }
 
   printf_filtered("\t-I              Print execution unit statistics\n");
   if (verbose) { printf_filtered("\n"); }
 
   printf_filtered("\t-I              Print execution unit statistics\n");
   if (verbose) { printf_filtered("\n"); }
@@ -163,6 +173,13 @@ psim_usage(int verbose)
   printf_filtered("\t                chirp - OEA + a few OpenBoot calls\n");
   printf_filtered("\n"); }
 
   printf_filtered("\t                chirp - OEA + a few OpenBoot calls\n");
   printf_filtered("\n"); }
 
+  printf_filtered("\t-E <endian>     Specify the endianness of the target\n");
+  if (verbose) { 
+  printf_filtered("\t                Can be any of the following:\n");
+  printf_filtered("\t                big - big endian target\n");
+  printf_filtered("\t                little - little endian target\n");
+  printf_filtered("\n"); }
+
   printf_filtered("\t-f <file>       Merge <file> into the device tree\n");
   if (verbose) { printf_filtered("\n"); }
 
   printf_filtered("\t-f <file>       Merge <file> into the device tree\n");
   if (verbose) { printf_filtered("\n"); }
 
@@ -199,13 +216,42 @@ psim_usage(int verbose)
     printf_filtered("\n");
     print_options();
   }
     printf_filtered("\n");
     print_options();
   }
-  error("");
+
+  if (kind == SIM_OPEN_STANDALONE)
+    {
+      if (REPORT_BUGS_TO[0])
+       printf ("Report bugs to %s\n", REPORT_BUGS_TO);
+      exit (help ? 0 : 1);
+    }
+}
+
+/* Test "string" for containing a string of digits that form a number
+between "min" and "max".  The return value is the number or "err". */
+static
+int is_num( char *string, int min, int max, int err)
+{
+  int result = 0;
+
+  for ( ; *string; ++string)
+  {
+    if (!isdigit(*string))
+    {
+      result = err;
+      break;
+    }
+    result = result * 10 + (*string - '0');
+  }
+  if (result < min || result > max)
+    result = err;
+
+  return result;
 }
 
 INLINE_PSIM\
 (char **)
 psim_options(device *root,
 }
 
 INLINE_PSIM\
 (char **)
 psim_options(device *root,
-            char **argv)
+            char **argv,
+            SIM_OPEN_KIND kind)
 {
   device *current = root;
   int argp;
 {
   device *current = root;
   int argp;
@@ -218,26 +264,50 @@ psim_options(device *root,
     while (*p != '\0') {
       switch (*p) {
       default:
     while (*p != '\0') {
       switch (*p) {
       default:
-       psim_usage(0);
-       error ("");
+       printf_filtered ("Invalid Option: %s\n", argv[argp]);
+       psim_usage (0, 0, kind);
+       return NULL;
+      case 'c':
+       param = find_arg("Missing <count> option for -c (max-iterations)\n", &argp, argv);
+       tree_parse(root, "/openprom/options/max-iterations %s", param);
        break;
       case 'e':
        break;
       case 'e':
-       param = find_arg("Missing <emul> option for -e\n", &argp, argv);
+       param = find_arg("Missing <emul> option for -e (os-emul)\n", &argp, argv);
        tree_parse(root, "/openprom/options/os-emul %s", param);
        break;
        tree_parse(root, "/openprom/options/os-emul %s", param);
        break;
+      case 'E':
+       /* endian spec, ignored for now */
+       param = find_arg("Missing <endian> option for -E (target-endian)\n", &argp, argv);
+       if (strcmp (param, "big") == 0)
+         tree_parse (root, "/options/little-endian? false");
+       else if (strcmp (param, "little") == 0)
+         tree_parse (root, "/options/little-endian? true");
+       else
+         {
+           printf_filtered ("Invalid <endian> option for -E (target-endian)\n");
+           psim_usage (0, 0, kind);
+           return NULL;
+         }
+       break;
       case 'f':
        param = find_arg("Missing <file> option for -f\n", &argp, argv);
        psim_merge_device_file(root, param);
        break;
       case 'h':
       case '?':
       case 'f':
        param = find_arg("Missing <file> option for -f\n", &argp, argv);
        psim_merge_device_file(root, param);
        break;
       case 'h':
       case '?':
-       psim_usage(1);
-       break;
+       psim_usage (1, 1, kind);
+       return NULL;
       case 'H':
       case 'H':
-       psim_usage(2);
-       break;
+       psim_usage (2, 1, kind);
+       return NULL;
       case 'i':
       case 'i':
-       tree_parse(root, "/openprom/trace/print-info 1");
+       if (isdigit(p[1])) {
+         tree_parse(root, "/openprom/trace/print-info %c", p[1]);
+         p++;
+       }
+       else {
+         tree_parse(root, "/openprom/trace/print-info 1");
+       }
        break;
       case 'I':
        tree_parse(root, "/openprom/trace/print-info 2");
        break;
       case 'I':
        tree_parse(root, "/openprom/trace/print-info 2");
@@ -245,29 +315,75 @@ psim_options(device *root,
                   MODEL_ISSUE_PROCESS);
        break;
       case 'm':
                   MODEL_ISSUE_PROCESS);
        break;
       case 'm':
-       param = find_arg("Missing <model> option for -m\n", &argp, argv);
+       param = find_arg("Missing <model> option for -m (model)\n", &argp, argv);
        tree_parse(root, "/openprom/options/model \"%s", param);
        break;
       case 'n':
        tree_parse(root, "/openprom/options/model \"%s", param);
        break;
       case 'n':
-       param = find_arg("Missing <nr-smp> option for -n\n", &argp, argv);
+       param = find_arg("Missing <nr-smp> option for -n (smp)\n", &argp, argv);
        tree_parse(root, "/openprom/options/smp %s", param);
        break;
       case 'o':
        param = find_arg("Missing <dev-spec> option for -o\n", &argp, argv);
        tree_parse(root, "/openprom/options/smp %s", param);
        break;
       case 'o':
        param = find_arg("Missing <dev-spec> option for -o\n", &argp, argv);
-       current = tree_parse(current, "%s", param);
+       if (memcmp(param, "mpc860c0", 8) == 0)
+        {
+          if (param[8] == '\0')
+            tree_parse(root, "/options/mpc860c0 5");
+          else if (param[8] == '=' && is_num(param+9, 1, 10, 0))
+          {
+            tree_parse(root, "/options/mpc860c0 %s", param+9);
+          }
+          else error("Invalid mpc860c0 option for -o\n");
+        }
+       else
+          current = tree_parse(current, "%s", param);
        break;
       case 'r':
        break;
       case 'r':
-       param = find_arg("Missing <ram-size> option for -r\n", &argp, argv);
+       param = find_arg("Missing <ram-size> option for -r (oea-memory-size)\n", &argp, argv);
        tree_parse(root, "/openprom/options/oea-memory-size %s",
                               param);
        break;
       case 't':
        tree_parse(root, "/openprom/options/oea-memory-size %s",
                               param);
        break;
       case 't':
-       param = find_arg("Missing <trace> option for -t\n", &argp, argv);
+       param = find_arg("Missing <trace> option for -t (trace/*)\n", &argp, argv);
        if (param[0] == '!')
          tree_parse(root, "/openprom/trace/%s 0", param+1);
        else
          tree_parse(root, "/openprom/trace/%s 1", param);
        break;
        if (param[0] == '!')
          tree_parse(root, "/openprom/trace/%s 0", param+1);
        else
          tree_parse(root, "/openprom/trace/%s 1", param);
        break;
+      case '-':
+       /* it's a long option of the form --optionname=optionvalue.
+          Such options can be passed through if we are invoked by
+          gdb.  */
+       if (strstr(argv[argp], "architecture") != NULL) {
+          /* we must consume the argument here, so that we get out
+             of the loop.  */
+         p = argv[argp] + strlen(argv[argp]) - 1;
+         printf_filtered("Warning - architecture parameter ignored\n");
+        }
+       else if (strcmp (argv[argp], "--help") == 0)
+         {
+           psim_usage (0, 1, kind);
+           return NULL;
+         }
+       else if (strncmp (argv[argp], "--sysroot=",
+                         sizeof ("--sysroot=") - 1) == 0)
+         /* Ignore this option.  */
+         p = argv[argp] + strlen(argv[argp]) - 1;
+       else if (strcmp (argv[argp], "--version") == 0)
+         {
+           extern const char version[];
+           printf ("GNU simulator %s%s\n", PKGVERSION, version);
+           if (kind == SIM_OPEN_STANDALONE)
+             exit (0);
+           else
+             return NULL;
+         }
+       else
+         {
+           printf_filtered ("Invalid option: %s\n", argv[argp]);
+           psim_usage (0, 0, kind);
+           return NULL;
+         }
+       break;
       }
       p += 1;
     }
       }
       p += 1;
     }
@@ -279,6 +395,11 @@ psim_options(device *root,
               NULL, 0,
               device_ioctl_set_trace);
 
               NULL, 0,
               device_ioctl_set_trace);
 
+  {
+    void semantic_init(device* root);
+    semantic_init(root);
+  }
+
   /* return where the options end */
   return argv + argp;
 }
   /* return where the options end */
   return argv + argp;
 }
@@ -466,11 +587,33 @@ INLINE_PSIM\
 psim_restart(psim *system,
             int current_cpu)
 {
 psim_restart(psim *system,
             int current_cpu)
 {
+  ASSERT(current_cpu >= 0 && current_cpu < system->nr_cpus);
+  ASSERT(system->path_to_restart != NULL);
   system->last_cpu = current_cpu;
   longjmp(*(jmp_buf*)(system->path_to_restart), current_cpu + 1);
 }
 
 
   system->last_cpu = current_cpu;
   longjmp(*(jmp_buf*)(system->path_to_restart), current_cpu + 1);
 }
 
 
+static void
+cntrl_c_simulation(void *data)
+{
+  psim *system = data;
+  psim_halt(system,
+           psim_nr_cpus(system),
+           was_continuing,
+           GDB_SIGNAL_INT);
+}
+
+INLINE_PSIM\
+(void)
+psim_stop(psim *system)
+{
+  event_queue_schedule_after_signal(psim_event_queue(system),
+                                   0 /*NOW*/,
+                                   cntrl_c_simulation,
+                                   system);
+}
+
 INLINE_PSIM\
 (void)
 psim_halt(psim *system,
 INLINE_PSIM\
 (void)
 psim_halt(psim *system,
@@ -478,13 +621,21 @@ psim_halt(psim *system,
          stop_reason reason,
          int signal)
 {
          stop_reason reason,
          int signal)
 {
-  ASSERT(current_cpu >= 0 && current_cpu < system->nr_cpus);
+  ASSERT(current_cpu >= 0 && current_cpu <= system->nr_cpus);
+  ASSERT(system->path_to_halt != NULL);
   system->last_cpu = current_cpu;
   system->last_cpu = current_cpu;
-  system->halt_status.cpu_nr = current_cpu;
   system->halt_status.reason = reason;
   system->halt_status.signal = signal;
   system->halt_status.reason = reason;
   system->halt_status.signal = signal;
-  system->halt_status.program_counter =
-    cpu_get_program_counter(system->processors[current_cpu]);
+  if (current_cpu == system->nr_cpus) {
+    system->halt_status.cpu_nr = 0;
+    system->halt_status.program_counter =
+      cpu_get_program_counter(system->processors[0]);
+  }
+  else {
+    system->halt_status.cpu_nr = current_cpu;
+    system->halt_status.program_counter =
+      cpu_get_program_counter(system->processors[current_cpu]);
+  }
   longjmp(*(jmp_buf*)(system->path_to_halt), current_cpu + 1);
 }
 
   longjmp(*(jmp_buf*)(system->path_to_halt), current_cpu + 1);
 }
 
@@ -540,6 +691,18 @@ psim_event_queue(psim *system)
 
 
 
 
 
 
+STATIC_INLINE_PSIM\
+(void)
+psim_max_iterations_exceeded(void *data)
+{
+  psim *system = data;
+  psim_halt(system,
+           system->nr_cpus, /* halted during an event */
+           was_signalled,
+           -1);
+}
+
+
 INLINE_PSIM\
 (void)
 psim_init(psim *system)
 INLINE_PSIM\
 (void)
 psim_init(psim *system)
@@ -552,6 +715,17 @@ psim_init(psim *system)
   /* trash any pending events */
   event_queue_init(system->events);
 
   /* trash any pending events */
   event_queue_init(system->events);
 
+  /* if needed, schedule a halt event.  FIXME - In the future this
+     will be replaced by a more generic change to psim_command().  A
+     new command `schedule NNN halt' being added. */
+  if (tree_find_property(system->devices, "/openprom/options/max-iterations")) {
+    event_queue_schedule(system->events,
+                        tree_find_integer_property(system->devices,
+                                                   "/openprom/options/max-iterations") - 2,
+                        psim_max_iterations_exceeded,
+                        system);
+  }
+
   /* scrub all the cpus */
   for (cpu_nr = 0; cpu_nr < system->nr_cpus; cpu_nr++)
     cpu_init(system->processors[cpu_nr]);
   /* scrub all the cpus */
   for (cpu_nr = 0; cpu_nr < system->nr_cpus; cpu_nr++)
     cpu_init(system->processors[cpu_nr]);
@@ -569,8 +743,8 @@ psim_init(psim *system)
     cpu_page_tlb_invalidate_all(processor);
   }
 
     cpu_page_tlb_invalidate_all(processor);
   }
 
-  /* force loop to start with first cpu (after processing events) */
-  system->last_cpu = system->nr_cpus - 1;
+  /* force loop to start with first cpu */
+  system->last_cpu = -1;
 }
 
 INLINE_PSIM\
 }
 
 INLINE_PSIM\
@@ -585,7 +759,8 @@ psim_stack(psim *system,
                                          "/openprom/init/stack");
   if (stack_device != (device*)0) {
     unsigned_word stack_pointer;
                                          "/openprom/init/stack");
   if (stack_device != (device*)0) {
     unsigned_word stack_pointer;
-    psim_read_register(system, 0, &stack_pointer, "sp", cooked_transfer);
+    ASSERT (psim_read_register(system, 0, &stack_pointer, "sp",
+                              cooked_transfer) > 0);
     device_ioctl(stack_device,
                 NULL, /*cpu*/
                 0, /*cia*/
     device_ioctl(stack_device,
                 NULL, /*cpu*/
                 0, /*cia*/
@@ -618,21 +793,11 @@ psim_run(psim *system)
              system->events, system->processors, system->nr_cpus);
 }
 
              system->events, system->processors, system->nr_cpus);
 }
 
-INLINE_PSIM\
-(void)
-psim_run_until_stop(psim *system,
-                   volatile int *keep_running)
-{
-  idecode_run_until_stop(system, keep_running,
-                        system->events, system->processors, system->nr_cpus);
-}
-
-
 
 /* storage manipulation functions */
 
 INLINE_PSIM\
 
 /* storage manipulation functions */
 
 INLINE_PSIM\
-(void)
+(int)
 psim_read_register(psim *system,
                   int which_cpu,
                   void *buf,
 psim_read_register(psim *system,
                   int which_cpu,
                   void *buf,
@@ -640,20 +805,26 @@ psim_read_register(psim *system,
                   transfer_mode mode)
 {
   register_descriptions description;
                   transfer_mode mode)
 {
   register_descriptions description;
-  char cooked_buf[sizeof(unsigned_8)];
+  char *cooked_buf;
   cpu *processor;
 
   /* find our processor */
   cpu *processor;
 
   /* find our processor */
-  if (which_cpu == MAX_NR_PROCESSORS)
-    which_cpu = system->last_cpu;
-  if (which_cpu < 0 || which_cpu >= system->nr_cpus)
-    error("psim_read_register() - invalid processor %d\n", which_cpu);
+  if (which_cpu == MAX_NR_PROCESSORS) {
+    if (system->last_cpu == system->nr_cpus
+       || system->last_cpu == -1)
+      which_cpu = 0;
+    else
+      which_cpu = system->last_cpu;
+  }
+  ASSERT(which_cpu >= 0 && which_cpu < system->nr_cpus);
+
   processor = system->processors[which_cpu];
 
   /* find the register description */
   description = register_description(reg);
   if (description.type == reg_invalid)
   processor = system->processors[which_cpu];
 
   /* find the register description */
   description = register_description(reg);
   if (description.type == reg_invalid)
-    error("psim_read_register() invalid register name `%s'\n", reg);
+    return 0;
+  cooked_buf = alloca (description.size);
 
   /* get the cooked value */
   switch (description.type) {
 
   /* get the cooked value */
   switch (description.type) {
@@ -686,6 +857,10 @@ psim_read_register(psim *system,
     *(msreg*)cooked_buf = cpu_registers(processor)->msr;
     break;
 
     *(msreg*)cooked_buf = cpu_registers(processor)->msr;
     break;
 
+  case reg_fpscr:
+    *(fpscreg*)cooked_buf = cpu_registers(processor)->fpscr;
+    break;
+
   case reg_insns:
     *(unsigned_word*)cooked_buf = mon_get_number_of_insns(system->monitor,
                                                          which_cpu);
   case reg_insns:
     *(unsigned_word*)cooked_buf = mon_get_number_of_insns(system->monitor,
                                                          which_cpu);
@@ -703,6 +878,30 @@ psim_read_register(psim *system,
     *(unsigned_word*)cooked_buf = model_get_number_of_cycles(cpu_model(processor));
     break;
 
     *(unsigned_word*)cooked_buf = model_get_number_of_cycles(cpu_model(processor));
     break;
 
+#ifdef WITH_ALTIVEC
+  case reg_vr:
+    *(vreg*)cooked_buf = cpu_registers(processor)->altivec.vr[description.index];
+    break;
+
+  case reg_vscr:
+    *(vscreg*)cooked_buf = cpu_registers(processor)->altivec.vscr;
+    break;
+#endif
+
+#ifdef WITH_E500
+  case reg_gprh:
+    *(gpreg*)cooked_buf = cpu_registers(processor)->e500.gprh[description.index];
+    break;
+
+  case reg_evr:
+    *(unsigned64*)cooked_buf = EVR(description.index);
+    break;
+
+  case reg_acc:
+    *(accreg*)cooked_buf = cpu_registers(processor)->e500.acc;
+    break;
+#endif
+
   default:
     printf_filtered("psim_read_register(processor=0x%lx,buf=0x%lx,reg=%s) %s\n",
                    (unsigned long)processor, (unsigned long)buf, reg,
   default:
     printf_filtered("psim_read_register(processor=0x%lx,buf=0x%lx,reg=%s) %s\n",
                    (unsigned long)processor, (unsigned long)buf, reg,
@@ -728,18 +927,34 @@ psim_read_register(psim *system,
     case 8:
       *(unsigned_8*)buf = H2T_8(*(unsigned_8*)cooked_buf);
       break;
     case 8:
       *(unsigned_8*)buf = H2T_8(*(unsigned_8*)cooked_buf);
       break;
+#ifdef WITH_ALTIVEC
+    case 16:
+      if (CURRENT_HOST_BYTE_ORDER != CURRENT_TARGET_BYTE_ORDER)
+        {
+         union { vreg v; unsigned_8 d[2]; } h, t;
+          memcpy(&h.v/*dest*/, cooked_buf/*src*/, description.size);
+         { _SWAP_8(t.d[0] =, h.d[1]); }
+         { _SWAP_8(t.d[1] =, h.d[0]); }
+          memcpy(buf/*dest*/, &t/*src*/, description.size);
+          break;
+        }
+      else
+        memcpy(buf/*dest*/, cooked_buf/*src*/, description.size);
+      break;
+#endif
     }
   }
   else {
     memcpy(buf/*dest*/, cooked_buf/*src*/, description.size);
   }
 
     }
   }
   else {
     memcpy(buf/*dest*/, cooked_buf/*src*/, description.size);
   }
 
+  return description.size;
 }
 
 
 
 INLINE_PSIM\
 }
 
 
 
 INLINE_PSIM\
-(void)
+(int)
 psim_write_register(psim *system,
                    int which_cpu,
                    const void *buf,
 psim_write_register(psim *system,
                    int which_cpu,
                    const void *buf,
@@ -748,28 +963,33 @@ psim_write_register(psim *system,
 {
   cpu *processor;
   register_descriptions description;
 {
   cpu *processor;
   register_descriptions description;
-  char cooked_buf[sizeof(unsigned_8)];
+  char *cooked_buf;
 
   /* find our processor */
 
   /* find our processor */
-  if (which_cpu == MAX_NR_PROCESSORS)
-    which_cpu = system->last_cpu;
+  if (which_cpu == MAX_NR_PROCESSORS) {
+    if (system->last_cpu == system->nr_cpus
+       || system->last_cpu == -1)
+      which_cpu = 0;
+    else
+      which_cpu = system->last_cpu;
+  }
+
+  /* find the description of the register */
+  description = register_description(reg);
+  if (description.type == reg_invalid)
+    return 0;
+  cooked_buf = alloca (description.size);
+
   if (which_cpu == -1) {
     int i;
     for (i = 0; i < system->nr_cpus; i++)
       psim_write_register(system, i, buf, reg, mode);
   if (which_cpu == -1) {
     int i;
     for (i = 0; i < system->nr_cpus; i++)
       psim_write_register(system, i, buf, reg, mode);
-    return;
-  }
-  else if (which_cpu < 0 || which_cpu >= system->nr_cpus) {
-    error("psim_read_register() - invalid processor %d\n", which_cpu);
+    return description.size;
   }
   }
+  ASSERT(which_cpu >= 0 && which_cpu < system->nr_cpus);
 
   processor = system->processors[which_cpu];
 
 
   processor = system->processors[which_cpu];
 
-  /* find the description of the register */
-  description = register_description(reg);
-  if (description.type == reg_invalid)
-    error("psim_write_register() invalid register name %s\n", reg);
-
   /* If the data is comming in raw (target order), need to cook it
      into host order before putting it into PSIM's internal structures */
   if (mode == raw_transfer) {
   /* If the data is comming in raw (target order), need to cook it
      into host order before putting it into PSIM's internal structures */
   if (mode == raw_transfer) {
@@ -786,6 +1006,20 @@ psim_write_register(psim *system,
     case 8:
       *(unsigned_8*)cooked_buf = T2H_8(*(unsigned_8*)buf);
       break;
     case 8:
       *(unsigned_8*)cooked_buf = T2H_8(*(unsigned_8*)buf);
       break;
+#ifdef WITH_ALTIVEC
+    case 16:
+      if (CURRENT_HOST_BYTE_ORDER != CURRENT_TARGET_BYTE_ORDER)
+        {
+         union { vreg v; unsigned_8 d[2]; } h, t;
+          memcpy(&t.v/*dest*/, buf/*src*/, description.size);
+         { _SWAP_8(h.d[0] =, t.d[1]); }
+         { _SWAP_8(h.d[1] =, t.d[0]); }
+          memcpy(cooked_buf/*dest*/, &h/*src*/, description.size);
+          break;
+        }
+      else
+        memcpy(cooked_buf/*dest*/, buf/*src*/, description.size);
+#endif
     }
   }
   else {
     }
   }
   else {
@@ -823,6 +1057,39 @@ psim_write_register(psim *system,
     cpu_registers(processor)->msr = *(msreg*)cooked_buf;
     break;
 
     cpu_registers(processor)->msr = *(msreg*)cooked_buf;
     break;
 
+  case reg_fpscr:
+    cpu_registers(processor)->fpscr = *(fpscreg*)cooked_buf;
+    break;
+
+#ifdef WITH_E500
+  case reg_gprh:
+    cpu_registers(processor)->e500.gprh[description.index] = *(gpreg*)cooked_buf;
+    break;
+
+  case reg_evr:
+    {
+      unsigned64 v;
+      v = *(unsigned64*)cooked_buf;
+      cpu_registers(processor)->e500.gprh[description.index] = v >> 32;
+      cpu_registers(processor)->gpr[description.index] = v;
+      break;
+    }
+
+  case reg_acc:
+    cpu_registers(processor)->e500.acc = *(accreg*)cooked_buf;
+    break;
+#endif
+
+#ifdef WITH_ALTIVEC
+  case reg_vr:
+    cpu_registers(processor)->altivec.vr[description.index] = *(vreg*)cooked_buf;
+    break;
+
+  case reg_vscr:
+    cpu_registers(processor)->altivec.vscr = *(vscreg*)cooked_buf;
+    break;
+#endif
+
   default:
     printf_filtered("psim_write_register(processor=0x%lx,cooked_buf=0x%lx,reg=%s) %s\n",
                    (unsigned long)processor, (unsigned long)cooked_buf, reg,
   default:
     printf_filtered("psim_write_register(processor=0x%lx,cooked_buf=0x%lx,reg=%s) %s\n",
                    (unsigned long)processor, (unsigned long)cooked_buf, reg,
@@ -831,6 +1098,7 @@ psim_write_register(psim *system,
 
   }
 
 
   }
 
+  return description.size;
 }
 
 
 }
 
 
@@ -844,10 +1112,13 @@ psim_read_memory(psim *system,
                 unsigned nr_bytes)
 {
   cpu *processor;
                 unsigned nr_bytes)
 {
   cpu *processor;
-  if (which_cpu == MAX_NR_PROCESSORS)
-    which_cpu = system->last_cpu;
-  if (which_cpu < 0 || which_cpu >= system->nr_cpus)
-    error("psim_read_memory() invalid cpu\n");
+  if (which_cpu == MAX_NR_PROCESSORS) {
+    if (system->last_cpu == system->nr_cpus
+       || system->last_cpu == -1)
+      which_cpu = 0;
+    else
+      which_cpu = system->last_cpu;
+  }
   processor = system->processors[which_cpu];
   return vm_data_map_read_buffer(cpu_data_map(processor),
                                 buffer, vaddr, nr_bytes,
   processor = system->processors[which_cpu];
   return vm_data_map_read_buffer(cpu_data_map(processor),
                                 buffer, vaddr, nr_bytes,
@@ -865,10 +1136,14 @@ psim_write_memory(psim *system,
                  int violate_read_only_section)
 {
   cpu *processor;
                  int violate_read_only_section)
 {
   cpu *processor;
-  if (which_cpu == MAX_NR_PROCESSORS)
-    which_cpu = system->last_cpu;
-  if (which_cpu < 0 || which_cpu >= system->nr_cpus)
-    error("psim_read_memory() invalid cpu\n");
+  if (which_cpu == MAX_NR_PROCESSORS) {
+    if (system->last_cpu == system->nr_cpus
+       || system->last_cpu == -1)
+      which_cpu = 0;
+    else
+      which_cpu = system->last_cpu;
+  }
+  ASSERT(which_cpu >= 0 && which_cpu < system->nr_cpus);
   processor = system->processors[which_cpu];
   return vm_data_map_write_buffer(cpu_data_map(processor),
                                  buffer, vaddr, nr_bytes, 1/*violate-read-only*/,
   processor = system->processors[which_cpu];
   return vm_data_map_write_buffer(cpu_data_map(processor),
                                  buffer, vaddr, nr_bytes, 1/*violate-read-only*/,
This page took 0.030677 seconds and 4 git commands to generate.