Home | History | Annotate | Line # | Download | only in arm
armsupp.c revision 1.1
      1 /*  armsupp.c -- ARMulator support code:  ARM6 Instruction Emulator.
      2     Copyright (C) 1994 Advanced RISC Machines Ltd.
      3 
      4     This program is free software; you can redistribute it and/or modify
      5     it under the terms of the GNU General Public License as published by
      6     the Free Software Foundation; either version 3 of the License, or
      7     (at your option) any later version.
      8 
      9     This program is distributed in the hope that it will be useful,
     10     but WITHOUT ANY WARRANTY; without even the implied warranty of
     11     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     12     GNU General Public License for more details.
     13 
     14     You should have received a copy of the GNU General Public License
     15     along with this program; if not, see <http://www.gnu.org/licenses/>. */
     16 
     17 #include "armdefs.h"
     18 #include "armemu.h"
     19 #include "ansidecl.h"
     20 
     21 /* Definitions for the support routines.  */
     22 
     23 static ARMword ModeToBank (ARMword);
     24 static void    EnvokeList (ARMul_State *, unsigned long, unsigned long);
     25 
     26 struct EventNode
     27 {					/* An event list node.  */
     28   unsigned (*func) (ARMul_State *);	/* The function to call.  */
     29   struct EventNode *next;
     30 };
     31 
     32 /* This routine returns the value of a register from a mode.  */
     33 
     34 ARMword
     35 ARMul_GetReg (ARMul_State * state, unsigned mode, unsigned reg)
     36 {
     37   mode &= MODEBITS;
     38   if (mode != state->Mode)
     39     return (state->RegBank[ModeToBank ((ARMword) mode)][reg]);
     40   else
     41     return (state->Reg[reg]);
     42 }
     43 
     44 /* This routine sets the value of a register for a mode.  */
     45 
     46 void
     47 ARMul_SetReg (ARMul_State * state, unsigned mode, unsigned reg, ARMword value)
     48 {
     49   mode &= MODEBITS;
     50   if (mode != state->Mode)
     51     state->RegBank[ModeToBank ((ARMword) mode)][reg] = value;
     52   else
     53     state->Reg[reg] = value;
     54 }
     55 
     56 /* This routine returns the value of the PC, mode independently.  */
     57 
     58 ARMword
     59 ARMul_GetPC (ARMul_State * state)
     60 {
     61   if (state->Mode > SVC26MODE)
     62     return state->Reg[15];
     63   else
     64     return R15PC;
     65 }
     66 
     67 /* This routine returns the value of the PC, mode independently.  */
     68 
     69 ARMword
     70 ARMul_GetNextPC (ARMul_State * state)
     71 {
     72   if (state->Mode > SVC26MODE)
     73     return state->Reg[15] + isize;
     74   else
     75     return (state->Reg[15] + isize) & R15PCBITS;
     76 }
     77 
     78 /* This routine sets the value of the PC.  */
     79 
     80 void
     81 ARMul_SetPC (ARMul_State * state, ARMword value)
     82 {
     83   if (ARMul_MODE32BIT)
     84     state->Reg[15] = value & PCBITS;
     85   else
     86     state->Reg[15] = R15CCINTMODE | (value & R15PCBITS);
     87   FLUSHPIPE;
     88 }
     89 
     90 /* This routine returns the value of register 15, mode independently.  */
     91 
     92 ARMword
     93 ARMul_GetR15 (ARMul_State * state)
     94 {
     95   if (state->Mode > SVC26MODE)
     96     return (state->Reg[15]);
     97   else
     98     return (R15PC | ECC | ER15INT | EMODE);
     99 }
    100 
    101 /* This routine sets the value of Register 15.  */
    102 
    103 void
    104 ARMul_SetR15 (ARMul_State * state, ARMword value)
    105 {
    106   if (ARMul_MODE32BIT)
    107     state->Reg[15] = value & PCBITS;
    108   else
    109     {
    110       state->Reg[15] = value;
    111       ARMul_R15Altered (state);
    112     }
    113   FLUSHPIPE;
    114 }
    115 
    116 /* This routine returns the value of the CPSR.  */
    117 
    118 ARMword
    119 ARMul_GetCPSR (ARMul_State * state)
    120 {
    121   return (CPSR | state->Cpsr);
    122 }
    123 
    124 /* This routine sets the value of the CPSR.  */
    125 
    126 void
    127 ARMul_SetCPSR (ARMul_State * state, ARMword value)
    128 {
    129   state->Cpsr = value;
    130   ARMul_CPSRAltered (state);
    131 }
    132 
    133 /* This routine does all the nasty bits involved in a write to the CPSR,
    134    including updating the register bank, given a MSR instruction.  */
    135 
    136 void
    137 ARMul_FixCPSR (ARMul_State * state, ARMword instr, ARMword rhs)
    138 {
    139   state->Cpsr = ARMul_GetCPSR (state);
    140 
    141   if (state->Mode != USER26MODE
    142       && state->Mode != USER32MODE)
    143     {
    144       /* In user mode, only write flags.  */
    145       if (BIT (16))
    146 	SETPSR_C (state->Cpsr, rhs);
    147       if (BIT (17))
    148 	SETPSR_X (state->Cpsr, rhs);
    149       if (BIT (18))
    150 	SETPSR_S (state->Cpsr, rhs);
    151     }
    152   if (BIT (19))
    153     SETPSR_F (state->Cpsr, rhs);
    154   ARMul_CPSRAltered (state);
    155 }
    156 
    157 /* Get an SPSR from the specified mode.  */
    158 
    159 ARMword
    160 ARMul_GetSPSR (ARMul_State * state, ARMword mode)
    161 {
    162   ARMword bank = ModeToBank (mode & MODEBITS);
    163 
    164   if (! BANK_CAN_ACCESS_SPSR (bank))
    165     return ARMul_GetCPSR (state);
    166 
    167   return state->Spsr[bank];
    168 }
    169 
    170 /* This routine does a write to an SPSR.  */
    171 
    172 void
    173 ARMul_SetSPSR (ARMul_State * state, ARMword mode, ARMword value)
    174 {
    175   ARMword bank = ModeToBank (mode & MODEBITS);
    176 
    177   if (BANK_CAN_ACCESS_SPSR (bank))
    178     state->Spsr[bank] = value;
    179 }
    180 
    181 /* This routine does a write to the current SPSR, given an MSR instruction.  */
    182 
    183 void
    184 ARMul_FixSPSR (ARMul_State * state, ARMword instr, ARMword rhs)
    185 {
    186   if (BANK_CAN_ACCESS_SPSR (state->Bank))
    187     {
    188       if (BIT (16))
    189 	SETPSR_C (state->Spsr[state->Bank], rhs);
    190       if (BIT (17))
    191 	SETPSR_X (state->Spsr[state->Bank], rhs);
    192       if (BIT (18))
    193 	SETPSR_S (state->Spsr[state->Bank], rhs);
    194       if (BIT (19))
    195 	SETPSR_F (state->Spsr[state->Bank], rhs);
    196     }
    197 }
    198 
    199 /* This routine updates the state of the emulator after the Cpsr has been
    200    changed.  Both the processor flags and register bank are updated.  */
    201 
    202 void
    203 ARMul_CPSRAltered (ARMul_State * state)
    204 {
    205   ARMword oldmode;
    206 
    207   if (state->prog32Sig == LOW)
    208     state->Cpsr &= (CCBITS | INTBITS | R15MODEBITS);
    209 
    210   oldmode = state->Mode;
    211 
    212   if (state->Mode != (state->Cpsr & MODEBITS))
    213     {
    214       state->Mode =
    215 	ARMul_SwitchMode (state, state->Mode, state->Cpsr & MODEBITS);
    216 
    217       state->NtransSig = (state->Mode & 3) ? HIGH : LOW;
    218     }
    219   state->Cpsr &= ~MODEBITS;
    220 
    221   ASSIGNINT (state->Cpsr & INTBITS);
    222   state->Cpsr &= ~INTBITS;
    223   ASSIGNN ((state->Cpsr & NBIT) != 0);
    224   state->Cpsr &= ~NBIT;
    225   ASSIGNZ ((state->Cpsr & ZBIT) != 0);
    226   state->Cpsr &= ~ZBIT;
    227   ASSIGNC ((state->Cpsr & CBIT) != 0);
    228   state->Cpsr &= ~CBIT;
    229   ASSIGNV ((state->Cpsr & VBIT) != 0);
    230   state->Cpsr &= ~VBIT;
    231   ASSIGNS ((state->Cpsr & SBIT) != 0);
    232   state->Cpsr &= ~SBIT;
    233 #ifdef MODET
    234   ASSIGNT ((state->Cpsr & TBIT) != 0);
    235   state->Cpsr &= ~TBIT;
    236 #endif
    237 
    238   if (oldmode > SVC26MODE)
    239     {
    240       if (state->Mode <= SVC26MODE)
    241 	{
    242 	  state->Emulate = CHANGEMODE;
    243 	  state->Reg[15] = ECC | ER15INT | EMODE | R15PC;
    244 	}
    245     }
    246   else
    247     {
    248       if (state->Mode > SVC26MODE)
    249 	{
    250 	  state->Emulate = CHANGEMODE;
    251 	  state->Reg[15] = R15PC;
    252 	}
    253       else
    254 	state->Reg[15] = ECC | ER15INT | EMODE | R15PC;
    255     }
    256 }
    257 
    258 /* This routine updates the state of the emulator after register 15 has
    259    been changed.  Both the processor flags and register bank are updated.
    260    This routine should only be called from a 26 bit mode.  */
    261 
    262 void
    263 ARMul_R15Altered (ARMul_State * state)
    264 {
    265   if (state->Mode != R15MODE)
    266     {
    267       state->Mode = ARMul_SwitchMode (state, state->Mode, R15MODE);
    268       state->NtransSig = (state->Mode & 3) ? HIGH : LOW;
    269     }
    270 
    271   if (state->Mode > SVC26MODE)
    272     state->Emulate = CHANGEMODE;
    273 
    274   ASSIGNR15INT (R15INT);
    275 
    276   ASSIGNN ((state->Reg[15] & NBIT) != 0);
    277   ASSIGNZ ((state->Reg[15] & ZBIT) != 0);
    278   ASSIGNC ((state->Reg[15] & CBIT) != 0);
    279   ASSIGNV ((state->Reg[15] & VBIT) != 0);
    280 }
    281 
    282 /* This routine controls the saving and restoring of registers across mode
    283    changes.  The regbank matrix is largely unused, only rows 13 and 14 are
    284    used across all modes, 8 to 14 are used for FIQ, all others use the USER
    285    column.  It's easier this way.  old and new parameter are modes numbers.
    286    Notice the side effect of changing the Bank variable.  */
    287 
    288 ARMword
    289 ARMul_SwitchMode (ARMul_State * state, ARMword oldmode, ARMword newmode)
    290 {
    291   unsigned i;
    292   ARMword  oldbank;
    293   ARMword  newbank;
    294 
    295   oldbank = ModeToBank (oldmode);
    296   newbank = state->Bank = ModeToBank (newmode);
    297 
    298   /* Do we really need to do it?  */
    299   if (oldbank != newbank)
    300     {
    301       /* Save away the old registers.  */
    302       switch (oldbank)
    303 	{
    304 	case USERBANK:
    305 	case IRQBANK:
    306 	case SVCBANK:
    307 	case ABORTBANK:
    308 	case UNDEFBANK:
    309 	  if (newbank == FIQBANK)
    310 	    for (i = 8; i < 13; i++)
    311 	      state->RegBank[USERBANK][i] = state->Reg[i];
    312 	  state->RegBank[oldbank][13] = state->Reg[13];
    313 	  state->RegBank[oldbank][14] = state->Reg[14];
    314 	  break;
    315 	case FIQBANK:
    316 	  for (i = 8; i < 15; i++)
    317 	    state->RegBank[FIQBANK][i] = state->Reg[i];
    318 	  break;
    319 	case DUMMYBANK:
    320 	  for (i = 8; i < 15; i++)
    321 	    state->RegBank[DUMMYBANK][i] = 0;
    322 	  break;
    323 	default:
    324 	  abort ();
    325 	}
    326 
    327       /* Restore the new registers.  */
    328       switch (newbank)
    329 	{
    330 	case USERBANK:
    331 	case IRQBANK:
    332 	case SVCBANK:
    333 	case ABORTBANK:
    334 	case UNDEFBANK:
    335 	  if (oldbank == FIQBANK)
    336 	    for (i = 8; i < 13; i++)
    337 	      state->Reg[i] = state->RegBank[USERBANK][i];
    338 	  state->Reg[13] = state->RegBank[newbank][13];
    339 	  state->Reg[14] = state->RegBank[newbank][14];
    340 	  break;
    341 	case FIQBANK:
    342 	  for (i = 8; i < 15; i++)
    343 	    state->Reg[i] = state->RegBank[FIQBANK][i];
    344 	  break;
    345 	case DUMMYBANK:
    346 	  for (i = 8; i < 15; i++)
    347 	    state->Reg[i] = 0;
    348 	  break;
    349 	default:
    350 	  abort ();
    351 	}
    352     }
    353 
    354   return newmode;
    355 }
    356 
    357 /* Given a processor mode, this routine returns the
    358    register bank that will be accessed in that mode.  */
    359 
    360 static ARMword
    361 ModeToBank (ARMword mode)
    362 {
    363   static ARMword bankofmode[] =
    364   {
    365     USERBANK,  FIQBANK,   IRQBANK,   SVCBANK,
    366     DUMMYBANK, DUMMYBANK, DUMMYBANK, DUMMYBANK,
    367     DUMMYBANK, DUMMYBANK, DUMMYBANK, DUMMYBANK,
    368     DUMMYBANK, DUMMYBANK, DUMMYBANK, DUMMYBANK,
    369     USERBANK,  FIQBANK,   IRQBANK,   SVCBANK,
    370     DUMMYBANK, DUMMYBANK, DUMMYBANK, ABORTBANK,
    371     DUMMYBANK, DUMMYBANK, DUMMYBANK, UNDEFBANK,
    372     DUMMYBANK, DUMMYBANK, DUMMYBANK, SYSTEMBANK
    373   };
    374 
    375   if (mode >= (sizeof (bankofmode) / sizeof (bankofmode[0])))
    376     return DUMMYBANK;
    377 
    378   return bankofmode[mode];
    379 }
    380 
    381 /* Returns the register number of the nth register in a reg list.  */
    382 
    383 unsigned
    384 ARMul_NthReg (ARMword instr, unsigned number)
    385 {
    386   unsigned bit, upto;
    387 
    388   for (bit = 0, upto = 0; upto <= number; bit ++)
    389     if (BIT (bit))
    390       upto ++;
    391 
    392   return (bit - 1);
    393 }
    394 
    395 /* Assigns the N and Z flags depending on the value of result.  */
    396 
    397 void
    398 ARMul_NegZero (ARMul_State * state, ARMword result)
    399 {
    400   if (NEG (result))
    401     {
    402       SETN;
    403       CLEARZ;
    404     }
    405   else if (result == 0)
    406     {
    407       CLEARN;
    408       SETZ;
    409     }
    410   else
    411     {
    412       CLEARN;
    413       CLEARZ;
    414     }
    415 }
    416 
    417 /* Compute whether an addition of A and B, giving RESULT, overflowed.  */
    418 
    419 int
    420 AddOverflow (ARMword a, ARMword b, ARMword result)
    421 {
    422   return ((NEG (a) && NEG (b) && POS (result))
    423 	  || (POS (a) && POS (b) && NEG (result)));
    424 }
    425 
    426 /* Compute whether a subtraction of A and B, giving RESULT, overflowed.  */
    427 
    428 int
    429 SubOverflow (ARMword a, ARMword b, ARMword result)
    430 {
    431   return ((NEG (a) && POS (b) && POS (result))
    432 	  || (POS (a) && NEG (b) && NEG (result)));
    433 }
    434 
    435 /* Assigns the C flag after an addition of a and b to give result.  */
    436 
    437 void
    438 ARMul_AddCarry (ARMul_State * state, ARMword a, ARMword b, ARMword result)
    439 {
    440   ASSIGNC ((NEG (a) && NEG (b)) ||
    441 	   (NEG (a) && POS (result)) || (NEG (b) && POS (result)));
    442 }
    443 
    444 /* Assigns the V flag after an addition of a and b to give result.  */
    445 
    446 void
    447 ARMul_AddOverflow (ARMul_State * state, ARMword a, ARMword b, ARMword result)
    448 {
    449   ASSIGNV (AddOverflow (a, b, result));
    450 }
    451 
    452 /* Assigns the C flag after an subtraction of a and b to give result.  */
    453 
    454 void
    455 ARMul_SubCarry (ARMul_State * state, ARMword a, ARMword b, ARMword result)
    456 {
    457   ASSIGNC ((NEG (a) && POS (b)) ||
    458 	   (NEG (a) && POS (result)) || (POS (b) && POS (result)));
    459 }
    460 
    461 /* Assigns the V flag after an subtraction of a and b to give result.  */
    462 
    463 void
    464 ARMul_SubOverflow (ARMul_State * state, ARMword a, ARMword b, ARMword result)
    465 {
    466   ASSIGNV (SubOverflow (a, b, result));
    467 }
    468 
    469 /* This function does the work of generating the addresses used in an
    470    LDC instruction.  The code here is always post-indexed, it's up to the
    471    caller to get the input address correct and to handle base register
    472    modification. It also handles the Busy-Waiting.  */
    473 
    474 void
    475 ARMul_LDC (ARMul_State * state, ARMword instr, ARMword address)
    476 {
    477   unsigned cpab;
    478   ARMword data;
    479 
    480   UNDEF_LSCPCBaseWb;
    481 
    482   if (! CP_ACCESS_ALLOWED (state, CPNum))
    483     {
    484       ARMul_UndefInstr (state, instr);
    485       return;
    486     }
    487 
    488   if (ADDREXCEPT (address))
    489     INTERNALABORT (address);
    490 
    491   cpab = (state->LDC[CPNum]) (state, ARMul_FIRST, instr, 0);
    492   while (cpab == ARMul_BUSY)
    493     {
    494       ARMul_Icycles (state, 1, 0);
    495 
    496       if (IntPending (state))
    497 	{
    498 	  cpab = (state->LDC[CPNum]) (state, ARMul_INTERRUPT, instr, 0);
    499 	  return;
    500 	}
    501       else
    502 	cpab = (state->LDC[CPNum]) (state, ARMul_BUSY, instr, 0);
    503     }
    504   if (cpab == ARMul_CANT)
    505     {
    506       CPTAKEABORT;
    507       return;
    508     }
    509 
    510   cpab = (state->LDC[CPNum]) (state, ARMul_TRANSFER, instr, 0);
    511   data = ARMul_LoadWordN (state, address);
    512   BUSUSEDINCPCN;
    513 
    514   if (BIT (21))
    515     LSBase = state->Base;
    516   cpab = (state->LDC[CPNum]) (state, ARMul_DATA, instr, data);
    517 
    518   while (cpab == ARMul_INC)
    519     {
    520       address += 4;
    521       data = ARMul_LoadWordN (state, address);
    522       cpab = (state->LDC[CPNum]) (state, ARMul_DATA, instr, data);
    523     }
    524 
    525   if (state->abortSig || state->Aborted)
    526     TAKEABORT;
    527 }
    528 
    529 /* This function does the work of generating the addresses used in an
    530    STC instruction.  The code here is always post-indexed, it's up to the
    531    caller to get the input address correct and to handle base register
    532    modification. It also handles the Busy-Waiting.  */
    533 
    534 void
    535 ARMul_STC (ARMul_State * state, ARMword instr, ARMword address)
    536 {
    537   unsigned cpab;
    538   ARMword data;
    539 
    540   UNDEF_LSCPCBaseWb;
    541 
    542   if (! CP_ACCESS_ALLOWED (state, CPNum))
    543     {
    544       ARMul_UndefInstr (state, instr);
    545       return;
    546     }
    547 
    548   if (ADDREXCEPT (address) || VECTORACCESS (address))
    549     INTERNALABORT (address);
    550 
    551   cpab = (state->STC[CPNum]) (state, ARMul_FIRST, instr, &data);
    552   while (cpab == ARMul_BUSY)
    553     {
    554       ARMul_Icycles (state, 1, 0);
    555       if (IntPending (state))
    556 	{
    557 	  cpab = (state->STC[CPNum]) (state, ARMul_INTERRUPT, instr, 0);
    558 	  return;
    559 	}
    560       else
    561 	cpab = (state->STC[CPNum]) (state, ARMul_BUSY, instr, &data);
    562     }
    563 
    564   if (cpab == ARMul_CANT)
    565     {
    566       CPTAKEABORT;
    567       return;
    568     }
    569 #ifndef MODE32
    570   if (ADDREXCEPT (address) || VECTORACCESS (address))
    571     INTERNALABORT (address);
    572 #endif
    573   BUSUSEDINCPCN;
    574   if (BIT (21))
    575     LSBase = state->Base;
    576   cpab = (state->STC[CPNum]) (state, ARMul_DATA, instr, &data);
    577   ARMul_StoreWordN (state, address, data);
    578 
    579   while (cpab == ARMul_INC)
    580     {
    581       address += 4;
    582       cpab = (state->STC[CPNum]) (state, ARMul_DATA, instr, &data);
    583       ARMul_StoreWordN (state, address, data);
    584     }
    585 
    586   if (state->abortSig || state->Aborted)
    587     TAKEABORT;
    588 }
    589 
    590 /* This function does the Busy-Waiting for an MCR instruction.  */
    591 
    592 void
    593 ARMul_MCR (ARMul_State * state, ARMword instr, ARMword source)
    594 {
    595   unsigned cpab;
    596 
    597   if (! CP_ACCESS_ALLOWED (state, CPNum))
    598     {
    599       ARMul_UndefInstr (state, instr);
    600       return;
    601     }
    602 
    603   cpab = (state->MCR[CPNum]) (state, ARMul_FIRST, instr, source);
    604 
    605   while (cpab == ARMul_BUSY)
    606     {
    607       ARMul_Icycles (state, 1, 0);
    608 
    609       if (IntPending (state))
    610 	{
    611 	  cpab = (state->MCR[CPNum]) (state, ARMul_INTERRUPT, instr, 0);
    612 	  return;
    613 	}
    614       else
    615 	cpab = (state->MCR[CPNum]) (state, ARMul_BUSY, instr, source);
    616     }
    617 
    618   if (cpab == ARMul_CANT)
    619     ARMul_Abort (state, ARMul_UndefinedInstrV);
    620   else
    621     {
    622       BUSUSEDINCPCN;
    623       ARMul_Ccycles (state, 1, 0);
    624     }
    625 }
    626 
    627 /* This function does the Busy-Waiting for an MRC instruction.  */
    628 
    629 ARMword
    630 ARMul_MRC (ARMul_State * state, ARMword instr)
    631 {
    632   unsigned cpab;
    633   ARMword result = 0;
    634 
    635   if (! CP_ACCESS_ALLOWED (state, CPNum))
    636     {
    637       ARMul_UndefInstr (state, instr);
    638       return result;
    639     }
    640 
    641   cpab = (state->MRC[CPNum]) (state, ARMul_FIRST, instr, &result);
    642   while (cpab == ARMul_BUSY)
    643     {
    644       ARMul_Icycles (state, 1, 0);
    645       if (IntPending (state))
    646 	{
    647 	  cpab = (state->MRC[CPNum]) (state, ARMul_INTERRUPT, instr, 0);
    648 	  return (0);
    649 	}
    650       else
    651 	cpab = (state->MRC[CPNum]) (state, ARMul_BUSY, instr, &result);
    652     }
    653   if (cpab == ARMul_CANT)
    654     {
    655       ARMul_Abort (state, ARMul_UndefinedInstrV);
    656       /* Parent will destroy the flags otherwise.  */
    657       result = ECC;
    658     }
    659   else
    660     {
    661       BUSUSEDINCPCN;
    662       ARMul_Ccycles (state, 1, 0);
    663       ARMul_Icycles (state, 1, 0);
    664     }
    665 
    666   return result;
    667 }
    668 
    669 /* This function does the Busy-Waiting for an CDP instruction.  */
    670 
    671 void
    672 ARMul_CDP (ARMul_State * state, ARMword instr)
    673 {
    674   unsigned cpab;
    675 
    676   if (! CP_ACCESS_ALLOWED (state, CPNum))
    677     {
    678       ARMul_UndefInstr (state, instr);
    679       return;
    680     }
    681 
    682   cpab = (state->CDP[CPNum]) (state, ARMul_FIRST, instr);
    683   while (cpab == ARMul_BUSY)
    684     {
    685       ARMul_Icycles (state, 1, 0);
    686       if (IntPending (state))
    687 	{
    688 	  cpab = (state->CDP[CPNum]) (state, ARMul_INTERRUPT, instr);
    689 	  return;
    690 	}
    691       else
    692 	cpab = (state->CDP[CPNum]) (state, ARMul_BUSY, instr);
    693     }
    694   if (cpab == ARMul_CANT)
    695     ARMul_Abort (state, ARMul_UndefinedInstrV);
    696   else
    697     BUSUSEDN;
    698 }
    699 
    700 /* This function handles Undefined instructions, as CP isntruction.  */
    701 
    702 void
    703 ARMul_UndefInstr (ARMul_State * state, ARMword instr ATTRIBUTE_UNUSED)
    704 {
    705   ARMul_Abort (state, ARMul_UndefinedInstrV);
    706 }
    707 
    708 /* Return TRUE if an interrupt is pending, FALSE otherwise.  */
    709 
    710 unsigned
    711 IntPending (ARMul_State * state)
    712 {
    713   if (state->Exception)
    714     {
    715       /* Any exceptions.  */
    716       if (state->NresetSig == LOW)
    717 	{
    718 	  ARMul_Abort (state, ARMul_ResetV);
    719 	  return TRUE;
    720 	}
    721       else if (!state->NfiqSig && !FFLAG)
    722 	{
    723 	  ARMul_Abort (state, ARMul_FIQV);
    724 	  return TRUE;
    725 	}
    726       else if (!state->NirqSig && !IFLAG)
    727 	{
    728 	  ARMul_Abort (state, ARMul_IRQV);
    729 	  return TRUE;
    730 	}
    731     }
    732 
    733   return FALSE;
    734 }
    735 
    736 /* Align a word access to a non word boundary.  */
    737 
    738 ARMword
    739 ARMul_Align (state, address, data)
    740      ARMul_State * state ATTRIBUTE_UNUSED;
    741      ARMword address;
    742      ARMword data;
    743 {
    744   /* This code assumes the address is really unaligned,
    745      as a shift by 32 is undefined in C.  */
    746 
    747   address = (address & 3) << 3;	/* Get the word address.  */
    748   return ((data >> address) | (data << (32 - address)));	/* rot right */
    749 }
    750 
    751 /* This routine is used to call another routine after a certain number of
    752    cycles have been executed. The first parameter is the number of cycles
    753    delay before the function is called, the second argument is a pointer
    754    to the function. A delay of zero doesn't work, just call the function.  */
    755 
    756 void
    757 ARMul_ScheduleEvent (ARMul_State * state, unsigned long delay,
    758 		     unsigned (*what) (ARMul_State *))
    759 {
    760   unsigned long when;
    761   struct EventNode *event;
    762 
    763   if (state->EventSet++ == 0)
    764     state->Now = ARMul_Time (state);
    765   when = (state->Now + delay) % EVENTLISTSIZE;
    766   event = (struct EventNode *) malloc (sizeof (struct EventNode));
    767   event->func = what;
    768   event->next = *(state->EventPtr + when);
    769   *(state->EventPtr + when) = event;
    770 }
    771 
    772 /* This routine is called at the beginning of
    773    every cycle, to envoke scheduled events.  */
    774 
    775 void
    776 ARMul_EnvokeEvent (ARMul_State * state)
    777 {
    778   static unsigned long then;
    779 
    780   then = state->Now;
    781   state->Now = ARMul_Time (state) % EVENTLISTSIZE;
    782   if (then < state->Now)
    783     /* Schedule events.  */
    784     EnvokeList (state, then, state->Now);
    785   else if (then > state->Now)
    786     {
    787       /* Need to wrap around the list.  */
    788       EnvokeList (state, then, EVENTLISTSIZE - 1L);
    789       EnvokeList (state, 0L, state->Now);
    790     }
    791 }
    792 
    793 /* Envokes all the entries in a range.  */
    794 
    795 static void
    796 EnvokeList (ARMul_State * state, unsigned long from, unsigned long to)
    797 {
    798   for (; from <= to; from++)
    799     {
    800       struct EventNode *anevent;
    801 
    802       anevent = *(state->EventPtr + from);
    803       while (anevent)
    804 	{
    805 	  (anevent->func) (state);
    806 	  state->EventSet--;
    807 	  anevent = anevent->next;
    808 	}
    809       *(state->EventPtr + from) = NULL;
    810     }
    811 }
    812 
    813 /* This routine is returns the number of clock ticks since the last reset.  */
    814 
    815 unsigned long
    816 ARMul_Time (ARMul_State * state)
    817 {
    818   return (state->NumScycles + state->NumNcycles +
    819 	  state->NumIcycles + state->NumCcycles + state->NumFcycles);
    820 }
    821