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