OSDN Git Service

Add support for v4 SystemMode.
authornickc <nickc>
Tue, 30 May 2000 17:13:37 +0000 (17:13 +0000)
committernickc <nickc>
Tue, 30 May 2000 17:13:37 +0000 (17:13 +0000)
sim/arm/ChangeLog
sim/arm/Makefile.in
sim/arm/armcopro.c
sim/arm/armdefs.h
sim/arm/armemu.c
sim/arm/arminit.c
sim/arm/armos.c
sim/arm/armsupp.c
sim/arm/configure
sim/arm/configure.in
sim/arm/wrapper.c

index b58b9ad..f7b7895 100644 (file)
@@ -1,4 +1,30 @@
-Tue May 23 21:39:23 2000  Andrew Cagney  <cagney@b1.cygnus.com>
+2000-05-25  Nick Clifton  <nickc@cygnus.com>
+
+       * armcopro.c (MMUMCR): Only indicate mode change if a singal has
+       really changed.
+       (MMUWrite): Only indicate mode change if a singal has really
+       changed.
+
+       * armdefs.h (SYSTEMMODE): Define.
+       (BANK_CAN_ACEESS_SPSR): Define.
+
+       * armemu.c (ARM_Emulate26): If the mode has changed allow the PC
+       to advance before stopping the emulation.
+
+       * arminit.c (ARMul_Reset): Ensure Mode field of State is set
+       correctly.
+
+       * armos.c (ARMul_OSInit): Create a initial stack pointer for
+       System mode.
+
+       * armsupp.c (ModeToBank): Remove unused first parameter.
+       Add support for System Mode.
+       (ARMul_GetSPSR): Use BANK_CAN_ACCESS_SPSR macro.
+       (ARMul_SetSPSR): Use BANK_CAN_ACCESS_SPSR macro.
+       (ARMul_FixSPSR): Use BANK_CAN_ACCESS_SPSR macro.
+       (ARMulSwitchMode): Add support for System Mode.
+
+Wed May 24 14:40:34 2000  Andrew Cagney  <cagney@b1.cygnus.com>
 
        * configure: Regenerated to track ../common/aclocal.m4 changes.
 
index b6ae2af..19a9bca 100644 (file)
 
 ## COMMON_PRE_CONFIG_FRAG
 
-SIM_EXTRA_CFLAGS = -DMODET
+SIM_EXTRA_CFLAGS = -DMODET -DNEED_UI_LOOP_HOOK
 
-SIM_OBJS = armcopro.o armemu26.o armemu32.o arminit.o armos.o armsupp.o \
-       armvirt.o bag.o thumbemu.o wrapper.o sim-load.o
+COPRO=@COPRO@
+
+SIM_OBJS = armemu26.o armemu32.o arminit.o armos.o armsupp.o \
+       armvirt.o bag.o thumbemu.o wrapper.o sim-load.o $(COPRO) 
 
 ## COMMON_POST_CONFIG_FRAG
 
 
 armos.o: armos.c armdefs.h armos.h armfpe.h
 
-armcopro.o: armcopro.c armdefs.h 
+armcopro.o: armcopro.c armdefs.h
 
 armemu26.o: armemu.c armdefs.h armemu.h 
        $(CC) -c $< -o armemu26.o $(ALL_CFLAGS)
index 579446c..48be680 100644 (file)
@@ -16,6 +16,7 @@
     Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
 
 #include "armdefs.h"
+#include "armemu.h"
 #include "ansidecl.h"
 
 extern unsigned ARMul_CoProInit (ARMul_State * state);
@@ -79,15 +80,29 @@ MMUMCR (ARMul_State * state, unsigned type ATTRIBUTE_UNUSED, ARMword instr, ARMw
   int reg = BITS (16, 19) & 7;
 
   MMUReg[reg] = value;
+  
   if (reg == 1)
     {
+      ARMword p,d,l,b;
+
+      p = state->prog32Sig;
+      d = state->data32Sig;
+      l = state->lateabtSig;
+      b = state->bigendSig;
+      
       state->prog32Sig = value >> 4 & 1;
       state->data32Sig = value >> 5 & 1;
       state->lateabtSig = value >> 6 & 1;
       state->bigendSig = value >> 7 & 1;
-      state->Emulate = TRUE;   /* force ARMulator to notice these now ! */
+
+      if (p != state->prog32Sig
+         || d != state->data32Sig
+         || l != state->lateabtSig
+         || b != state->bigendSig)
+       state->Emulate = CHANGEMODE;    /* Force ARMulator to notice these now.  */
     }
-  return (ARMul_DONE);
+  
+  return ARMul_DONE;
 }
 
 
