Home | History | Annotate | Line # | Download | only in arm
      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 
     28 static ARMword ModeToBank (ARMword);
     29 static void    EnvokeList (ARMul_State *, unsigned long, unsigned long);
     30 
     31 struct 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 
     39 ARMword
     40 ARMul_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 
     51 void
     52 ARMul_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 
     63 ARMword
     64 ARMul_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 
     74 ARMword
     75 ARMul_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 
     85 void
     86 ARMul_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 
     97 ARMword
     98 ARMul_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 
    108 void
    109 ARMul_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 
    123 ARMword
    124 ARMul_GetCPSR (ARMul_State * state)
    125 {
    126   return (CPSR | state->Cpsr);
    127 }
    128 
    129 /* This routine sets the value of the CPSR.  */
    130 
    131 void
    132 ARMul_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 
    141 void
    142 ARMul_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 
    164 ARMword
    165 ARMul_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 
    177 void
    178 ARMul_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 
    188 void
    189 ARMul_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 
    207 void
    208 ARMul_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 
    267 void
    268 ARMul_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 
    293 ARMword
    294 ARMul_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 
    365 static ARMword
    366 ModeToBank (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 
    388 unsigned
    389 ARMul_NthReg (ARMword instr, unsigned number)
    390 {
    391   unsigned bit, up_to;
    392 
    393   for (bit = 0, up_to = 0; up_to <= number; bit ++)
    394     if (BIT (bit))
    395       up_to ++;
    396 
    397   return (bit - 1);
    398 }
    399 
    400 /* Assigns the N and Z flags depending on the value of result.  */
    401 
    402 void
    403 ARMul_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 
    424 int
    425 AddOverflow (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 
    433 int
    434 SubOverflow (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 
    442 void
    443 ARMul_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 
    451 void
    452 ARMul_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 
    459 void
    460 ARMul_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 
    468 void
    469 ARMul_SubOverflow (ARMul_State * state, ARMword a, ARMword b, ARMword result)
    470 {
    471   ASSIGNV (SubOverflow (a, b, result));
    472 }
    473 
    474 static void
    475 handle_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 
    895 void
    896 ARMul_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 
    961 void
    962 ARMul_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 
   1025 void
   1026 ARMul_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 
   1062 ARMword
   1063 ARMul_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 
   1102 static void
   1103 handle_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 
   1552 void
   1553 ARMul_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 
   1589 void
   1590 ARMul_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 
   1597 unsigned
   1598 IntPending (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 
   1625 ARMword
   1626 ARMul_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 
   1640 void
   1641 ARMul_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 
   1659 void
   1660 ARMul_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 
   1679 static void
   1680 EnvokeList (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 
   1699 unsigned long
   1700 ARMul_Time (ARMul_State * state)
   1701 {
   1702   return (state->NumScycles + state->NumNcycles +
   1703 	  state->NumIcycles + state->NumCcycles + state->NumFcycles);
   1704 }
   1705