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