@@ -106,15 +121,30 @@ MMUWrite (ARMul_State * state, unsigned reg, ARMword value)
 {
   if (reg < 8)
     MMUReg[reg] = value;
+  
   if (reg == 1)
     {
+      ARMword p,d,l,b;
+
+      p = state->prog32Sig;
+      d = state->data32Sig;
+      l = state->lateabtSig;
+      b = state->bigendSig;
+      
       state->prog32Sig = value >> 4 & 1;
       state->data32Sig = value >> 5 & 1;
       state->lateabtSig = value >> 6 & 1;
       state->bigendSig = value >> 7 & 1;
-      state->Emulate = TRUE;   /* force ARMulator to notice these now ! */
+
+      
+      if (p != state->prog32Sig
+         || d != state->data32Sig
+         || l != state->lateabtSig
+         || b != state->bigendSig)
+       state->Emulate = CHANGEMODE;    /* Force ARMulator to notice these now.  */
     }
-  return (TRUE);
+  
+  return TRUE;
 }
 
 
index bce638d..b23f26f 100644 (file)
@@ -200,16 +200,17 @@ struct ARMul_State
 *                          Mode and Bank Constants                          *
 \***************************************************************************/
 
-#define USER26MODE 0L
-#define FIQ26MODE 1L
-#define IRQ26MODE 2L
-#define SVC26MODE 3L
-#define USER32MODE 16L
-#define FIQ32MODE 17L
-#define IRQ32MODE 18L
-#define SVC32MODE 19L
+#define USER26MODE   0L
+#define FIQ26MODE    1L
+#define IRQ26MODE    2L
+#define SVC26MODE    3L
+#define USER32MODE  16L
+#define FIQ32MODE   17L
+#define IRQ32MODE   18L
+#define SVC32MODE   19L
 #define ABORT32MODE 23L
 #define UNDEF32MODE 27L
+#define SYSTEMMODE  31L
 
 #define ARM32BITMODE (state->Mode > 3)
 #define ARM26BITMODE (state->Mode <= 3)
@@ -225,6 +226,10 @@ struct ARMul_State
 #define ABORTBANK 4
 #define UNDEFBANK 5
 #define DUMMYBANK 6
+#define SYSTEMBANK 7
+
+#define BANK_CAN_ACCESS_SPSR(bank)  \
+  ((bank) != USERBANK && (bank) != SYSTEMBANK && (bank) != DUMMYBANK)
 
 /***************************************************************************\
 *                  Definitons of things in the emulator                     *
index d890cda..acbcb75 100644 (file)
@@ -2864,6 +2864,9 @@ ARMul_Emulate26 (register ARMul_State * state)
 
       if (state->Emulate == ONCE)
        state->Emulate = STOP;
+      /* If we have changed mode, allow the PC to advance before stopping.  */
+      else if (state->Emulate == CHANGEMODE)
+       continue;
       else if (state->Emulate != RUN)
        break;
     }
@@ -2872,7 +2875,8 @@ ARMul_Emulate26 (register ARMul_State * state)
   state->decoded = decoded;
   state->loaded = loaded;
   state->pc = pc;
-  return (pc);
+
+  return pc;
 }                              /* Emulate 26/32 in instruction based mode */
 
 
index 9ef7b1c..0105c17 100644 (file)
 *                 Definitions for the emulator architecture                 *
 \***************************************************************************/
 
-void ARMul_EmulateInit(void) ;
-ARMul_State *ARMul_NewState(void) ;
-void ARMul_Reset(ARMul_State *state) ;
-ARMword ARMul_DoCycle(ARMul_State *state) ;
-unsigned ARMul_DoCoPro(ARMul_State *state) ;
-ARMword ARMul_DoProg(ARMul_State *state) ;
-ARMword ARMul_DoInstr(ARMul_State *state) ;
-void ARMul_Abort(ARMul_State *state, ARMword address) ;
-
-unsigned ARMul_MultTable[32] = {1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,
-                                10,10,11,11,12,12,13,13,14,14,15,15,16,16,16} ;
-ARMword ARMul_ImmedTable[4096] ; /* immediate DP LHS values */
-char ARMul_BitList[256] ; /* number of bits in a byte table */
+void ARMul_EmulateInit (void);
+ARMul_State *ARMul_NewState (void);
+void ARMul_Reset (ARMul_State * state);
+ARMword ARMul_DoCycle (ARMul_State * state);
+unsigned ARMul_DoCoPro (ARMul_State * state);
+ARMword ARMul_DoProg (ARMul_State * state);
+ARMword ARMul_DoInstr (ARMul_State * state);
+void ARMul_Abort (ARMul_State * state, ARMword address);
+
+unsigned ARMul_MultTable[32] =
+  { 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9,
+  10, 10, 11, 11, 12, 12, 13, 13, 14, 14, 15, 15, 16, 16, 16
+};
+ARMword ARMul_ImmedTable[4096];        /* immediate DP LHS values */
+char ARMul_BitList[256];       /* number of bits in a byte table */
 
 /***************************************************************************\
 *         Call this routine once to set up the emulator's tables.           *
 \***************************************************************************/
 
