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