include/
[external/binutils.git] / sim / arm / wrapper.c
index 9aa462e..b10eeca 100644 (file)
@@ -1,23 +1,21 @@
 /* run front end support for arm
-   Copyright (C) 1995, 1996, 1997, 2000, 2001, 2002
+   Copyright (C) 1995, 1996, 1997, 2000, 2001, 2002, 2007, 2008, 2009
    Free Software Foundation, Inc.
 
    This file is part of ARM SIM.
 
-   GCC 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, or (at your
-   option) any later version.
+   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 3 of the License, or
+   (at your option) any later version.
 
-   GCC is distributed in the hope that it will be useful, but
-   WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.   See
-   the GNU General Public License for more details.
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   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.  */
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
 
 /* This file provides the interface between the simulator and
    run.c and gdb (when the simulator is linked with gdb).
@@ -36,6 +34,8 @@
 #include "ansidecl.h"
 #include "sim-utils.h"
 #include "run-sim.h"
+#include "gdb/sim-arm.h"
+#include "gdb/signals.h"
 
 host_callback *sim_callback;
 
@@ -48,7 +48,7 @@ static SIM_OPEN_KIND sim_kind;
 static char *myname;
 
 /* Memory size in bytes.  */
-static int mem_size = (1 << 23);
+static int mem_size = (1 << 21);
 
 /* Non-zero to display start up banner, and maybe other things.  */
 static int verbosity;
@@ -58,6 +58,38 @@ static int big_endian;
 
 int stop_simulator;
 
+/* Cirrus DSP registers.
+
+   We need to define these registers outside of maverick.c because
+   maverick.c might not be linked in unless --target=arm9e-* in which
+   case wrapper.c will not compile because it tries to access Cirrus
+   registers.  This should all go away once we get the Cirrus and ARM
+   Coprocessor to coexist in armcopro.c-- aldyh.  */
+
+struct maverick_regs
+{
+  union
+  {
+    int i;
+    float f;
+  } upper;
+  
+  union
+  {
+    int i;
+    float f;
+  } lower;
+};
+
+union maverick_acc_regs
+{
+  long double ld;              /* Acc registers are 72-bits.  */
+};
+
+struct maverick_regs     DSPregs[16];
+union maverick_acc_regs  DSPacc[4];
+ARMword DSPsc;
+
 static void
 init ()
 {
@@ -70,7 +102,6 @@ init ()
       state->bigendSig = (big_endian ? HIGH : LOW);
       ARMul_MemoryInit (state, mem_size);
       ARMul_OSInit (state);
-      ARMul_CoProInit (state);
       state->verbose = verbosity;
       done = 1;
     }
@@ -203,7 +234,7 @@ sim_resume (sd, step, siggnal)
 SIM_RC
 sim_create_inferior (sd, abfd, argv, env)
      SIM_DESC sd ATTRIBUTE_UNUSED;
