gdb:
[platform/upstream/binutils.git] / sim / arm / armsupp.c
index 67edd95..e2bac55 100644 (file)
@@ -3,7 +3,7 @@
  
     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,
     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/>. */
 
 #include "armdefs.h"
 #include "armemu.h"
+#include "ansidecl.h"
 
-/***************************************************************************\
-*                    Definitions for the support routines                   *
-\***************************************************************************/
-
-ARMword ARMul_GetReg(ARMul_State *state, unsigned mode, unsigned reg) ;
-void ARMul_SetReg(ARMul_State *state, unsigned mode, unsigned reg, ARMword value) ;
-ARMword ARMul_GetPC(ARMul_State *state) ;
-ARMword ARMul_GetNextPC(ARMul_State *state) ;
-void ARMul_SetPC(ARMul_State *state, ARMword value) ;
-ARMword ARMul_GetR15(ARMul_State *state) ;
-void ARMul_SetR15(ARMul_State *state, ARMword value) ;
-
-ARMword ARMul_GetCPSR(ARMul_State *state) ;
-void ARMul_SetCPSR(ARMul_State *state, ARMword value) ;
-void ARMul_FixCPSR(ARMul_State *state, ARMword instr, ARMword rhs) ;
-ARMword ARMul_GetSPSR(ARMul_State *state, ARMword mode) ;
-void ARMul_SetSPSR(ARMul_State *state, ARMword mode, ARMword value) ;
-void ARMul_FixSPSR(ARMul_State *state, ARMword instr, ARMword rhs) ;
-
-void ARMul_CPSRAltered(ARMul_State *state) ;
-void ARMul_R15Altered(ARMul_State *state) ;
-
-ARMword ARMul_SwitchMode(ARMul_State *state,ARMword oldmode, ARMword newmode) ;
-static ARMword ModeToBank(ARMul_State *state,ARMword mode) ;
-
-unsigned ARMul_NthReg(ARMword instr, unsigned number) ;
-
-void ARMul_NegZero(ARMul_State *state, ARMword result) ;
-void ARMul_AddCarry(ARMul_State *state, ARMword a, ARMword b, ARMword result) ;
-void ARMul_AddOverflow(ARMul_State *state, ARMword a, ARMword b, ARMword result) ;
-void ARMul_SubCarry(ARMul_State *state, ARMword a, ARMword b, ARMword result) ;
-void ARMul_SubOverflow(ARMul_State *state, ARMword a, ARMword b, ARMword result) ;
-
-void ARMul_LDC(ARMul_State *state,ARMword instr,ARMword address) ;
-void ARMul_STC(ARMul_State *state,ARMword instr,ARMword address) ;
-void ARMul_MCR(ARMul_State *state,ARMword instr, ARMword source) ;
-ARMword ARMul_MRC(ARMul_State *state,ARMword instr) ;
-void ARMul_CDP(ARMul_State *state,ARMword instr) ;
-void ARMul_UndefInstr(ARMul_State *state,ARMword instr) ;
-unsigned IntPending(ARMul_State *state) ;
-
-ARMword ARMul_Align(ARMul_State *state, ARMword address, ARMword data) ;
-
-void ARMul_ScheduleEvent(ARMul_State *state, unsigned long delay,
-                         unsigned (*what)()) ;
-void ARMul_EnvokeEvent(ARMul_State *state) ;
-unsigned long ARMul_Time(ARMul_State *state) ;
-static void EnvokeList(ARMul_State *state, unsigned long from, unsigned long to) ;
-
-struct EventNode { /* An event list node */
-      unsigned (*func)() ; /* The function to call */
-      struct EventNode *next ;
-      } ;
-
-/***************************************************************************\
-* This routine returns the value of a register from a mode.                 *
-\***************************************************************************/
-
-ARMword ARMul_GetReg(ARMul_State *state, unsigned mode, unsigned reg)
-{mode &= MODEBITS ;
- if (mode != state->Mode)
-    return(state->RegBank[ModeToBank(state,(ARMword)mode)][reg]) ;
- else
-    return(state->Reg[reg]) ;
-}
-
-/***************************************************************************\
-* This routine sets the value of a register for a mode.                     *
-\***************************************************************************/
-
-void 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 ;
- else
-    state->Reg[reg] = value ;
-}
-
-/***************************************************************************\
-* This routine returns the value of the PC, mode independently.             *
-\***************************************************************************/
-
-ARMword ARMul_GetPC(ARMul_State *state)
-{if (state->Mode > SVC26MODE)
-    return(state->Reg[15]) ;
- else
-    return(R15PC) ;
-}
-
-/***************************************************************************\
-* This routine returns the value of the PC, mode independently.             *
-\***************************************************************************/
-
-ARMword ARMul_GetNextPC(ARMul_State *state)
-{if (state->Mode > SVC26MODE)
-    return(state->Reg[15] + isize) ;
- else
-    return((state->Reg[15] + isize) & R15PCBITS) ;
-}
-
-/***************************************************************************\
-* This routine sets the value of the PC.                                    *
-\***************************************************************************/
-
-void ARMul_SetPC(ARMul_State *state, ARMword value)
-{if (ARMul_MODE32BIT)
-    state->Reg[15] = value & PCBITS ;
- else
-    state->Reg[15] = R15CCINTMODE | (value & R15PCBITS) ;
- FLUSHPIPE ;
-}
+/* Definitions for the support routines.  */
 
-/***************************************************************************\
-* This routine returns the value of register 15, mode independently.        *
-\***************************************************************************/
+static ARMword ModeToBank (ARMword);
+static void    EnvokeList (ARMul_State *, unsigned long, unsigned long);
 
