* armemu.h (INSN_SIZE): New macro.
authorAlexandre Oliva <aoliva@redhat.com>
Tue, 4 Jul 2000 06:52:30 +0000 (06:52 +0000)
committerAlexandre Oliva <aoliva@redhat.com>
Tue, 4 Jul 2000 06:52:30 +0000 (06:52 +0000)
(SET_ABORT): Save CPSR in SPSR and set LR.
* armemu.c (ARMul_Emulate, isize): Set to INSN_SIZE.
(WriteR15, WriteSR15): Do not discard bit 1 in Thumb mode.
* arminit.c (ARMul_Abort): Use new SETABORT and INSN_SIZE.

sim/arm/ChangeLog
sim/arm/armemu.c
sim/arm/armemu.h
sim/arm/arminit.c

index 06345b2..9e4bdc0 100644 (file)
@@ -1,5 +1,11 @@
 2000-07-04  Alexandre Oliva  <aoliva@redhat.com>
 
+       * armemu.h (INSN_SIZE): New macro.
+       (SET_ABORT): Save CPSR in SPSR and set LR.
+       * armemu.c (ARMul_Emulate, isize): Set to INSN_SIZE.
+       (WriteR15, WriteSR15): Do not discard bit 1 in Thumb mode.
+       * arminit.c (ARMul_Abort): Use new SETABORT and INSN_SIZE.
+
        * armemu.c (LoadSMult): Use WriteR15() to discard the least
        significant bits of PC.
 
index 43cd6dc..31bd327 100644 (file)
@@ -299,14 +299,7 @@ ARMul_Emulate26 (register ARMul_State * state)
 
   do
     {                          /* just keep going */
-#ifdef MODET
-      if (TFLAG)
-       {
-         isize = 2;
-       }
-      else
-#endif
-       isize = 4;
+      isize = INSN_SIZE;
       switch (state->NextInstr)
        {
        case SEQ:
@@ -3104,8 +3097,15 @@ WriteR15 (ARMul_State * state, ARMword src)
 {
   /* The ARM documentation states that the two least significant bits
      are discarded when setting PC, except in the cases handled by
-     WriteR15Branch() below.  */
-  src &= 0xfffffffc;
+     WriteR15Branch() below.  It's probably an oversight: in THUMB
+     mode, the second least significant bit should probably not be
+     discarded.  */
+#ifdef MODET
+  if (TFLAG)
+    src &= 0xfffffffe;
+  else
+#endif
+    src &= 0xfffffffc;
 #ifdef MODE32
   state->Reg[15] = src & PCBITS;
 #else
@@ -3122,15 +3122,26 @@ WriteR15 (ARMul_State * state, ARMword src)
 static void
 WriteSR15 (ARMul_State * state, ARMword src)
 {
-  src &= 0xfffffffc;
 #ifdef MODE32
-  state->Reg[15] = src & PCBITS;
   if (state->Bank > 0)
     {
       state->Cpsr = state->Spsr[state->Bank];
       ARMul_CPSRAltered (state);
     }
+#ifdef MODET
+  if (TFLAG)
+    src &= 0xfffffffe;
+  else
+#endif
+    src &= 0xfffffffc;
+  state->Reg[15] = src & PCBITS;
 #else
+#ifdef MODET
+  if (TFLAG)
+    abort (); /* ARMul_R15Altered would have to support it.  */
+  else
+#endif
+    src &= 0xfffffffc;
   if (state->Bank == USERBANK)
     state->Reg[15] = (src & (CCBITS | R15PCBITS)) | ER15INT | EMODE;
   else
index ad89294..de836cb 100644 (file)
@@ -73,6 +73,9 @@ extern ARMword isize;
 #define SETT state->TFlag = 1
 #define CLEART state->TFlag = 0
 #define ASSIGNT(res) state->TFlag = res
+#define INSN_SIZE (TFLAG ? 2 : 4)
+#else
+#define INSN_SIZE 4
 #endif
 
 #define NFLAG state->NFlag
@@ -179,7 +182,13 @@ extern ARMword isize;
                         state->Reg[15] = R15PC | ((s) & (CCBITS | R15INTBITS | R15MODEBITS)) ; \
                         ARMul_R15Altered (state) ; \
                         }
-#define SETABORT(i,m) state->Cpsr = ECC | EINT | (i) | (m)
+#define SETABORT(i,m,d) do { \
+  int SETABORT_mode = (m); \
+  ARMul_SetSPSR (state, SETABORT_mode, ARMul_GetCPSR (state)); \
+  ARMul_SetCPSR (state, ((ARMul_GetCPSR (state) & ~(EMODE | TBIT)) \
+                        | (i) | SETABORT_mode)); \
+  state->Reg[14] = temp - (d); \
+} while (0)
 
 #ifndef MODE32
 #define VECTORS 0x20
index 0105c17..66e6dad 100644 (file)
@@ -253,6 +253,7 @@ void
 ARMul_Abort (ARMul_State * state, ARMword vector)
 {
   ARMword temp;
+  int isize = INSN_SIZE;
 
   state->Aborted = FALSE;
 
@@ -270,53 +271,29 @@ ARMul_Abort (ARMul_State * state, ARMword vector)
   switch (vector)
     {
     case ARMul_ResetV:         /* RESET */
-      state->Spsr[SVCBANK] = CPSR;
-      SETABORT (INTBITS, state->prog32Sig ? SVC32MODE : SVC26MODE);
-      ARMul_CPSRAltered (state);
-      state->Reg[14] = temp;
+      SETABORT (INTBITS, state->prog32Sig ? SVC32MODE : SVC26MODE, 0);
       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;
+      SETABORT (IBIT, state->prog32Sig ? UNDEF32MODE : SVC26MODE, isize);
       break;
     case ARMul_SWIV:           /* Software Interrupt */
-      state->Spsr[SVCBANK] = CPSR;
-      SETABORT (IBIT, state->prog32Sig ? SVC32MODE : SVC26MODE);
-      ARMul_CPSRAltered (state);
-      state->Reg[14] = temp - 4;
+      SETABORT (IBIT, state->prog32Sig ? SVC32MODE : SVC26MODE, isize);
       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;
+      SETABORT (IBIT, state->prog32Sig ? ABORT32MODE : SVC26MODE, isize);
       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 */
+      SETABORT (IBIT, state->prog32Sig ? ABORT32MODE : SVC26MODE, isize);
       break;
     case ARMul_AddrExceptnV:   /* Address Exception */
-      state->Spsr[SVCBANK] = CPSR;
-      SETABORT (IBIT, SVC26MODE);
-      ARMul_CPSRAltered (state);
-      state->Reg[14] = temp - 4;
+      SETABORT (IBIT, SVC26MODE, isize);
       break;
     case ARMul_IRQV:           /* IRQ */
-      state->Spsr[IRQBANK] = CPSR;
-      SETABORT (IBIT, state->prog32Sig ? IRQ32MODE : IRQ26MODE);
-      ARMul_CPSRAltered (state);
-      state->Reg[14] = temp - 4;
+      SETABORT (IBIT, state->prog32Sig ? IRQ32MODE : IRQ26MODE, isize);
       break;
     case ARMul_FIQV:           /* FIQ */
-      state->Spsr[FIQBANK] = CPSR;
-      SETABORT (INTBITS, state->prog32Sig ? FIQ32MODE : FIQ26MODE);
-      ARMul_CPSRAltered (state);
-      state->Reg[14] = temp - 4;
+      SETABORT (INTBITS, state->prog32Sig ? FIQ32MODE : FIQ26MODE, isize);
       break;
     }
   if (ARMul_MODE32BIT)