-void ARMul_EmulateInit(void)
-{unsigned long i, j ;
+void
+ARMul_EmulateInit (void)
+{
+  unsigned long i, j;
 
- for (i = 0 ; i < 4096 ; i++) { /* the values of 12 bit dp rhs's */
-    ARMul_ImmedTable[i] = ROTATER(i & 0xffL,(i >> 7L) & 0x1eL) ;
+  for (i = 0; i < 4096; i++)
+    {                          /* the values of 12 bit dp rhs's */
+      ARMul_ImmedTable[i] = ROTATER (i & 0xffL, (i >> 7L) & 0x1eL);
     }
 
- for (i = 0 ; i < 256 ; ARMul_BitList[i++] = 0 ) ; /* how many bits in LSM */
- for (j = 1 ; j < 256 ; j <<= 1)
-    for (i = 0 ; i < 256 ; i++)
-       if ((i & j) > 0 )
-          ARMul_BitList[i]++ ;
+  for (i = 0; i < 256; ARMul_BitList[i++] = 0);        /* how many bits in LSM */
+  for (j = 1; j < 256; j <<= 1)
+    for (i = 0; i < 256; i++)
+      if ((i & j) > 0)
+       ARMul_BitList[i]++;
+
+  for (i = 0; i < 256; i++)
+    ARMul_BitList[i] *= 4;     /* you always need 4 times these values */
 
-  for (i = 0 ; i < 256 ; i++)
-    ARMul_BitList[i] *= 4 ; /* you always need 4 times these values */
-    
 }
 
 /***************************************************************************\
 *            Returns a new instantiation of the ARMulator's state           *
 \***************************************************************************/
 
-ARMul_State *ARMul_NewState(void)
-{ARMul_State *state ;
- unsigned i, j ;
-
- state = (ARMul_State *)malloc(sizeof(ARMul_State)) ;
- memset (state, 0, sizeof (ARMul_State));
-
- state->Emulate = RUN ;
- for (i = 0 ; i < 16 ; i++) {
-    state->Reg[i] = 0 ;
-    for (j = 0 ; j < 7 ; j++)
-       state->RegBank[j][i] = 0 ;
+ARMul_State *
+ARMul_NewState (void)
+{
+  ARMul_State *state;
+  unsigned i, j;
+
+  state = (ARMul_State *) malloc (sizeof (ARMul_State));
+  memset (state, 0, sizeof (ARMul_State));
+
+  state->Emulate = RUN;
+  for (i = 0; i < 16; i++)
+    {
+      state->Reg[i] = 0;
+      for (j = 0; j < 7; j++)
+       state->RegBank[j][i] = 0;
     }
- for (i = 0 ; i < 7 ; i++)
-    state->Spsr[i] = 0 ;
- state->Mode = 0 ;
-
- state->CallDebug = FALSE ;
- state->Debug = FALSE ;
- state->VectorCatch = 0 ;
- state->Aborted = FALSE ;
- state->Reseted = FALSE ;
- state->Inted = 3 ;
- state->LastInted = 3 ;
-
- state->MemDataPtr = NULL ;
- state->MemInPtr = NULL ;
- state->MemOutPtr = NULL ;
- state->MemSparePtr = NULL ;
- state->MemSize = 0 ;
-
- state->OSptr = NULL ;
- state->CommandLine = NULL ;
-
- state->EventSet = 0 ;
- state->Now = 0 ;
- state->EventPtr = (struct EventNode **)malloc((unsigned)EVENTLISTSIZE *
-                                               sizeof(struct EventNode *)) ;
- for (i = 0 ; i < EVENTLISTSIZE ; i++)
-    *(state->EventPtr + i) = NULL ;
+  for (i = 0; i < 7; i++)
+    state->Spsr[i] = 0;
+  
+  state->Mode = USER26MODE;
+
+  state->CallDebug = FALSE;
+  state->Debug = FALSE;
+  state->VectorCatch = 0;
+  state->Aborted = FALSE;
+  state->Reseted = FALSE;
+  state->Inted = 3;
+  state->LastInted = 3;
+
+  state->MemDataPtr = NULL;
+  state->MemInPtr = NULL;
+  state->MemOutPtr = NULL;
+  state->MemSparePtr = NULL;
+  state->MemSize = 0;
+
+  state->OSptr = NULL;
+  state->CommandLine = NULL;
+
+  state->EventSet = 0;
+  state->Now = 0;
+  state->EventPtr = (struct EventNode **) malloc ((unsigned) EVENTLISTSIZE *
+                                                 sizeof (struct EventNode
+                                                         *));
+  for (i = 0; i < EVENTLISTSIZE; i++)
+    *(state->EventPtr + i) = NULL;
 
 #ifdef ARM61
state->prog32Sig = LOW ;
state->data32Sig = LOW ;
 state->prog32Sig = LOW;
 state->data32Sig = LOW;
 #else
state->prog32Sig = HIGH ;
state->data32Sig = HIGH ;
 state->prog32Sig = HIGH;
 state->data32Sig = HIGH;
 #endif
 
state->lateabtSig = LOW ;
state->bigendSig = LOW ;
 state->lateabtSig = LOW;
 state->bigendSig = LOW;
 
ARMul_Reset(state) ;
return(state) ;
- }
 ARMul_Reset (state);
 return (state);
+}
 
 /***************************************************************************\
 *       Call this routine to set ARMulator to model a certain processor     *
 \***************************************************************************/
-void ARMul_SelectProcessor(ARMul_State *state, unsigned processor) {
-  if (processor & ARM_Fix26_Prop) {
-    state->prog32Sig = LOW;
-    state->data32Sig = LOW;
-  }else{
-    state->prog32Sig = HIGH;
-    state->data32Sig = HIGH;
-  }
+
+void
+ARMul_SelectProcessor (ARMul_State * state, unsigned processor)
+{
+  if (processor & ARM_Fix26_Prop)
+    {
+      state->prog32Sig = LOW;
+      state->data32Sig = LOW;
+    }
+  else
+    {
+      state->prog32Sig = HIGH;
+      state->data32Sig = HIGH;
+    }
+
   state->lateabtSig = LOW;
 }
 
@@ -138,41 +153,50 @@ void ARMul_SelectProcessor(ARMul_State *state, unsigned processor) {
 * Call this routine to set up the initial machine state (or perform a RESET *
 \***************************************************************************/
 
-void ARMul_Reset(ARMul_State *state)
-{state->NextInstr = 0 ;
- if (state->prog32Sig) {
-    state->Reg[15] = 0 ;
-    state->Cpsr = INTBITS | SVC32MODE ;
+void
+ARMul_Reset (ARMul_State * state)
+{
+  state->NextInstr = 0;
+
+  if (state->prog32Sig)
+    {
+      state->Reg[15] = 0;
+      state->Cpsr = INTBITS | SVC32MODE;
+      state->Mode = SVC32MODE;
     }
- else {
-    state->Reg[15] = R15INTBITS | SVC26MODE ;
-    state->Cpsr = INTBITS | SVC26MODE ;
+  else
+    {
+      state->Reg[15] = R15INTBITS | SVC26MODE;
+      state->Cpsr = INTBITS | SVC26MODE;
+      state->Mode = SVC26MODE;
     }
- ARMul_CPSRAltered(state) ;
- state->Bank = SVCBANK ;
- FLUSHPIPE ;
-
- state->EndCondition = 0 ;
- state->ErrorCode = 0 ;
-
- state->Exception = FALSE ;
- state->NresetSig = HIGH ;
- state->NfiqSig = HIGH ;
- state->NirqSig = HIGH ;
- state->NtransSig = (state->Mode & 3)?HIGH:LOW ;
- state->abortSig = LOW ;
- state->AbortAddr = 1 ;
-
- state->NumInstrs = 0 ;
- state->NumNcycles = 0 ;
- state->NumScycles = 0 ;
- state->NumIcycles = 0 ;
- state->NumCcycles = 0 ;
- state->NumFcycles = 0 ;
-#ifdef ASIM    
-  (void)ARMul_MemoryInit() ;
-  ARMul_OSInit(state) ;
-#endif  
+
+  ARMul_CPSRAltered (state);
+  state->Bank = SVCBANK;
+
+  FLUSHPIPE;
+
+  state->EndCondition = 0;
+  state->ErrorCode = 0;
+
+  state->Exception = FALSE;
+  state->NresetSig = HIGH;
+  state->NfiqSig = HIGH;
+  state->NirqSig = HIGH;
+  state->NtransSig = (state->Mode & 3) ? HIGH : LOW;
+  state->abortSig = LOW;
+  state->AbortAddr = 1;
+
+  state->NumInstrs = 0;
+  state->NumNcycles = 0;
+  state->NumScycles = 0;
+  state->NumIcycles = 0;
+  state->NumCcycles = 0;
+  state->NumFcycles = 0;
+#ifdef ASIM
+  (void) ARMul_MemoryInit ();
+  ARMul_OSInit (state);
+#endif
 }
 
 
@@ -182,19 +206,22 @@ void ARMul_Reset(ARMul_State *state)
 * address of the last instruction that is executed.                         *
 \***************************************************************************/
 
-ARMword ARMul_DoProg(ARMul_State *state)
-{ARMword pc = 0 ;
-
- state->Emulate = RUN ;
- while (state->Emulate != STOP) {
-    state->Emulate = RUN ;
-    if (state->prog32Sig && ARMul_MODE32BIT)
-       pc = ARMul_Emulate32(state) ;
-    else
-       pc = ARMul_Emulate26(state) ;
+ARMword
+ARMul_DoProg (ARMul_State * state)
+{
+  ARMword pc = 0;
+
+  state->Emulate = RUN;
+  while (state->Emulate != STOP)
+    {
+      state->Emulate = RUN;
+      if (state->prog32Sig && ARMul_MODE32BIT)
+       pc = ARMul_Emulate32 (state);
+      else
+       pc = ARMul_Emulate26 (state);
     }
return(pc) ;
- }
 return (pc);
+}
 
 /***************************************************************************\
 * Emulate the execution of one instruction.  Start the correct emulator     *
@@ -202,17 +229,19 @@ ARMword ARMul_DoProg(ARMul_State *state)
 * address of the instruction that is executed.                              *
 \***************************************************************************/
 
-ARMword ARMul_DoInstr(ARMul_State *state)
-{ARMword pc = 0 ;
+ARMword
+ARMul_DoInstr (ARMul_State * state)
+{
+  ARMword pc = 0;
 
state->Emulate = ONCE ;
- if (state->prog32Sig && ARMul_MODE32BIT)
-    pc = ARMul_Emulate32(state) ;
- else
-    pc = ARMul_Emulate26(state) ;
 state->Emulate = ONCE;
 if (state->prog32Sig && ARMul_MODE32BIT)
+    pc = ARMul_Emulate32 (state);
 else
+    pc = ARMul_Emulate26 (state);
 
return(pc) ;
- }
 return (pc);
+}
 
 /***************************************************************************\
 * This routine causes an Abort to occur, including selecting the correct    *
@@ -220,75 +249,78 @@ ARMword ARMul_DoInstr(ARMul_State *state)
 * appropriate vector's memory address (0,4,8 ....)                          *
 \***************************************************************************/
 
-void ARMul_Abort(ARMul_State *state, ARMword vector)
-{ARMword temp ;
+void
+ARMul_Abort (ARMul_State * state, ARMword vector)
+{
+  ARMword temp;
 
state->Aborted = FALSE ;
 state->Aborted = FALSE;
 
if (ARMul_OSException(state,vector,ARMul_GetPC(state)))
-    return ;
 if (ARMul_OSException (state, vector, ARMul_GetPC (state)))
+    return;
 
- if (state->prog32Sig)
 if (state->prog32Sig)
     if (ARMul_MODE26BIT)
-       temp = R15PC ;
+      temp = R15PC;
     else
-       temp = state->Reg[15] ;
- else
-    temp = R15PC | ECC | ER15INT | EMODE ;
-
- switch (vector) {
-    case ARMul_ResetV : /* RESET */
-       state->Spsr[SVCBANK] = CPSR ;
-       SETABORT(INTBITS,state->prog32Sig?SVC32MODE:SVC26MODE) ;
-       ARMul_CPSRAltered(state) ;
-       state->Reg[14] = temp ;
-       break ;
-    case ARMul_UndefinedInstrV : /* Undefined Instruction */
-       state->Spsr[state->prog32Sig?UNDEFBANK:SVCBANK] = CPSR ;
-       SETABORT(IBIT,state->prog32Sig?UNDEF32MODE:SVC26MODE) ;
-       ARMul_CPSRAltered(state) ;
-       state->Reg[14] = temp - 4 ;
-       break ;
-    case ARMul_SWIV : /* Software Interrupt */
-       state->Spsr[SVCBANK] = CPSR ;
-       SETABORT(IBIT,state->prog32Sig?SVC32MODE:SVC26MODE) ;
-       ARMul_CPSRAltered(state) ;
-       state->Reg[14] = temp - 4 ;
-       break ;
-    case ARMul_PrefetchAbortV : /* Prefetch Abort */
-       state->AbortAddr = 1 ;
-       state->Spsr[state->prog32Sig?ABORTBANK:SVCBANK] = CPSR ;
-       SETABORT(IBIT,state->prog32Sig?ABORT32MODE:SVC26MODE) ;
-       ARMul_CPSRAltered(state) ;
-       state->Reg[14] = temp - 4 ;
-       break ;
-    case ARMul_DataAbortV : /* Data Abort */
-       state->Spsr[state->prog32Sig?ABORTBANK:SVCBANK] = CPSR ;
-       SETABORT(IBIT,state->prog32Sig?ABORT32MODE:SVC26MODE) ;
-       ARMul_CPSRAltered(state) ;
-       state->Reg[14] = temp - 4 ; /* the PC must have been incremented */
-       break ;
-    case ARMul_AddrExceptnV : /* Address Exception */
-       state->Spsr[SVCBANK] = CPSR ;
-       SETABORT(IBIT,SVC26MODE) ;
-       ARMul_CPSRAltered(state) ;
-       state->Reg[14] = temp - 4 ;
-       break ;
-    case ARMul_IRQV : /* IRQ */
-       state->Spsr[IRQBANK] = CPSR ;
-       SETABORT(IBIT,state->prog32Sig?IRQ32MODE:IRQ26MODE) ;
-       ARMul_CPSRAltered(state) ;
-       state->Reg[14] = temp - 4 ;
-       break ;
-    case ARMul_FIQV : /* FIQ */
-       state->Spsr[FIQBANK] = CPSR ;
-       SETABORT(INTBITS,state->prog32Sig?FIQ32MODE:FIQ26MODE) ;
-       ARMul_CPSRAltered(state) ;
-       state->Reg[14] = temp - 4 ;
-       break ;
+      temp = state->Reg[15];
+  else
+    temp = R15PC | ECC | ER15INT | EMODE;
+
+  switch (vector)
+    {
+    case ARMul_ResetV:         /* RESET */
+      state->Spsr[SVCBANK] = CPSR;
+      SETABORT (INTBITS, state->prog32Sig ? SVC32MODE : SVC26MODE);
+      ARMul_CPSRAltered (state);
+      state->Reg[14] = temp;
+      break;
+    case ARMul_UndefinedInstrV:        /* Undefined Instruction */
+      state->Spsr[state->prog32Sig ? UNDEFBANK : SVCBANK] = CPSR;
+      SETABORT (IBIT, state->prog32Sig ? UNDEF32MODE : SVC26MODE);
+      ARMul_CPSRAltered (state);
+      state->Reg[14] = temp - 4;
+      break;
+    case ARMul_SWIV:           /* Software Interrupt */
+      state->Spsr[SVCBANK] = CPSR;
+      SETABORT (IBIT, state->prog32Sig ? SVC32MODE : SVC26MODE);
+      ARMul_CPSRAltered (state);
+      state->Reg[14] = temp - 4;
+      break;
+    case ARMul_PrefetchAbortV: /* Prefetch Abort */
+      state->AbortAddr = 1;
+      state->Spsr[state->prog32Sig ? ABORTBANK : SVCBANK] = CPSR;
+      SETABORT (IBIT, state->prog32Sig ? ABORT32MODE : SVC26MODE);
+      ARMul_CPSRAltered (state);
+      state->Reg[14] = temp - 4;
+      break;
+    case ARMul_DataAbortV:     /* Data Abort */
+      state->Spsr[state->prog32Sig ? ABORTBANK : SVCBANK] = CPSR;
+      SETABORT (IBIT, state->prog32Sig ? ABORT32MODE : SVC26MODE);
+      ARMul_CPSRAltered (state);
+      state->Reg[14] = temp - 4;       /* the PC must have been incremented */
+      break;
+    case ARMul_AddrExceptnV:   /* Address Exception */
+      state->Spsr[SVCBANK] = CPSR;
+      SETABORT (IBIT, SVC26MODE);
+      ARMul_CPSRAltered (state);
+      state->Reg[14] = temp - 4;
+      break;
+    case ARMul_IRQV:           /* IRQ */
+      state->Spsr[IRQBANK] = CPSR;
+      SETABORT (IBIT, state->prog32Sig ? IRQ32MODE : IRQ26MODE);
+      ARMul_CPSRAltered (state);
+      state->Reg[14] = temp - 4;
+      break;
+    case ARMul_FIQV:           /* FIQ */
+      state->Spsr[FIQBANK] = CPSR;
+      SETABORT (INTBITS, state->prog32Sig ? FIQ32MODE : FIQ26MODE);
+      ARMul_CPSRAltered (state);
+      state->Reg[14] = temp - 4;
+      break;
     }
- if (ARMul_MODE32BIT)
-    ARMul_SetR15(state,vector) ;
- else
-    ARMul_SetR15(state,R15CCINTMODE | vector) ;
 if (ARMul_MODE32BIT)
+    ARMul_SetR15 (state, vector);
 else
+    ARMul_SetR15 (state, R15CCINTMODE | vector);
 }
index 67dd51c..958d4cd 100644 (file)
@@ -165,6 +165,7 @@ ARMul_OSInit (ARMul_State * state)
   ARMul_SetReg (state, SVC32MODE, 13, ADDRSUPERSTACK); /* and for supervisor mode */
   ARMul_SetReg (state, ABORT32MODE, 13, ADDRSUPERSTACK);       /* and for abort 32 mode */
   ARMul_SetReg (state, UNDEF32MODE, 13, ADDRSUPERSTACK);       /* and for undef 32 mode */
+  ARMul_SetReg (state, SYSTEMMODE, 13, ADDRSUPERSTACK);        /* and for system mode */
   instr = 0xe59ff000 | (ADDRSOFTVECTORS - 8);  /* load pc from soft vector */
   for (i = ARMul_ResetV; i <= ARMFIQV; i += 4)
     ARMul_WriteWord (state, i, instr); /* write hardware vectors */
index 154d520..5c18ddd 100644 (file)
@@ -42,7 +42,7 @@ void ARMul_R15Altered (ARMul_State * state);
 
 ARMword ARMul_SwitchMode (ARMul_State * state, ARMword oldmode,
                          ARMword newmode);
-static ARMword ModeToBank (ARMul_State * state, ARMword mode);
+static ARMword ModeToBank (ARMword mode);
 
 unsigned ARMul_NthReg (ARMword instr, unsigned number);
 
@@ -87,7 +87,7 @@ ARMul_GetReg (ARMul_State * state, unsigned mode, unsigned reg)
 {
   mode &= MODEBITS;
   if (mode != state->Mode)
-    return (state->RegBank[ModeToBank (state, (ARMword) mode)][reg]);
+    return (state->RegBank[ModeToBank ((ARMword) mode)][reg]);
   else
     return (state->Reg[reg]);
 }
@@ -101,7 +101,7 @@ ARMul_SetReg (ARMul_State * state, unsigned mode, unsigned reg, ARMword value)
 {
   mode &= MODEBITS;
   if (mode != state->Mode)
-    state->RegBank[ModeToBank (state, (ARMword) mode)][reg] = value;
+    state->RegBank[ModeToBank ((ARMword) mode)][reg] = value;
   else
     state->Reg[reg] = value;
 }
@@ -233,11 +233,12 @@ ARMul_FixCPSR (ARMul_State * state, ARMword instr, ARMword rhs)
 ARMword
 ARMul_GetSPSR (ARMul_State * state, ARMword mode)
 {
-  ARMword bank = ModeToBank (state, mode & MODEBITS);
-  if (bank == USERBANK || bank == DUMMYBANK)
-    return (CPSR);
-  else
-    return (state->Spsr[bank]);
+  ARMword bank = ModeToBank (mode & MODEBITS);
+
+  if (! BANK_CAN_ACCESS_SPSR (bank))
+    return CPSR;
+
+  return state->Spsr[bank];
 }
 
 /***************************************************************************\
@@ -247,8 +248,9 @@ ARMul_GetSPSR (ARMul_State * state, ARMword mode)
 void
 ARMul_SetSPSR (ARMul_State * state, ARMword mode, ARMword value)
 {
-  ARMword bank = ModeToBank (state, mode & MODEBITS);
-  if (bank != USERBANK && bank != DUMMYBANK)
+  ARMword bank = ModeToBank (mode & MODEBITS);
+  
+  if (BANK_CAN_ACCESS_SPSR (bank))
     state->Spsr[bank] = value;
 }
 
@@ -259,7 +261,7 @@ ARMul_SetSPSR (ARMul_State * state, ARMword mode, ARMword value)
 void
 ARMul_FixSPSR (ARMul_State * state, ARMword instr, ARMword rhs)
 {
-  if (state->Bank != USERBANK && state->Bank != DUMMYBANK)
+  if (BANK_CAN_ACCESS_SPSR (state->Bank))
     {
       if (BITS (16, 19) == 9)
        SETPSR (state->Spsr[state->Bank], rhs);
@@ -282,11 +284,14 @@ ARMul_CPSRAltered (ARMul_State * state)
 
   if (state->prog32Sig == LOW)
     state->Cpsr &= (CCBITS | INTBITS | R15MODEBITS);
+
   oldmode = state->Mode;
+  
   if (state->Mode != (state->Cpsr & MODEBITS))
     {
       state->Mode =
        ARMul_SwitchMode (state, state->Mode, state->Cpsr & MODEBITS);
+      
       state->NtransSig = (state->Mode & 3) ? HIGH : LOW;
     }
 
@@ -317,7 +322,6 @@ ARMul_CPSRAltered (ARMul_State * state)
       else
        state->Reg[15] = ECC | ER15INT | EMODE | R15PC;
     }
-
 }
 
 /***************************************************************************\
@@ -355,23 +359,30 @@ ARMword
 ARMul_SwitchMode (ARMul_State * state, ARMword oldmode, ARMword newmode)
 {
   unsigned i;
-
-  oldmode = ModeToBank (state, oldmode);
-  state->Bank = ModeToBank (state, newmode);
-  if (oldmode != state->Bank)
+  ARMword  oldbank;
+  ARMword  newbank;
+  
+  oldbank = ModeToBank (oldmode);
+  newbank = state->Bank = ModeToBank (newmode);
+  
+  if (oldbank != newbank)
     {                          /* really need to do it */
-      switch (oldmode)
+      switch (oldbank)
        {                       /* save away the old registers */
+       case SYSTEMBANK:
+         /* The System mode uses the USER bank.  */
+         oldbank = USERBANK;
+         /* Fall through.  */
        case USERBANK:
        case IRQBANK:
        case SVCBANK:
        case ABORTBANK:
        case UNDEFBANK:
-         if (state->Bank == FIQBANK)
+         if (newbank == FIQBANK)
            for (i = 8; i < 13; i++)
              state->RegBank[USERBANK][i] = state->Reg[i];
-         state->RegBank[oldmode][13] = state->Reg[13];
-         state->RegBank[oldmode][14] = state->Reg[14];
+         state->RegBank[oldbank][13] = state->Reg[13];
+         state->RegBank[oldbank][14] = state->Reg[14];
          break;
        case FIQBANK:
          for (i = 8; i < 15; i++)
@@ -381,20 +392,25 @@ ARMul_SwitchMode (ARMul_State * state, ARMword oldmode, ARMword newmode)
          for (i = 8; i < 15; i++)
            state->RegBank[DUMMYBANK][i] = 0;
          break;
-
+       default:
+         abort ();
        }
-      switch (state->Bank)
+      
+      switch (newbank)
        {                       /* restore the new registers */
+       case SYSTEMBANK:
+         newbank = USERBANK;
+         /* Fall through.  */
        case USERBANK:
        case IRQBANK:
        case SVCBANK:
        case ABORTBANK:
        case UNDEFBANK:
-         if (oldmode == FIQBANK)
+         if (oldbank == FIQBANK)
            for (i = 8; i < 13; i++)
              state->Reg[i] = state->RegBank[USERBANK][i];
-         state->Reg[13] = state->RegBank[state->Bank][13];
-         state->Reg[14] = state->RegBank[state->Bank][14];
+         state->Reg[13] = state->RegBank[newbank][13];
+         state->Reg[14] = state->RegBank[newbank][14];
          break;
        case FIQBANK:
          for (i = 8; i < 15; i++)
@@ -404,9 +420,12 @@ ARMul_SwitchMode (ARMul_State * state, ARMword oldmode, ARMword newmode)
          for (i = 8; i < 15; i++)
            state->Reg[i] = 0;
          break;
+       default:
+         abort ();
        }                       /* switch */
     }                          /* if */
-  return (newmode);
+  
+  return newmode;
 }
 
 /***************************************************************************\
@@ -415,21 +434,24 @@ ARMul_SwitchMode (ARMul_State * state, ARMword oldmode, ARMword newmode)
 \***************************************************************************/
 
 static ARMword
-ModeToBank (ARMul_State * state ATTRIBUTE_UNUSED, ARMword mode)
+ModeToBank (ARMword mode)
 {
-  static ARMword bankofmode[] = { USERBANK, FIQBANK, IRQBANK, SVCBANK,
+  static ARMword bankofmode[] =
+  {
+    USERBANK,  FIQBANK,   IRQBANK,   SVCBANK,
     DUMMYBANK, DUMMYBANK, DUMMYBANK, DUMMYBANK,
     DUMMYBANK, DUMMYBANK, DUMMYBANK, DUMMYBANK,
     DUMMYBANK, DUMMYBANK, DUMMYBANK, DUMMYBANK,
-    USERBANK, FIQBANK, IRQBANK, SVCBANK,
+    USERBANK,  FIQBANK,   IRQBANK,   SVCBANK,
     DUMMYBANK, DUMMYBANK, DUMMYBANK, ABORTBANK,
-    DUMMYBANK, DUMMYBANK, DUMMYBANK, UNDEFBANK
+    DUMMYBANK, DUMMYBANK, DUMMYBANK, UNDEFBANK,
+    DUMMYBANK, DUMMYBANK, DUMMYBANK, SYSTEMBANK
   };
 
-  if (mode > UNDEF32MODE)
-    return (DUMMYBANK);
-  else
-    return (bankofmode[mode]);
+  if (mode >= (sizeof (bankofmode) / sizeof (bankofmode[0])))
+    return DUMMYBANK;
+
+  return bankofmode[mode];
 }
 
 /***************************************************************************\
@@ -650,9 +672,11 @@ ARMul_MCR (ARMul_State * state, ARMword instr, ARMword source)
   unsigned cpab;
 
   cpab = (state->MCR[CPNum]) (state, ARMul_FIRST, instr, source);
+
   while (cpab == ARMul_BUSY)
     {
       ARMul_Icycles (state, 1, 0);
+
       if (IntPending (state))
        {
          cpab = (state->MCR[CPNum]) (state, ARMul_INTERRUPT, instr, 0);
@@ -661,6 +685,7 @@ ARMul_MCR (ARMul_State * state, ARMword instr, ARMword source)
       else
        cpab = (state->MCR[CPNum]) (state, ARMul_BUSY, instr, source);
     }
+
   if (cpab == ARMul_CANT)
     ARMul_Abort (state, ARMul_UndefinedInstrV);
   else
index 2720d6b..2c574e4 100755 (executable)
@@ -3534,6 +3534,7 @@ fi
 done
 
 
+COPRO=armcopro.o
 
 
 trap '' 1 2 15
@@ -3744,6 +3745,7 @@ s%@sim_stdio@%$sim_stdio%g
 s%@sim_trace@%$sim_trace%g
 s%@sim_profile@%$sim_profile%g
 s%@EXEEXT@%$EXEEXT%g
+s%@COPRO@%$COPRO%g
 
 CEOF
 EOF
index 033b0bc..cbfac44 100644 (file)
@@ -7,4 +7,7 @@ SIM_AC_COMMON
 
 AC_CHECK_HEADERS(unistd.h)
 
+COPRO=armcopro.o
+AC_SUBST(COPRO)
+
 SIM_AC_OUTPUT
index 003dec6..8fca85d 100644 (file)
@@ -205,13 +205,11 @@ sim_create_inferior (sd, abfd, argv, env)
   else
     ARMul_SetPC (state, 0);    /* ??? */
 
-#if 1                          /* JGS */
   /* We explicitly select a processor capable of supporting the ARM
-     32bit mode, and then we force the simulated CPU into the 32bit
-     User mode: */
+     32bit mode.  JGS  */
   ARMul_SelectProcessor (state, ARM600);
+  /* And then we force the simulated CPU into the 32bit User mode.  */
   ARMul_SetCPSR (state, USER32MODE);
-#endif
 
   if (argv != NULL)
     {
@@ -359,7 +357,7 @@ sim_open (kind, ptr, abfd, argv)
 {
   sim_kind = kind;
   if (myname) free (myname);
-  myname = xstrdup (argv[0]);
+  myname = (char *) xstrdup (argv[0]);
   sim_callback = ptr;
 
   /* Decide upon the endian-ness of the processor.