-ARMword ARMul_GetR15(ARMul_State *state)
-{if (state->Mode > SVC26MODE)
-    return(state->Reg[15]) ;
- else
-    return(R15PC | ECC | ER15INT | EMODE) ;
+struct EventNode
+{                                      /* An event list node.  */
+  unsigned (*func) (ARMul_State *);    /* The function to call.  */
+  struct EventNode *next;
+};
+
+/* This routine returns the value of a register from a mode.  */
+
+ARMword
+ARMul_GetReg (ARMul_State * state, unsigned mode, unsigned reg)
+{
+  mode &= MODEBITS;
+  if (mode != state->Mode)
+    return (state->RegBank[ModeToBank ((ARMword) mode)][reg]);
+  else
+    return (state->Reg[reg]);
 }
-
-/***************************************************************************\
-* This routine sets the value of Register 15.                               *
-\***************************************************************************/
-
-void ARMul_SetR15(ARMul_State *state, ARMword value)
-{
- if (ARMul_MODE32BIT)
-    state->Reg[15] = value & PCBITS ;
- else {
-    state->Reg[15] = value ;
-    ARMul_R15Altered(state) ;
-    }
- FLUSHPIPE ;
+
+/* This routine sets the value of a register for a mode.  */
+
+void
+ARMul_SetReg (ARMul_State * state, unsigned mode, unsigned reg, ARMword value)
+{
+  mode &= MODEBITS;
+  if (mode != state->Mode)
+    state->RegBank[ModeToBank ((ARMword) mode)][reg] = value;
+  else
+    state->Reg[reg] = value;
+}
+
+/* This routine returns the value of the PC, mode independently.  */
+
+ARMword
+ARMul_GetPC (ARMul_State * state)
+{
+  if (state->Mode > SVC26MODE)
+    return state->Reg[15];
+  else
+    return R15PC;
 }
 
-/***************************************************************************\
-* This routine returns the value of the CPSR                                *
-\***************************************************************************/
+/* This routine returns the value of the PC, mode independently.  */
 
-ARMword ARMul_GetCPSR(ARMul_State *state)
+ARMword
+ARMul_GetNextPC (ARMul_State * state)
 {
- return(CPSR) ;
- }
+  if (state->Mode > SVC26MODE)
+    return state->Reg[15] + isize;
+  else
+    return (state->Reg[15] + isize) & R15PCBITS;
+}
 
-/***************************************************************************\
-* This routine sets the value of the CPSR                                   *
-\***************************************************************************/
+/* This routine sets the value of the PC.  */
 
-void ARMul_SetCPSR(ARMul_State *state, ARMword value)
-{state->Cpsr = CPSR ;
- SETPSR(state->Cpsr,value) ;
- ARMul_CPSRAltered(state) ;
- }
+void
+ARMul_SetPC (ARMul_State * state, ARMword value)
+{
+  if (ARMul_MODE32BIT)
+    state->Reg[15] = value & PCBITS;
+  else
+    state->Reg[15] = R15CCINTMODE | (value & R15PCBITS);
+  FLUSHPIPE;
+}
 
-/***************************************************************************\
-* This routine does all the nasty bits involved in a write to the CPSR,     *
-* including updating the register bank, given a MSR instruction.                    *
-\***************************************************************************/
+/* This routine returns the value of register 15, mode independently.  */
 
-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) ;
+ARMword
+ARMul_GetR15 (ARMul_State * state)
+{
+  if (state->Mode > SVC26MODE)
+    return (state->Reg[15]);
+  else
+    return (R15PC | ECC | ER15INT | EMODE);
+}
+
+/* This routine sets the value of Register 15.  */
+
+void
+ARMul_SetR15 (ARMul_State * state, ARMword value)
+{
+  if (ARMul_MODE32BIT)
+    state->Reg[15] = value & PCBITS;
+  else
+    {
+      state->Reg[15] = value;
+      ARMul_R15Altered (state);
     }
ARMul_CPSRAltered(state) ;
- }
 FLUSHPIPE;
+}
 
-/***************************************************************************\
-* Get an SPSR from the specified mode                                       *
-\***************************************************************************/
+/* This routine returns the value of the CPSR.  */
 
-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
+ARMul_GetCPSR (ARMul_State * state)
+{
+  return (CPSR | state->Cpsr);
 }
 
-/***************************************************************************\
-* This routine does a write to an SPSR                                      *
-\***************************************************************************/
+/* This routine sets the value of the CPSR.  */
 
