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