-     struct _bfd * abfd;
+     struct bfd * abfd;
      char ** argv;
      char ** env;
 {
@@ -231,8 +262,36 @@ sim_create_inferior (sd, abfd, argv, env)
       /* We wouldn't set the machine type with earlier toolchains, so we
         explicitly select a processor capable of supporting all ARMs in
         32bit mode.  */
+      /* We choose the XScale rather than the iWMMXt, because the iWMMXt
+        removes the FPE emulator, since it conflicts with its coprocessors.
+        For the most generic ARM support, we want the FPE emulator in place.  */
     case bfd_mach_arm_XScale:
-      ARMul_SelectProcessor (state, ARM_v5_Prop | ARM_v5e_Prop | ARM_XScale_Prop);
+      ARMul_SelectProcessor (state, ARM_v5_Prop | ARM_v5e_Prop | ARM_XScale_Prop | ARM_v6_Prop);
+      break;
+
+    case bfd_mach_arm_iWMMXt:
+      {
+       extern int SWI_vector_installed;
+       ARMword i;
+
+       if (! SWI_vector_installed)
+         {
+           /* Intialise the hardware vectors to zero.  */
+           if (! SWI_vector_installed)
+             for (i = ARMul_ResetV; i <= ARMFIQV; i += 4)
+               ARMul_WriteWord (state, i, 0);
+
+           /* ARM_WriteWord will have detected the write to the SWI vector,
+              but we want SWI_vector_installed to remain at 0 so that thumb
+              mode breakpoints will work.  */
+           SWI_vector_installed = 0;
+         }
+      }
+      ARMul_SelectProcessor (state, ARM_v5_Prop | ARM_v5e_Prop | ARM_XScale_Prop | ARM_iWMMXt_Prop);
+      break;
+
+    case bfd_mach_arm_ep9312:
+      ARMul_SelectProcessor (state, ARM_v4_Prop | ARM_ep9312_Prop);
       break;
 
     case bfd_mach_arm_5:
@@ -386,13 +445,103 @@ sim_store_register (sd, rn, memory, length)
 {
   init ();
 
-  if (rn == 25)
+  switch ((enum sim_arm_regs) rn)
     {
+    case SIM_ARM_R0_REGNUM:
+    case SIM_ARM_R1_REGNUM:
+    case SIM_ARM_R2_REGNUM:
+    case SIM_ARM_R3_REGNUM:
+    case SIM_ARM_R4_REGNUM:
+    case SIM_ARM_R5_REGNUM:
+    case SIM_ARM_R6_REGNUM:
+    case SIM_ARM_R7_REGNUM:
+    case SIM_ARM_R8_REGNUM:
+    case SIM_ARM_R9_REGNUM:
+    case SIM_ARM_R10_REGNUM:
+    case SIM_ARM_R11_REGNUM:
+    case SIM_ARM_R12_REGNUM:
+    case SIM_ARM_R13_REGNUM:
+    case SIM_ARM_R14_REGNUM:
+    case SIM_ARM_R15_REGNUM: /* PC */
+    case SIM_ARM_FP0_REGNUM:
+    case SIM_ARM_FP1_REGNUM:
+    case SIM_ARM_FP2_REGNUM:
+    case SIM_ARM_FP3_REGNUM:
+    case SIM_ARM_FP4_REGNUM:
+    case SIM_ARM_FP5_REGNUM:
+    case SIM_ARM_FP6_REGNUM:
+    case SIM_ARM_FP7_REGNUM:
+    case SIM_ARM_FPS_REGNUM:
+      ARMul_SetReg (state, state->Mode, rn, frommem (state, memory));
+      break;
+
+    case SIM_ARM_PS_REGNUM:
       state->Cpsr = frommem (state, memory);
       ARMul_CPSRAltered (state);
+      break;
+
+    case SIM_ARM_MAVERIC_COP0R0_REGNUM:
+    case SIM_ARM_MAVERIC_COP0R1_REGNUM:
+    case SIM_ARM_MAVERIC_COP0R2_REGNUM:
+    case SIM_ARM_MAVERIC_COP0R3_REGNUM:
+    case SIM_ARM_MAVERIC_COP0R4_REGNUM:
+    case SIM_ARM_MAVERIC_COP0R5_REGNUM:
+    case SIM_ARM_MAVERIC_COP0R6_REGNUM:
+    case SIM_ARM_MAVERIC_COP0R7_REGNUM:
+    case SIM_ARM_MAVERIC_COP0R8_REGNUM:
+    case SIM_ARM_MAVERIC_COP0R9_REGNUM:
+    case SIM_ARM_MAVERIC_COP0R10_REGNUM:
+    case SIM_ARM_MAVERIC_COP0R11_REGNUM:
+    case SIM_ARM_MAVERIC_COP0R12_REGNUM:
+    case SIM_ARM_MAVERIC_COP0R13_REGNUM:
+    case SIM_ARM_MAVERIC_COP0R14_REGNUM:
+    case SIM_ARM_MAVERIC_COP0R15_REGNUM:
+      memcpy (& DSPregs [rn - SIM_ARM_MAVERIC_COP0R0_REGNUM],
+             memory, sizeof (struct maverick_regs));
+      return sizeof (struct maverick_regs);
+
+    case SIM_ARM_MAVERIC_DSPSC_REGNUM:
+      memcpy (&DSPsc, memory, sizeof DSPsc);
+      return sizeof DSPsc;
+
+    case SIM_ARM_IWMMXT_COP0R0_REGNUM:
+    case SIM_ARM_IWMMXT_COP0R1_REGNUM:
+    case SIM_ARM_IWMMXT_COP0R2_REGNUM:
+    case SIM_ARM_IWMMXT_COP0R3_REGNUM:
+    case SIM_ARM_IWMMXT_COP0R4_REGNUM:
+    case SIM_ARM_IWMMXT_COP0R5_REGNUM:
+    case SIM_ARM_IWMMXT_COP0R6_REGNUM:
+    case SIM_ARM_IWMMXT_COP0R7_REGNUM:
+    case SIM_ARM_IWMMXT_COP0R8_REGNUM:
+    case SIM_ARM_IWMMXT_COP0R9_REGNUM:
+    case SIM_ARM_IWMMXT_COP0R10_REGNUM:
+    case SIM_ARM_IWMMXT_COP0R11_REGNUM:
+    case SIM_ARM_IWMMXT_COP0R12_REGNUM:
+    case SIM_ARM_IWMMXT_COP0R13_REGNUM:
+    case SIM_ARM_IWMMXT_COP0R14_REGNUM:
+    case SIM_ARM_IWMMXT_COP0R15_REGNUM:
+    case SIM_ARM_IWMMXT_COP1R0_REGNUM:
+    case SIM_ARM_IWMMXT_COP1R1_REGNUM:
+    case SIM_ARM_IWMMXT_COP1R2_REGNUM:
+    case SIM_ARM_IWMMXT_COP1R3_REGNUM:
+    case SIM_ARM_IWMMXT_COP1R4_REGNUM:
+    case SIM_ARM_IWMMXT_COP1R5_REGNUM:
+    case SIM_ARM_IWMMXT_COP1R6_REGNUM:
+    case SIM_ARM_IWMMXT_COP1R7_REGNUM:
+    case SIM_ARM_IWMMXT_COP1R8_REGNUM:
+    case SIM_ARM_IWMMXT_COP1R9_REGNUM:
+    case SIM_ARM_IWMMXT_COP1R10_REGNUM:
+    case SIM_ARM_IWMMXT_COP1R11_REGNUM:
+    case SIM_ARM_IWMMXT_COP1R12_REGNUM:
+    case SIM_ARM_IWMMXT_COP1R13_REGNUM:
+    case SIM_ARM_IWMMXT_COP1R14_REGNUM:
+    case SIM_ARM_IWMMXT_COP1R15_REGNUM:
+      return Store_Iwmmxt_Register (rn - SIM_ARM_IWMMXT_COP0R0_REGNUM, memory);
+
+    default:
+      return 0;
     }
-  else
-    ARMul_SetReg (state, state->Mode, rn, frommem (state, memory));
+
   return -1;
 }
 
@@ -407,14 +556,104 @@ sim_fetch_register (sd, rn, memory, length)
 
   init ();
 
-  if (rn < 16)
-    regval = ARMul_GetReg (state, state->Mode, rn);
-  else if (rn == 25)
-    /* FIXME: use PS_REGNUM from gdb/config/arm/tm-arm.h.  */
-    regval = ARMul_GetCPSR (state);
-  else
-    /* FIXME: should report an error.  */
-    regval = 0;
+  switch ((enum sim_arm_regs) rn)
+    {
+    case SIM_ARM_R0_REGNUM:
+    case SIM_ARM_R1_REGNUM:
+    case SIM_ARM_R2_REGNUM:
+    case SIM_ARM_R3_REGNUM:
+    case SIM_ARM_R4_REGNUM:
+    case SIM_ARM_R5_REGNUM:
+    case SIM_ARM_R6_REGNUM:
+    case SIM_ARM_R7_REGNUM:
+    case SIM_ARM_R8_REGNUM:
+    case SIM_ARM_R9_REGNUM:
+    case SIM_ARM_R10_REGNUM:
+    case SIM_ARM_R11_REGNUM:
+    case SIM_ARM_R12_REGNUM:
+    case SIM_ARM_R13_REGNUM:
+    case SIM_ARM_R14_REGNUM:
+    case SIM_ARM_R15_REGNUM: /* PC */
+      regval = ARMul_GetReg (state, state->Mode, rn);
+      break;
+
+    case SIM_ARM_FP0_REGNUM:
+    case SIM_ARM_FP1_REGNUM:
+    case SIM_ARM_FP2_REGNUM:
+    case SIM_ARM_FP3_REGNUM:
+    case SIM_ARM_FP4_REGNUM:
+    case SIM_ARM_FP5_REGNUM:
+    case SIM_ARM_FP6_REGNUM:
+    case SIM_ARM_FP7_REGNUM:
+    case SIM_ARM_FPS_REGNUM:
+      memset (memory, 0, length);
+      return 0;
+
+    case SIM_ARM_PS_REGNUM:
+      regval = ARMul_GetCPSR (state);
+      break;
+
+    case SIM_ARM_MAVERIC_COP0R0_REGNUM:
+    case SIM_ARM_MAVERIC_COP0R1_REGNUM:
+    case SIM_ARM_MAVERIC_COP0R2_REGNUM:
+    case SIM_ARM_MAVERIC_COP0R3_REGNUM:
+    case SIM_ARM_MAVERIC_COP0R4_REGNUM:
+    case SIM_ARM_MAVERIC_COP0R5_REGNUM:
+    case SIM_ARM_MAVERIC_COP0R6_REGNUM:
+    case SIM_ARM_MAVERIC_COP0R7_REGNUM:
+    case SIM_ARM_MAVERIC_COP0R8_REGNUM:
+    case SIM_ARM_MAVERIC_COP0R9_REGNUM:
+    case SIM_ARM_MAVERIC_COP0R10_REGNUM:
+    case SIM_ARM_MAVERIC_COP0R11_REGNUM:
+    case SIM_ARM_MAVERIC_COP0R12_REGNUM:
+    case SIM_ARM_MAVERIC_COP0R13_REGNUM:
+    case SIM_ARM_MAVERIC_COP0R14_REGNUM:
+    case SIM_ARM_MAVERIC_COP0R15_REGNUM:
+      memcpy (memory, & DSPregs [rn - SIM_ARM_MAVERIC_COP0R0_REGNUM],
+             sizeof (struct maverick_regs));
+      return sizeof (struct maverick_regs);
+
+    case SIM_ARM_MAVERIC_DSPSC_REGNUM:
+      memcpy (memory, & DSPsc, sizeof DSPsc);
+      return sizeof DSPsc;
+
+    case SIM_ARM_IWMMXT_COP0R0_REGNUM:
+    case SIM_ARM_IWMMXT_COP0R1_REGNUM:
+    case SIM_ARM_IWMMXT_COP0R2_REGNUM:
+    case SIM_ARM_IWMMXT_COP0R3_REGNUM:
+    case SIM_ARM_IWMMXT_COP0R4_REGNUM:
+    case SIM_ARM_IWMMXT_COP0R5_REGNUM:
+    case SIM_ARM_IWMMXT_COP0R6_REGNUM:
+    case SIM_ARM_IWMMXT_COP0R7_REGNUM:
+    case SIM_ARM_IWMMXT_COP0R8_REGNUM:
+    case SIM_ARM_IWMMXT_COP0R9_REGNUM:
+    case SIM_ARM_IWMMXT_COP0R10_REGNUM:
+    case SIM_ARM_IWMMXT_COP0R11_REGNUM:
+    case SIM_ARM_IWMMXT_COP0R12_REGNUM:
+    case SIM_ARM_IWMMXT_COP0R13_REGNUM:
+    case SIM_ARM_IWMMXT_COP0R14_REGNUM:
+    case SIM_ARM_IWMMXT_COP0R15_REGNUM:
+    case SIM_ARM_IWMMXT_COP1R0_REGNUM:
+    case SIM_ARM_IWMMXT_COP1R1_REGNUM:
+    case SIM_ARM_IWMMXT_COP1R2_REGNUM:
+    case SIM_ARM_IWMMXT_COP1R3_REGNUM:
+    case SIM_ARM_IWMMXT_COP1R4_REGNUM:
+    case SIM_ARM_IWMMXT_COP1R5_REGNUM:
+    case SIM_ARM_IWMMXT_COP1R6_REGNUM:
+    case SIM_ARM_IWMMXT_COP1R7_REGNUM:
+    case SIM_ARM_IWMMXT_COP1R8_REGNUM:
+    case SIM_ARM_IWMMXT_COP1R9_REGNUM:
+    case SIM_ARM_IWMMXT_COP1R10_REGNUM:
+    case SIM_ARM_IWMMXT_COP1R11_REGNUM:
+    case SIM_ARM_IWMMXT_COP1R12_REGNUM:
+    case SIM_ARM_IWMMXT_COP1R13_REGNUM:
+    case SIM_ARM_IWMMXT_COP1R14_REGNUM:
+    case SIM_ARM_IWMMXT_COP1R15_REGNUM:
+      return Fetch_Iwmmxt_Register (rn - SIM_ARM_IWMMXT_COP0R0_REGNUM, memory);
+
+    default:
+      return 0;
+    }
 
   while (length)
     {
@@ -529,13 +768,16 @@ sim_target_parse_arg_array (argv)
   for (i = 0; argv[i]; i++)
     ;
 
-  return (void) sim_target_parse_command_line (i, argv);
+  sim_target_parse_command_line (i, argv);
 }
 
 void
-sim_target_display_usage ()
+sim_target_display_usage (help)
+     int help;
 {
-  fprintf (stderr, "%s=<list>  Comma seperated list of SWI protocols to supoport.\n\
+  FILE *stream = help ? stdout : stderr;
+
+  fprintf (stream, "%s=<list>  Comma seperated list of SWI protocols to supoport.\n\
                 This list can contain: NONE, DEMON, ANGEL, REDBOOT and/or ALL.\n",
           SWI_SWITCH);
 }
@@ -545,7 +787,7 @@ SIM_DESC
 sim_open (kind, ptr, abfd, argv)
      SIM_OPEN_KIND kind;
      host_callback *ptr;
-     struct _bfd *abfd;
+     struct bfd *abfd;
      char **argv;
 {
   sim_kind = kind;
@@ -567,7 +809,7 @@ sim_open (kind, ptr, abfd, argv)
     {
       int i;
 
-      /* Scan for endian-ness switch.  */
+      /* Scan for endian-ness and memory-size switches.  */
       for (i = 0; (argv[i] != NULL) && (argv[i][0] != 0); i++)
        if (argv[i][0] == '-' && argv[i][1] == 'E')
          {
@@ -602,6 +844,23 @@ sim_open (kind, ptr, abfd, argv)
                break;
              }
          }
+       else if (argv[i][0] == '-' && argv[i][1] == 'm')
+         {
+           if (argv[i][2] != '\0')
+             sim_size (atoi (&argv[i][2]));
+           else if (argv[i + 1] != NULL)
+             {
+               sim_size (atoi (argv[i + 1]));
+               i++;
+             }
+           else
+             {
+               sim_callback->printf_filtered (sim_callback,
+                                              "Missing argument to -m option\n");
+               return NULL;
+             }
+             
+         }
     }
 
   return (SIM_DESC) 1;
@@ -645,7 +904,7 @@ sim_stop_reason (sd, reason, sigrc)
   if (stop_simulator)
     {
       *reason = sim_stopped;
-      *sigrc = SIGINT;
+      *sigrc = TARGET_SIGNAL_INT;
     }
   else if (state->EndCondition == 0)
     {
@@ -656,7 +915,10 @@ sim_stop_reason (sd, reason, sigrc)
     {
       *reason = sim_stopped;
       if (state->EndCondition == RDIError_BreakpointReached)
-       *sigrc = SIGTRAP;
+       *sigrc = TARGET_SIGNAL_TRAP;
+      else if (   state->EndCondition == RDIError_DataAbort
+              || state->EndCondition == RDIError_AddressException)
+       *sigrc = TARGET_SIGNAL_BUS;
       else
        *sigrc = 0;
     }