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 3 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, see <http://www.gnu.org/licenses/>. */
16
17/* This must come before any other includes.  */
18#include "defs.h"
19
20#include "armdefs.h"
21#include "armemu.h"
22#include "ansidecl.h"
23#include "libiberty.h"
24#include <math.h>
25
26/* Definitions for the support routines.  */
27
28static ARMword ModeToBank (ARMword);
29static void    EnvokeList (ARMul_State *, unsigned long, unsigned long);
30
31struct EventNode
32{					/* An event list node.  */
33  unsigned (*func) (ARMul_State *);	/* The function to call.  */
34  struct EventNode *next;
35};
36
37/* This routine returns the value of a register from a mode.  */
38
39ARMword
40ARMul_GetReg (ARMul_State * state, unsigned mode, unsigned reg)
41{
42  mode &= MODEBITS;
43  if (mode != state->Mode)
44    return (state->RegBank[ModeToBank ((ARMword) mode)][reg]);
45  else
46    return (state->Reg[reg]);
47}
48
49/* This routine sets the value of a register for a mode.  */
50
51void
52ARMul_SetReg (ARMul_State * state, unsigned mode, unsigned reg, ARMword value)
53{
54  mode &= MODEBITS;
55  if (mode != state->Mode)
56    state->RegBank[ModeToBank ((ARMword) mode)][reg] = value;
57  else
58    state->Reg[reg] = value;
59}
60
61/* This routine returns the value of the PC, mode independently.  */
62
63ARMword
64ARMul_GetPC (ARMul_State * state)
65{
66  if (state->Mode > SVC26MODE)
67    return state->Reg[15];
68  else
69    return R15PC;
70}
71
72/* This routine returns the value of the PC, mode independently.  */
73
74ARMword
75ARMul_GetNextPC (ARMul_State * state)
76{
77  if (state->Mode > SVC26MODE)
78    return state->Reg[15] + isize;
79  else
80    return (state->Reg[15] + isize) & R15PCBITS;
81}
82
83/* This routine sets the value of the PC.  */
84
85void
86ARMul_SetPC (ARMul_State * state, ARMword value)
87{
88  if (ARMul_MODE32BIT)
89    state->Reg[15] = value & PCBITS;
90  else
91    state->Reg[15] = R15CCINTMODE | (value & R15PCBITS);
92  FLUSHPIPE;
93}
94
95/* This routine returns the value of register 15, mode independently.  */
96
97ARMword
98ARMul_GetR15 (ARMul_State * state)
99{
100  if (state->Mode > SVC26MODE)
101    return (state->Reg[15]);
102  else
103    return (R15PC | ECC | ER15INT | EMODE);
104}
105
106/* This routine sets the value of Register 15.  */
107
108void
109ARMul_SetR15 (ARMul_State * state, ARMword value)
110{
111  if (ARMul_MODE32BIT)
112    state->Reg[15] = value & PCBITS;
113  else
114    {
115      state->Reg[15] = value;
116      ARMul_R15Altered (state);
117    }
118  FLUSHPIPE;
119}
120
121/* This routine returns the value of the CPSR.  */
122
123ARMword
124ARMul_GetCPSR (ARMul_State * state)
125{
126  return (CPSR | state->Cpsr);
127}
128
129/* This routine sets the value of the CPSR.  */
130
131void
132ARMul_SetCPSR (ARMul_State * state, ARMword value)
133{
134  state->Cpsr = value;
135  ARMul_CPSRAltered (state);
136}
137
138/* This routine does all the nasty bits involved in a write to the CPSR,
139   including updating the register bank, given a MSR instruction.  */
140
141void
142ARMul_FixCPSR (ARMul_State * state, ARMword instr, ARMword rhs)
143{
144  state->Cpsr = ARMul_GetCPSR (state);
145
146  if (state->Mode != USER26MODE
147      && state->Mode != USER32MODE)
148    {
149      /* In user mode, only write flags.  */
150      if (BIT (16))
151	SETPSR_C (state->Cpsr, rhs);
152      if (BIT (17))
153	SETPSR_X (state->Cpsr, rhs);
154      if (BIT (18))
155	SETPSR_S (state->Cpsr, rhs);
156    }
157  if (BIT (19))
158    SETPSR_F (state->Cpsr, rhs);
159  ARMul_CPSRAltered (state);
160}
161
162/* Get an SPSR from the specified mode.  */
163
164ARMword
165ARMul_GetSPSR (ARMul_State * state, ARMword mode)
166{
167  ARMword bank = ModeToBank (mode & MODEBITS);
168
169  if (! BANK_CAN_ACCESS_SPSR (bank))
170    return ARMul_GetCPSR (state);
171
172  return state->Spsr[bank];
173}
174
175/* This routine does a write to an SPSR.  */
176
177void
178ARMul_SetSPSR (ARMul_State * state, ARMword mode, ARMword value)
179{
180  ARMword bank = ModeToBank (mode & MODEBITS);
181
182  if (BANK_CAN_ACCESS_SPSR (bank))
183    state->Spsr[bank] = value;
184}
185
186/* This routine does a write to the current SPSR, given an MSR instruction.  */
187
188void
189ARMul_FixSPSR (ARMul_State * state, ARMword instr, ARMword rhs)
190{
191  if (BANK_CAN_ACCESS_SPSR (state->Bank))
192    {
193      if (BIT (16))
194	SETPSR_C (state->Spsr[state->Bank], rhs);
195      if (BIT (17))
196	SETPSR_X (state->Spsr[state->Bank], rhs);
197      if (BIT (18))
198	SETPSR_S (state->Spsr[state->Bank], rhs);
199      if (BIT (19))
200	SETPSR_F (state->Spsr[state->Bank], rhs);
201    }
202}
203
204/* This routine updates the state of the emulator after the Cpsr has been
205   changed.  Both the processor flags and register bank are updated.  */
206
207void
208ARMul_CPSRAltered (ARMul_State * state)
209{
210  ARMword oldmode;
211
212  if (state->prog32Sig == LOW)
213    state->Cpsr &= (CCBITS | INTBITS | R15MODEBITS);
214
215  oldmode = state->Mode;
216
217  if (state->Mode != (state->Cpsr & MODEBITS))
218    {
219      state->Mode =
220	ARMul_SwitchMode (state, state->Mode, state->Cpsr & MODEBITS);
221
222      state->NtransSig = (state->Mode & 3) ? HIGH : LOW;
223    }
224  state->Cpsr &= ~MODEBITS;
225
226  ASSIGNINT (state->Cpsr & INTBITS);
227  state->Cpsr &= ~INTBITS;
228  ASSIGNN ((state->Cpsr & NBIT) != 0);
229  state->Cpsr &= ~NBIT;
230  ASSIGNZ ((state->Cpsr & ZBIT) != 0);
231  state->Cpsr &= ~ZBIT;
232  ASSIGNC ((state->Cpsr & CBIT) != 0);
233  state->Cpsr &= ~CBIT;
234  ASSIGNV ((state->Cpsr & VBIT) != 0);
235  state->Cpsr &= ~VBIT;
236  ASSIGNS ((state->Cpsr & SBIT) != 0);
237  state->Cpsr &= ~SBIT;
238#ifdef MODET
239  ASSIGNT ((state->Cpsr & TBIT) != 0);
240  state->Cpsr &= ~TBIT;
241#endif
242
243  if (oldmode > SVC26MODE)
244    {
245      if (state->Mode <= SVC26MODE)
246	{
247	  state->Emulate = CHANGEMODE;
248	  state->Reg[15] = ECC | ER15INT | EMODE | R15PC;
249	}
250    }
251  else
252    {
253      if (state->Mode > SVC26MODE)
254	{
255	  state->Emulate = CHANGEMODE;
256	  state->Reg[15] = R15PC;
257	}
258      else
259	state->Reg[15] = ECC | ER15INT | EMODE | R15PC;
260    }
261}
262
263/* This routine updates the state of the emulator after register 15 has
264   been changed.  Both the processor flags and register bank are updated.
265   This routine should only be called from a 26 bit mode.  */
266
267void
268ARMul_R15Altered (ARMul_State * state)
269{
270  if (state->Mode != R15MODE)
271    {
272      state->Mode = ARMul_SwitchMode (state, state->Mode, R15MODE);
273      state->NtransSig = (state->Mode & 3) ? HIGH : LOW;
274    }
275
276  if (state->Mode > SVC26MODE)
277    state->Emulate = CHANGEMODE;
278
279  ASSIGNR15INT (R15INT);
280
281  ASSIGNN ((state->Reg[15] & NBIT) != 0);
282  ASSIGNZ ((state->Reg[15] & ZBIT) != 0);
283  ASSIGNC ((state->Reg[15] & CBIT) != 0);
284  ASSIGNV ((state->Reg[15] & VBIT) != 0);
285}
286
287/* This routine controls the saving and restoring of registers across mode
288   changes.  The regbank matrix is largely unused, only rows 13 and 14 are
289   used across all modes, 8 to 14 are used for FIQ, all others use the USER
290   column.  It's easier this way.  old and new parameter are modes numbers.
291   Notice the side effect of changing the Bank variable.  */
292
293ARMword
294ARMul_SwitchMode (ARMul_State * state, ARMword oldmode, ARMword newmode)
295{
296  unsigned i;
297  ARMword  oldbank;
298  ARMword  newbank;
299
300  oldbank = ModeToBank (oldmode);
301  newbank = state->Bank = ModeToBank (newmode);
302
303  /* Do we really need to do it?  */
304  if (oldbank != newbank)
305    {
306      /* Save away the old registers.  */
307      switch (oldbank)
308	{
309	case USERBANK:
310	case IRQBANK:
311	case SVCBANK:
312	case ABORTBANK:
313	case UNDEFBANK:
314	  if (newbank == FIQBANK)
315	    for (i = 8; i < 13; i++)
316	      state->RegBank[USERBANK][i] = state->Reg[i];
317	  state->RegBank[oldbank][13] = state->Reg[13];
318	  state->RegBank[oldbank][14] = state->Reg[14];
319	  break;
320	case FIQBANK:
321	  for (i = 8; i < 15; i++)
322	    state->RegBank[FIQBANK][i] = state->Reg[i];
323	  break;
324	case DUMMYBANK:
325	  for (i = 8; i < 15; i++)
326	    state->RegBank[DUMMYBANK][i] = 0;
327	  break;
328	default:
329	  abort ();
330	}
331
332      /* Restore the new registers.  */
333      switch (newbank)
334	{
335	case USERBANK:
336	case IRQBANK:
337	case SVCBANK:
338	case ABORTBANK:
339	case UNDEFBANK:
340	  if (oldbank == FIQBANK)
341	    for (i = 8; i < 13; i++)
342	      state->Reg[i] = state->RegBank[USERBANK][i];
343	  state->Reg[13] = state->RegBank[newbank][13];
344	  state->Reg[14] = state->RegBank[newbank][14];
345	  break;
346	case FIQBANK:
347	  for (i = 8; i < 15; i++)
348	    state->Reg[i] = state->RegBank[FIQBANK][i];
349	  break;
350	case DUMMYBANK:
351	  for (i = 8; i < 15; i++)
352	    state->Reg[i] = 0;
353	  break;
354	default:
355	  abort ();
356	}
357    }
358
359  return newmode;
360}
361
362/* Given a processor mode, this routine returns the
363   register bank that will be accessed in that mode.  */
364
365static ARMword
366ModeToBank (ARMword mode)
367{
368  static ARMword bankofmode[] =
369  {
370    USERBANK,  FIQBANK,   IRQBANK,   SVCBANK,
371    DUMMYBANK, DUMMYBANK, DUMMYBANK, DUMMYBANK,
372    DUMMYBANK, DUMMYBANK, DUMMYBANK, DUMMYBANK,
373    DUMMYBANK, DUMMYBANK, DUMMYBANK, DUMMYBANK,
374    USERBANK,  FIQBANK,   IRQBANK,   SVCBANK,
375    DUMMYBANK, DUMMYBANK, DUMMYBANK, ABORTBANK,
376    DUMMYBANK, DUMMYBANK, DUMMYBANK, UNDEFBANK,
377    DUMMYBANK, DUMMYBANK, DUMMYBANK, SYSTEMBANK
378  };
379
380  if (mode >= ARRAY_SIZE (bankofmode))
381    return DUMMYBANK;
382
383  return bankofmode[mode];
384}
385
386/* Returns the register number of the nth register in a reg list.  */
387
388unsigned
389ARMul_NthReg (ARMword instr, unsigned number)
390{
391  unsigned bit, upto;
392
393  for (bit = 0, upto = 0; upto <= number; bit ++)
394    if (BIT (bit))
395      upto ++;
396
397  return (bit - 1);
398}
399
400/* Assigns the N and Z flags depending on the value of result.  */
401
402void
403ARMul_NegZero (ARMul_State * state, ARMword result)
404{
405  if (NEG (result))
406    {
407      SETN;
408      CLEARZ;
409    }
410  else if (result == 0)
411    {
412      CLEARN;
413      SETZ;
414    }
415  else
416    {
417      CLEARN;
418      CLEARZ;
419    }
420}
421
422/* Compute whether an addition of A and B, giving RESULT, overflowed.  */
423
424int
425AddOverflow (ARMword a, ARMword b, ARMword result)
426{
427  return ((NEG (a) && NEG (b) && POS (result))
428	  || (POS (a) && POS (b) && NEG (result)));
429}
430
431/* Compute whether a subtraction of A and B, giving RESULT, overflowed.  */
432
433int
434SubOverflow (ARMword a, ARMword b, ARMword result)
435{
436  return ((NEG (a) && POS (b) && POS (result))
437	  || (POS (a) && NEG (b) && NEG (result)));
438}
439
440/* Assigns the C flag after an addition of a and b to give result.  */
441
442void
443ARMul_AddCarry (ARMul_State * state, ARMword a, ARMword b, ARMword result)
444{
445  ASSIGNC ((NEG (a) && NEG (b)) ||
446	   (NEG (a) && POS (result)) || (NEG (b) && POS (result)));
447}
448
449/* Assigns the V flag after an addition of a and b to give result.  */
450
451void
452ARMul_AddOverflow (ARMul_State * state, ARMword a, ARMword b, ARMword result)
453{
454  ASSIGNV (AddOverflow (a, b, result));
455}
456
457/* Assigns the C flag after an subtraction of a and b to give result.  */
458
459void
460ARMul_SubCarry (ARMul_State * state, ARMword a, ARMword b, ARMword result)
461{
462  ASSIGNC ((NEG (a) && POS (b)) ||
463	   (NEG (a) && POS (result)) || (POS (b) && POS (result)));
464}
465
466/* Assigns the V flag after an subtraction of a and b to give result.  */
467
468void
469ARMul_SubOverflow (ARMul_State * state, ARMword a, ARMword b, ARMword result)
470{
471  ASSIGNV (SubOverflow (a, b, result));
472}
473
474static void
475handle_VFP_xfer (ARMul_State * state, ARMword instr)
476{
477  if (TOPBITS (28) == NV)
478    {
479      fprintf (stderr, "SIM: UNDEFINED VFP instruction\n");
480      return;
481    }
482
483  if (BITS (25, 27) != 0x6)
484    {
485      fprintf (stderr, "SIM: ISE: VFP handler called incorrectly\n");
486      return;
487    }
488
489  switch (BITS (20, 24))
490    {
491    case 0x04:
492    case 0x05:
493      {
494	/* VMOV double precision to/from two ARM registers.  */
495	int vm  = BITS (0, 3);
496	int rt1 = BITS (12, 15);
497	int rt2 = BITS (16, 19);
498
499	/* FIXME: UNPREDICTABLE if rt1 == 15 or rt2 == 15.  */
500	if (BIT (20))
501	  {
502	    /* Transfer to ARM.  */
503	    /* FIXME: UPPREDICTABLE if rt1 == rt2.  */
504	    state->Reg[rt1] = VFP_dword (vm) & 0xffffffff;
505	    state->Reg[rt2] = VFP_dword (vm) >> 32;
506	  }
507	else
508	  {
509	    VFP_dword (vm) = state->Reg[rt2];
510	    VFP_dword (vm) <<= 32;
511	    VFP_dword (vm) |= (state->Reg[rt1] & 0xffffffff);
512	  }
513	return;
514      }
515
516    case 0x08:
517    case 0x0A:
518    case 0x0C:
519    case 0x0E:
520      {
521	/* VSTM with PUW=011 or PUW=010.  */
522	int n = BITS (16, 19);
523	int imm8 = BITS (0, 7);
524
525	ARMword address = state->Reg[n];
526	if (BIT (21))
527	  state->Reg[n] = address + (imm8 << 2);
528
529	if (BIT (8))
530	  {
531	    int src = (BIT (22) << 4) | BITS (12, 15);
532	    imm8 >>= 1;
533	    while (imm8--)
534	      {
535		if (state->bigendSig)
536		  {
537		    ARMul_StoreWordN (state, address, VFP_dword (src) >> 32);
538		    ARMul_StoreWordN (state, address + 4, VFP_dword (src));
539		  }
540		else
541		  {
542		    ARMul_StoreWordN (state, address, VFP_dword (src));
543		    ARMul_StoreWordN (state, address + 4, VFP_dword (src) >> 32);
544		  }
545		address += 8;
546		src += 1;
547	      }
548	  }
549	else
550	  {
551	    int src = (BITS (12, 15) << 1) | BIT (22);
552	    while (imm8--)
553	      {
554		ARMul_StoreWordN (state, address, VFP_uword (src));
555		address += 4;
556		src += 1;
557	      }
558	  }
559      }
560      return;
561
562    case 0x10:
563    case 0x14:
564    case 0x18:
565    case 0x1C:
566      {
567	/* VSTR */
568	ARMword imm32 = BITS (0, 7) << 2;
569	int base = state->Reg[LHSReg];
570	ARMword address;
571	int dest;
572
573	if (LHSReg == 15)
574	  base = (base + 3) & ~3;
575
576	address = base + (BIT (23) ? imm32 : - imm32);
577
578	if (CPNum == 10)
579	  {
580	    dest = (DESTReg << 1) + BIT (22);
581
582	    ARMul_StoreWordN (state, address, VFP_uword (dest));
583	  }
584	else
585	  {
586	    dest = (BIT (22) << 4) + DESTReg;
587
588	    if (state->bigendSig)
589	      {
590		ARMul_StoreWordN (state, address, VFP_dword (dest) >> 32);
591		ARMul_StoreWordN (state, address + 4, VFP_dword (dest));
592	      }
593	    else
594	      {
595		ARMul_StoreWordN (state, address, VFP_dword (dest));
596		ARMul_StoreWordN (state, address + 4, VFP_dword (dest) >> 32);
597	      }
598	  }
599      }
600      return;
601
602    case 0x12:
603    case 0x16:
604      if (BITS (16, 19) == 13)
605	{
606	  /* VPUSH */
607	  ARMword address = state->Reg[13] - (BITS (0, 7) << 2);
608	  state->Reg[13] = address;
609
610	  if (BIT (8))
611	    {
612	      int dreg = (BIT (22) << 4) | BITS (12, 15);
613	      int num  = BITS (0, 7) >> 1;
614	      while (num--)
615		{
616		  if (state->bigendSig)
617		    {
618		      ARMul_StoreWordN (state, address, VFP_dword (dreg) >> 32);
619		      ARMul_StoreWordN (state, address + 4, VFP_dword (dreg));
620		    }
621		  else
622		    {
623		      ARMul_StoreWordN (state, address, VFP_dword (dreg));
624		      ARMul_StoreWordN (state, address + 4, VFP_dword (dreg) >> 32);
625		    }
626		  address += 8;
627		  dreg += 1;
628		}
629	    }
630	  else
631	    {
632	      int sreg = (BITS (12, 15) << 1) | BIT (22);
633	      int num  = BITS (0, 7);
634	      while (num--)
635		{
636		  ARMul_StoreWordN (state, address, VFP_uword (sreg));
637		  address += 4;
638		  sreg += 1;
639		}
640	    }
641	}
642      else if (BITS (9, 11) != 0x5)
643	break;
644      else
645	{
646	  /* VSTM PUW=101 */
647	  int n = BITS (16, 19);
648	  int imm8 = BITS (0, 7);
649	  ARMword address = state->Reg[n] - (imm8 << 2);
650	  state->Reg[n] = address;
651
652	  if (BIT (8))
653	    {
654	      int src = (BIT (22) << 4) | BITS (12, 15);
655
656	      imm8 >>= 1;
657	      while (imm8--)
658		{
659		  if (state->bigendSig)
660		    {
661		      ARMul_StoreWordN (state, address, VFP_dword (src) >> 32);
662		      ARMul_StoreWordN (state, address + 4, VFP_dword (src));
663		    }
664		  else
665		    {
666		      ARMul_StoreWordN (state, address, VFP_dword (src));
667		      ARMul_StoreWordN (state, address + 4, VFP_dword (src) >> 32);
668		    }
669		  address += 8;
670		  src += 1;
671		}
672	    }
673	  else
674	    {
675	      int src = (BITS (12, 15) << 1) | BIT (22);
676
677	      while (imm8--)
678		{
679		  ARMul_StoreWordN (state, address, VFP_uword (src));
680		  address += 4;
681		  src += 1;
682		}
683	    }
684	}
685      return;
686
687    case 0x13:
688    case 0x17:
689      /* VLDM PUW=101 */
690    case 0x09:
691    case 0x0D:
692      /* VLDM PUW=010 */
693	{
694	  int n = BITS (16, 19);
695	  int imm8 = BITS (0, 7);
696
697	  ARMword address = state->Reg[n];
698	  if (BIT (23) == 0)
699	    address -= imm8 << 2;
700	  if (BIT (21))
701	    state->Reg[n] = BIT (23) ? address + (imm8 << 2) : address;
702
703	  if (BIT (8))
704	    {
705	      int dest = (BIT (22) << 4) | BITS (12, 15);
706	      imm8 >>= 1;
707	      while (imm8--)
708		{
709		  if (state->bigendSig)
710		    {
711		      VFP_dword (dest) = ARMul_LoadWordN (state, address);
712		      VFP_dword (dest) <<= 32;
713		      VFP_dword (dest) |= ARMul_LoadWordN (state, address + 4);
714		    }
715		  else
716		    {
717		      VFP_dword (dest) = ARMul_LoadWordN (state, address + 4);
718		      VFP_dword (dest) <<= 32;
719		      VFP_dword (dest) |= ARMul_LoadWordN (state, address);
720		    }
721
722		  if (trace)
723		    fprintf (stderr, " VFP: VLDM: D%d = %g\n", dest, VFP_dval (dest));
724
725		  address += 8;
726		  dest += 1;
727		}
728	    }
729	  else
730	    {
731	      int dest = (BITS (12, 15) << 1) | BIT (22);
732
733	      while (imm8--)
734		{
735		  VFP_uword (dest) = ARMul_LoadWordN (state, address);
736		  address += 4;
737		  dest += 1;
738		}
739	    }
740	}
741      return;
742
743    case 0x0B:
744    case 0x0F:
745      if (BITS (16, 19) == 13)
746	{
747	  /* VPOP */
748	  ARMword address = state->Reg[13];
749	  state->Reg[13] = address + (BITS (0, 7) << 2);
750
751	  if (BIT (8))
752	    {
753	      int dest = (BIT (22) << 4) | BITS (12, 15);
754	      int num  = BITS (0, 7) >> 1;
755
756	      while (num--)
757		{
758		  if (state->bigendSig)
759		    {
760		      VFP_dword (dest) = ARMul_LoadWordN (state, address);
761		      VFP_dword (dest) <<= 32;
762		      VFP_dword (dest) |= ARMul_LoadWordN (state, address + 4);
763		    }
764		  else
765		    {
766		      VFP_dword (dest) = ARMul_LoadWordN (state, address + 4);
767		      VFP_dword (dest) <<= 32;
768		      VFP_dword (dest) |= ARMul_LoadWordN (state, address);
769		    }
770
771		  if (trace)
772		    fprintf (stderr, " VFP: VPOP: D%d = %g\n", dest, VFP_dval (dest));
773
774		  address += 8;
775		  dest += 1;
776		}
777	    }
778	  else
779	    {
780	      int sreg = (BITS (12, 15) << 1) | BIT (22);
781	      int num  = BITS (0, 7);
782
783	      while (num--)
784		{
785		  VFP_uword (sreg) = ARMul_LoadWordN (state, address);
786		  address += 4;
787		  sreg += 1;
788		}
789	    }
790	}
791      else if (BITS (9, 11) != 0x5)
792	break;
793      else
794	{
795	  /* VLDM PUW=011 */
796	  int n = BITS (16, 19);
797	  int imm8 = BITS (0, 7);
798	  ARMword address = state->Reg[n];
799	  state->Reg[n] += imm8 << 2;
800
801	  if (BIT (8))
802	    {
803	      int dest = (BIT (22) << 4) | BITS (12, 15);
804
805	      imm8 >>= 1;
806	      while (imm8--)
807		{
808		  if (state->bigendSig)
809		    {
810		      VFP_dword (dest) = ARMul_LoadWordN (state, address);
811		      VFP_dword (dest) <<= 32;
812		      VFP_dword (dest) |= ARMul_LoadWordN (state, address + 4);
813		    }
814		  else
815		    {
816		      VFP_dword (dest) = ARMul_LoadWordN (state, address + 4);
817		      VFP_dword (dest) <<= 32;
818		      VFP_dword (dest) |= ARMul_LoadWordN (state, address);
819		    }
820
821		  if (trace)
822		    fprintf (stderr, " VFP: VLDM: D%d = %g\n", dest, VFP_dval (dest));
823
824		  address += 8;
825		  dest += 1;
826		}
827	    }
828	  else
829	    {
830	      int dest = (BITS (12, 15) << 1) | BIT (22);
831	      while (imm8--)
832		{
833		  VFP_uword (dest) = ARMul_LoadWordN (state, address);
834		  address += 4;
835		  dest += 1;
836		}
837	    }
838	}
839      return;
840
841    case 0x11:
842    case 0x15:
843    case 0x19:
844    case 0x1D:
845      {
846	/* VLDR */
847	ARMword imm32 = BITS (0, 7) << 2;
848	int base = state->Reg[LHSReg];
849	ARMword address;
850	int dest;
851
852	if (LHSReg == 15)
853	  base = (base + 3) & ~3;
854
855	address = base + (BIT (23) ? imm32 : - imm32);
856
857	if (CPNum == 10)
858	  {
859	    dest = (DESTReg << 1) + BIT (22);
860
861	    VFP_uword (dest) = ARMul_LoadWordN (state, address);
862	  }
863	else
864	  {
865	    dest = (BIT (22) << 4) + DESTReg;
866
867	    if (state->bigendSig)
868	      {
869		VFP_dword (dest) = ARMul_LoadWordN (state, address);
870		VFP_dword (dest) <<= 32;
871		VFP_dword (dest) |= ARMul_LoadWordN (state, address + 4);
872	      }
873	    else
874	      {
875		VFP_dword (dest) = ARMul_LoadWordN (state, address + 4);
876		VFP_dword (dest) <<= 32;
877		VFP_dword (dest) |= ARMul_LoadWordN (state, address);
878	      }
879
880	    if (trace)
881	      fprintf (stderr, " VFP: VLDR: D%d = %g\n", dest, VFP_dval (dest));
882	  }
883      }
884      return;
885    }
886
887  fprintf (stderr, "SIM: VFP: Unimplemented: %0x\n", BITS (20, 24));
888}
889
890/* This function does the work of generating the addresses used in an
891   LDC instruction.  The code here is always post-indexed, it's up to the
892   caller to get the input address correct and to handle base register
893   modification. It also handles the Busy-Waiting.  */
894
895void
896ARMul_LDC (ARMul_State * state, ARMword instr, ARMword address)
897{
898  unsigned cpab;
899  ARMword data;
900
901  if (CPNum == 10 || CPNum == 11)
902    {
903      handle_VFP_xfer (state, instr);
904      return;
905    }
906
907  UNDEF_LSCPCBaseWb;
908
909  if (! CP_ACCESS_ALLOWED (state, CPNum))
910    {
911      ARMul_UndefInstr (state, instr);
912      return;
913    }
914
915  if (ADDREXCEPT (address))
916    INTERNALABORT (address);
917
918  cpab = (state->LDC[CPNum]) (state, ARMul_FIRST, instr, 0);
919  while (cpab == ARMul_BUSY)
920    {
921      ARMul_Icycles (state, 1, 0);
922
923      if (IntPending (state))
924	{
925	  cpab = (state->LDC[CPNum]) (state, ARMul_INTERRUPT, instr, 0);
926	  return;
927	}
928      else
929	cpab = (state->LDC[CPNum]) (state, ARMul_BUSY, instr, 0);
930    }
931  if (cpab == ARMul_CANT)
932    {
933      CPTAKEABORT;
934      return;
935    }
936
937  cpab = (state->LDC[CPNum]) (state, ARMul_TRANSFER, instr, 0);
938  data = ARMul_LoadWordN (state, address);
939  BUSUSEDINCPCN;
940
941  if (BIT (21))
942    LSBase = state->Base;
943  cpab = (state->LDC[CPNum]) (state, ARMul_DATA, instr, data);
944
945  while (cpab == ARMul_INC)
946    {
947      address += 4;
948      data = ARMul_LoadWordN (state, address);
949      cpab = (state->LDC[CPNum]) (state, ARMul_DATA, instr, data);
950    }
951
952  if (state->abortSig || state->Aborted)
953    TAKEABORT;
954}
955
956/* This function does the work of generating the addresses used in an
957   STC instruction.  The code here is always post-indexed, it's up to the
958   caller to get the input address correct and to handle base register
959   modification. It also handles the Busy-Waiting.  */
960
961void
962ARMul_STC (ARMul_State * state, ARMword instr, ARMword address)
963{
964  unsigned cpab;
965  ARMword data;
966
967  if (CPNum == 10 || CPNum == 11)
968    {
969      handle_VFP_xfer (state, instr);
970      return;
971    }
972
973  UNDEF_LSCPCBaseWb;
974
975  if (! CP_ACCESS_ALLOWED (state, CPNum))
976    {
977      ARMul_UndefInstr (state, instr);
978      return;
979    }
980
981  if (ADDREXCEPT (address) || VECTORACCESS (address))
982    INTERNALABORT (address);
983
984  cpab = (state->STC[CPNum]) (state, ARMul_FIRST, instr, &data);
985  while (cpab == ARMul_BUSY)
986    {
987      ARMul_Icycles (state, 1, 0);
988      if (IntPending (state))
989	{
990	  cpab = (state->STC[CPNum]) (state, ARMul_INTERRUPT, instr, 0);
991	  return;
992	}
993      else
994	cpab = (state->STC[CPNum]) (state, ARMul_BUSY, instr, &data);
995    }
996
997  if (cpab == ARMul_CANT)
998    {
999      CPTAKEABORT;
1000      return;
1001    }
1002#ifndef MODE32
1003  if (ADDREXCEPT (address) || VECTORACCESS (address))
1004    INTERNALABORT (address);
1005#endif
1006  BUSUSEDINCPCN;
1007  if (BIT (21))
1008    LSBase = state->Base;
1009  cpab = (state->STC[CPNum]) (state, ARMul_DATA, instr, &data);
1010  ARMul_StoreWordN (state, address, data);
1011
1012  while (cpab == ARMul_INC)
1013    {
1014      address += 4;
1015      cpab = (state->STC[CPNum]) (state, ARMul_DATA, instr, &data);
1016      ARMul_StoreWordN (state, address, data);
1017    }
1018
1019  if (state->abortSig || state->Aborted)
1020    TAKEABORT;
1021}
1022
1023/* This function does the Busy-Waiting for an MCR instruction.  */
1024
1025void
1026ARMul_MCR (ARMul_State * state, ARMword instr, ARMword source)
1027{
1028  unsigned cpab;
1029
1030  if (! CP_ACCESS_ALLOWED (state, CPNum))
1031    {
1032      ARMul_UndefInstr (state, instr);
1033      return;
1034    }
1035
1036  cpab = (state->MCR[CPNum]) (state, ARMul_FIRST, instr, source);
1037
1038  while (cpab == ARMul_BUSY)
1039    {
1040      ARMul_Icycles (state, 1, 0);
1041
1042      if (IntPending (state))
1043	{
1044	  cpab = (state->MCR[CPNum]) (state, ARMul_INTERRUPT, instr, 0);
1045	  return;
1046	}
1047      else
1048	cpab = (state->MCR[CPNum]) (state, ARMul_BUSY, instr, source);
1049    }
1050
1051  if (cpab == ARMul_CANT)
1052    ARMul_Abort (state, ARMul_UndefinedInstrV);
1053  else
1054    {
1055      BUSUSEDINCPCN;
1056      ARMul_Ccycles (state, 1, 0);
1057    }
1058}
1059
1060/* This function does the Busy-Waiting for an MRC instruction.  */
1061
1062ARMword
1063ARMul_MRC (ARMul_State * state, ARMword instr)
1064{
1065  unsigned cpab;
1066  ARMword result = 0;
1067
1068  if (! CP_ACCESS_ALLOWED (state, CPNum))
1069    {
1070      ARMul_UndefInstr (state, instr);
1071      return result;
1072    }
1073
1074  cpab = (state->MRC[CPNum]) (state, ARMul_FIRST, instr, &result);
1075  while (cpab == ARMul_BUSY)
1076    {
1077      ARMul_Icycles (state, 1, 0);
1078      if (IntPending (state))
1079	{
1080	  cpab = (state->MRC[CPNum]) (state, ARMul_INTERRUPT, instr, 0);
1081	  return (0);
1082	}
1083      else
1084	cpab = (state->MRC[CPNum]) (state, ARMul_BUSY, instr, &result);
1085    }
1086  if (cpab == ARMul_CANT)
1087    {
1088      ARMul_Abort (state, ARMul_UndefinedInstrV);
1089      /* Parent will destroy the flags otherwise.  */
1090      result = ECC;
1091    }
1092  else
1093    {
1094      BUSUSEDINCPCN;
1095      ARMul_Ccycles (state, 1, 0);
1096      ARMul_Icycles (state, 1, 0);
1097    }
1098
1099  return result;
1100}
1101
1102static void
1103handle_VFP_op (ARMul_State * state, ARMword instr)
1104{
1105  int dest;
1106  int srcN;
1107  int srcM;
1108
1109  if (BITS (9, 11) != 0x5 || BIT (4) != 0)
1110    {
1111      fprintf (stderr, "SIM: VFP: Unimplemented: Float op: %08x\n", BITS (0,31));
1112      return;
1113    }
1114
1115  if (BIT (8))
1116    {
1117      dest = BITS(12,15) + (BIT (22) << 4);
1118      srcN = LHSReg  + (BIT (7) << 4);
1119      srcM = BITS (0,3) + (BIT (5) << 4);
1120    }
1121  else
1122    {
1123      dest = (BITS(12,15) << 1) + BIT (22);
1124      srcN = (LHSReg << 1) + BIT (7);
1125      srcM = (BITS (0,3) << 1) + BIT (5);
1126    }
1127
1128  switch (BITS (20, 27))
1129    {
1130    case 0xE0:
1131    case 0xE4:
1132      /* VMLA VMLS */
1133      if (BIT (8))
1134	{
1135	  ARMdval val = VFP_dval (srcN) * VFP_dval (srcM);
1136
1137	  if (BIT (6))
1138	    {
1139	      if (trace)
1140		fprintf (stderr, " VFP: VMLS: %g = %g - %g * %g\n",
1141			 VFP_dval (dest) - val,
1142			 VFP_dval (dest), VFP_dval (srcN), VFP_dval (srcM));
1143	      VFP_dval (dest) -= val;
1144	    }
1145	  else
1146	    {
1147	      if (trace)
1148		fprintf (stderr, " VFP: VMLA: %g = %g + %g * %g\n",
1149			 VFP_dval (dest) + val,
1150			 VFP_dval (dest), VFP_dval (srcN), VFP_dval (srcM));
1151	      VFP_dval (dest) += val;
1152	    }
1153	}
1154      else
1155	{
1156	  ARMfval val = VFP_fval (srcN) * VFP_fval (srcM);
1157
1158	  if (BIT (6))
1159	    {
1160	      if (trace)
1161		fprintf (stderr, " VFP: VMLS: %g = %g - %g * %g\n",
1162			 VFP_fval (dest) - val,
1163			 VFP_fval (dest), VFP_fval (srcN), VFP_fval (srcM));
1164	      VFP_fval (dest) -= val;
1165	    }
1166	  else
1167	    {
1168	      if (trace)
1169		fprintf (stderr, " VFP: VMLA: %g = %g + %g * %g\n",
1170			 VFP_fval (dest) + val,
1171			 VFP_fval (dest), VFP_fval (srcN), VFP_fval (srcM));
1172	      VFP_fval (dest) += val;
1173	    }
1174	}
1175      return;
1176
1177    case 0xE1:
1178    case 0xE5:
1179      if (BIT (8))
1180	{
1181	  ARMdval product = VFP_dval (srcN) * VFP_dval (srcM);
1182
1183	  if (BIT (6))
1184	    {
1185	      /* VNMLA */
1186	      if (trace)
1187		fprintf (stderr, " VFP: VNMLA: %g = -(%g + (%g * %g))\n",
1188			 -(VFP_dval (dest) + product),
1189			 VFP_dval (dest), VFP_dval (srcN), VFP_dval (srcM));
1190	      VFP_dval (dest) = -(product + VFP_dval (dest));
1191	    }
1192	  else
1193	    {
1194	      /* VNMLS */
1195	      if (trace)
1196		fprintf (stderr, " VFP: VNMLS: %g = -(%g + (%g * %g))\n",
1197			 -(VFP_dval (dest) + product),
1198			 VFP_dval (dest), VFP_dval (srcN), VFP_dval (srcM));
1199	      VFP_dval (dest) = product - VFP_dval (dest);
1200	    }
1201	}
1202      else
1203	{
1204	  ARMfval product = VFP_fval (srcN) * VFP_fval (srcM);
1205
1206	  if (BIT (6))
1207	    /* VNMLA */
1208	    VFP_fval (dest) = -(product + VFP_fval (dest));
1209	  else
1210	    /* VNMLS */
1211	    VFP_fval (dest) = product - VFP_fval (dest);
1212	}
1213      return;
1214
1215    case 0xE2:
1216    case 0xE6:
1217      if (BIT (8))
1218	{
1219	  ARMdval product = VFP_dval (srcN) * VFP_dval (srcM);
1220
1221	  if (BIT (6))
1222	    {
1223	      if (trace)
1224		fprintf (stderr, " VFP: VMUL: %g = %g * %g\n",
1225			 - product, VFP_dval (srcN), VFP_dval (srcM));
1226	      /* VNMUL */
1227	      VFP_dval (dest) = - product;
1228	    }
1229	  else
1230	    {
1231	      if (trace)
1232		fprintf (stderr, " VFP: VMUL: %g = %g * %g\n",
1233			 product, VFP_dval (srcN), VFP_dval (srcM));
1234	      /* VMUL */
1235	      VFP_dval (dest) = product;
1236	    }
1237	}
1238      else
1239	{
1240	  ARMfval product = VFP_fval (srcN) * VFP_fval (srcM);
1241
1242	  if (BIT (6))
1243	    {
1244	      if (trace)
1245		fprintf (stderr, " VFP: VNMUL: %g = %g * %g\n",
1246			 - product, VFP_fval (srcN), VFP_fval (srcM));
1247
1248	      VFP_fval (dest) = - product;
1249	    }
1250	  else
1251	    {
1252	      if (trace)
1253		fprintf (stderr, " VFP: VMUL: %g = %g * %g\n",
1254			 product, VFP_fval (srcN), VFP_fval (srcM));
1255
1256	      VFP_fval (dest) = product;
1257	    }
1258	}
1259      return;
1260
1261    case 0xE3:
1262    case 0xE7:
1263      if (BIT (6) == 0)
1264	{
1265	  /* VADD */
1266	  if (BIT(8))
1267	    {
1268	      if (trace)
1269		fprintf (stderr, " VFP: VADD %g = %g + %g\n",
1270			 VFP_dval (srcN) + VFP_dval (srcM),
1271			 VFP_dval (srcN),
1272			 VFP_dval (srcM));
1273	      VFP_dval (dest) = VFP_dval (srcN) + VFP_dval (srcM);
1274	    }
1275	  else
1276	    VFP_fval (dest) = VFP_fval (srcN) + VFP_fval (srcM);
1277
1278	}
1279      else
1280	{
1281	  /* VSUB */
1282	  if (BIT(8))
1283	    {
1284	      if (trace)
1285		fprintf (stderr, " VFP: VSUB %g = %g - %g\n",
1286			 VFP_dval (srcN) - VFP_dval (srcM),
1287			 VFP_dval (srcN),
1288			 VFP_dval (srcM));
1289	      VFP_dval (dest) = VFP_dval (srcN) - VFP_dval (srcM);
1290	    }
1291	  else
1292	    VFP_fval (dest) = VFP_fval (srcN) - VFP_fval (srcM);
1293	}
1294      return;
1295
1296    case 0xE8:
1297    case 0xEC:
1298      if (BIT (6) == 1)
1299	break;
1300
1301      /* VDIV */
1302      if (BIT (8))
1303	{
1304	  ARMdval res = VFP_dval (srcN) / VFP_dval (srcM);
1305	  if (trace)
1306	    fprintf (stderr, " VFP: VDIV (64bit): %g = %g / %g\n",
1307		     res, VFP_dval (srcN), VFP_dval (srcM));
1308	  VFP_dval (dest) = res;
1309	}
1310      else
1311	{
1312	  if (trace)
1313	    fprintf (stderr, " VFP: VDIV: %g = %g / %g\n",
1314		     VFP_fval (srcN) / VFP_fval (srcM),
1315		     VFP_fval (srcN), VFP_fval (srcM));
1316
1317	  VFP_fval (dest) = VFP_fval (srcN) / VFP_fval (srcM);
1318	}
1319      return;
1320
1321    case 0xEB:
1322    case 0xEF:
1323      if (BIT (6) != 1)
1324	break;
1325
1326      switch (BITS (16, 19))
1327	{
1328	case 0x0:
1329	  if (BIT (7) == 0)
1330	    {
1331	      if (BIT (8))
1332		{
1333		  /* VMOV.F64 <Dd>, <Dm>.  */
1334		  VFP_dval (dest) = VFP_dval (srcM);
1335		  if (trace)
1336		    fprintf (stderr, " VFP: VMOV d%d, d%d: %g\n", dest, srcM, VFP_dval (srcM));
1337		}
1338	      else
1339		{
1340		  /* VMOV.F32 <Sd>, <Sm>.  */
1341		  VFP_fval (dest) = VFP_fval (srcM);
1342		  if (trace)
1343		    fprintf (stderr, " VFP: VMOV s%d, s%d: %g\n", dest, srcM, VFP_fval (srcM));
1344		}
1345	    }
1346	  else
1347	    {
1348	      /* VABS */
1349	      if (BIT (8))
1350		{
1351		  ARMdval src = VFP_dval (srcM);
1352
1353		  VFP_dval (dest) = fabs (src);
1354		  if (trace)
1355		    fprintf (stderr, " VFP: VABS (%g) = %g\n", src, VFP_dval (dest));
1356		}
1357	      else
1358		{
1359		  ARMfval src = VFP_fval (srcM);
1360
1361		  VFP_fval (dest) = fabsf (src);
1362		  if (trace)
1363		    fprintf (stderr, " VFP: VABS (%g) = %g\n", src, VFP_fval (dest));
1364		}
1365	    }
1366	  return;
1367
1368	case 0x1:
1369	  if (BIT (7) == 0)
1370	    {
1371	      /* VNEG */
1372	      if (BIT (8))
1373		VFP_dval (dest) = - VFP_dval (srcM);
1374	      else
1375		VFP_fval (dest) = - VFP_fval (srcM);
1376	    }
1377	  else
1378	    {
1379	      /* VSQRT */
1380	      if (BIT (8))
1381		{
1382		  if (trace)
1383		    fprintf (stderr, " VFP: %g = root(%g)\n",
1384			     sqrt (VFP_dval (srcM)), VFP_dval (srcM));
1385
1386		  VFP_dval (dest) = sqrt (VFP_dval (srcM));
1387		}
1388	      else
1389		{
1390		  if (trace)
1391		    fprintf (stderr, " VFP: %g = root(%g)\n",
1392			     sqrtf (VFP_fval (srcM)), VFP_fval (srcM));
1393
1394		  VFP_fval (dest) = sqrtf (VFP_fval (srcM));
1395		}
1396	    }
1397	  return;
1398
1399	case 0x4:
1400	case 0x5:
1401	  /* VCMP, VCMPE */
1402	  if (BIT(8))
1403	    {
1404	      ARMdval res = VFP_dval (dest);
1405
1406	      if (BIT (16) == 0)
1407		{
1408		  ARMdval src = VFP_dval (srcM);
1409
1410		  if (isinf (res) && isinf (src))
1411		    {
1412		      if (res > 0.0 && src > 0.0)
1413			res = 0.0;
1414		      else if (res < 0.0 && src < 0.0)
1415			res = 0.0;
1416		      /* else leave res alone.   */
1417		    }
1418		  else
1419		    res -= src;
1420		}
1421
1422	      /* FIXME: Add handling of signalling NaNs and the E bit.  */
1423
1424	      state->FPSCR &= 0x0FFFFFFF;
1425	      if (res < 0.0)
1426		state->FPSCR |= NBIT;
1427	      else
1428		state->FPSCR |= CBIT;
1429	      if (res == 0.0)
1430		state->FPSCR |= ZBIT;
1431	      if (isnan (res))
1432		state->FPSCR |= VBIT;
1433
1434	      if (trace)
1435		fprintf (stderr, " VFP: VCMP (64bit) %g vs %g res %g, flags: %c%c%c%c\n",
1436			 VFP_dval (dest), BIT (16) ? 0.0 : VFP_dval (srcM), res,
1437			 state->FPSCR & NBIT ? 'N' : '-',
1438			 state->FPSCR & ZBIT ? 'Z' : '-',
1439			 state->FPSCR & CBIT ? 'C' : '-',
1440			 state->FPSCR & VBIT ? 'V' : '-');
1441	    }
1442	  else
1443	    {
1444	      ARMfval res = VFP_fval (dest);
1445
1446	      if (BIT (16) == 0)
1447		{
1448		  ARMfval src = VFP_fval (srcM);
1449
1450		  if (isinf (res) && isinf (src))
1451		    {
1452		      if (res > 0.0 && src > 0.0)
1453			res = 0.0;
1454		      else if (res < 0.0 && src < 0.0)
1455			res = 0.0;
1456		      /* else leave res alone.   */
1457		    }
1458		  else
1459		    res -= src;
1460		}
1461
1462	      /* FIXME: Add handling of signalling NaNs and the E bit.  */
1463
1464	      state->FPSCR &= 0x0FFFFFFF;
1465	      if (res < 0.0)
1466		state->FPSCR |= NBIT;
1467	      else
1468		state->FPSCR |= CBIT;
1469	      if (res == 0.0)
1470		state->FPSCR |= ZBIT;
1471	      if (isnan (res))
1472		state->FPSCR |= VBIT;
1473
1474	      if (trace)
1475		fprintf (stderr, " VFP: VCMP (32bit) %g vs %g res %g, flags: %c%c%c%c\n",
1476			 VFP_fval (dest), BIT (16) ? 0.0 : VFP_fval (srcM), res,
1477			 state->FPSCR & NBIT ? 'N' : '-',
1478			 state->FPSCR & ZBIT ? 'Z' : '-',
1479			 state->FPSCR & CBIT ? 'C' : '-',
1480			 state->FPSCR & VBIT ? 'V' : '-');
1481	    }
1482	  return;
1483
1484	case 0x7:
1485	  if (BIT (8))
1486	    {
1487	      dest = (DESTReg << 1) + BIT (22);
1488	      VFP_fval (dest) = VFP_dval (srcM);
1489	    }
1490	  else
1491	    {
1492	      dest = DESTReg + (BIT (22) << 4);
1493	      VFP_dval (dest) = VFP_fval (srcM);
1494	    }
1495	  return;
1496
1497	case 0x8:
1498	case 0xC:
1499	case 0xD:
1500	  /* VCVT integer <-> FP */
1501	  if (BIT (18))
1502	    {
1503	      /* To integer.  */
1504	      if (BIT (8))
1505		{
1506		  dest = (BITS(12,15) << 1) + BIT (22);
1507		  if (BIT (16))
1508		    VFP_sword (dest) = VFP_dval (srcM);
1509		  else
1510		    VFP_uword (dest) = VFP_dval (srcM);
1511		}
1512	      else
1513		{
1514		  if (BIT (16))
1515		    VFP_sword (dest) = VFP_fval (srcM);
1516		  else
1517		    VFP_uword (dest) = VFP_fval (srcM);
1518		}
1519	    }
1520	  else
1521	    {
1522	      /* From integer.  */
1523	      if (BIT (8))
1524		{
1525		  srcM = (BITS (0,3) << 1) + BIT (5);
1526		  if (BIT (7))
1527		    VFP_dval (dest) = VFP_sword (srcM);
1528		  else
1529		    VFP_dval (dest) = VFP_uword (srcM);
1530		}
1531	      else
1532		{
1533		  if (BIT (7))
1534		    VFP_fval (dest) = VFP_sword (srcM);
1535		  else
1536		    VFP_fval (dest) = VFP_uword (srcM);
1537		}
1538	    }
1539	  return;
1540	}
1541
1542      fprintf (stderr, "SIM: VFP: Unimplemented: Float op3: %03x\n", BITS (16,27));
1543      return;
1544    }
1545
1546  fprintf (stderr, "SIM: VFP: Unimplemented: Float op2: %02x\n", BITS (20, 27));
1547  return;
1548}
1549
1550/* This function does the Busy-Waiting for an CDP instruction.  */
1551
1552void
1553ARMul_CDP (ARMul_State * state, ARMword instr)
1554{
1555  unsigned cpab;
1556
1557  if (CPNum == 10 || CPNum == 11)
1558    {
1559      handle_VFP_op (state, instr);
1560      return;
1561    }
1562
1563  if (! CP_ACCESS_ALLOWED (state, CPNum))
1564    {
1565      ARMul_UndefInstr (state, instr);
1566      return;
1567    }
1568
1569  cpab = (state->CDP[CPNum]) (state, ARMul_FIRST, instr);
1570  while (cpab == ARMul_BUSY)
1571    {
1572      ARMul_Icycles (state, 1, 0);
1573      if (IntPending (state))
1574	{
1575	  cpab = (state->CDP[CPNum]) (state, ARMul_INTERRUPT, instr);
1576	  return;
1577	}
1578      else
1579	cpab = (state->CDP[CPNum]) (state, ARMul_BUSY, instr);
1580    }
1581  if (cpab == ARMul_CANT)
1582    ARMul_Abort (state, ARMul_UndefinedInstrV);
1583  else
1584    BUSUSEDN;
1585}
1586
1587/* This function handles Undefined instructions, as CP isntruction.  */
1588
1589void
1590ARMul_UndefInstr (ARMul_State * state, ARMword instr ATTRIBUTE_UNUSED)
1591{
1592  ARMul_Abort (state, ARMul_UndefinedInstrV);
1593}
1594
1595/* Return TRUE if an interrupt is pending, FALSE otherwise.  */
1596
1597unsigned
1598IntPending (ARMul_State * state)
1599{
1600  if (state->Exception)
1601    {
1602      /* Any exceptions.  */
1603      if (state->NresetSig == LOW)
1604	{
1605	  ARMul_Abort (state, ARMul_ResetV);
1606	  return TRUE;
1607	}
1608      else if (!state->NfiqSig && !FFLAG)
1609	{
1610	  ARMul_Abort (state, ARMul_FIQV);
1611	  return TRUE;
1612	}
1613      else if (!state->NirqSig && !IFLAG)
1614	{
1615	  ARMul_Abort (state, ARMul_IRQV);
1616	  return TRUE;
1617	}
1618    }
1619
1620  return FALSE;
1621}
1622
1623/* Align a word access to a non word boundary.  */
1624
1625ARMword
1626ARMul_Align (ARMul_State *state ATTRIBUTE_UNUSED, ARMword address, ARMword data)
1627{
1628  /* This code assumes the address is really unaligned,
1629     as a shift by 32 is undefined in C.  */
1630
1631  address = (address & 3) << 3;	/* Get the word address.  */
1632  return ((data >> address) | (data << (32 - address)));	/* rot right */
1633}
1634
1635/* This routine is used to call another routine after a certain number of
1636   cycles have been executed. The first parameter is the number of cycles
1637   delay before the function is called, the second argument is a pointer
1638   to the function. A delay of zero doesn't work, just call the function.  */
1639
1640void
1641ARMul_ScheduleEvent (ARMul_State * state, unsigned long delay,
1642		     unsigned (*what) (ARMul_State *))
1643{
1644  unsigned long when;
1645  struct EventNode *event;
1646
1647  if (state->EventSet++ == 0)
1648    state->Now = ARMul_Time (state);
1649  when = (state->Now + delay) % EVENTLISTSIZE;
1650  event = (struct EventNode *) malloc (sizeof (struct EventNode));
1651  event->func = what;
1652  event->next = *(state->EventPtr + when);
1653  *(state->EventPtr + when) = event;
1654}
1655
1656/* This routine is called at the beginning of
1657   every cycle, to envoke scheduled events.  */
1658
1659void
1660ARMul_EnvokeEvent (ARMul_State * state)
1661{
1662  static unsigned long then;
1663
1664  then = state->Now;
1665  state->Now = ARMul_Time (state) % EVENTLISTSIZE;
1666  if (then < state->Now)
1667    /* Schedule events.  */
1668    EnvokeList (state, then, state->Now);
1669  else if (then > state->Now)
1670    {
1671      /* Need to wrap around the list.  */
1672      EnvokeList (state, then, EVENTLISTSIZE - 1L);
1673      EnvokeList (state, 0L, state->Now);
1674    }
1675}
1676
1677/* Envokes all the entries in a range.  */
1678
1679static void
1680EnvokeList (ARMul_State * state, unsigned long from, unsigned long to)
1681{
1682  for (; from <= to; from++)
1683    {
1684      struct EventNode *anevent;
1685
1686      anevent = *(state->EventPtr + from);
1687      while (anevent)
1688	{
1689	  (anevent->func) (state);
1690	  state->EventSet--;
1691	  anevent = anevent->next;
1692	}
1693      *(state->EventPtr + from) = NULL;
1694    }
1695}
1696
1697/* This routine is returns the number of clock ticks since the last reset.  */
1698
1699unsigned long
1700ARMul_Time (ARMul_State * state)
1701{
1702  return (state->NumScycles + state->NumNcycles +
1703	  state->NumIcycles + state->NumCcycles + state->NumFcycles);
1704}
1705