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