-void ARMul_SetSPSR(ARMul_State *state, ARMword mode, ARMword value)
-{ARMword bank = ModeToBank(state,mode & MODEBITS) ;
- if (bank != USERBANK && bank !=DUMMYBANK)
-    state->Spsr[bank] = value ;
+void
+ARMul_SetCPSR (ARMul_State * state, ARMword value)
+{
+  state->Cpsr = value;
+  ARMul_CPSRAltered (state);
 }
 
-/***************************************************************************\
-* This routine does a write to the current SPSR, given an MSR instruction   *
-\***************************************************************************/
+/* This routine does all the nasty bits involved in a write to the CPSR,
+   including updating the register bank, given a MSR instruction.  */
 
-void ARMul_FixSPSR(ARMul_State *state, ARMword instr, ARMword rhs)
-{if (state->Bank != USERBANK && state->Bank !=DUMMYBANK) {
-    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) ;
+void
+ARMul_FixCPSR (ARMul_State * state, ARMword instr, ARMword rhs)
+{
+  state->Cpsr = ARMul_GetCPSR (state);
+
+  if (state->Mode != USER26MODE
+      && state->Mode != USER32MODE)
+    {
+      /* 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);
+}
+
+/* Get an SPSR from the specified mode.  */
+
+ARMword
+ARMul_GetSPSR (ARMul_State * state, ARMword mode)
+{
+  ARMword bank = ModeToBank (mode & MODEBITS);
+
+  if (! BANK_CAN_ACCESS_SPSR (bank))
+    return ARMul_GetCPSR (state);
+
+  return state->Spsr[bank];
 }
 
-/***************************************************************************\
-* This routine updates the state of the emulator after the Cpsr has been    *
-* changed.  Both the processor flags and register bank are updated.         *
-\***************************************************************************/
+/* This routine does a write to an SPSR.  */
 
-void ARMul_CPSRAltered(ARMul_State *state)
-{ARMword oldmode ;
+void
+ARMul_SetSPSR (ARMul_State * state, ARMword mode, ARMword value)
+{
+  ARMword bank = ModeToBank (mode & MODEBITS);
+  
+  if (BANK_CAN_ACCESS_SPSR (bank))
+    state->Spsr[bank] = value;
+}
 
- 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 ;
+/* This routine does a write to the current SPSR, given an MSR instruction.  */
+
+void
+ARMul_FixSPSR (ARMul_State * state, ARMword instr, ARMword rhs)
+{
+  if (BANK_CAN_ACCESS_SPSR (state->Bank))
+    {
+      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);
     }
+}
+
+/* This routine updates the state of the emulator after the Cpsr has been
+   changed.  Both the processor flags and register bank are updated.  */
 
- ASSIGNINT(state->Cpsr & INTBITS) ;
- ASSIGNN((state->Cpsr & NBIT) != 0) ;
- ASSIGNZ((state->Cpsr & ZBIT) != 0) ;
- ASSIGNC((state->Cpsr & CBIT) != 0) ;
- ASSIGNV((state->Cpsr & VBIT) != 0) ;
+void
+ARMul_CPSRAltered (ARMul_State * state)
+{
+  ARMword oldmode;
+
+  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);
+  ASSIGNT ((state->Cpsr & TBIT) != 0);
+  state->Cpsr &= ~TBIT;
 #endif
 
- if (oldmode > SVC26MODE) {
-    if (state->Mode <= SVC26MODE) {
-       state->Emulate = CHANGEMODE ;
-       state->Reg[15] = ECC | ER15INT | EMODE | R15PC ;
-       }
+  if (oldmode > SVC26MODE)
+    {
+      if (state->Mode <= SVC26MODE)
+       {
+         state->Emulate = CHANGEMODE;
+         state->Reg[15] = ECC | ER15INT | EMODE | R15PC;
+       }
     }
- else {
-    if (state->Mode > SVC26MODE) {
-       state->Emulate = CHANGEMODE ;
-       state->Reg[15] = R15PC ;
-       }
-    else
-       state->Reg[15] = ECC | ER15INT | EMODE | R15PC ;
+  else
+    {
+      if (state->Mode > SVC26MODE)
+       {
+         state->Emulate = CHANGEMODE;
+         state->Reg[15] = R15PC;
+       }
+      else
+       state->Reg[15] = ECC | ER15INT | EMODE | R15PC;
     }
+}
+
+/* This routine updates the state of the emulator after register 15 has
+   been changed.  Both the processor flags and register bank are updated.
+   This routine should only be called from a 26 bit mode.  */
+
+void
+ARMul_R15Altered (ARMul_State * state)
+{
+  if (state->Mode != R15MODE)
+    {
+      state->Mode = ARMul_SwitchMode (state, state->Mode, R15MODE);
+      state->NtransSig = (state->Mode & 3) ? HIGH : LOW;
+    }
+
+  if (state->Mode > SVC26MODE)
+    state->Emulate = CHANGEMODE;
+
+  ASSIGNR15INT (R15INT);
 
+  ASSIGNN ((state->Reg[15] & NBIT) != 0);
+  ASSIGNZ ((state->Reg[15] & ZBIT) != 0);
+  ASSIGNC ((state->Reg[15] & CBIT) != 0);
+  ASSIGNV ((state->Reg[15] & VBIT) != 0);
 }
 
-/***************************************************************************\
-* This routine updates the state of the emulator after register 15 has      *
-* been changed.  Both the processor flags and register bank are updated.    *
-* This routine should only be called from a 26 bit mode.                    *
-\***************************************************************************/
+/* This routine controls the saving and restoring of registers across mode
+   changes.  The regbank matrix is largely unused, only rows 13 and 14 are
+   used across all modes, 8 to 14 are used for FIQ, all others use the USER
+   column.  It's easier this way.  old and new parameter are modes numbers.
+   Notice the side effect of changing the Bank variable.  */
 
-void ARMul_R15Altered(ARMul_State *state)
+ARMword
+ARMul_SwitchMode (ARMul_State * state, ARMword oldmode, ARMword newmode)
 {
- if (state->Mode != R15MODE) {
-    state->Mode = ARMul_SwitchMode(state,state->Mode,R15MODE) ;
-    state->NtransSig = (state->Mode & 3)?HIGH:LOW ;
+  unsigned i;
+  ARMword  oldbank;
+  ARMword  newbank;
+  
+  oldbank = ModeToBank (oldmode);
+  newbank = state->Bank = ModeToBank (newmode);
+  
+  /* Do we really need to do it?  */
+  if (oldbank != newbank)
+    {
+      /* Save away the old registers.  */
+      switch (oldbank)
+       {
+       case USERBANK:
+       case IRQBANK:
+       case SVCBANK:
+       case ABORTBANK:
+       case UNDEFBANK:
+         if (newbank == FIQBANK)
+           for (i = 8; i < 13; i++)
+             state->RegBank[USERBANK][i] = state->Reg[i];
+         state->RegBank[oldbank][13] = state->Reg[13];
+         state->RegBank[oldbank][14] = state->Reg[14];
+         break;
+       case FIQBANK:
+         for (i = 8; i < 15; i++)
+           state->RegBank[FIQBANK][i] = state->Reg[i];
+         break;
+       case DUMMYBANK:
+         for (i = 8; i < 15; i++)
+           state->RegBank[DUMMYBANK][i] = 0;
+         break;
+       default:
+         abort ();
+       }
+      
+      /* Restore the new registers.  */
+      switch (newbank)
+       {
+       case USERBANK:
+       case IRQBANK:
+       case SVCBANK:
+       case ABORTBANK:
+       case UNDEFBANK:
+         if (oldbank == FIQBANK)
+           for (i = 8; i < 13; i++)
+             state->Reg[i] = state->RegBank[USERBANK][i];
+         state->Reg[13] = state->RegBank[newbank][13];
+         state->Reg[14] = state->RegBank[newbank][14];
+         break;
+       case FIQBANK:
+         for (i = 8; i < 15; i++)
+           state->Reg[i] = state->RegBank[FIQBANK][i];
+         break;
+       case DUMMYBANK:
+         for (i = 8; i < 15; i++)
+           state->Reg[i] = 0;
+         break;
+       default:
+         abort ();
+       }
     }
- if (state->Mode > SVC26MODE)
-    state->Emulate = CHANGEMODE ;
- ASSIGNR15INT(R15INT) ;
- ASSIGNN((state->Reg[15] & NBIT) != 0) ;
- ASSIGNZ((state->Reg[15] & ZBIT) != 0) ;
- ASSIGNC((state->Reg[15] & CBIT) != 0) ;
- ASSIGNV((state->Reg[15] & VBIT) != 0) ;
-}
-
-/***************************************************************************\
-* This routine controls the saving and restoring of registers across mode   *
-* changes.  The regbank matrix is largely unused, only rows 13 and 14 are   *
-* used across all modes, 8 to 14 are used for FIQ, all others use the USER  *
-* column.  It's easier this way.  old and new parameter are modes numbers.  *
-* Notice the side effect of changing the Bank variable.                     *
-\***************************************************************************/
-
-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) { /* really need to do it */
-    switch (oldmode) { /* save away the old registers */
-       case USERBANK  :
-       case IRQBANK   :
-       case SVCBANK   :
-       case ABORTBANK :
-       case UNDEFBANK : if (state->Bank == 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] ;
-                        break ;
-       case FIQBANK   : for (i = 8 ; i < 15 ; i++)
-                           state->RegBank[FIQBANK][i] = state->Reg[i] ;
-                        break ;
-       case DUMMYBANK : for (i = 8 ; i < 15 ; i++)
-                           state->RegBank[DUMMYBANK][i] = 0 ;
-                        break ;
-
-       }
-    switch (state->Bank) { /* restore the new registers */
-       case USERBANK  :
-       case IRQBANK   :
-       case SVCBANK   :
-       case ABORTBANK :
-       case UNDEFBANK : if (oldmode == 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] ;
-                        break ;
-       case FIQBANK  : for (i = 8 ; i < 15 ; i++)
-                           state->Reg[i] = state->RegBank[FIQBANK][i] ;
-                        break ;
-       case DUMMYBANK : for (i = 8 ; i < 15 ; i++)
-                           state->Reg[i] = 0 ;
-                        break ;
-       } /* switch */
-    } /* if */
-    return(newmode) ;
-}
-
-/***************************************************************************\
-* Given a processor mode, this routine returns the register bank that       *
-* will be accessed in that mode.                                            *
-\***************************************************************************/
-
-static ARMword ModeToBank(ARMul_State *state, ARMword mode)
-{static ARMword bankofmode[] = {USERBANK,  FIQBANK,   IRQBANK,   SVCBANK,
-                                DUMMYBANK, DUMMYBANK, DUMMYBANK, DUMMYBANK,
-                                DUMMYBANK, DUMMYBANK, DUMMYBANK, DUMMYBANK,
-                                DUMMYBANK, DUMMYBANK, DUMMYBANK, DUMMYBANK,
-                                USERBANK,  FIQBANK,   IRQBANK,   SVCBANK,
-                                DUMMYBANK, DUMMYBANK, DUMMYBANK, ABORTBANK,
-                                DUMMYBANK, DUMMYBANK, DUMMYBANK, UNDEFBANK
-                                } ;
-
- if (mode > UNDEF32MODE)
-    return(DUMMYBANK) ;
- else
-    return(bankofmode[mode]) ;
- }
-
-/***************************************************************************\
-* Returns the register number of the nth register in a reg list.            *
-\***************************************************************************/
-
-unsigned ARMul_NthReg(ARMword instr, unsigned number)
-{unsigned bit, upto ;
-
- for (bit = 0, upto = 0 ; upto <= number ; bit++)
-    if (BIT(bit)) upto++ ;
- return(bit - 1) ;
-}
-
-/***************************************************************************\
-* Assigns the N and Z flags depending on the value of result                *
-\***************************************************************************/
-
-void ARMul_NegZero(ARMul_State *state, ARMword result)
-{
- if (NEG(result)) { SETN ; CLEARZ ; }
- else if (result == 0) { CLEARN ; SETZ ; }
- else { CLEARN ; CLEARZ ; } ;
- }
-
-/***************************************************************************\
-* Assigns the C flag after an addition of a and b to give result            *
-\***************************************************************************/
-
-void ARMul_AddCarry(ARMul_State *state, ARMword a,ARMword b,ARMword result)
-{
- ASSIGNC( (NEG(a) && NEG(b)) ||
-          (NEG(a) && POS(result)) ||
-          (NEG(b) && POS(result)) ) ;
- }
-
-/***************************************************************************\
-* Assigns the V flag after an addition of a and b to give result            *
-\***************************************************************************/
-
-void ARMul_AddOverflow(ARMul_State *state, ARMword a,ARMword b,ARMword result)
-{
- ASSIGNV( (NEG(a) && NEG(b) && POS(result)) ||
-          (POS(a) && POS(b) && NEG(result)) ) ;
- }
-
-/***************************************************************************\
-* Assigns the C flag after an subtraction of a and b to give result         *
-\***************************************************************************/
-
-void ARMul_SubCarry(ARMul_State *state, ARMword a,ARMword b,ARMword result)
-{
-ASSIGNC( (NEG(a) && POS(b)) ||
-         (NEG(a) && POS(result)) ||
-         (POS(b) && POS(result)) ) ;
-}
-
-/***************************************************************************\
-* Assigns the V flag after an subtraction of a and b to give result         *
-\***************************************************************************/
-
-void ARMul_SubOverflow(ARMul_State *state,ARMword a,ARMword b,ARMword result)
-{
-ASSIGNV( (NEG(a) && POS(b) && POS(result)) ||
-         (POS(a) && NEG(b) && NEG(result)) ) ;
-}
+  
+  return newmode;
+}
+
+/* Given a processor mode, this routine returns the
+   register bank that will be accessed in that mode.  */
+
+static ARMword
+ModeToBank (ARMword mode)
+{
+  static ARMword bankofmode[] =
+  {
+    USERBANK,  FIQBANK,   IRQBANK,   SVCBANK,
+    DUMMYBANK, DUMMYBANK, DUMMYBANK, DUMMYBANK,
+    DUMMYBANK, DUMMYBANK, DUMMYBANK, DUMMYBANK,
+    DUMMYBANK, DUMMYBANK, DUMMYBANK, DUMMYBANK,
+    USERBANK,  FIQBANK,   IRQBANK,   SVCBANK,
+    DUMMYBANK, DUMMYBANK, DUMMYBANK, ABORTBANK,
+    DUMMYBANK, DUMMYBANK, DUMMYBANK, UNDEFBANK,
+    DUMMYBANK, DUMMYBANK, DUMMYBANK, SYSTEMBANK
+  };
+
+  if (mode >= (sizeof (bankofmode) / sizeof (bankofmode[0])))
+    return DUMMYBANK;
+
+  return bankofmode[mode];
+}
+
+/* Returns the register number of the nth register in a reg list.  */
+
+unsigned
+ARMul_NthReg (ARMword instr, unsigned number)
+{
+  unsigned bit, upto;
+
+  for (bit = 0, upto = 0; upto <= number; bit ++)
+    if (BIT (bit))
+      upto ++;
 
-/***************************************************************************\
-* This function does the work of generating the addresses used in an        *
-* LDC instruction.  The code here is always post-indexed, it's up to the    *
-* caller to get the input address correct and to handle base register       *
-* modification. It also handles the Busy-Waiting.                           *
-\***************************************************************************/
+  return (bit - 1);
+}
 
-void ARMul_LDC(ARMul_State *state,ARMword instr,ARMword address)
-{unsigned cpab ;
- ARMword data ;
+/* Assigns the N and Z flags depending on the value of result.  */
 
- UNDEF_LSCPCBaseWb ;
- if (ADDREXCEPT(address)) {
-    INTERNALABORT(address) ;
+void
+ARMul_NegZero (ARMul_State * state, ARMword result)
+{
+  if (NEG (result))
+    {
+      SETN;
+      CLEARZ;
     }
- cpab = (state->LDC[CPNum])(state,ARMul_FIRST,instr,0) ;
- while (cpab == ARMul_BUSY) {
-    ARMul_Icycles(state,1,0) ;
-    if (IntPending(state)) {
-       cpab = (state->LDC[CPNum])(state,ARMul_INTERRUPT,instr,0) ;
-       return ;
-       }
-    else
-       cpab = (state->LDC[CPNum])(state,ARMul_BUSY,instr,0) ;
+  else if (result == 0)
+    {
+      CLEARN;
+      SETZ;
     }
- if (cpab == ARMul_CANT) {
-    CPTAKEABORT ;
-    return ;
+  else
+    {
+      CLEARN;
+      CLEARZ;
     }
- cpab = (state->LDC[CPNum])(state,ARMul_TRANSFER,instr,0) ;
- data = ARMul_LoadWordN(state,address) ;
- BUSUSEDINCPCN ;
- if (BIT(21))
-    LSBase = state->Base ;
- cpab = (state->LDC[CPNum])(state,ARMul_DATA,instr,data) ;
- while (cpab == ARMul_INC) {
-    address += 4 ;
-    data = ARMul_LoadWordN(state,address) ;
-    cpab = (state->LDC[CPNum])(state,ARMul_DATA,instr,data) ;
+}
+
+/* Compute whether an addition of A and B, giving RESULT, overflowed.  */
+
+int
+AddOverflow (ARMword a, ARMword b, ARMword result)
+{
+  return ((NEG (a) && NEG (b) && POS (result))
+         || (POS (a) && POS (b) && NEG (result)));
+}
+
+/* Compute whether a subtraction of A and B, giving RESULT, overflowed.  */
+
+int
+SubOverflow (ARMword a, ARMword b, ARMword result)
+{
+  return ((NEG (a) && POS (b) && POS (result))
+         || (POS (a) && NEG (b) && NEG (result)));
+}
+
+/* Assigns the C flag after an addition of a and b to give result.  */
+
+void
+ARMul_AddCarry (ARMul_State * state, ARMword a, ARMword b, ARMword result)
+{
+  ASSIGNC ((NEG (a) && NEG (b)) ||
+          (NEG (a) && POS (result)) || (NEG (b) && POS (result)));
+}
+
+/* Assigns the V flag after an addition of a and b to give result.  */
+
+void
+ARMul_AddOverflow (ARMul_State * state, ARMword a, ARMword b, ARMword result)
+{
+  ASSIGNV (AddOverflow (a, b, result));
+}
+
+/* Assigns the C flag after an subtraction of a and b to give result.  */
+
+void
+ARMul_SubCarry (ARMul_State * state, ARMword a, ARMword b, ARMword result)
+{
+  ASSIGNC ((NEG (a) && POS (b)) ||
+          (NEG (a) && POS (result)) || (POS (b) && POS (result)));
+}
+
+/* Assigns the V flag after an subtraction of a and b to give result.  */
+
+void
+ARMul_SubOverflow (ARMul_State * state, ARMword a, ARMword b, ARMword result)
+{
+  ASSIGNV (SubOverflow (a, b, result));
+}
+
+/* This function does the work of generating the addresses used in an
+   LDC instruction.  The code here is always post-indexed, it's up to the
+   caller to get the input address correct and to handle base register
+   modification. It also handles the Busy-Waiting.  */
+
+void
+ARMul_LDC (ARMul_State * state, ARMword instr, ARMword address)
+{
+  unsigned cpab;
+  ARMword data;
+
+  UNDEF_LSCPCBaseWb;
+
+  if (! CP_ACCESS_ALLOWED (state, CPNum))
+    {
+      ARMul_UndefInstr (state, instr);
+      return;
     }
- if (state->abortSig || state->Aborted) {
-    TAKEABORT ;
+
+  if (ADDREXCEPT (address))
+    INTERNALABORT (address);
+
+  cpab = (state->LDC[CPNum]) (state, ARMul_FIRST, instr, 0);
+  while (cpab == ARMul_BUSY)
+    {
+      ARMul_Icycles (state, 1, 0);
+
+      if (IntPending (state))
+       {
+         cpab = (state->LDC[CPNum]) (state, ARMul_INTERRUPT, instr, 0);
+         return;
+       }
+      else
+       cpab = (state->LDC[CPNum]) (state, ARMul_BUSY, instr, 0);
+    }
+  if (cpab == ARMul_CANT)
+    {
+      CPTAKEABORT;
+      return;
+    }
+
+  cpab = (state->LDC[CPNum]) (state, ARMul_TRANSFER, instr, 0);
+  data = ARMul_LoadWordN (state, address);
+  BUSUSEDINCPCN;
+
+  if (BIT (21))
+    LSBase = state->Base;
+  cpab = (state->LDC[CPNum]) (state, ARMul_DATA, instr, data);
+
+  while (cpab == ARMul_INC)
+    {
+      address += 4;
+      data = ARMul_LoadWordN (state, address);
+      cpab = (state->LDC[CPNum]) (state, ARMul_DATA, instr, data);
     }
- }
-
-/***************************************************************************\
-* This function does the work of generating the addresses used in an        *
-* STC instruction.  The code here is always post-indexed, it's up to the    *
-* caller to get the input address correct and to handle base register       *
-* modification. It also handles the Busy-Waiting.                           *
-\***************************************************************************/
-
-void ARMul_STC(ARMul_State *state,ARMword instr,ARMword address)
-{unsigned cpab ;
- ARMword data ;
-
- UNDEF_LSCPCBaseWb ;
- if (ADDREXCEPT(address) || VECTORACCESS(address)) {
-    INTERNALABORT(address) ;
+
+  if (state->abortSig || state->Aborted)
+    TAKEABORT;
+}
+
+/* This function does the work of generating the addresses used in an
+   STC instruction.  The code here is always post-indexed, it's up to the
+   caller to get the input address correct and to handle base register
+   modification. It also handles the Busy-Waiting.  */
+
+void
+ARMul_STC (ARMul_State * state, ARMword instr, ARMword address)
+{
+  unsigned cpab;
+  ARMword data;
+
+  UNDEF_LSCPCBaseWb;
+
+  if (! CP_ACCESS_ALLOWED (state, CPNum))
+    {
+      ARMul_UndefInstr (state, instr);
+      return;
     }
- cpab = (state->STC[CPNum])(state,ARMul_FIRST,instr,&data) ;
- while (cpab == ARMul_BUSY) {
-    ARMul_Icycles(state,1,0) ;
-    if (IntPending(state)) {
-       cpab = (state->STC[CPNum])(state,ARMul_INTERRUPT,instr,0) ;
-       return ;
-       }
-    else
-       cpab = (state->STC[CPNum])(state,ARMul_BUSY,instr,&data) ;
+
+  if (ADDREXCEPT (address) || VECTORACCESS (address))
+    INTERNALABORT (address);
+
+  cpab = (state->STC[CPNum]) (state, ARMul_FIRST, instr, &data);
+  while (cpab == ARMul_BUSY)
+    {
+      ARMul_Icycles (state, 1, 0);
+      if (IntPending (state))
+       {
+         cpab = (state->STC[CPNum]) (state, ARMul_INTERRUPT, instr, 0);
+         return;
+       }
+      else
+       cpab = (state->STC[CPNum]) (state, ARMul_BUSY, instr, &data);
     }
- if (cpab == ARMul_CANT) {
-    CPTAKEABORT ;
-    return ;
+
+  if (cpab == ARMul_CANT)
+    {
+      CPTAKEABORT;
+      return;
     }
 #ifndef MODE32
- if (ADDREXCEPT(address) || VECTORACCESS(address)) {
-    INTERNALABORT(address) ;
-    }
+  if (ADDREXCEPT (address) || VECTORACCESS (address))
+    INTERNALABORT (address);
 #endif
- BUSUSEDINCPCN ;
- if (BIT(21))
-    LSBase = state->Base ;
- cpab = (state->STC[CPNum])(state,ARMul_DATA,instr,&data) ;
- ARMul_StoreWordN(state,address,data) ;
- while (cpab == ARMul_INC) {
-    address += 4 ;
-    cpab = (state->STC[CPNum])(state,ARMul_DATA,instr,&data) ;
-    ARMul_StoreWordN(state,address,data) ;
+  BUSUSEDINCPCN;
+  if (BIT (21))
+    LSBase = state->Base;
+  cpab = (state->STC[CPNum]) (state, ARMul_DATA, instr, &data);
+  ARMul_StoreWordN (state, address, data);
+
+  while (cpab == ARMul_INC)
+    {
+      address += 4;
+      cpab = (state->STC[CPNum]) (state, ARMul_DATA, instr, &data);
+      ARMul_StoreWordN (state, address, data);
     }
- if (state->abortSig || state->Aborted) {
-    TAKEABORT ;
+
+  if (state->abortSig || state->Aborted)
+    TAKEABORT;
+}
+
+/* This function does the Busy-Waiting for an MCR instruction.  */
+
+void
+ARMul_MCR (ARMul_State * state, ARMword instr, ARMword source)
+{
+  unsigned cpab;
+
+  if (! CP_ACCESS_ALLOWED (state, CPNum))
+    {
+      ARMul_UndefInstr (state, instr);
+      return;
     }
- }
-
-/***************************************************************************\
-*        This function does the Busy-Waiting for an MCR instruction.        *
-\***************************************************************************/
-
-void 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) ;
-       return ;
-       }
-    else
-       cpab = (state->MCR[CPNum])(state,ARMul_BUSY,instr,source) ;
+
+  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);
+         return;
+       }
+      else
+       cpab = (state->MCR[CPNum]) (state, ARMul_BUSY, instr, source);
+    }
+
+  if (cpab == ARMul_CANT)
+    ARMul_Abort (state, ARMul_UndefinedInstrV);
+  else
+    {
+      BUSUSEDINCPCN;
+      ARMul_Ccycles (state, 1, 0);
     }
- if (cpab == ARMul_CANT)
-    ARMul_Abort(state,ARMul_UndefinedInstrV) ;
- else {
-    BUSUSEDINCPCN ;
-    ARMul_Ccycles(state,1,0) ;
+}
+
+/* This function does the Busy-Waiting for an MRC instruction.  */
+
+ARMword
+ARMul_MRC (ARMul_State * state, ARMword instr)
+{
+  unsigned cpab;
+  ARMword result = 0;
+
+  if (! CP_ACCESS_ALLOWED (state, CPNum))
+    {
+      ARMul_UndefInstr (state, instr);
+      return result;
     }
- }
-
-/***************************************************************************\
-*        This function does the Busy-Waiting for an MRC instruction.        *
-\***************************************************************************/
-
-ARMword ARMul_MRC(ARMul_State *state,ARMword instr)
-{unsigned cpab ;
- ARMword result = 0 ;
-
- cpab = (state->MRC[CPNum])(state,ARMul_FIRST,instr,&result) ;
- while (cpab == ARMul_BUSY) {
-    ARMul_Icycles(state,1,0) ;
-    if (IntPending(state)) {
-       cpab = (state->MRC[CPNum])(state,ARMul_INTERRUPT,instr,0) ;
-       return(0) ;
-       }
-    else
-       cpab = (state->MRC[CPNum])(state,ARMul_BUSY,instr,&result) ;
+
+  cpab = (state->MRC[CPNum]) (state, ARMul_FIRST, instr, &result);
+  while (cpab == ARMul_BUSY)
+    {
+      ARMul_Icycles (state, 1, 0);
+      if (IntPending (state))
+       {
+         cpab = (state->MRC[CPNum]) (state, ARMul_INTERRUPT, instr, 0);
+         return (0);
+       }
+      else
+       cpab = (state->MRC[CPNum]) (state, ARMul_BUSY, instr, &result);
     }
- if (cpab == ARMul_CANT) {
-    ARMul_Abort(state,ARMul_UndefinedInstrV) ;
-    result = ECC ; /* Parent will destroy the flags otherwise */
+  if (cpab == ARMul_CANT)
+    {
+      ARMul_Abort (state, ARMul_UndefinedInstrV);
+      /* Parent will destroy the flags otherwise.  */
+      result = ECC;
     }
- else {
-    BUSUSEDINCPCN ;
-    ARMul_Ccycles(state,1,0) ;
-    ARMul_Icycles(state,1,0) ;
+  else
+    {
+      BUSUSEDINCPCN;
+      ARMul_Ccycles (state, 1, 0);
+      ARMul_Icycles (state, 1, 0);
     }
- return(result) ;
+
+  return result;
 }
 
-/***************************************************************************\
-*        This function does the Busy-Waiting for an CDP instruction.        *
-\***************************************************************************/
+/* This function does the Busy-Waiting for an CDP instruction.  */
 
-void ARMul_CDP(ARMul_State *state,ARMword instr)
-{unsigned cpab ;
+void
+ARMul_CDP (ARMul_State * state, ARMword instr)
+{
+  unsigned cpab;
 
- cpab = (state->CDP[CPNum])(state,ARMul_FIRST,instr) ;
- while (cpab == ARMul_BUSY) {
-    ARMul_Icycles(state,1,0) ;
-    if (IntPending(state)) {
-       cpab = (state->CDP[CPNum])(state,ARMul_INTERRUPT,instr) ;
-       return ;
-       }
-    else
-       cpab = (state->CDP[CPNum])(state,ARMul_BUSY,instr) ;
+  if (! CP_ACCESS_ALLOWED (state, CPNum))
+    {
+      ARMul_UndefInstr (state, instr);
+      return;
     }
- if (cpab == ARMul_CANT)
-    ARMul_Abort(state,ARMul_UndefinedInstrV) ;
- else
-    BUSUSEDN ;
+
+  cpab = (state->CDP[CPNum]) (state, ARMul_FIRST, instr);
+  while (cpab == ARMul_BUSY)
+    {
+      ARMul_Icycles (state, 1, 0);
+      if (IntPending (state))
+       {
+         cpab = (state->CDP[CPNum]) (state, ARMul_INTERRUPT, instr);
+         return;
+       }
+      else
+       cpab = (state->CDP[CPNum]) (state, ARMul_BUSY, instr);
+    }
+  if (cpab == ARMul_CANT)
+    ARMul_Abort (state, ARMul_UndefinedInstrV);
+  else
+    BUSUSEDN;
 }
 
-/***************************************************************************\
-*      This function handles Undefined instructions, as CP isntruction      *
-\***************************************************************************/
+/* This function handles Undefined instructions, as CP isntruction.  */
 
-void ARMul_UndefInstr(ARMul_State *state,ARMword instr)
+void
+ARMul_UndefInstr (ARMul_State * state, ARMword instr ATTRIBUTE_UNUSED)
 {
ARMul_Abort(state,ARMul_UndefinedInstrV) ;
 ARMul_Abort (state, ARMul_UndefinedInstrV);
 }
 
-/***************************************************************************\
-*           Return TRUE if an interrupt is pending, FALSE otherwise.        *
-\***************************************************************************/
+/* Return TRUE if an interrupt is pending, FALSE otherwise.  */
 
-unsigned IntPending(ARMul_State *state)
+unsigned
+IntPending (ARMul_State * state)
 {
- if (state->Exception) { /* Any exceptions */
-    if (state->NresetSig == LOW) {
-       ARMul_Abort(state,ARMul_ResetV) ;
-       return(TRUE) ;
-       }
-    else if (!state->NfiqSig && !FFLAG) {
-       ARMul_Abort(state,ARMul_FIQV) ;
-       return(TRUE) ;
-       }
-    else if (!state->NirqSig && !IFLAG) {
-       ARMul_Abort(state,ARMul_IRQV) ;
-       return(TRUE) ;
-       }
+  if (state->Exception)
+    {
+      /* Any exceptions.  */
+      if (state->NresetSig == LOW)
+       {
+         ARMul_Abort (state, ARMul_ResetV);
+         return TRUE;
+       }
+      else if (!state->NfiqSig && !FFLAG)
+       {
+         ARMul_Abort (state, ARMul_FIQV);
+         return TRUE;
+       }
+      else if (!state->NirqSig && !IFLAG)
+       {
+         ARMul_Abort (state, ARMul_IRQV);
+         return TRUE;
+       }
     }
- return(FALSE) ;
- }
-
-/***************************************************************************\
-*               Align a word access to a non word boundary                  *
-\***************************************************************************/
-
-ARMword ARMul_Align(ARMul_State *state, ARMword address, ARMword data)
-{/* this code assumes the address is really unaligned,
-    as a shift by 32 is undefined in C */
-
- address = (address & 3) << 3 ; /* get the word address */
- return( ( data >> address) | (data << (32 - address)) ) ; /* rot right */
-}
-
-/***************************************************************************\
-* This routine is used to call another routine after a certain number of    *
-* cycles have been executed. The first parameter is the number of cycles    *
-* delay before the function is called, the second argument is a pointer     *
-* to the function. A delay of zero doesn't work, just call the function.    *
-\***************************************************************************/
-
-void ARMul_ScheduleEvent(ARMul_State *state, unsigned long delay, unsigned (*what)())
-{unsigned long when ;
- struct EventNode *event ;
-
- if (state->EventSet++ == 0)
-    state->Now = ARMul_Time(state) ;
- when = (state->Now + delay) % EVENTLISTSIZE ;
- event = (struct EventNode *)malloc(sizeof(struct EventNode)) ;
- event->func = what ;
- event->next = *(state->EventPtr + when) ;
- *(state->EventPtr + when) = event ;
-}
-
-/***************************************************************************\
-* This routine is called at the beginning of every cycle, to envoke         *
-* scheduled events.                                                         *
-\***************************************************************************/
-
-void ARMul_EnvokeEvent(ARMul_State *state)
-{static unsigned long then ;
-
- then = state->Now ;
- state->Now = ARMul_Time(state) % EVENTLISTSIZE ;
- if (then < state->Now) /* schedule events */
-    EnvokeList(state,then,state->Now) ;
- else if (then > state->Now) { /* need to wrap around the list */
-    EnvokeList(state,then,EVENTLISTSIZE-1L) ;
-    EnvokeList(state,0L,state->Now) ;
+
+  return FALSE;
+}
+
+/* Align a word access to a non word boundary.  */
+
+ARMword
+ARMul_Align (state, address, data)
+     ARMul_State * state ATTRIBUTE_UNUSED;
+     ARMword address;
+     ARMword data;
+{
+  /* This code assumes the address is really unaligned,
+     as a shift by 32 is undefined in C.  */
+
+  address = (address & 3) << 3;        /* Get the word address.  */
+  return ((data >> address) | (data << (32 - address)));       /* rot right */
+}
+
+/* This routine is used to call another routine after a certain number of
+   cycles have been executed. The first parameter is the number of cycles
+   delay before the function is called, the second argument is a pointer
+   to the function. A delay of zero doesn't work, just call the function.  */
+
+void
+ARMul_ScheduleEvent (ARMul_State * state, unsigned long delay,
+                    unsigned (*what) (ARMul_State *))
+{
+  unsigned long when;
+  struct EventNode *event;
+
+  if (state->EventSet++ == 0)
+    state->Now = ARMul_Time (state);
+  when = (state->Now + delay) % EVENTLISTSIZE;
+  event = (struct EventNode *) malloc (sizeof (struct EventNode));
+  event->func = what;
+  event->next = *(state->EventPtr + when);
+  *(state->EventPtr + when) = event;
+}
+
+/* This routine is called at the beginning of
+   every cycle, to envoke scheduled events.  */
+
+void
+ARMul_EnvokeEvent (ARMul_State * state)
+{
+  static unsigned long then;
+
+  then = state->Now;
+  state->Now = ARMul_Time (state) % EVENTLISTSIZE;
+  if (then < state->Now)
+    /* Schedule events.  */
+    EnvokeList (state, then, state->Now);
+  else if (then > state->Now)
+    {
+      /* Need to wrap around the list.  */
+      EnvokeList (state, then, EVENTLISTSIZE - 1L);
+      EnvokeList (state, 0L, state->Now);
     }
- }
-
-static void EnvokeList(ARMul_State *state, unsigned long from, unsigned long to)
-/* envokes all the entries in a range */
-{struct EventNode *anevent ;
-
- for (; from <= to ; from++) {
-    anevent = *(state->EventPtr + from) ;
-    while (anevent) {
-       (anevent->func)(state) ;
-       state->EventSet-- ;
-       anevent = anevent->next ;
-       }
-    *(state->EventPtr + from) = NULL ;
+}
+
+/* Envokes all the entries in a range.  */
+
+static void
+EnvokeList (ARMul_State * state, unsigned long from, unsigned long to)
+{
+  for (; from <= to; from++)
+    {
+      struct EventNode *anevent;
+
+      anevent = *(state->EventPtr + from);
+      while (anevent)
+       {
+         (anevent->func) (state);
+         state->EventSet--;
+         anevent = anevent->next;
+       }
+      *(state->EventPtr + from) = NULL;
     }
- }
+}
 
-/***************************************************************************\
-* This routine is returns the number of clock ticks since the last reset.   *
-\***************************************************************************/
+/* This routine is returns the number of clock ticks since the last reset.  */
 
-unsigned long ARMul_Time(ARMul_State *state)
-{return(state->NumScycles + state->NumNcycles +
-        state->NumIcycles + state->NumCcycles + state->NumFcycles) ;
+unsigned long
+ARMul_Time (ARMul_State * state)
+{
+  return (state->NumScycles + state->NumNcycles +
+         state->NumIcycles + state->NumCcycles + state->NumFcycles);
 }