Add support for ARM's v5TE architecture and Intel's XScale extenstions
[deliverable/binutils-gdb.git] / sim / arm / armsupp.c
index 154d520d216e1d25ee0fe030b22d07f00d84ec19..2d0390d1cbe6b99c11e8550c3f7fd9410b7ea8f7 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;
 }
@@ -183,7 +183,7 @@ ARMul_SetR15 (ARMul_State * state, ARMword value)
 ARMword
 ARMul_GetCPSR (ARMul_State * state)
 {
-  return (CPSR);
+  return (CPSR | state->Cpsr);
 }
 
 /***************************************************************************\
@@ -193,8 +193,7 @@ ARMul_GetCPSR (ARMul_State * state)
 void
 ARMul_SetCPSR (ARMul_State * state, ARMword value)
 {
-  state->Cpsr = CPSR;
-  SETPSR (state->Cpsr, value);
+  state->Cpsr = value;
   ARMul_CPSRAltered (state);
 }
 
@@ -206,23 +205,18 @@ ARMul_SetCPSR (ARMul_State * state, ARMword value)
 void
 ARMul_FixCPSR (ARMul_State * state, ARMword instr, ARMword rhs)
 {
-  state->Cpsr = CPSR;
-  if (state->Bank == USERBANK)
-    {                          /* Only write flags in user mode */
-      if (BIT (19))
-       {
-         SETCC (state->Cpsr, rhs);
-       }
-    }
-  else
-    {                          /* Not a user mode */
-      if (BITS (16, 19) == 9)
-       SETPSR (state->Cpsr, rhs);
-      else if (BIT (16))
-       SETINTMODE (state->Cpsr, rhs);
-      else if (BIT (19))
-       SETCC (state->Cpsr, rhs);
+  state->Cpsr = ARMul_GetCPSR (state);
+  if (state->Bank != USERBANK)
+    {                          /* In user mode, only write flags */
+      if (BIT (16))
+       SETPSR_C (state->Cpsr, rhs);
+      if (BIT (17))
+       SETPSR_X (state->Cpsr, rhs);
+      if (BIT (18))
+       SETPSR_S (state->Cpsr, rhs);
     }
+  if (BIT (19))
+    SETPSR_F (state->Cpsr, rhs);
   ARMul_CPSRAltered (state);
 }
 
@@ -233,11 +227,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 ARMul_GetCPSR (state);
+
+  return state->Spsr[bank];
 }
 
 /***************************************************************************\
@@ -247,8 +242,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,14 +255,16 @@ 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);
-      else if (BIT (16))
-       SETINTMODE (state->Spsr[state->Bank], rhs);
-      else if (BIT (19))
-       SETCC (state->Spsr[state->Bank], rhs);
+      if (BIT (16))
+       SETPSR_C (state->Spsr[state->Bank], rhs);
+      if (BIT (17))
+       SETPSR_X (state->Spsr[state->Bank], rhs);
+      if (BIT (18))
+       SETPSR_S (state->Spsr[state->Bank], rhs);
+      if (BIT (19))
+       SETPSR_F (state->Spsr[state->Bank], rhs);
     }
 }
 
@@ -282,21 +280,33 @@ 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;
     }
+  state->Cpsr &= ~MODEBITS;
 
   ASSIGNINT (state->Cpsr & INTBITS);
+  state->Cpsr &= ~INTBITS;
   ASSIGNN ((state->Cpsr & NBIT) != 0);
+  state->Cpsr &= ~NBIT;
   ASSIGNZ ((state->Cpsr & ZBIT) != 0);
+  state->Cpsr &= ~ZBIT;
   ASSIGNC ((state->Cpsr & CBIT) != 0);
+  state->Cpsr &= ~CBIT;
   ASSIGNV ((state->Cpsr & VBIT) != 0);
+  state->Cpsr &= ~VBIT;
+  ASSIGNS ((state->Cpsr & SBIT) != 0);
+  state->Cpsr &= ~SBIT;
 #ifdef MODET
   ASSIGNT ((state->Cpsr & TBIT) != 0);
+  state->Cpsr &= ~TBIT;
 #endif
 
   if (oldmode > SVC26MODE)
@@ -317,7 +327,6 @@ ARMul_CPSRAltered (ARMul_State * state)
       else
        state->Reg[15] = ECC | ER15INT | EMODE | R15PC;
     }
-
 }
 
 /***************************************************************************\
@@ -355,23 +364,26 @@ 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 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 +393,22 @@ 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 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 +418,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 +432,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 +670,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 +683,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
This page took 0.028253 seconds and 4 git commands to generate.