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